* Add `set --function`
This makes the function's scope available, even inside of blocks. Outside of blocks it's the toplevel local scope.
This removes the need to declare variables locally before use, and will probably end up being the main way variables get set.
E.g.:
```fish
set -l thing
if condition
set thing one
else
set thing two
end
```
could be written as
```fish
if condition
set -f thing one
else
set -f thing two
end
```
Note: Many scripts shipped with fish use workarounds like `and`/`or`
instead of `if`, so it isn't easy to find good examples.
Also, if there isn't an else-branch in that above, just with
```fish
if condition
set -f thing one
end
```
that means something different from setting it before! Now, if
`condition` isn't true, it would use a global (or universal) variable of
te same name!
Some more interesting parts:
Because it *is* a local scope, setting a variable `-f` and
`-l` in the toplevel of a function ends up the same:
```fish
function foo2
set -l foo bar
set -f foo baz # modifies the *same* variable!
end
```
but setting it locally inside a block creates a new local variable
that shadows the function-scoped variable:
```fish
function foo3
set -f foo bar
begin
set -l foo banana
# $foo is banana
end
# $foo is bar again
end
```
This is how local variables already work. "Local" is actually "block-scoped".
Also `set --show` will only show the closest local scope, so it won't
show a shadowed function-level variable. Again, this is how local
variables already work, and could be done as a separate change.
As a fun tidbit, functions with --no-scope-shadowing can now use this to set variables in the calling function. That's probably okay given that it's already an escape hatch (but to be clear: if it turns out to problematic I reserve the right to remove it).
Fixes#565
Currently, if a "return" is given outside of a function, we'd just
throw an error.
That always struck me as a bit weird, given that scripts can also
return a value.
So simply let "return" outside also exit the script, kinda like "exit"
does.
However, unlike "exit" it doesn't quit an interactive shell - it seems
weird to have "return" do that as well. It sets $status, so it can be
used to quickly set that, in case you want to test something.
For builtins that have the same name as common commands, it might not
be entirely obvious that there is another page.
So, for those builtins, we add a note, but only in the man pages.
(exception is true and false because the note would be longer than the
page, and it's fridging true and false)
Fixes#8077.
`fish_config theme`:
- `list` to list all available themes (files in the two theme
directories - either the web_config/themes one or
~/.config/fish/themes!)
- `show` to show select (or all) themes right in the terminal - this
starts another fish that reads the theme file and prints the sample
text, manually colored
- `choose` to load a theme *now*, setting the variables globally
- `save` to load a theme and save the variables universally
- `dump` to write the current theme in .theme format (to stdout)
- `demo` to display the current theme
* string: Allow `collect --no-empty` to avoid empty ellision
Currently we still have that issue where
test -n (thing | string collect)
can return true if `thing` doesn't print anything, because the
collected argument will still be removed.
So, what we do is allow `--no-empty` to be used, in which case we
print one empty argument.
This means
test -n (thing | string collect -n)
can now be safely used.
"no-empty" isn't the best name for this flag, but string's design
really incentivizes reusing names, and it's not *terrible*.
* Switch to `--allow-empty`
`--no-empty` does the exact opposite for `string split` and split0.
Since `-a`/`--allow-empty` already exists, use it.
This introduces two functions to
- toggle a process prefix, used for adding "sudo"
- add a job suffix, used for adding "&| less"
Not sure if they are very useful; we'll see.
Closes#7905
The file is called "config.fish", not "init.fish". We'll call it
"configuration" now.
"Initialization" might be slightly more precise, but in an irritating
way.
Also some wording improvements to the section. In particular we now
mention config.fish *early*, before the whole shebang.
Prior to this change, a function with an on-job-exit event handler must be
added with the pgid of the job. But sometimes the pgid of the job is fish
itself (if job control is disabled) and the previous commit made last_pid
an actual pid from the job, instead of its pgroup.
Switch on-job-exit to accept any pid from the job (except fish itself).
This allows it to be used directly with $last_pid, except that it now
works if job control is off. This is implemented by "resolving" the pid to
the internal job id at the point the event handler is added.
Also switch to passing the last pid of the job, rather than its pgroup.
This aligns better with $last_pid.
It's a bit weird to *have* to fire up a browser to get fish_config to
choose a prompt.
So this adds a `prompt` subcommand to `fish_config`:
- `fish_config prompt list` shows all the available prompt names
- `fish_config prompt show` demos the available sample prompts
- `fish_config prompt choose` sources a prompt
- `fish_config prompt save` makes the choice permanent
A bare `fish_config` or `fish_config browse` opens the web UI.
Part of #3625.
TODO: This shows the right prompt on a new line. Showing it in-line is awkward
to do because we'd have to move it to the right.
This prints a description of the "host". Currently that's
`(chroot:debianchroot) $USER@$hostname`
with the chroot part when needed.
This also switches the default and terlar prompts to use it, the other
prompts have slightly different coloring or logic here.
* math: Make function parentheses optional
It's a bit annoying to use parentheses here because that requires
quoting or escaping.
This allows the parens to be omitted, so
math sin pi
is the same as
math 'sin(pi)'
Function calls have the lowest precedence, so
math sin 2 + 6
is the same as
math 'sin(2 + 6)'
* Add more tests
* Add a note to the docs
* even moar docs
Moar docca
* moar tests
Call me Nikola Testla
Unlike links, these are checked by sphinx and it complains if they
don't match.
Also they have a better chance of doing something useful in outputs
other than html.
After commit 6dd6a57c60, 3 remaining
builtins were affected by uint8_t overflow: `exit`, `return`, and
`functions --query`.
This commit:
- Moves the overflow check from `builtin_set_query` to `builtin_run`.
- Removes a conflicting int -> uint8_t conversion in `builtin_return`.
- Adds tests for the 3 remaining affected builtins.
- Simplifies the wording for the documentation for `set --query`.
- Does not change documentation for `functions --query`, because it does
not state the exit code in its API.
- Updates the CHANGELOG to reflect the change to all builtins.
builtin_set_query returns the number of missing variables. Because the
return value passed to the shell is an 8-bit unsigned integer, if the
number of missing variables is a multiple of 256, it would overflow to 0.
This commit saturates the return value at 255 if there are more than 255
missing variables.
This goes to a separate file because that makes option parsing easier
and allows profiling both at the same time.
The "normal" profile now contains only the profile data of the actual
run, which is much more useful - you can now profile a function by
running
fish -C 'source /path/to/thing' --profile /tmp/thefunction.prof -c 'thefunction'
and won't need to filter out extraneous information.
Currently binding `exit` to a key checks too late that it's exitted,
so it leaves the shell hanging around until the user does an execute
or similar.
As I understand it, the `exit` builtin is supposed to only exit the
current "thread" (once that actually becomes a thing), and the
bindings would probably run in a dedicated one, so the simplest
solution here is to just add an `exit` bind function.
Fixes#7604.
It was always a bit ridiculous that argparse required `X-longflag` if
that "X" short flag was never actually used anywhere.
Since the short letter is for getopt's benefit, we can hack around
this with our old friend: Unicode Private Use Areas.
We have a counter, starting at 0xE000 and going to 0xF8FF, that counts
up for all options that don't have a short flag and provides one. This
gives us up to 6400 long-only options.
6.4K should be enough for everybody.
When building from source, there is a warning:
../doc_src/cmds/string-match.rst:13: WARNING: Inline emphasis
start-string without end-string.
One fix appears to be putting a space after the epmhasized 'n' character,
e.g., `*n* th` instead of `*n*th`.
E.g. if we do `string match -q`, and we find a match, nothing about
the input can change anything, so we quit early.
This is mainly useful for performance, but it also allows `string`
with `-q` to be used with infinite input (e.g. `yes`).
Alternative to #7495.
Currently a bit limited, unfortunately printf's `%a` specifier is
absolutely unreadable.
So we add `hex` and `octal` with `0x` and `0` prefixes respectively,
and also take a number but currently only allow 16 and 8.
The output is truncated to integer, so scale values other than 0 are
invalid and 0 is implied.
The docs mention this may change.
This switch is no longer necessary when only one command is given.
Internally completions are stored separately for each command,
so we only every print one command name per "complete" line anyway.
If the padding is not divisible by the char's width without remainder,
we pad the remainder with spaces, so the total width of the output is correct.
Also add completions, changelog entry, adjust documentation, add examples
with emoji and some tests. Apply some minor style nitpicks and avoid extra
allocations of the input strings.
Technically the equivalence would be something like
string length -q $str
test -n (string join \n -- $str | string collect)
To handle when str has multiple empty strings;
but quoting is easier to remember and enough for most practical purposes.
This reads any additional positional arguments given to `fish -c` into
$argv.
We don't handle the first argument specially (as `$0`) as that's confusing and
doesn't seem very useful.
Fixes#2314.
This allows
bind -k backspace suppress-autosuggestion or backward-delete-char
To remove the suggestion on the first press and then delete
chars.
Note: This requires that we then don't reenable suggestions
immediately afterwards. Currently we don't after deletion.
Fixes#1419.
The person reading this is "you". It's completely okay and sounds
better to address them directly.
When we're talking about OS users or users of fish script the reader
writes, "the user" is still okay.
[ci skip]
The case for symlinked directories being duplicated a lot isn't there,
but there *is* a usecase for adding the symlink rather than the
target, and that's homebrew.
E.g. homebrew installs ruby into /usr/local/Cellar/ruby/2.7.1_2/bin,
and links to it from /usr/local/opt/ruby/bin. If we add the target, we
would miss updates.
Having path entries that point to the same location isn't a big
problem - it's a path lookup, so it takes a teensy bit longer. The
canonicalization is mainly so paths don't end up duplicated via weird
spelling and so relative paths can be used.
Taken from GNU realpath, this one makes realpath not resolve symlinks.
It still makes paths absolute and handles duplicate and trailing
slashes.
(useful in fish_add_path)
Currently, completions have to be specified like
```fish
complete -c foo -l opt
```
while
```fish
complete foo -l opt
```
just complains about there being too many arguments.
That's kinda useless, so we just assume if there is one left-over
argument that it's meant to be the command.
Theoretically we could also use *all* the arguments as commands to
complete, but that seems unlikely to be what the user wants.
(I don't think multi-command completions really happen)
Currently only `complete` will list completions, and it will list all
of them.
That's a bit ridiculous, especially since `complete -c foo` just does nothing.
So just make `complete -c foo` list all the completions for `foo`.
Previously, when a command wasn't found, fish would emit the
"fish_command_not_found" *event*.
This was annoying as it was hard to override (the code ended up
checking for a function called `__fish_command_not_found_handler`
anyway!), the setup was ugly,
and it's useless - there is no use case for multiple command-not-found handlers.
Instead, let's just call a function `fish_command_not_found` if it
exists, or print the default message otherwise.
The event is completely removed, but because a missing event is not an error
(MEISNAE in C++-speak) this isn't an issue.
Note that, for backwards-compatibility, we still keep the default
handler function around even tho the new one is hard-coded in C++.
Also, if we detect a previous handler, the new handler just calls it.
This way, the backwards-compatible way to install a custom handler is:
```fish
function __fish_command_not_found_handler --on-event fish_command_not_found
# do a little dance, make a little love, get down tonight
end
```
and the new hotness is
```fish
function fish_command_not_found
# do the thing
end
```
Fixes#7293.
Now command, jobs, type, abbr, builtin, functions and set take `-q` to
query for existence, but the long option is inconsistent.
The first three use `--quiet`, the latter use `--query`. Add `--query`
to the first three, but keep `--quiet` around.
Fixes#7276.
Instead of informing the bell character (hex 07), the example was using
an escaped \ followed by x07.
$ echo \\x07
\x07
$ echo \x07
$ echo \x07 | od -a
0000000 bel nl
0000002
$
* docs: Use \u instead of \\u
Instead of informing the Unicode character 慡, this example was using an
escaped \ followed by u6161.
$ echo \\u6161
\u6161
$ echo \u6161
慡
Before:
$ string escape --style=var 'a1 b2'\\u6161 | string unescape --style=var
a1 b2\u6161
Now:
$ string escape --style=var 'a1 b2'\u6161 | string unescape --style=var
a1 b2慡
Just as `math "bitand(5,3)"` and `math "bitor(6,2)"`.
These cast to long long before doing their thing,
so they truncate to an integer, producing weird results with floats.
That's to be expected because float representation is *very*
different, and performing bitwise operations on floats feels quite useless.
Fixes#7281.
Was: "parameter expansion takes before expressions are evaluated."
Now: "parameter expansion happens before expressions are evaluated."
I suspect the original intent was to use "takes place," but I see "happens" as less idiomatic and therefore may benefit non-English-native users.
Also return the number of failed files.
I decided to *just* print the filenames (newline-separated because
NULLs are annoying here) to make it easier to deal with.
See #7251.
This was always awkward as fish script, and had problems with
interrupting the autoloading.
Note that we still leave the old function intact to facilitate easier
upgrading for now.
Fixes#7145.
Add a helper function to check if the user is root. This function can be
useful for the prompts for example. Modify the prompts made root checked
to use the function instead. Add also the support of Administrator like
a root user.
Fixes: #7031
There's a terrible number of fishscripts that start with
set path (dirname (status filename))
And that's really just a bit boring.
So let's let it be
set path (status dirname)
* Add an "_" builtin to call into gettext
We already have gettext in C++ (if available), so it seems weird to
fork off a command to start it from script.
This is only for fish's own translations. There's no way to call into
other catalogs, it just translates all arguments separately.
This is faster by a factor of ~1000, which allows us to call
translations much more, especially from scripts.
E.g. making fish_greeting global by default would hurt cost-wise,
given that my fish starts up in 8ms and just calling the current `_`
function takes 2ms, and that would have two calls.
Incidentally, this also makes us rely on a weirdly defined function
less, so it:
Fixes#6804.
* docs: Add `_` docs
Let's see if that filename works out.
* Reword _ docs
This is a function you can either execute once, interactively, or
stick in config.fish, and it will do the right thing.
Some options are included to choose some slightly different behavior,
like setting $PATH directly instead of $fish_user_paths, or moving
already existing components to the front/back instead of ignoring
them, or appending new components instead of prepending them.
The defaults were chosen because they are the most safe, and
especially because they allow it to be idempotent - running it again
and again and again won't change anything, it won't even run the
actual `set` because it skips that if all components are already in.
Fixes#6960.
When we say "the XYZ command/builtin", we should typically include a
link. The exceptions are
- In the documentation for that command - no need to link to ulimit in
the ulimit page
- When we've already linked before - not every thing needs to be
clickable, or clicking it will cause the browser to mark fifty words
as visited. This is roughly what wikipedia does for crosslinks.
[ci skip]
This adds a new readline command self-insert-notfirst, which is
analogous to self-insert, except that it does nothing if the cursor
is at the beginning. This will serve as a higher-performance implementation
for stripping leading spaces on paste.
The default hg prompt is slow on large repositories (hg status takes
2-3 seconds on mozilla-central) which is unacceptable as a default.
Mimick our git prompt: by default, only show the current branch.
If the new variable $fish_prompt_hg_show_informative_status is set,
then use the old behavior.
[ci skip]
This was written before local-exported variables did anything useful.
Passing these vars as local-exports removes the need to define the
validation function with `--no-scope-shadowing` which is quite the
hack.
This is apparently quite slow on large svn repos (like 40 seconds
slow), and we don't have a good thing to display other than the full
file information.
So we'll have to disable it for now.
Fixes#6681.
[ci skip]