This can happen if your filesystem on macOS has xattrs, so the newly
created dirs will also have them and `ls` will print an "@" indicator.
Fixes#11137
(cherry picked from commit 414293521e)
The majority of users will be going straight from 3.7 to 4.0. The 4.0 notes
should reflect this transition, rather than the changes that were only in 4.0b1.
iTerm has a bug where it'll send Option-Left as Left instead of the
proper Alt-Left. This was reported upstream and fixed in
480f059bce
which is contained in the 3.5.12-beta2 tag, so let's assume that fixes
it.
Fixes#11025
(not necessary in 4.1)
parse_util_lineno() returns 1-based line numbers but
parse_util_get_offset_from_line() expects zero based line offsets.
Fixes#11162
(cherry picked from commit afbdb9f268)
Commit 4f536d6a9b (Update commandline state snapshot lazily,
2024-04-13) add an optimization to update the search field only if
necessary. The optimization accidentally prevents us from resetting
the search field.
Fixes#11161
(cherry picked from commit 72f2433120)
Custom formats for --pretty/--format option can only be written in [pretty]
section, thus only this section is searched.
[ja: add ? to the regex]
Closes#11065
(cherry picked from commit dfa77e6c19)
To work around terminal bugs.
The flag "keyboard-protocols" defaults to "on" and enables keyboard protocols,
but can be turned off by setting "no-keyboard-protocols".
This has downsides as a feature flag - if you use multiple terminals and
one of them can't do it you'll have to disable it in all,
but anything else would require us to hook this up to env-dispatch,
and ensure that we turn the protocols *off* when the flag is disabled.
Since this is a temporary inconvenience, this would be okay to ask
zellij and Jetbrains-with-WSL users.
I'm running fish 4.0b1 locally and I tried running `help abbr` and
browsing the docs. I noticed one example which wasn't formatted
correctly.
I'm not too familiar with rst, but based on looking at the file, it
seems that this is how example code should be represented.
(cherry picked from commit d47a4899b4)
alt-{left,right} move in the directory history (like in browsers).
Arrow keys can be inconvenient to reach on some keyboards, so
let's alias this to alt-{b,f}, which already have similar behavior.
(historically the behavior was the same; we're considering changing
that back on some platforms).
This happens to fix alt-{left,right} in Terminal.app (where we had
a workaround for some cases), Ghostty, though that alone should not
be the reason for this change.
Cherry-picked from commit f4503af037.
Closes#11105
Comments by macOS users have shown that, apparently, on that platform
this isn't wanted.
The functions are there for people to use,
but we need more time to figure out if and how we're going to bind
these by default.
For example, we could change these bindings depending on the OS in future.
This reverts most of commit 6af96a81a8.
Fixes#10926
See #11107
This can no longer be overridden, which means we have a broken "test"
target now. Instead, you need to call "make fish_run_tests".
Blergh.
Fixes#11116
(cherry picked from commit 8d6fdfd9de)
To check:
```fish
fish_config theme choose None
set -g fish_pager_color_selected_completion blue
```
Now the selected color will only apply to the parentheses
Missed in 43e2d7b48c (Port pager.cpp)
(cherry picked from commit 6c4d658c15)
The version where a feature became the default is now described inline,
to make it a single source of truth. I could have fixed the other
section where this was described, but this seemed easier.
I also removed a few details that seem no longer relevant.
(cherry picked from commit 064d867873)
This documents some non-argument options for the window and panes
commands. The choice of what to document is somewhat arbitrary,
this commit is biased towards options that I find confusing or
misleading without documentation (is `-a` "all" or "after"?)
and the command that seem more useful to me.
I also didn't cover the options that would be covered by
#10855 (though this PR can be used independently). I'm not
sure how much difference this made, it might not matter at
all.
(cherry picked from commit f241187c4a)
These dynamic completions are exhaustive, but not as well-documented or
as ergonomic as the manual completions. So, any manual completions
should override them.
(cherry picked from commit 183e20cc3a)
For example, `tmux shell<tab>` now completes to `if-shell` and
`run-shell`, though no additional information is provided.
(cherry picked from commit 27e5ed7456)
If you don't care about file paths containing '=' or ':', you can
stop reading now.
In tokens like
env var=/some/path
PATH=/bin:/usr/local/b
file completion starts after the last separator (#2178).
Commit db365b5ef8 (Do not treat \: or \= as file completion anchor,
2024-04-19) allowed to override this behavior by escaping separators,
matching Bash.
Commit e97a4fab71 (Escape : and = in file completions, 2024-04-19)
adds this escaping automatically (also matching Bash).
The automatic escaping can be jarring and confusing, because separators
have basically no special meaning in the tokenizer; the escaping is
purely a hint to the completion engine, and often unnecessary.
For "/path/to/some:file", we compute completions for "file" and for
"/path/to/some:file". Usually the former already matches nothing,
meaning that escaping isn't necessary.
e97a4fab71 refers us to f7dac82ed6 (Escape separators (colon and
equals) to improve completion, 2019-08-23) for the original motivation:
$ ls /sys/bus/acpi/devices/d<tab>
$ ls /sys/bus/acpi/devices/device:
device:00/ device:0a/ …
Before automatic escaping, this scenario would suggest all files from
$PWD in addition to the expected completions shown above.
Since this seems to be mainly about the case where the suffix after
the separator is empty,
Let's remove the automatic escaping and add a heuristic to skip suffix
completions if:
1. the suffix is empty, to specifically address the above case.
2. the whole token completes to at least one appending completion.
This makes sure that "git log -- :!:" still gets completions.
(Not sure about the appending requirement)
This heuristic is probably too conservative; we can relax it later
should we hit this again.
Since this reverts most of e97a4fab71, we address the code clone
pointed out in 421ce13be6 (Fix replacing completions spuriously quoting
~, 2024-12-06). Note that e97a4fab71 quietly fixed completions for
variable overrides with brackets.
a=bracket[
But it did so in a pretty intrusive way, forcing a lot of completions
to become replacing. Let's move this logic to a more appropriate place.
---
Additionally, we could sort every whole-token completion before every
suffix-completion. That would probably improve the situation further,
but by itself it wouldn't address the immediate issue.
Closes#11027
(cherry picked from commit b6c249be0c)
Mainly to make the next commit's diff smaller. Not much functional
change: since file completions never have the DONT_SORT flag set,
these results will be sorted, and there are no data dependencies --
unless we're overflowing the max number of completions. But in that
case the whole-token completions seem more important anyway.
(cherry picked from commit 0cfc95993a)
Commit 798527d79a (completions: fix double evaluation of tokenized
commandline, 2024-01-06) fixed some completions such as the "watchexec"
ones by adding "string escape" here:
set argv (commandline -opc | string escape) (commandline -ct)
This fixed double evaluation when we later call `complete -C"$argv"`.
Unfortunately -- searching for "complete -C" and
"__fish_complete_subcommand" -- it seems like that commit missed some
completions such as sudo. Fix them the same way.
Alternatively, we could defer expansion of those arguments (via
--tokens-raw), since the recursive call to completion will expand
them anyway, and we don't really need to know their value.
But there are (contrived) examples where we do want to expand first,
to correctly figure out where the subcommand starts:
sudo {-u,someuser} make ins
By definition, the tokens returned by `commandline -opc` do not
contain the token at cursor (which we're currently completing).
So the expansion should not hurt us. There is an edge case where
cartesian product expansion would produce too many results, and we
pass on the unexpanded input. In that case the extra escaping is very
unlikely to have negative effects.
Fixes # 11041
Closes # 11067
Co-authored-by: kerty <g.kabakov@inbox.ru>
We capture the process already, and we use argv by reference for the
other cases.
argv can be big, and this reduces allocations and thereby memory usage
and speed.
E.g. `set -l foo **` with 200k matches has 25% reduced memory usage
and ~5% reduced runtime.
Wgetopt needs a ":" at the beginning to turn on this type of error.
I'm not sure why that is now, and we might want to change it (but tbh
wgetopt could do with a replacement anyway).
Fixes#11049
And leave the old behavior under the name "cancel-commandline".
This renames "cancel-commandline-traditional" back to
"cancel-commandline", so the old name triggers the old behavior.
Fixes#10935
Ubuntu Focal calls the package with col "bsdmainutils", which is a
transitional package on newer version of both Debian and Ubuntu.
Closes#11037.
(Adapted from commit 54fef433e9)
This needs to be tested more, it has shown issues in MS conhost,
and potentially others.
Changing strategy after beta isn't the greatest idea.
This reverts commit 4decacb933.
See #10994
I believe this fixes more cases than it breaks. For example
this should fix Termux which seems to be popular among fish
users. Unfortunately I haven't yet managed to test that one.
Cherry-pick of all of
- e49dde87cc (Probe for kitty keyboard protocol support, 2025-01-03)
- 10f1f21a4f (Don't send kitty kbd protocol probe until ECHO is disabled, 2025-01-05)
- dda4371679 (Stop sending CSI 5n when querying for kitty keyboard support, 2025-01-05)
To make it more familiar to vi/vim users.
In all mode, ctrl-k is bind to kill-line.
In Vi visual mode:
* press v or i turn into normal or insert mode respectively.
* press I turn to insert mode and move the cursor to beginning of line.
* because fish doesn't have upcase/locase-selection, and most people reach for
g-U rather than g-u, g-U binds to togglecase-selection temporarily.
(cherry picked from commit f9b79926f1)
The `gcloud` and `gsutil` Google Cloud commands use argcomplete, so integrating them is easy with the `__fish_argcomplete_complete` function.
(cherry picked from commit d842a6560e)
cursor_selection_mode=inclusive means the commandline position is
bounded by the last character. Fix a loop that fails to account
for this.
Fixes d51f669647 (Vi mode: avoid placing cursor beyond last character,
2024-02-14).
This change looks very odd because if the commandline is like
echo foo.
it makes us try to uppercase the trailing period even though that's
not part of word range. Hopefully this is harmless.
Note that there seem to be more issues remaining, for example Vi-mode
paste leaves the cursor in an out-of-bounds odd position.
Fixes#10952Closes#10953
Reported-by: Lzu Tao <taolzu@gmail.com>
(cherry picked from commit 69f0d960cf)
Fixes#10980.
This would, if a commandline was given, still revert to checking
the *real* commandline if it was empty.
Unfortunately, in those cases, it could have found a command and tried
to complete it.
If a commandline is given, that is what needs to be completed.
(note this means this is basically useless in completions that use it
like `sudo` and could just be replaced with `complete -C"$commandline"`)
(cherry picked from commit d5efef1cc5)
These are quite mechanical, but include all the commands (as of tmux
3.5a) in the "Windows and Panes" section of `man tmux`. For these
commands, I included the target-pane/session/client/window flags and the
-F formatstring flags (but not the less generic flags specific to
individual commands).
Nice completion is implemented for those flags where the helper
functions were already implemented previously.
After this, tmux pane<tab> will hopefully be useful.
A few TODOs mention low-hanging fruit for somebody who better
understands fish's `complete` command syntax (or a future me).
Another piece of low-hanging fruit would be completion for all the
target-window flags. This PR merely lists them.
(cherry picked from commit b1064ac3a0)
Before, it unnecessarily stated that there are three `--style` options, when
there are actually four.
I also align the default `--style=script` argument to the beginning of the line
to match the other options visually for easier scanning.
This can be used to get some information on how fish was built - the
version, the build system, the operating system and architecture, the
features.
(cherry picked from commit 6f9ca42a30)
If base directories (e.g. $HOME/.config/fish) need to be created,
create them with mode 0700 (i.e. restricted to the owner).
This both keeps the behavior of old fish versions (e.g. 3.7.1) and is
compliant with the XDG Base Directory Specification.
See: https://specifications.freedesktop.org/basedir-spec/0.8/#referencing
Instead of hardcoded 230px margin.
This also makes the ToC only take up a third of the screen when
narrow, and lets you scroll the rest.
Without, you'd have to scroll past the *entire* ToC, which is awkward
Remaining issue is the search box up top. Since this disables the one
in the sidebar once the window gets too narrow, that one is important,
and it isn't *great*
(cherry picked from commit 9b8793a2df)
It is, as the name implies, unused - it became SIGSYS, which we
already check.
Since it is entirely undefined on some architectures it causes a build
failure there, see discussion in #10633
The libc crate has a bug on BSD where WEXITSTATUS is not an 8-bit
value, causing assertion failures.
Any libc higher than our 0.2.155 would increase our MSRV, see libc
commit 5ddbdc29f (Bump MSRV to 1.71, 2024-01-07), so we want to
woraround this anyway. It's probably not worth using a patched
version of libc since it's just one line.
While at it, tighten some types I guess.
Upstream fix: https://github.com/rust-lang/libc/pull/4213Closes#10919
Cherry-picked from c1b460525c
__fish_cancel_commandline was unused (even before) and has some issues
on multiline commandlines. Make it use the previously active logic.
Closes#10935
Cherry-picked from 5de6f4bb3d
This seems more logical, especially since these need not be mentioned
in the "final" 4.0. When we merge the integration branch back into
master, we can combine changelog additions, so it won't be lost
from master.
* Pass path to install()
It was dirty that it would re-get $HOME there anyway.
* Import wcs2osstring
* Allow installable builds to use a relocatable tree
If you give a path to `--install`, it will install fish into a
relocatable tree there, so
PATH/share/fish contains the datafiles
PATH/bin/fish contains the fish executable
PATH/etc/fish is sysconf
I am absolutely not sold on that last one - the way I always used
sysconfdir is that it is always /etc. This would be easy to fix but
should probably also be fixed for "regular" relocatable builds (no
idea who uses them).
An attempt at #10916
* Move install path into "install/" subdir
* Disable --install harder if not installable
Commit 8bf8b10f68 (Extended & human-friendly keys, 2024-03-30) stopped
ctrl-c from exiting without a motivation. Unfortunately this was
only noticeable on terminals that speak the kitty keyboard protocol,
which is probably no one had noticed so far.
Closes#10928
This reverts commit 27c7578760.
dust generates its own completions (which are shipped in the wrong spot
in the Debian packages, but which are also more up-to-date).
Closes#10922.
The apple-codesign crate has a fairly aggressive MSRV policy, and the
compiler itself still targets 10.12 which is well below the minimum
version of macOS for aarch64. Just use stable.
The version of rclone is set during compilation and could be any crazy string depending on the packager, whether it's a dev build, etc. If it cannot be parsed, let's assume a recent version.
Follows up on cc8fa0f7
This is allowed
time a=b echo 123
but -- due to an oversight in 3de95038b0 (Make "time" a job prefix,
2019-12-21) -- this is not allowed:
not time a=b echo 123
Instead, this one one works:
not a=b time echo 123
which is weird because without the "not" this would run "/bin/time".
It seems wrong that "not" is not like the others. Swap the order
for consistency.
Note that unlike "not", "time" currently needs to come before variable
assignments, so "a=b time true" is disallowed. This matches zsh. POSIX
shells call "/bin/time" here. Since it's ambiguous, erroring out seems
fine. It's weird that we're inconsistent with not here but I guess
"command not" is not expected to have subtly different behavior.
Closes#10890
This was added accidentally in 971d257e67 (Port AST to Rust,
2023-04-02). It does not seem to be causing an observable effect
(although I didn't try hard).
It's pretty annoying that this panics without sphinx, because the
install itself would be *working*.
So instead we tell the user that they need to clean or set
$FISH_BUILD_DOCS if they want to try again.
We get "undefined reference to `__memmove_chk'" when compiling
pcre2 (via pcre2-sys) on newer Ubuntu.
That one is used with higher fortify_source levels, and Ubuntu 24.04
defaults to 3, while my arch system (where I cannot reproduce)
defaults to 2.
The values we would try are:
xterm-256color, xterm, ansi, dumb
This is a pretty useless list, because systems without
"xterm-256color" but with "ansi" basically don't exist,
and it is very likely that the actual terminal is more
xterm-compatible than it is ansi.
So instead we just use our xterm-256color definition, which has a high
likelihood of being basically correct.
This is fairly subtle.
When installable, and we either can't find the version file or it is
outdated, we ask the user to confirm installation (just like `--install`).
We do that only if we are really truly interactive (with a tty!) to
avoid `fish -c` running into problems.
This check could be tightened even more, because currently:
```fish
fish -ic 'echo foo'
```
asks, while
```fish
fish -ic 'echo foo' < /dev/null
```
does not.
`fish -c` will still error out if it can't find the config, but it
will just run if it is out of date.
Unfortunately it does not appear like #[cfg(test)] works for build.rs?
Investigating a better solution, but this is a good idea anyway (or `make
test` would generate man pages via build.rs!)
This is unfortunately necessary, because otherwise it would not rerun
the build script just because you installed sphinx.
Because we use the man pages for --help output, they're pretty
necessary.
To override it, you can set $FISH_BUILD_DOCS=0, like
```fish
FISH_BUILD_DOCS=0 cargo install --path .
```
fish will print messages for some jobs when they exit abnormally, such as
with SIGABRT. If a job exits abnormally inside the prompt, then (prior to
this commit) fish would print the message and re-trigger the prompt, which
could result in an infinite loop. This has existed for a very long time.
Fix it by reaping jobs after running the prompt, and NOT triggering a
redraw based on that reaping. We still print the message but the prompt is
not executed.
Add a test.
Fixes#9796
This built on my test system, might be version differences.
(it's also not enough to make it *work*, but a necessary step)
This reverts commit 6fded249cd.
Commit 29dc30711 (Insert some completions with quotes instead of
backslashes, 2024-04-13) wrongly copmletes
$ cat ~/space
to
$ cat '~/path with spaces'
Today completions can be either replacing or appending. We never quote
(but backslash-escape) appending completions (unless they "append"
to an empty token). We always quote replacing completions. The
assumption in this part of the code is that replacing completions
can be quoted without changing meaning.
This assumption is wrong for tildes. For the backslash-escaping code
path, we take care of this edge case via a special DONT_ESCAPE_TILDES
flag. However that flag does not take effect when using quotes for
escaping. Fix that.
Unfortunately, e97a4fab7 (Escape : and = in file completions,
2024-04-19) introduced a (hopefully temporary) code clone in
escape_separators, which made added an extra step to debugging here.
For x86_64 and cross-compiled for aarch64, manually triggered
It *seems* to work, but I had to explicitly disable gettext for it (which is AFAICT currently non-functional under musl anyway).
Also it will create one .zip containing two .tar.xzs. It is about 8MB, which should be fine, tbh.
When built with the default "installable" feature, the data files (share/) are
included in the fish binary itself.
Run `fish --install` or `fish --install=noconfirm` (for
non-interactive use) to install fish's data files into ~/.local/share/fish/install
To figure out if the data files are out of date, we write the current version
to a file on install, and read it on start.
CMake disables the default features so nothing changes for that, but this allows installing via `cargo install`,
and even making a static binary that you can then just upload and have extract itself.
We set $__fish_help_dir to empty for installable builds, because we do not have
a way to generate html docs (because we need fish_indent for highlighting).
The man pages are found via $__fish_data_dir/man
This now allows:
- Same argument (`random 5 5`)
- Swapped ends (`random 10 2`)
- One possibility (`random 0 5 4`)
This makes it easier to use with numbers generated elsewhere instead
of hard-coded, so you don't need to check as much before running it.
Fixes#10879
We don't really care if the process has a custom handler installed, we
can just set it to default.
The one we check is SIGHUP, which may be given to us via `nohup`.
This saves ~30 syscalls *per process* we spawn, so:
```fish
for f in (seq 1000)
command true
end
```
has ~30000 fewer rt_sigaction calls. These take up about ~30% of the
total time spent in syscalls according to strace.
We could also compute this set once at startup and then reuse it.
We turned it off, but for some reason (cmake version?) that stopped working on my system.
So instead we just remove all the code that does it.
To be honest I do not know why this exists anyway.
exists_no_autoload() wrongly thinks that tombstoned functions can be
autoloaded; fix that.
While at-it replace the use of get_props() with something simpler.
Co-authored-by: Himadri Bhattacharjee
Closes#10873
The [disambiguate flag](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#disambiguate) means that:
> In particular, ctrl+c will no longer generate the SIGINT signal,
> but instead be delivered as a CSI u escape code.
so cancellation only works while we turn off disambiguation.
Today we turn it off while running external commands that want to
claim the TTY. Also we do it (only as a workaround for this issue)
while expanding wildcards or while running builtin wait.
However there are other cases where we don't have a workaround,
like in trivial infinite loops or when opening a fifo.
Before we run "while true; end", we put the terminal back in ICANON
mode. This means it's line-buffered, so we won't be able to detect
if the user pressed ctrl-c.
Commit 8164855b7 (Disable terminal protocols throughout evaluation,
2024-04-02) had the right solution: simply disable terminal protocols
whenever we do computations that might take a long time.
eval_node() covers most of that; there are a few others.
As pointed out in #10494, the logic was fairly unsophisticated then:
it toggled terminal protocols many times. The fix in 29f2da8d1
(Toggle terminal protocols lazily, 2024-05-16) went to the extreme
other end of only toggling protocols when absolutely necessary.
Back out part of that commit by toggling in eval_node() again,
fixing cancellation. Fortunately, we can keep most of the benefits
of the lazy approach from 29f2da8d1: we toggle only 2 times instead
of 8 times for an empty prompt.
There are only two places left where we call signal_check_cancel()
without necessarily disabling the disambiguate flag
1. open_cloexec() we assume that the files we open outside eval_node()
are never blocking fifos.
2. fire_delayed(). Judging by commit history, this check is not
relevant for interactive sessions; we'll soon end up calling
eval_node() anyway.
In future, we can leave bracketed paste, modifyOtherKeys and
application keypad mode turned on again, until we actually run an
external command. We really only want to turn off the disambiguate
flag.
Since this is approach is overly complex, I plan to go with either
of these two alternatives in future:
- extend the kitty keyboard protocol to optionally support VINTR,
VSTOP and friends. Then we can drop most of these changes.
- poll stdin for ctrl-c. This promises a great simplification,
because it implies that terminal ownership (term_steal/term_donate)
will be perfectly synced with us enabling kitty keyboard protocol.
This is because polling requires us to turn off ICANON.
I started working on this change; I'm convinced it must work,
but it's not finished yet. Note that this will also want to
add stdin polling to builtin wait.
Closes#10864
Moving the "make empty ToLowercase iterator" logic to within the
`unwrap_or_else()` instead of always generating it brings most of the speedup;
unrolling the recursive call brings in the rest.
Using `c.is_uppercase()` instead of getting the iterator and checking if the
first (and only) lowercase letter of the sequence is the same as the original
input is 5-8x faster (measured via criterion against `/usr/share/dict/words`).
(Additional benefit of forcibly inlining the now iterator-based comparison not
taken into account; this necessitated changing from a closure to a local
function as the inline attribute on closures is not yet supported with the
stable compiler toolchain.)
This is still suboptimal because we are allocating a vector of indices to be
removed (but allocation-free in the normal case of no duplicates) but
significantly better than the previous version of the code that duplicated the
strings (which are larger and spread out all over the heap).
The ideal code (similar to what we had in the C++ version, iirc) would look like
this, but it's not allowed because the borrow checker hates you:
```
fn unique_in_place_illegal(comps: &mut Vec<Completion>) {
let mut seen = HashSet::with_capacity(comps.len());
let mut idx = 0;
while idx < comps.len() {
if !seen.insert(&comps[idx].completion) {
comps.remove(idx);
continue;
}
idx += 1;
}
}
```
This was an sh-script that just invoked fish again.
I can see how we could implement it in another language to avoid the
fish under test corrupting the results, but it literally invoked the
fish under test anyway.
Mostly we pass on the options - otherwise they would be ignored.
For `clear`, we do need the full checks, because that will
prompt *before* running the builtin.
But this makes it easier to eventually move that logic into the builtin
If a semicolon-delimited list of CSI parameters contained an (invalid) long
sequence of ascii numeric characters, the original code would keep multiplying
by ten and adding the most recent ones field until the `params[count][subcount]`
u32 value overflowed.
This was found via automated fuzz testing of the `try_readch()` routine against
a corpus of some proper/valid CSI escapes.
This lets us call into the entirety of the prior `readch()` with an exhaustible
input stream without panicking on the `unreachable!()` call. The previous
functionality is kept under the old name by calling `try_readch()` with the
`blocking` parameter set to `true` (100% same behavior as before).
While the `try_readch(false)` entrypoint isn't used directly by the current fish
codebase, it is required in order to automate input reader tests without the
overhead and complexity of running the test harness in a tty emulator emulator
like pexpect or tmux, which moreover necessitates out-of-process testing – which
is incompatible with most perf-guided testing harnesses.
I hope to be able to upstream harness integrations using this entry point in the
near future.
These are pretty basic, but get us roughly up to the level of the
official completions (that are also incomplete and offer disabled
options).
Fixes#10858
`print_help` is a hacky-wacky function used to support the `--help` command
of `fish_key_reader` and others. The Rust version panics on an error; fix
that and make it print more useful help messages.
* feat(function): move cmd completion function to a separate file
* feat(completion): support wine cmd subcommand
* feat(completion): support wine control subcommand
* feat(completion): support wine eject subcommand
* feat(completion): support wine explorer subcommand
* feat(completion): support wine explorer subcommand for desktops
* feat(completion): support wine start subcommand
* feat(completion): support wine winemenubuilder subcommand
* feat(completion): support wine winepath subcommand
* fix(function): rename function for cmd argument completion
* feat(function): implement function to complete registry keys
* feat(completion): support wine regedit subcommand
* feat(function): add top-level key descriptions
* fix(completion): remove redundant comment
* feat(completion): support wine msiexec subcommand
* refactor(completion): group code into functions
* feat(completion): enhance subcommand descriptions
I'm guessing this was missed in the port because there were comments referencing
using a hash set to perform the deduplication but there was no hashset. (The
TODO was added later.)
This caught an incorrect description for process/job exit handlers for ANY_PID
(now removed) which has been replaced with a message stating the handler is for
any process exit event.
The previous approach of "treat this field as an `Option<NonZeroU32>` and
remember to check `p.has_pid()` before accessing it" was a mix of C++ and rust
conventions and led to some bugs or incorrect behaviors.
* `jobs -p` would previously print both the (correct) external pid and the
(incorrect) internal value of `0` if a backgrounded command contained a
fish function (e.g. `function foo; end; cat | foo &; jobs`)
* Updating/calculating job cpu time and usage was incorrectly including all of
fish's cpu usage/time for each function/builtin member of the job pipeline.
Closes#10832
ctrl-r ctrl-s ctrl-s
Attemps to go before the beginning and asserts out. Instead refuse to
do that.
(there's some weirdness where it can reduce the pager to the first
entry if you keep pressing, which I haven't found yet, but that's better than *crashing*)
CMake Warning (dev) at cmake/Tests.cmake:56 (add_custom_command):
Exactly one of PRE_BUILD, PRE_LINK, or POST_BUILD must be given. Assuming
POST_BUILD to preserve backward compatibility.
Policy CMP0175 is not set: add_custom_command() rejects invalid arguments.
Run "cmake --help-policy CMP0175" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.
So we just keep it the same.
These are another way to spell the same thing that doesn't match what
`bind` would print.
They're also not documented and tested thoroughly.
Since they are just small shortcuts and unreleased we can just remove
them.
Fixes#10845
This has the side effect of changing the order of completions for a bare `git
diff` to show modified files before revisions; previously they came at the very
end after all revisions, stashes, local branches, remote branches, and tags.
That seems sensible to me?
As I understand the completions file, it seems to me that the intention was for
`git diff src/` to only show modified files to begin with it
previously/currently shows them all, so we might want to add a `-n 'not ...'`
condition for `git diff` to prevent that.
fish by default shows a git-aware prompt. Recall that on macOS, there are
two hazards we must avoid:
1. The command `/usr/bin/git` is installed by default. This command is not
actually git; instead it's a stub which pops open a dialog proposing to
install Xcode command line tools. Not a good experience.
2. Even after installing these tools, the first run of any `git` or other
command may be quite slow, because it's now a stub which invokes `xcrun`
which needs to populate a cache on a fresh boot. Another bad experience.
We previously attempted to fix this by having `xcrun` print out its cache
path and check if there's a file there. This worked because `xcrun` only
lazily created that file. However, this no longer works: `xcrun` now
eagerly creates the file, and only lazily populates it. Thus we think git
is ready, when it is not.
(This can be reproduced by running `xcrun --kill-cache` and then running
the default fish shell prompt - it will be slow).
Change the fix in the following way: using sh, run `/usr/bin/git --version;
touch /tmp/__fish_git_ready` in the background. Then detect the presence of
/tmp/__fish_git_ready as a mark that git is ready.
Fixes#10535
Given "printf %18446744073709551616s", we parse the number only in
the printf crate, which tells us that we overflowed somwhere (but
not where exactly).
We were previously printing the internal `INVALID_PID` value (since removed),
which was a meaningless `-2` constant, when there was no pgid associated with a
job.
This PR changes that to `-` to indicate no pgid available, which I prefer over
something like `0` or `-1`, but will cause problems for code that is hardcoded
to convert this field to an integral value.
Just like we already fix terminal modes if a command left them broken,
having an invisible cursor makes the terminal hard to use and so we
fix it.
We can't really use cnorm/cursor_normal because that often includes
other gunk like making the cursor blink, but it turns out every
terminfo entry agrees on the sequence to make the cursor visible, so
we hardcode it.
Fixes#10834
This is nicer when you use fish over ssh, and that system does not
have a browser. But the system where your terminal is has one, and so
now you can just click the link.
If we end up using this in more places, we can create a `Pid` newtype.
Note that while the constant is no longer used in code, its previous value of -2
is still printed by `jobs` when no pgid is associated with a job. I will open a
PR to change this to something else, likely either `0` or `-`.
If we try to memory map the history file, and we get back ENODEV meaning that
the underlying device does not support memory mapping, then treat that as a hint
that the filesystem is remote and disable history locking.
As of 04c913427 (Limit command line rendering to $LINES lines,
2024-10-25), we only render a part of the command line. This removes
valuable information from scrollback.
The reasons for the limit were
1. to enable redrawing the commandline (can't do that if part of it
is off-screen).
2. if the cursor is at the beginning of the command-line, we can't
really render the off-screen suffix (unless we can tell the terminal
to scroll back after doing that).
Fortunately these don't matter for the very last rendering of a
command line. Let's render the entire command just before executing,
fixing the scrollback for executed commands.
In future, we should fix it also for pre-execution renderings. This
needs a terminal command to clear part of the scrollback. Can't find
anything on https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
There is "Erase Saved Lines" but that deletes the entire scrollback.
See the discussion in #10827
Since f89909ae3 (Also handle overflown screens if editing pager search
field, 2024-10-27), cursor_arr is never None after the loop.
Assert that by unwrapping.
qa.sh
alt-e restores the cursor position received from the editor, moving by
one character at a time. This can be super slow on large commandlines,
even on release builds. Let's fix that by setting the coordinates
directly.
This happens when using alt-e to edit the command buffer,
adding some lines, leaving the cursor at the end
and quitting the editor without saving.
Let's avoid the noisy error that has sort of bad rendering (would
need __fish_echo).
Our recursive create_dir() first calls stat() to check if the directory
already exists and then mkdir() trying to create it. If another (fish)
process creates the same directory after our stat() but before our
mkdir(), then our mkdir() fails with EEXIST. This error is spurious
if there is already a directory at this path (and permissions are
correct).
Let's switch to the stdlib version, which promises to solve this issue.
They currently do it by running mkdir() first and ask stat() later.
This implies that they will only return success even if we don't have
any of rwx permissions on the directory, but that was already a problem
before this change. We silently don't write history in that case..
Fixes#10813
All-whitespace autocompletions are invisible, no matter the cursor
shape. We do offer such autosuggestions after typing a command name
such as "fish". Since the autosuggestion is invisible it's probably
not useful. It also does no harm except when using a binding like
bind ctrl-g '
if commandline --showing-suggestion
commandline -f accept-autosuggestion
else
up-or-search
end'
where typing "fish<ctrl-g>" surprisingly does not perform a history
search. Fix this by detecting this specific case. In future we
could probably stop showing autosuggestions whenever they only
contain whitespace.
With BSD man, "PAGER=vim man man | cat" hangs because
[man](https://cgit.freebsd.org/src/tree/usr.bin/man/man.sh) wrongly
calls the pager even though stdout is not a terminal.
This hang manifests in places where we call apropos in a subshell,
such as in "complete -Ccar".
Let's work around this I guess. This should really be fixed upstream
because it's a problem in every app that wants to display man pages
but doesn't emulate a complete terminal.
Weirdly, the Apple derivative of man.sh uses WHATISPAGER instead
of MANPAGER.
Closes#10820
A release build is recommended to most users (to avoid occasional slowness)
whereas developers may prefer debug builds for shorter build times and more
accurate debug information.
There are more users of "make install" than developers, so I think the
default should be optimized for users, i.e. an optimized build. I think
that's in line with what most of our peer projects do.
Even if developers don't know about the -DCMAKE_BUILD_TYPE=Debug
trick, they will likely be able to iterate quickly by using "cargo
{build,check,clippy,test}" and rust-analyzer, all of which use a debug
configuration by default, irrespective of cmake. Granted, users will need
to use cmake to run system tests. If a task needs a lot of iterations,
one can always convert the system test to a script that can be run with
target/build/fish. For building & running all system tests, the release
build takes 30% longer, so not that much.
Here are my build/test times and binary sizes; with debug:
$ time ninja -C build-Debug/
________________________________________________________
Executed in 25.30 secs fish external
usr time 68.33 secs 676.00 micros 68.32 secs
sys time 11.34 secs 41.00 micros 11.34 secs
$ du -h build-Debug/fish
43M build-Debug/fish
$ time ninja -C build-Debug/ test
________________________________________________________
Executed in 193.96 secs fish external
usr time 182.84 secs 1.53 millis 182.83 secs
sys time 30.97 secs 0.00 millis 30.97 secs
with release
$ time ninja -C build-RelWithDebInfo/
________________________________________________________
Executed in 106.80 secs fish external
usr time 164.98 secs 631.00 micros 164.98 secs
sys time 11.62 secs 41.00 micros 11.62 secs
$ du -h build-RelWithDebInfo/fish
4.6M build-RelWithDebInfo/fish
$ time ninja -C build-RelWithDebInfo/ test
________________________________________________________
Executed in 249.87 secs fish external
usr time 260.25 secs 1.43 millis 260.25 secs
sys time 29.86 secs 0.00 millis 29.86 secs
Tangentially related, the numbers with "lto = true" deleted. This seems
like a nice compromise for a default but I don't know much about the other
benefits of lto.
$ time ninja -C build-RelWithDebInfo-thin-lto/
________________________________________________________
Executed in 35.50 secs fish external
usr time 196.93 secs 0.00 micros 196.93 secs
sys time 13.00 secs 969.00 micros 13.00 secs
$ du -h build-RelWithDebInfo-thin-lto/fish
5.5M build-RelWithDebInfo-thin-lto/fish
$ time ninja -C build-RelWithDebInfo-thin-lto/ test
________________________________________________________
Executed in 178.62 secs fish external
usr time 287.48 secs 976.00 micros 287.48 secs
sys time 28.75 secs 115.00 micros 28.75 secs
Alternative solution: have no default at all, and error out until the user
chooses a build type.
Currently the only difference between RelWithDebInfo and Release is that
the former adds -g (aka debuginfo=2) though it doesn't seem to make a lot
of difference in my testing.
Since build_tools/make_pkg.sh and debian/rules use RelWithDebInfo, let's be
consistent with those.
Some background: fish has some files which should be updated atomically:
specifically the history file and the universal variables file. If two fish
processes modified these in-place at the same time, then that could result
in interleaved writes and corrupted files.
To prevent this, fish uses the write-to-adjacent-file-then-rename to
atomically swap in a new file (history is slightly more complicated than
this, for performance, but this remains true). This avoids corruption.
However if two fish processes attempt this at the same time, then one
process will win the race and the data from the other process will be lost.
To prevent this, fish attempts to take an (advisory) lock on the target
file before beginning this process. This prevents data loss because only
one fish instance can replace the target file at once. (fish checks to
ensure it's locked the right file).
However some filesystems, particularly remote file systems, may have locks
which hang for a long time, preventing the user from using their shell.
This is far more serious than data loss, which is not catastrophic: losing
a history item or variable is not a major deal. So fish just attempts to
skip locks on remote filesystems.
Unfortunately Linux does not have a good API for checking if a filesystem
is remote: the best you can do is check the file system's magic number
against a hard-coded list. Today, the list is NFS_SUPER_MAGIC,
SMB_SUPER_MAGIC, SMB2_MAGIC_NUMBER, and CIFS_MAGIC_NUMBER.
Expand it to AFS_SUPER_MAGIC, CODA_SUPER_MAGIC, NCP_SUPER_MAGIC,
NFS_SUPER_MAGIC, OCFS2_SUPER_MAGIC, SMB_SUPER_MAGIC, SMB2_MAGIC_NUMBER,
CIFS_MAGIC_NUMBER, V9FS_MAGIC which is believed to be exhaustive.
ALSO include FUSE_SUPER_MAGIC: if the user's home directory is some FUSE
filesystem, that's kind of sus and the fewer tricks we try to pull, the
better.
As mentioned in 04c913427 (Limit command line rendering to $LINES
lines, 2024-10-25) our rendering breaks when the command line overflows
the screen and we have a pager search field.
Let's also apply the overflow logic in this case.
Note that the search field still works, it's just not visible.
In future we should maybe show a small search field (~4 lines) in
this case (removing 4 screen lines worth of command line). But again,
this is not really important.
If the first physical line in the command line overflows the screen,
the cursor will be wrong and we'll fail to clear the prompt without
a manual ctrl-l. Let's fix that, and also don't print the OSC 133
marker in this case.
Currently, when we are scrolled, the first line on the screen still
gets an indentation that would normally be filled by the prompt.
This happens even for soft-wrapped lines, so they might be
torn apart in weird ways here.
In future, we might paint the prompt here. If not, the current
behavior for soft-wrapped lines is debatable but its' not super
important to fix. The main goal is to first get rid of glitches in
these edge cases.
This test does "isolated-tmux send-keys Escape" to exit copy mode. When
EDITOR contains "vi", tmux will use Vi keybindings where Escape does
something else ("q" would exit copy mode).
Tests want to have predictable behavior so let's declare the default
emacs key bindings unconditionally.
Fixes#10812
This added link args to target macOS 10.9, but these arguments are not necessary
when building via the make_pkg.sh script, and this file is causing other
problems.
Let's provide a sensible default here. Use a line for "insert" and an
underline for "replace_one" mode. Neovim does the same, it feels pretty
slick.
As mentioned in #10806
As of the parent commit, __fish_vi_key_bindings_remove_handlers
should be working properly now, so this is no longer necessary That
function also cleans up other stuff like fish_cursor_end_mode, that
fish_default_key_bindings doesn't know anything about.
Also this fixes a spurious exit status of 4 in some scenarios.
fish_key_bindings may be set directly
or via fish_{default,vi}_key_bindings.
The latter use "set --no-event" to simplify their control
flow. This (24836f965 (Use set --no-event in the key binding
functions, 2023-01-10)) broke Vi mode cleanup, since Vi mode
uses a variable hook. Let's update this variable also when using
fish_{default,vi}_key_bindings. Another reason to keep this variable
in sync is to make the fish_key_bindings handlers working as expected.
Render the command line buffer only until the last line we can fit
on the screen.
If the cursor pushes the viewport such that neither the prompt nor
the first line of the command line buffer are visible, then we are
"scrolled". In this case we need to make sure to erase any leftover
prompt, so add a hack to disable the "shared_prefix" optimization
that tries to minimize redraws.
Down-arrow scrolls down only when on the last line, and up-arrow always
scrolls up as much as possible. This is somewhat unconventional;
probably we should change the up-arrow behavior but I guess it's a
good idea to show the prompt whenever possible. In future we could
solve that in a different way: we could keep the prompt visible even
if we're scrolled. This would work well because at least the left
prompt lives in a different column from the command line buffer.
However this assumption breaks when the first line in the command
line buffer is soft-wrapped, so keep this approach for now.
Note that we're still broken when complete-and-search or history-pager
try to draw a pager on top of an overfull screen. Will try to fix
this later.
Closes#7296
It's a 9-char CSI and we've read 3 (`<ESC>[T`), so we need to read six more.
Verified against the previous C++ codebase and couldn't find a reason for the
change to consuming 10 chars in a `git blame` run.
Commit ba67d20b7 (Refresh TTY timestamps after nextd/prevd, 2024-10-13)
wasn't quite right because it also needs to fix it for arbitrary commands.
While at it, do this only when needed:
1. It seems to be only relevant for multiline prompts.
Note that we can wait until after evaluation to check if the prompt is
multiline, because repaint events go through the queue, see 5ba21cd29
(Send repaint requests through the input queue again, 2024-04-19).
2. When the binding doesn't execute any external command, we probably don't
need to fix up whatever the user printed. If they actually wanted to show
output and print another prompt, they should currently use "__fish_echo",
to properly support multiline prompts. Bindings should produce no other
output. What distinguishes external programs is that they can trigger this
issue even if they don't produce any output that remains visible in fish,
namely by using the terminal's alternate screen.
Would be nice if we could get rid of __fish_echo; I'm not yet sure how.
Fixes#10800
A side effect of cd9e50c2c (completions/set: Complete variables of all scopes
when setting, 2024-10-03) is that
HOME=$(mktemp -d) fish
fish_config choose ayu\ Light
set -S fish_color_
gives only completions that have the "Universal variable" description even
though most colors are also defined in the global scope which usually takes
precedence.
Fix this by reordering the completions. (The last-added completion is shown
first which is very surprising, we should change that).
This is not perfect; if the user has already specified `-U`, then we should
probably not show description of the global version. But that's still
worth the trade that this commit makes. Finally, the description could show
something like "Defined in universal and global scope" etc.
The test case shows that the pager rendering is not quite right. It renders
'{\', leaving out the newline. This rendering is ambiguous.
Let's fix it by rendering \n as control picture, like we do for other control
characters in the pager.
Given
$ echo {\
C
where C is the cursor.
Completions have prefix "{\\\n".
Since \n has a wcwidth of -1, this line always fails
let prefix_len = usize::try_from(fish_wcswidth(&self.prefix));
This triggers uncovers a regression in 43e2d7b48 (Port pager.cpp, 2023-12-02),
where we end up computing comp_width=0 for all completions.
Fix this. Test in the next commit.
The C++ version added the prefix width only if the completion had a valid
width. That seems wrong, let's do it always (if the prefix width is valid).
Completion on ": {*," used to work but nowadays our attempt to wildcard-expand
it fails with a syntax error and we do nothing. This behavior probably only
makes sense for the overflow case, so do that.
On a German keyboard, with a German keymap, and this ~/.wezterm.lua
local wezterm = require 'wezterm'
local config = wezterm.config_builder()
config.enable_kitty_keyboard = true
return config
when I press shift+# (which is single quote)
WezTerm sends the CSI u encoding shift-'.
Because of this, we completely disable kitty progressive enhancements and
modifyOtherKeys on WezTerm.
It makes no sense for every single app to work around WezTerm violating the
protocol. All these workarounds just create unnecessary version dependencies.
Also our workaround is brittle; it breaks as soon as you're inside something
like SSH.
Least importantly, the workarond prevents users of English keyboard layouts
to easily use the new features.
Since it seems so easy to work around by settting "enable_kitty_keyboard = false",
and most importantly, since that's the default, it seems better to remove
the workaround to simplify the world.
See #10663
This makes the default colorscheme less colorful for two reasons:
1. It makes it a little less "angry fruit salad"
2. Some terminals (like Microsoft's Windows Terminal) have a terrible
blue default that contrasts badly against a black background
The alternative is to make *parameters* "normal" and give commands the
current parameter color (cyan). But I've seen cyan be quite blue and
quite green depending on the terminal, so I don't want to rely on it.
`cargo build --git` clones a git repo without any tags, so you get a
version like
```
fish, version f3fc743fc
```
which is *just* the commit hash and missing the "3.7.1-NUM-g" part.
So, if we hit that case (detected because it has no ".", under the
assumption that we'll never make a version that's just "4" instead of
"4.0"), we prepend the version from Cargo.toml.
Commit 5db0bd5 (Lock history file before reading it, 2024-10-09)
rewrites the history file in place instead of using rename().
By writing to the same file (with the same inode), it corrupts
our memory-mapped snapshot; mmap(3) says:
> It is unspecified whether modifications to the underlying object done
> after the MAP_PRIVATE mapping is established are visible through the
> MAP_PRIVATE mapping.
Revert it (it was misguided anyway).
Closes#10777Closes#10782
There is no natural default binding for token movements. Add the
alt-{left,right,backspace,delete}, breaking some existing behavior.
For example, backward-delete-word is no longer bound to alt-backspace but
only to ctrl-backspace. Unfortunately some terminals (particularly tmux)
don't support distinguishing ctrl-backspace from ctrl-h yet, so the loss
of alt-backspace may be tragic.
---
I guess we could also add:
bind alt-B backward-token
bind alt-F forward-token
bind ctrl-W backward-kill-token
bind alt-D kill-token
Those might be intercepted by the terminal on Linux, but I don't know where
that happens.
Tested on foot, kitty, alacritty, xterm, tmux, konsole and gnome-terminal.
Closes#10766
Commit a91bf6d88 (builtin.c: builtin_source now checks that its argument is
a file., 2005-12-16) fixed an infinite loop for commands like "source /"
where the argument is a directory.
It did so by erroring out early unless the filename argument is a regular file.
This is too restrictive; it disallows reading from special files like /dev/null
and fifos.
Today we get a sensible error without this check, so remove it.
This fixes a macOS-specific bug. See 390b40e02 (Fix regression not refreshing
TTY timestamps after external command from binding, 2024-05-29) and 8a7c3ceec
(Don't abandon line after writing control sequences, 2024-04-06).
Fixes#10779
OSC 133 was added to tmux 3.4.
Also fix the test on macOS where we do have 3.5a in CI; for some reason we
get copy_cursor_y=6 there. I didn't investigate yet but at least that's
not the same bug this test was made to fix.
For multi-line prompts, we start each leading line with a clr_eol. Immediately
before printing these prompt lines we emit the OSC 133 prompt start marker.
Some terminals such as tmux interpret make clr_eol delete such markers,
hence prompt navigation is broken.
Fix this by printing the marker only after clr_eol.
The scenario where this triggers is quite odd. I haven't looked into why
the problem doesn't exist if I remove the recursive repaint request.
See https://github.com/tmux/tmux/issues/4183Closes#10776
Our panic handler attempts a blocking read from stdin and only exits
after the user presses Enter.
This is unconventional behavior and might cause surprise but there is a
significant upside: crashes become more visible for terminals that don't
already detect crashes (see ecdc9ce1d (Install a panic handler to avoid
dropping crash stacktraces, 2024-03-24)).
As reported in 4d0aa2b5d (Fix panic handler, 2024-08-28), the panic handler
failed to exit fish if the panic happens on background threads. It would
only exit the background thread (like autosuggestion/highlight/history-pager
performer) itself. The fix was to abort the whole process.
Aborting has the additional upside of generating a coredump.
However since abort() skips stack unwinding, 4d0aa2b5d makes us no longer
restore the terminal on panic. In particular, if the terminal supports kitty
progressive enhancements, keys like ctrl-p will no longer work in say,
a Bash parent shell. So it broke 121680147 (Use RAII for restoring term
modes, 2024-03-24).
Fix this while still aborting to create coredumps. This means we can't use
RAII (for better or worse). The bad part is that we have to deal with added
complexity; we need to make sure that we set the AT_EXIT handler only after
all its inputs (like TERMINAL_MODE_ON_STARTUP) are initialized to a safe
value, but also before any damage has been done to the terminal. I guess we
can add a bunch of assertions.
Unfortunately, if a background thread panics, I haven't yet figured out how
to tell the main thread to do the blocking read. So the trick of "Press
Enter to exit", which allows users to attach a debugger doesn't yet work for
panics in background threads. We can probably figure that out later. Maybe
use pthread_kill(3)? Of course we still create coredumps, so that's fine.
As a temporary workaround, let's sleep for a bit so the user can at least
see that there is a crash & stacktrace.
One ugly bit here is that unit tests run AT_EXIT twice but it should be
idempotent.
I don't think I really get why this newline is here. It moves the cursor
from the end of the newline to the beginning of the next line. Maybe it
was added only for panics in background threads? Either way it's fine.
We don't care to check the latest value of these variables;
these should only be read on startup and are not meant to
be overridden by the user ever. Hence we don't need a parser.
If SIGTERM is delivered to a background thread, a function call to sanitize
the reader state would crash in assert_is_main_thread(). In this case we
are about to exit so there's no need to fix the reader state. Skip it on
background threads.
Users may install two versions of fish and configure their terminal to run
the one that is second in $PATH. This is not really what I'd do but it
seems reasonable. We should not need $PATH for this.
Fixes#10770
We use optimistic concurrency when rewriting the history file to
minimize the lock scope. Unfortunately, old.mtime == new.mtime
does not imply that file is unchanged; we don't have guarantees
on the granularity of the modification time timestamp, see
https://stackoverflow.com/questions/14392975/timestamp-accuracy-on-ext4-sub-millsecond
So let's lock before reading any old contents and use the other
"write-to-tempfile-and-rename" code path only when locking fails.
Potentially fixes#10300
(untested) which probably happens because read_zero_padded() attempts to
read bytes that have not been flushed yet.
No functional change, since with the parent commit, we no longer treat
"DirRemoteness::local" different from "DirRemoteness::remote", but we might
do so in future, so make sure we don't give a false positive here.
Non-Linux systems have ST_LOCAL or MNT_LOCAL, so no unknowns there.
See #10434
mmap() fails with ENODEV on remote file systems. This means we always fail
to read any old history on network file systems on Linux (except on the file
systems we recognize which are NFS, SMB and CIFS).
Untested, so I'm not sure if this works.
Fixes#10434
We no longer use RAII for enabling/disabling these, so a full object is
overkill. Additionally this object doesn't allow us to recover from the case
where we receive SIGTERM while inside terminal_protocols_{enable,disable}.
We can simply run disable another time since they're idempotent. Untested.
When I run a command with leading space, it is not added to the on-disk
history. However we still call History::save(). After 25 of such calls,
we rewrite the history file (even though nothing was written by us).
This is annoying when diagnosing #10300 where the history of the current
shell (but not other shells) is broken; because the history rewrite will
make the problem go away. Let's not save in this case, to make it easier to
run commands to inspect the state of the history file.
Commit 4e79ec5f tried to restore the static PCRE2 build after the update to the
pcre2 crate, but it set an environment variable at configure time, not build
time.
Properly set the environment variable at build time.
Given a history like
- cmd: echo OLD
when: 1726157160
\x00\x00\x00- cmd: echo leading NUL bytes
when: 1726157160
- cmd: echo NEW
when: 1726157223
offset_of_next_item() happily records 3 items even though the second item
is corrupted.
decode_item() fails which makes the caller stop loading any older items --
we got knee capped.
Avoid this horrible failure mode by skipping over these items already in
offset computation. For now we still lose the corrupted item itself.
In future we should probably try to delete the NUL bytes or avoid the
corruption in the first place.
See #10300 and others.
This should make the sort have a strict weak ordering, which rust
requires since 1.81 (or it will panic).
Note: This changes the order, but that's *fine* since the current
order is random weirdness anyway.
Fixes#10763
This was overly smart and tried to not show you e.g. global variables
unless you were setting without scope or explicitly global.
That is annoying when you do
`set -g fish_col<TAB>`
and don't get colors because they're universal, but you could
overwrite them.
We *could* elide e.g. local variables if we're setting a global, but I
can see someone wanting to set a universal variable on basis of a
global ("save this"), so I would rather not try to find the very
specific cases where this works.
1. Leave the indentation
2. Leave the "NAME" header - without the first line would be
unindented
3. Leave the "SYNOPSIS" header
We use $MANPAGER here, so it should be formatted like a manpage.
The alternative is to write special docs for this use-case, which
would be shorter and point towards the full man page.
Fixes#10625
They are already presented in normal mode, and I presume were forgotten to be
added in visual mode
I don't add it to ./CHANGELOG.rst because it's a minor change that can be
considered as a bug fix
The recent update to the rust-pcre2 crate lost the property where a static
PCRE2 build could be enabled with a Cargo feature. This means that static
PCRE2 builds can no longer be forced.
Switch to setting the "PCRE2_SYS_STATIC" variable again, which is how the
official rust-pcre2 crate expects to work.
Commit c921c124e (docs: use canonical key names in :kbd: tags, 2024-04-13)
removed the box highlighting from elements like :kbd:`ctrl-c`.
This is because Sphinx for some reason converts this into
<kbd>
<kbd>ctrl</kbd>
-
<kbd>c</kbd>
</kbd>
which results in duplicate boxes.
(See https://github.com/sphinx-doc/sphinx/issues/7530)
Our current style looks a bit ugly (it's
definitely worse than github's rendering at
https://github.com/fish-shell/fish-shell/blob/master/CHANGELOG.rst).
Let's restore the old style but make sure to only apply it only to the
outermost kbd element.
While at it, use the same monospace font as for inline code.
Commit b00899179 (Don't indent multi-line quoted strings; do indent inside
(), 2024-04-28) made parse_util_compute_indents() crash on `echo "$()"'x`.
After recursively indenting the command substitution, we indent the "'x
suffix. We skip the quoted part by setting "done=2". Later we wrongly
index "self.indents[done..range.start+offset+1]" (= "self.indents[2..1]").
Fix this by making sure that "start >= done", thus not setting any indents
for the quoted suffix. There is no need to do so; only the first character
in each line needs an indent.
In particular, this fixes the case
ctrl-r foo ctrl-r
where foo substring-matches no more than one page's worth of results.
The second attempt will fall back to subsequence matching which is wrong.
In case a terminal resize[1] causes us
to repaint a multi-line prompt that changes width like
function fish_prompt
for i in 1 2 3
random choice 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbb'
end
end
we add a clr_eol after each line[2] , to make sure
that a "b" line does not have leftover "a" letters
(80aaae5b7 (Clear to end of each line in left prompt, 2020-10-25)).
Unfortunately, if a prompt line takes up all the columns, clr_eol will
wrongly clear the last column. Reproduce with
function fish_prompt
string repeat $COLUMNS -
echo "$PWD> "
end
and observe that the last "-" is missing.
Previous (reverted) attempt d3ceba107 (Clear to eol before outputting line
in multi-line prompt, 2021-05-17) found the right fix but had an off-by-one
error which reintroduced the leftover "a" letters in the "random choice"
prompt above.
Given prompt string "aa\nbb\ncc", it wrongly printed
clr_eol "aa" clr_eol "\nbb" "\ncc"
Observe that the first line is cleared twice, while the second line is
never cleared. Fix that.
[1]: or an async "commandline -f repaint" triggered by a uvar change /
async prompt update
[2]: except after the last line where we probably already emit clr_eol
elsewhere..
Alternative fix: emit both clr_eol and clr_bol *before* drawing the current
line. However, if fish and the terminal disagree on character width, that
approach might erase too much.
Closes#8164
I guess it's nice to know that these two are the same but that info is not
needed here, it just adds confusion. The user must have pressed ctrl-j if
we get here, so echo that back.
See the parent commit.
This is just too confusing; \b sounds like it would map backspace but it's
actually just ctrl-h. Backspace is a different key ("bind backspace"),
so let's move away from \b.
Reproduce by typing ctrl-h in fish_key_reader, or, for even more confusion,
use a terminal like tmux and type ctrl-backspace which also sends ctrl-h.
I've thought about changing \b (and its aliases like \ch and \x08) to mean
backspace but that seems like unnecessary breakage, since they all already
mean ctrl-h, and can usually be mapped independent of backspace.
See the discussion in #10738
Make fish-printf no longer depend on the widestring crate, as other clients
won't use it; instead this is an optional feature.
Make format strings a generic type, so that both narrow and wide strings can
serve. This removes a lot of the complexity around converting from narrow to
wide.
Add a README.md to this crate.
This gave a weird error when you did e.g. `math Foo / 6`:
"Missing Operator" and only the "F" marked.
Adding an operator here anywhere won't help, so calling this an
"Unknown function" is closer to the truth. We also get nicer markings
because we know the extent of the identifier.
Fix 7308dbc7a (fish_indent: Prevent overwriting file with identical content,
2024-07-21) in a different way by passing O_TRUNC again.
If we don't want regressions we could use code review.
When `manpath` prints a symlink to a directory, `/usr/libexec/makewhatis`
ignores the entire directory:
```
$ /usr/libexec/makewhatis -o /tmp/whatis \
(/usr/bin/manpath | string split :)
makewhatis: /Users/wiggles/.nix-profile/share/man: Not a directory
```
This means that the built-in `man` completions will not index any commands in
these directories.
If we pass the directories to `readlink -f` first, `makewhatis` correctly
indexes the `man` pages.
```
$ /usr/libexec/makewhatis -o /tmp/whatis \
(/usr/bin/manpath | string split : | xargs readlink -f)
```
We used deque in C++ because this vector may be large, and so it avoids
repeated re-allocations. But VecDeque is different in Rust - it's contiguous -
so there's no benefit. Just use Vec.
For implementation reasons, we special-case cd in several ways
1. it gets different completions (handle_as_special_cd)
2. when highlighting, we honor CDPATH
3. we discard autosuggestions from history that don't have valid path arguments
There are some third-party tools like zoxide that redefine cd ("function cd
--wraps ...; ...; end"). We can't support this in general but let's try to
make an effort.
zoxide tries to be a superset of cd, so special case 1 is still
valid but 2 and 3 are not, because zoxide accepts some paths
that cd doesn't accept.
Let's add a hack to detect when "cd" actually means something else by checking
if there is any --wraps argument.
A cleaner solution is definitely possible but more effort.
Closes#10719
fish adds ~/.local/share/fish/man to its MANPATH for builtins etc. But pages
like fish-doc are unambiguous so it seems like they should be accessible
from outside fish by default.
Closes#10711
In some cases we add the wildcard twice.
$ fish -c '../jj; complete -C"ls cli/*/conf/tem"'
cli/*/*/config/templates.toml
Fix that. Test in the next commit.
There seems to be another bug in 3.7.1 where we fail to apply this completion
to the command line. This appears fixed. (FWIW we might want to revert
the quoting change in completion_apply_to_command_line(), maybe that one
accidentally fix this).
Fixes#10703
The HashMap is used to generate the __fish_describe_command integration
completions. Given the nature of the allocations and the numbers that we use, a
BTreeMap would theoretically perform better. Benchmarks show a 2-9%
improvement in completion times consistently in favor of BTreeMap.
Warnings were appearing under GCC 13.2
(void) alone is insufficient under modern compilers, workaround with logical
negation taken from GCC bug tracker.
Worth including because mold is rather popular in the rust world and because the
bug affects mold versions coincident with the development of the fish rust port.
The bug affects all currently released versions of mold from 2.30.0 (Mar 2024)
onwards under at least FreeBSD (though quite likely other platforms as well).
See https://github.com/rui314/mold/issues/1338 for reference.
We keep having to extend these with new terminals, and I can no longer
find a terminal that fails this.
Even emacs' ansi-term can now at least reliably ignore the sequence.
- the __fish_seen_any_argument function did not work
- the xxd_exclusive_args specification was not correct
- longer old-style options were missing
- technically short options are also old-style options in xxd
- some options were missing
Static linking against glibc has crashes depending on the name
resolution setup (I think when it needs to dlopen). It is a fundamental glibc
limitation that we cannot fix on our end.
It will crash when doing `echo ~<TAB>`.
This carves out a specific exception for "gnu", i.e. glibc, targets.
Other targets, including musl and other operating systems, continue to
allow static linking.
The previous control flow logic wasn't sound and would leave the shell in a hung
state when `break` would be encountered.
The behavior is now straightforward, the shell reads until <Enter> or <q> is
pressed, at which point it aborts.
This was based on a misunderstanding.
On musl, 64-bit time_t on 32-bit architectures was introduced in version 1.2.0,
by introducing new symbols. The old symbols still exist, to allow programs compiled against older versions
to keep running on 1.2.0+, preserving ABI-compatibility. (see musl commit 38143339646a4ccce8afe298c34467767c899f51)
Programs compiled against 1.2.0+ will get the new symbols, and will therefore think time_t is 64-bit.
Unfortunately, rust's libc crate uses its own definition of these types, and does not check for musl version.
Currently, it includes the pre-1.2.0 32-bit type.
That means:
- If you run on a 32-bit system like i686
- ... and compile against a C-library other than libc
- ... and pass it a time_t-containing struct like timespec or stat
... you need to arrange for that library to be built against musl <1.2.0.
Or, as https://github.com/ericonr/rust-time64 says:
> Therefore, for "old" 32-bit targets (riscv32 is supposed to default to time64),
> any Rust code that interacts with C code built on musl after 1.2.0,
> using types based on time_t (arguably, the main ones are struct timespec and struct stat) in their interface,
> will be completely miscompiled.
However, while fish runs on i686 and compiles against pcre2, we do not pass pcre2 a time_t.
Our only uses of time_t are confined to interactions with libc, in which case with musl we would simply use the legacy ABI.
I have compiled an i686 fish against musl to confirm and can find no issue.
This reverts commit 55196ee2a0.
This reverts commit 4992f88966.
This reverts commit 46c8ba2c9f.
This reverts commit 3a9b4149da.
This reverts commit 5f9e9cbe74.
This reverts commit 338579b78c.
This reverts commit d19e5508d7.
This reverts commit b64045dc18.
Closes#10634
Add kqueue-based uvar notifier for BSD
Tested under FreeBSD 13.3.
This also works under all versions of macOS, and has some
benefits over the current notifyd choice.
Mutex is used because of the non-mut `notification_fd_became_readable()` `&self`
reference, but contention is not expected.
This restores a hack to trigger a command line repaint when "$fish_color_*" or
"$fish_pager_color_*" changes. These allow the command line to react immediately
to changes in other sessions or web_config.
This was removed in ff62d172e5 but there does not
appear to be a handler which actually redraws these.
Revert of ff62d172e5
The generated assembly is more or less the same and the previously generated
version had been manually verified, but this PR removes the usage of
`MaybeUninit::assume_init()` and replaces it with direct pointer writes.
This should result in no observable change: it continues to pass the functional
tests and benchmarks identically. The safety of the new code has been verified
with Miri.
[0]: https://github.com/mqudsi/fish-yaml-unescape-benchmark
- -q silenced warnings in apk 2.x but not in in 3.x, so redirect stderr
to /dev/null to avoid seeing warnings while completing (-q is still
passed to `apk search` as it strips package versions and releases)
- Drop `-q` from `apk info`, as on apk 3.x it prevents apk info from
outputting anything at all
I've tested these changes on both Chimera Linux (which uses apk 3.x)
and Alpine Linux (which is still using 2.x).
This does not work as-is ("CSI a" is shift-up, not up).
I'm not sure if we want to implement these.
It's not a regression so there is no pressure.
This reverts commit 350598cb99.
byte_to_symbol was broken because it didn't iterate by byte, it
iterated by rust-char, which is a codepoint.
So it failed for everything outside of ascii and, because of a
mistaken bound, ascii chars from 0x21 to 0x2F ("!" to "/" - all the punctuation).
char_to_symbol will print printable codepoints as-is and
others escaped. This is okay - something like `decoded from: +` or
`decoded from: ö` is entirely understandable, there is no need to tell
you that "ö" is \xc3\xb6.
This reverts commit 423e5f6c03.
This except clause was too narrow, so it would fail here even on other
systems just because webbrowser.get() returned nothing usable
Now it will fail *later* with "could not locate runnable browser", but
at least it won't say anything about chromeos on non-chromeos systems.
Array starts at 0, goes up to 27, that's 28 entries... *BUT* we also
need the catch-all entry after, so it's 29.
To be honest there's got to be a better way to write this.
WezTerm supports CSI u but unfortunately, typing single quote on a German
keyboard makes WezTerm send what gets decoded as `shift-'`.
This is bad, so disable it until this is fixed. In future we should maybe
add a runtime option to allow the user to override this decision.
See #10663
The \e\e\[A style is bad but iTerm and putty (alt-left) use it.
The main motivation for this change is to improve fish_key_reader output.
Part of #10663
As of rust 1.78, the Unix stdlib implementation is affected by the same issue:
pub fn sleep(dur: Duration) {
let mut secs = dur.as_secs();
let mut nsecs = dur.subsec_nanos() as _;
// If we're awoken with a signal then the return value will be -1 and
// nanosleep will fill in `ts` with the remaining time.
unsafe {
while secs > 0 || nsecs > 0 {
let mut ts = libc::timespec {
tv_sec: cmp::min(libc::time_t::MAX as u64, secs) as libc::time_t,
tv_nsec: nsecs,
};
secs -= ts.tv_sec as u64;
let ts_ptr = core::ptr::addr_of_mut!(ts);
if libc::nanosleep(ts_ptr, ts_ptr) == -1 {
assert_eq!(os::errno(), libc::EINTR);
secs += ts.tv_sec as u64;
nsecs = ts.tv_nsec;
} else {
nsecs = 0;
}
}
}
}
Note that there is a small behavior change here -- sleep() will continue
after signals; I'm not sure if we want that but it seems harmless?
Part of #10634
iTerm2 deviates from protocol, so back out c3c832761 (Stop using stack for
kitty progressive enhancement, 2024-08-03) in that case.
Note that we use several ways of detecting iTerm2 (ITERM_PROFILE,
TERM_PROGRAM=iTerm.app, ITERM_SESSION_ID).
LC_TERMINAL seems superior because it works over ssh.
This new one should hopefully go away eventually.
- Ubuntu focal is the lowest LTS release that we can support with only
distro packages (e.g. no rustup).
- Remove tsan from Cirrus (it's not working currently, and also not really
important).
- Remove Centos (it passes tests but I'm not sure it's worth adding; there
isn't even an official docker image for CentOS Stream).
Today fish pushes/pops kitty progressive enhancements everytime control is
transfered to/from fish. This constitutes a regression relative to 3.7.1:
$ fish
$ ssh somehost fish
(network disconnect, now we missed our chance to pop from the stack)
$ bash # or some ncurses application etc
(keyboard shortcuts like ctrl-p are broken)
When invoking bash, we pop one entry off the stack but there is another one.
There seems to be a simple solution: don't use the stack but always reset
the current set of flags. Do that since I did not find a strong use case
for using the stack[1] (Note that it was recommended by terminal developers
to use the stack, so I might be wrong).
Note that there is still a regression if the outer shell is bash.
[1]: https://github.com/kovidgoyal/kitty/issues/7603#issuecomment-2256949384Closes#10603
According to the discussion in #2315, we adopt TTY modes for external commands
mainly for "stty". If our child process crashes (or SSH disconnect), we
might get weird modes. Let's ignore the modes in the failure case.
Co-authored-by: Johannes Altmanninger <aclopte@gmail.com>
Part of #10603
Run
printf \Xf6 | wl-copy # ö in ISO-8859-1
LANG=de_DE LC_ALL=$LANG gnome-terminal -- build/fish
and press ctrl-v. The pasted data looks like this:
$ set data (wl-paste -n 2>/dev/null | string collect -N)
$ set -S data
$data: set in local scope, unexported, with 1 elements
$data[1]: |\Xf6|
we pass $data directly to "commandline -i", which is supposed to insert it
into the commandline verbatim. What's actually inserted is "�".
This is because of all of:
1. We never decode "\Xf6 -> ö" in this scenario. Decoding it -- like we do
for non-pasted keyboard input -- would fix the issue.
2. We've switched to using Rust's char, which, for better or worse, disallows
code points that are not valid in Unicode (see b77d1d0e2 (Stop crashing
on invalid Unicode input, 2024-02-27)). This means that we don't simply
store \Xf6 as '\u{00f6}'. Instead we use our PUA encoding trick, making it
\u{f6f6} internally.
3. Finally, b77d1d0e2 renders reserved codepoints (which includes PUA chars)
using the replacement character � (sic). This was deemed more
user-friendly than printing an invalid character (which is probably not
mapped to a glyph). Yet it causes problems here: since we think that
\u{f6f6} is garbage, we try to render the replacement character. Apparently
that one is not defined(?) in ISO-8859-1; we get "�".
Fix this regression by removing the replacement character feature.
In future we should maybe decode pasted input instead. We could do that
lazily in "commandline -i", or eagerly in "set data (wl-paste ...)".
Commit 29f2da8d1 (Toggle terminal protocols lazily, 2024-05-16) made it so
the wildcard expansion in "echo **" (in a large directory tree) can't be
canceled with ctrl-c. Fix this by disabling terminal protocols already at
expansion time (not waiting until execution).
Using
SHELL=$(command -v fish) mc
Midnight Commander will spawn a fish child with
"function fish_prompt;"
"echo \"$PWD\">&%d; fish_prompt_mc; kill -STOP %%self; end\n",
So fish_prompt will SIGSTOP itself using an uncatchable signal.
On ctrl-o, mc will send SIGCONT to give back control to the shell.
Another ctrl-o will be intercepted by mc to put the shell back to sleep.
Since mc wants to intercept at least ctrl-o -- also while fish is in control
-- we can't use the CSI u encoding until mc either understands that, or uses
a different way of passing control between mc and fish.
Let's disable it for now.
Note that mc still uses %self but we've added a feature flag
to disable that. So if you use "set fish_features all"
you'll want to add a " no-remove-percent-self". A patch
to make mc use $fish_pid has been submitted upstream at
https://lists.midnight-commander.org/pipermail/mc-devel/2024-July/011226.html.
Closes#10640
When applying a wildcard, it's important to keep track of the files that have
been visited, to avoid symlink loops. Previously fish used a FileId for the
purpose. However FileId also includes richer information like modification time;
thus if a file is modified during wildcard expansion then fish may believe that
the file is different and visit it twice.
The richer information like modification time is important for atomic file
writes but should be ignored for wildcard expansion; just use the (dev, inode)
pair instead.
This also somewhat reduces our reliance on struct stat, but we still need it for
fstatat which Rust does not expose.
Returns 0 (true) in case an autosuggestion is currently being displayed.
This was first requested in #5000 then again in #10580 after the existing
workaround for this missing functionality was broken as part of a change to the
overall behavior of `commandline` (for the better).
Since we have a mix of both 0-based and 1-based line numbers in the code base,
we can now distinguish between them by type alone. Also stop using 0 as a
placeholder value for "no line number available" except in explicit helper
functions such as `get_lineno_for_display()`.
Both are plenty fast enough, but this way the output of fish_trace isn't
completely taken over by the loops (seems fair since fish_trace probably gets
used rather heavily for completions).
I've often needed a way to get the last bit of performance out of unwieldy
completions that involve a lot of string processing (apt completions come to
mind, and I ran into it just now with parsing man pages for kldload
completions).
Since many times we are looking for just one exact string in the haystack, an
easy optimization here is to introduce a way for `string match` or `string
replace` to early exit after a specific number of matches (typically one) have
been found.
Depending on the size of the input, this can be a huge boon. For example,
parsing the description from FreeBSD kernel module man pages with
zcat /usr/share/man/man4/zfs.4.gz | string match -m1 '.Nd *'
runs 35% faster with -m1 than without, while processing all files under
/usr/share/man/man4/*.4.gz in a loop (so a mix of files ranging from very short
to moderately long) runs about 10% faster overall with -m1.
Preliminary work. Might be important to check version if options I added aren't widely available.
Changed some short options to old-style options since they can't be grouped and don't even need spaces before their arguments, such as `less -ooutputfile` which creates `outputfile`.
The -Dxcolor argument is commented out because its arguments follow complex rules I didn't look into in depth
Part of #1842
The implementation is obviously isn't 100% vi compatible, but works good enough
for major cases
This commit depends on previous commits where jump-{to, till}-matching-bracket
motions were introduces
Part of #1842
It's like jump-to-matching-bracket, but jumps right before the bracket
I will use it to mimic vi 'ab' and 'ib' text objects in the next commit
Given complicated semantics of jump-till-matching-bracket, an alternative name
could be 'jump-inside-matching-brackets'. But that would make names non-symmetrical.
I'm not sure what is worse.
Part of #1842
Split to:
- jump_and_remember_last_jump. What previously was called jump, now called
jump_and_remember_last_jump
- jump. Only jump, don't remember last jump. Now it's also possible to pass
vector of targets
The commit is pure refactoring, no functional changes are introduced.
The refactoring is needed for the next commits
When we changed our default from RelWithDebInfo to Debug, we inadvertently ended
up with all CI building and running in Debug mode. Change at least one of them
back to Release to make sure we don't have any optimizations that cause funky
stuff.
I'm changing the Ubuntu CI image because it's hopefully the fastest (since rust
is relatively dog-slow to compile in release mode).
__fish_apropos is a huge hack under macOS and it seems that it's either broken
or man pages are missing/not indexed under CI. In all cases, hard-code the
results of __fish_describe_command to test the integration machinery
specifically and get the test to pass under macOS CI.
Command completion descriptions were not being generated from `apropos`. Well,
they were being generated but that was not being correctly used by fish core.
Not sure when this was broken, but there's a possibility it was during the rust
port.
In addition to simply not working, it seems the old code tried to avoid
allocations but String::split_at_mut() allocates a new string (since one
allocation from the global allocator can't be split into two allocations to be
freed separately). Use `String::as_mut_utfstr()` before splitting the &wstr
instead of splitting the &str to actually do this alloc-free.
This was vexing me for a while because the extraneous output presented as a
valid (but unwanted) completion, i.e. with RUSTC_WRAPPER exported, `env RUSTC_W`
would offer `RUSTC_W=` and `RUSTC_WRAPPER=` as completions (when only the latter
should have been offered up).
This blames to a40b019, when @floam made some changes to various completions,
but this one seems to not quite fit the pattern and had a copy/paste error
resulting in using an undeclared variable.
Also disable filename completion on port.
__kld_whatis is an order of magnitude faster than calling `whatis` by means of
`__fish_whatis`. (It could be even faster if we could somehow tell `string
replace` to return after the first result, since the .Nd line comes at the start
of the file.)
It still takes some ~3.5 to print descriptions for all available klds (864 under
FreeBSD 13), so we still need to decide when it's prudent to do so and when it's
not.
The "principal" parser is the one and only today; in the future we hope to
have multiple parsers to execute fish script in parallel.
Having a globally accessible "principle" parser is suspicious; now we can
get rid of it.
The "principal" environment stack was the one that was associated with the
"principal" parser and would dispatch changes like to TZ, etc.
This was always very suspicious, as a global; now we can remove it.
Prior to this commit, there was a stack of ReaderDatas, each one has a
reference to a Parser (same Parser in each, for now). However, the current
ReaderData is globally accessible. Because it holds a Parser, effectively
anything can run fish script; this also prevents us from making the Parser
&mut.
Split these up. Create ReaderData, which holds the data portion of the
reader machinery, and then create Reader which holds a ReaderData and a
Parser. Now `reader_current_data()` can only return the data itself; it
cannot execute fish script.
This results in some other nice simplifications.
This is a start on untangling input. Prior to this, a ReaderData and an
Inputter would communicate with each other; this is natural in C++ but
difficult in Rust because the Reader would own an Inputter and therefore
the Inputter could not easily reference the Reader. This was previously
"resolved" via unsafe code.
Fix this by collapsing Inputter into Reader. Now they're the same object!
Migrate Inputter's logic into a trait, so we get some modularity, and then
directly implement the remaining input methods on ReaderData.
* completions/magento: Fixes module aggregation for module related commmands
Previousely when attempting completion for commands `module:enable`,
`mmodule:disable` and `module:uninstall` and error would be disaplyed,
stating that "magento" was not found.
Upon inspection of the issue in the related completion script it became
clear that:
1. The shell command `magento` does not exist as the CLI script of
Magentoresides under `bin/magento`.
2. The module aggregation would not work after referncing the
appropriate CLI command as an undeclared variable was being
introspected.
3. Using Magento's CLI command took too long to respond as it has to
bootstrap the whole Magento stack in order to deliver modules.
Thus the whole aggregation was rewritten to a form that actually works
and reduces the aggregation to reading the appropriate information
directly from the configuration file, provided that the file exists and
PHP is installed.
* completions/magento: Refactors module aggregation for module related commmands to not use PHP script
Executing random scripts from fish completion poses a threat to the
system. While this would indicate that the Magento installation has been
corrupted, it still is better to not run `app/etc/config.php` to get
hold of the modules.
Thus the module aggregation was rewritten to make use of `sed` instead,
which has the additional benefit of being faster than using PHP.
Add round options, but I think can also add floor, ceiling, etc. And
the default mode is trunc.
Closes#9117
Co-authored-by: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
A few specific tests fail under i586 due to its inherent floating point
inaccuracy issues (rust-lang/rust#114479), so ignore these tests if certain
are met.
We have specific integration tests elsewhere in fish to check that even under
i586 we get mostly sane results, so this is OK. I tried to modify the assert
macros to check for a loose string match (up to one character difference) or an
f64 abs diff of less than epsilon, but it was a lot of code with little value
and increased the friction to contributing to the tests. Also, let's just
acknowledge the fact that all of i686, let alone i586 specifically, is a dead
end and not worth investing such time and effort into so long as it more or less
"works".
Closes#10474.
Due to the inherent floating point accuracy issues under i586 described
in #10474 and at https://github.com/rust-lang/rust/issues/114479, we need to add
a workaround to our littlecheck math tests to perform less stringent comparisons
when fish was built for x86 without SSE2 support.
This commit addresses the littlecheck issues that caused #10474 to be re-opened,
but I still have to reproduce the cargo test failures for
`negative_precision_width`, `test_float`, `test_float_g`, and `test_locale`.
The CMake `cargo test` integration was broken if Rust_CARGO_TARGET were used
with `CARGO_FLAGS` set to `-Zbuild-std` (e.g. to target i586 under i686 without
the i586 toolchain installed).
This would fail the FreeBSD tests whenever we merge or push multiple
times in quick succession.
Basically:
- Commits up to ABCDEF are pushed, which triggers a CI run
- Cirrus starts up, but takes a while - it knows to use commit ABCDEF
- More commits are pushed up to 123456
- Cirrus does a shallow clone, only has 123456
- Cirrus tries to check out ABCDEF, but doesn't know it - instant failure
Instead, let's use 100 commits, which should be enough
We require 3.19
This also makes skipped tests visible, which showed that the
print-help test was never run because the REQUIRES line was off.
In sh-mode, bash's `command -v` returns true if *all* commands exist.
The special input functions self-insert, self-insert-not-first, and
and or used to be handled by inputter_t::readch, but they aren't
anymore with `commandline -f`.
I am unsure if these *would* have worked, I can't come up with a use.
So, for now, do nothing instead of panicking.
This would crash if you ran `commandline -f backward-jump`.
The C++ version would read a char (but badly), this doesn't anymore.
So, at least instead of crashing, just do nothing.
One issue with fish_add_path at the moment is that it is sometimes a bit too intransparent.
You'll try to add a path, but it won't appear - was that because it wasn't a directory,
or because it doesn't exist, or because it was already included?
If it isn't usable after, did fish_add_path not add it because of something or did something *else* remove it?
So we give more explanations - "skipping this because it's a file", "not setting anything because no paths are left to add", ...
fish_add_path can be used either interactively, in the commandline,
or in config.fish. That's its greatest strength, it's a very
DWIM-style command.
One of the compromises that entails, however, is that it can't really
be very loud about what it does. If it skips a path, it can't write a
warning because it might be used in config.fish.
But it *can* if it's used interactively. So we try to detect that case
and enable verbose mode automatically.
That means if you do
```fish
fish_add_path /opt/mytool/bin/mytool
```
it may tell you "Skipping path because it is a file instead of a
directory:".
The check isn't perfect, it goes through status current-command and
isatty, but it should be good for most cases (and be false in config.fish).
The prompt regex for pexpect was:
```
return re.compile(
r"""(?:\r\n?|^) # beginning of line
(?:\x1b[\d[KB(m]*)* # optional colors
(?:\x1b[\?2004h) # Bracketed paste
(?:\x1b[>4;1m) # XTerm's modifyOtherKeys
(?:\x1b[>5u) # CSI u with kitty progressive enhancement
(?:\x1b=) # set application keypad mode, so the keypad keys send unique codes
(?:\[.\]\ )? # optional vi mode prompt
"""
+ (r"prompt\ %d>" % counter) # prompt with counter
+ r"""
(?:\x1b[\d\[KB(m]*)* # optional colors
""",
re.VERBOSE,
)
```
This has a terrible bug: an accidentally unescaped bracket here:
(?:\x1b[>4;1m) # XTerm's modifyOtherKeys
^
This bracket then extends throughout the entire regex, and is
accidentally terminated here:
(?:\x1b[\d\[KB(m]*)* # optional colors
^
Thus the whole regex is busted; in particular the prompt counters are
not being tested correctly.
A second issue is that these escape sequences are not emitted before the
first prompt, so correcting the regex will cause every test to fail.
Fix this by ignoring all of the escape sequences and merely look for
the "prompt %d>" portion.
THIS DELIBERATELY CAUSES TEST FAILURES.
The tests were already broken and falsely reported as passing.
These will be fixed in followup commits.
Good news is that the tests should become way more reliable after
this is fixed - hopefully no more introducing random sleep() calls.
This doesn't pull its weight. Block size is not a particularly big
problem,
and this both complicates the code a bit and would arbitrarily cause issues
if a fish script exceeded 65k lines.
This reverts commit edd6533a14.
This doesn't have any effect on the size of the struct (due to alignment
requirements and padding) but reduces the complexity by turning
Block::wants_pop_env into an emergent property dependent on the type rather than
something we have to manually manage.
We only increment it and check if it's non-zero, we never decrement or check the
actual count. As such, change it to a bool and bring the size of `Block` down
from 32 to 24 bytes.
We almost never access any of this and having it stored directly in the `Block`
struct increases its size (reducing how many we can fit in L1 and L2, and
increasing memory copy traffic).
Gets rid of BlockData::None so we can avoid allocating a Box at all when we have
no data (at the cost of yet-another-wrapper-type), which is the usual case.
This has a few advantages,
* We now statically assert that all fields used by a particular block type are
correctly initialized (i.e. you can't assign the function name but forget to
assign its arguments),
* Conversely, we can match directly on `BlockData` and be guaranteed that the
fields we want to access are initialized and present,
* We reduce the number of assertions, effectively "unwrapping" only once based
off the block type instead of each time we try to access a conditional field,
* We reduce the size of the `Block` struct by coalescing fields that cannot
co-exist, bringing it down from 104 bytes to 88 bytes.
It would be nice to make all of `Block` itself an enum, but it currently
requires `Copy` and we take advantage of that to copy it around everywhere.
Putting these fields directly in `Block` directly would mean a lot more memory
traffic just checking block types.
There's no need for two separate block types when one is merely a variant of the
other. This may have been required under C++ but thanks to sum types (rust's
enums) we don't need to do that any more.
The value completions were rendered almost entirely useless due to the forced
inclusion of file completions at all tokens, including in the head/command
position thanks to the use of `__fish_complete_subcommand` which doesn't
understand the semantics of `env` and expects something like `ssh`. But we don't
need it at all.
If the backgrounded/stopped job was using the tty, sending it SIGCONT first
might cause it to immediately wake and try to use the tty (which fish still has
control over), causing it to immediately stop again after receiving a SIGTTOU.
We are supposed to send SIGHUP first so that when the process resumes it sees
the queued SIGHUP and executes its registered handler!
Don't fork/exec an external process, especially one performing IO, if we don't
have to.
This, in turn, speeds up __fish_source_cached_completions which is rather slow
under WSL (and slower than it needs to be on other platforms).
Use "directories" explicitly instead of "components" to make it more
clear that the arguments need to be directories, not files.
Also a bit on intent and variable scope.
There's no guarantee that a condition variable is stateful. The docs for
`Condvar::notify_one()` actually say the opposite:
> If there is a blocked thread on this condition variable, then it will be woken
> up from its call to wait or wait_timeout. Calls to notify_one are not buffered
> in any way.
This test was relying on the main loop obtaining the lock and entering the
condition variable sleep before the thread was scheduled and got around to
notifying the condition variable. If this non-deterministic behavior was not
upheld, the test would time out since it would obtain the lock (either before or
after the variable were updated) then call `condvar.wait()` *after* the variable
had been updated and the condvar signalled, but without (atomically or even at
all) checking to see if the desired wake precondition was fulfilled. As the
child thread had already run and the wake notification was NOT buffered, there
was nothing to wake the running thread.
There really wasn't any way to salvage the test as originally written, since the
write to `ctx.val` was not in any way linked to the acquire/release of the mutex
so regardless of whether or not the main thread obtained the mutex and checked
the value precondition before calling `condvar.wait()`, the child thread's write
could have happened after the check but before the wait() call. As such, the
test has been rewritten to use `wait_while()` but then also updated to bail in
case of a timeout instead of hanging indefinitely (since neither the `ctest`
runner nor the `cargo test` harness was timing out; `cargo test` would only
report that the test had exceeded 60 seconds but as long as it was not executed
with `cargo test -- -Z --ensure-time` (which is only available under nightly),
the test would not halt.
If this test were *intentionally* written to test the scenario that was timing
out, it should be written deterministically in such a way that the main loop
did not run until after it was guaranteed that the variable had been updated
(i.e. by looping until val became 5 or waiting for an AtomicBool indicating the
update had completed to be set), but I'm not sure what the benefit in that would
be since the docs actually guarantee the opposite behavior (the notified state
is explicitly not cached/buffered).
If we have fish code written with the assumption that condvar notifications
prior to *any* call to `Condvar::wait()` *are* buffered, then that code should
of course be revisited in light of this.
Commit 8a7c3ce (Don't abandon line after writing control sequences, 2024-04-06)
was broken by 29f2da8 (Toggle terminal protocols lazily, 2024-05-16), fix that.
Fixes#10529
Reminder that reStructuredText is awkward and you can't make sphinx treat these
as inline code; they'll be formatted as italic text only.
Vim search expression:
\([`:]\)\@<!`[^`:]\+`\(`\)\@!
Followed by
ysi``
does the trick quite nicely.
* feat: improve konsole completion
* Improve konsole profile completion to be dynamic
Directly complete --profile as a long argument
* Dynamically complete konsole -p
This makes `path basename` a more useful replacement for the stock `basename`
command, which can be used with `-s .ext` to trim `.ext` from the base name.
Previously, this would have required the equivalent of
path change-extension "" (path basename $path)
but now it can be just
path basename -E $path
* Properly handle a lot more -Z completion formats as suggested by `rustc -Z
help`
* Don't run any `rustc` commands when sourcing `rustc.fish`; these invocations
are instead deferred until the user attempts to complete the specific switch.
* Support CSV -A/F/D/W values
This adds a crate containing a new implementation of printf, ported from musl.
This has some advantages:
- locale support is direct instead of being "applied after".
- No dependencies on libc printf. No unsafe code at all.
- No more WideWrite - just uses std::fmt::Write.
- Rounding is handled directly in all cases, instead of relying on Rust and/or
libc.
- No essential dependency on WString.
- Supports %n.
- Implementation is more likely to be correct since it's based on a widely used
printf, instead of a low-traffic Rust crate.
- Significantly faster.
Mostly replacing std::<type>::MAX with <type>::MAX.
Surprising here is replacing
.expect(format!(...))
with
.unwrap_or_else(|_| panic!(...))
It explains that this is because the "format!" would always be called.
This enabled the profile in fish_setlocale, which caused startup
profile to always be on, so
```fish
fish --profile file -c 'foo'
```
would show the entire startup as well
Hex float parsing may come about through wcstod, for example:
printf "%f" '0x8p2'
should output 32.0.
Currently we use a not-great fork of hexponent. Hexponent has been dormant for
years, and has some issues: doesn't round properly, allocates unnecessarily,
doesn't handle denormals, is more complicated than necessary.
Just rewrite hex float parsing, fixing those problems and getting us off of this
weird fork.
ThreadId is way slower than it should be for the sense that we use it in; it
doesn't cache the id and allocates an Arc internally.
We don't care about the thread id used in crate::threads correlating with any
other thread id the code uses anywhere (not that it does) because it's only used
for our own bookkeeping. Change to something much simpler instead.
Verified that std::sync::OnceLock<T> compiles to the same assembly at the
*access* site as the Option<T> we were using. The additional overhead upon init
is fine. No need for extra Box<T> indirection for IO_THREAD_POOL.
While obtaining an uncontested mutex from the same thread (without reentrance)
is basically ~free, the use of `MainThread<RefCell<T>>` instead of `Mutex<T>`
makes it clear that there is no actual synchronization taking place, hopefully
making the code easier to understand.
We don't set this variable ourselves, but some might set it in their config out
of habit coming from shells that don't automatically colorize ls output.
This variable overrides stdout tty detection for `ls --color=auto` (but does not
modify the behavior of `ls --color=never` or `ls --color=always` regardless of
its value) under at least the BSD version of `ls`. (Under the GNU version, it
influences colorization only if stdout *is* a tty.)
If we detect CLICOLOR_FORCE *and* we are not writing directly to the tty, we
skip colorization (by clearing-but-not-erasing `$__fish_ls_color_opt`, so that
we don't end up accidentally using its value from another scope).
This automatically assigns the 'completions' label and the 'fish next-3.x'
milestone to completions-only PRs.
A completions-only PR is defined as being one that touches
share/completions/*.fish but does not touch any files outside of share/
The C++ version of this code simply copied the entire uvar table.
Today we take a reference. It's not clear which one is better.
Removal of locale variables like LC_ALL triggers variable change handlers
which call EnvStackImpl::get. This deadlocks because we still hold the lock
to protect the reference to all uvars. Work around this.
Closes#10513
It is short and simple enough to write yourself if you need it and it encourages
bad behavior by a) always returning owned strings, b) always allocating them in
a vector. If/where possible, it is better to a) use &wstr, b) use an iterator.
In rust, it's an anti-pattern to unnecessarily abstract over allocating
operations. Some of the call sites even called split_string(..).into_iter().
This updates is_windows_subsystem_for_linux() to take a WSL version to test for
(any, v1, or v2) and returns the boolean result depending on the system. I've
benchmarked and when running on regular Linux, this is still just as fast as the
previous binary check; it's only when it's WSL that this takes about 20ns
longer to figure out which variant.
Note that older WSLv2 kernels had a `-microsoft-standard` suffix while newer
ones appear to have a `-microsoft-standard-WSL2` suffix, so we make sure to test
for the least common denominator. (It doesn't matter to us, but note that newer
WSLv2 kernels have four dots in the version string!)
WSL workarounds pertaining to the default Windows terminal or executable
behavior of win32 binaries under a WSL shell are extended to WSLv2 while those
specific to oddities in kernel behavior are confined to WSLv1 only. (It
technically wouldn't hurt to extend them to WSLv2 but there's no good reason to
do so, either.)
A common complaint has been the massive amount of directories Windows appends to
$PATH slowing down fish when it attempts to find a non-existent binary (which it
does a lot more often than someone not in the know might think). The typical
workaround suggested is to trim unneeded entries from $PATH, but this a) has
considerable friction, b) breaks resolution of Windows binaries (you can no
longer use `clip.exe`, `cmd.exe`, etc).
This patch introduces a two-PATH workaround. If the cmd we are executing does
not contain a period (i.e. has no extension) it by definition cannot be a
Windows executable. In this case, we skip searching for it in any of the
auto-mounted, auto-PATH-appended directories like `/mnt/c/Windows/` or
`/mnt/c/Program Files`, but we *do* include those directories if what we're
searching for could be a Windows executable. (For now, instead of hard-coding a
list of known Windows executable extensions like .bat, .cmd, .exe, etc, we just
depend on the presence of an extension at all).
e.g. this is what starting up fish prints with logging enabled (that has been
removed):
bypassing 100 dirs for lookup of kill
bypassing 100 dirs for lookup of zoxide
bypassing 100 dirs for lookup of zoxide
bypassing 100 dirs for lookup of fd
not bypassing dirs for lookup of open.exe
not bypassing dirs for lookup of git.exe
This has resulted in a massive speedup of common fish functions, especially
anywhere we internally use or perform the equivalent of `if command -q foo`.
Note that the `is_windows_subsystem_for_linux()` check will need to be patched to
extend this workaround to WSLv2, but I'll do that separately.
Under WSL:
* Benchmark `external_cmds` improves by 10%
* Benchmark `load_completions` improves by an incredible 77%
c0bcd817ba removed some key bindings, including the bindings of
ESC ESC [ C for Alt-Right. the commit claimed that
"Sequences like \e\eOC are Escape followed by an SS3 arrow key which we
can already decode separately." but for whatever reason this doesn't work:
Alt-Right is broken in iTerm2 by default.
Restore the default ESC ESC [ X bindings for iTerm2 compatibility.
On this binding we fail to disable CSI u
bind c-t '
begin
set -lx FZF_DEFAULT_OPTS --height 40% --bind=ctrl-z:ignore
eval fzf | while read -l r; echo read $r; end
end
'
because for "fzf", ParseExecutionContext::setup_group() returns early with the
parent process group (which should be fish's own) , hence "wants_terminal"
is false. This seems questionable, I don't think the eval should make a
difference here.
For now, don't touch it; use the more accurate way of detecting whether
a process may read keyboard input. In many of such cases "wants_terminal"
is false, like
echo (echo 1\n2\n3 | fzf)
Fixes#10504
Don't unconditionally execute the plumbing to get `rustc -C` completions (use it
only when trying to complete `rustc -C`), filter out deprecated options, and use
fewer calls to the `string` builtin to optimize further.
Need to do the same thing for the `-Z` completions next, those hang the shell
for a good 1.5+ seconds.
I've been needing this for some time to generate completions for functions that
we can dynamically generate completions for that take one or more
comma-separated values in any order.
Try not to let `cargo asm` build a large project and hang the terminal (and make
the fans go crazy) if we try to generate a list of functions/paths and the
project is in a dirty state. Also support dynamic completion of --target.
If rustup is installed, use the existing `__rustup_installed_targets` to get a
list of installed targets to compile for. If it's not, print a list of all
targets known to rustc.
It sucks that the completions file is currently architected in a way where we
have to manually specify the arguments for each subcommand. 🤷
This hot function dominates the flamegraphs for the completions thread, and any
optimizations are worthwhile.
A variety of different approaches were tested and benchmarked against real-world
fish-history file inputs and this is the one that won out across all rustc
target-cpu variations tried.
Benchmarks and code at https://github.com/mqudsi/fish-yaml-unescape-benchmark
Fixes the build on Ubuntu distributions with aggressive enabling of LTO
for all builds.
This build profile sets CFLAGS and CXXFLAGS in a way that prevents cargo
tests from linking. This manifests as errors like:
= note: make[5]: *** read jobs pipe: Bad file descriptor. Stop.
make[5]: *** Waiting for unfinished jobs....
lto-wrapper: fatal error: make returned 2 exit status
compilation terminated.
/usr/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status
We don't forward this variable for storage in any structs, so there's no reason
to go through an Arc instead of returning the `&'static EnvStack` directly.
NB: This particular change was safe, and passes all tests on its own.
We don't forward this variable for storage in any structs, so there's no reason
to go through an Arc instead of returning the `&'static EnvStack` directly.
These have clearer sync/unsync semantics and now ship with rust itself.
They don't paper over any possible cross-thread issues, and we can specifically
choose which we want for the purpose.
`Parser` is a single-threaded `!Send`, `!Sync` type and does not need to use
`Arc` for anything. We were using it because that's all we had for the parser's
`EnvStack`, but though that is *technically* protected internally by a mutex
(shared with global EnvStack), there's nothing to say that other parsers with a
narrower scope/lifetime on other threads will be necessarily using the same
backing mutex.
We can safely marshal the existing `Arc<EnvStack>` we get from
`environment::principal()` into an `Rc<EnvStack>` since the underlying reference
is always valid. To prove this point, we could have PRINCIPAL_STACK be a static
`EnvStack` and have `environment::principal()` use `Arc::from_raw()` to turn
that into an `Arc<EnvStack>`, but there's no need to factorize this process.
By inverting the order of storage, we can use an `OnceCell`/`unsync::Lazy`
inside the Send/Sync `MainThread<T>` and remove the need for a lock altogether.
It's reasonable since this is only checking to see that the history file
contains the expected format and if it's corrupted but we at least got what we
expect to be the correct key/value pairs, then that's all we can do.
Of course the real motivation is to speed up this very hot function in any way
possible!
On the completions and history thread, the parent function
HistoryFileContents::decode_item() is responsible for ~60% of the CPU time, and
extract_prefix_and_unescape_yaml() alone comprising 14% (of the total).
This change removes allocations in the event that the history item is either
fully or partially plain yaml with no escapes to begin with, and brings down the
execution time of this function to only 7% of the total execution time.
The bulk of the remaining time is spent in wcs2string(), which is called
unconditionally and is naturally alloc-heavy.
- Remove duplicated options - we had `-type` 9 times!
- Remove deprecated options and synonyms
- Make descriptions shorter, even removing some - when they're inscrutable they might as well not be there.
Really, 99.8% of these options are of interest to nobody except possibly (a subset of) gcc developers, so it pays to have *less* on your screen that you don't use anyway.
We ignore typed control characters 33a7172ee (Revert to not inserting control
characters from keyboard input, 2024-03-02).
We used to do the same for bracketed paste but that changed in 8bf8b10f6
(Extended & human-friendly keys, 2024-03-30) which made bracketed paste
behave like fish_clipboard_paste; it inserts the exact input (minus leading
whitespace etc). At that time it wasn't clear to me which behavior was the
right one (because of the inconsistency between terminal and bracketed paste).
As reported in
https://matrix.to/#/!YLTeaulxSDauOOxBoR:matrix.org/$PEEOAoyJY-644amIio0CWmq1TkpEDdSy2QnfJdK-dco
trailing tabs in pasted text can be confusing.
There seems to be not real need to insert raw control characters into the
command line, so let's strip them when pasting.
Now the only way to insert a raw control character into the command line is
to recall it from command history. Not sure what the behavior should be for
that case, we can revisit that later. If we get rid of raw control characters
entirely, then we can also delete the new "control pictures" rendering :)
This allows running `set` without triggering any event handlers.
That is useful, for example, if you want to set a variable in an event
handler for that variable - we could do it, for example, in the
fish_user_path or fish_key_bindings handlers.
This is something the `block` builtin was supposed to be for, but it
never really worked because it only allows suppressing the event for
the duration, they would fire later. See #9030.
Because it is possible to abuse this, we only have a long-option so
that people see what is up.
Commit a583fe723 ("commandline -f foo" to skip queue and execute immediately,
2024-04-08) fixed the execution order of some bindings but was partially
backed out in 5ba21cd29 (Send repaint requests through the input queue again,
2024-04-19) because repainting outside toplevel yields surprising results
(wrong $status etc).
Transient prompts wants to first repaint and then execute some more readline
commands, all within a single binding. This was broken by the second commit
because that one defers the repaint until after the binding has finished.
Work around this problem by deferring input events again while a readline
event was queued. This is closest to the historical behavior.
The implementation feels hacky; we might find odd situations.
For example,
commandline -f repaint end-of-line
set token (commandline -t)
sets the wrong token.
Probably not a very important case. We could throw an error or make it work
by letting "commandline -t" drain the input queue.
That seems too complicated, better change repaints to not use the input queue
(and fake $status etc). Let's try to do that in future.
Closes#10492
[w]open_dir does not pass O_CREAT, so the mode argument to open is never used.
also, O_CREAT | O_DIRECTORY could not be used (portably) to create a directory.
(on POSIX does not specify what should happen, on Linux it is EINVAL.)
This new feature in rsconf 0.2.0 resolves the compile-time warnings we get under
rustc 1.80+ about unrecognized cfg names by informing cargo of all valid cfg
names/values even when the cfg in question isn't enabled.
rustc 1.80 now complains about features not declared in Cargo.toml and cfg
keys/values not declared by build.rs to protect against typos or misuse (you
think you're using the right condition but you're not). See
rust-lang/cargo#10554 and rust-lang/rust#82450.
(We're not actually using TSAN under CI at this time, but I do want to re-enable
it at some point — especially if we get multithreaded execution going — using
the rust-native TSAN configuration.)
I'll be updating the `rsconf` crate and patching `build.rs` accordingly to also
handle the warnings about unknown cfg values, but tsan is a feature and not a
cfg and these can be dealt with in `Cargo.toml` directly.
We were passing a slice (and not a vec) to `CString::new()`, meaning it would
allocate a new Vec internally to hold the bytes.
Also document that the resulting CString will be silently truncated at the first
interior NUL.
The function was repeatedly calling `s.char_at(n)` which is O(1) only for UTF-32
strings (so not a problem at the moment). But it was also calling `hex_digit(n)`
twice for each `n` in the 3-digit case, causing unnecessary repeated parsing of
individual characters into their radix-16 numeric equivalents, which could be
avoided just by reusing the already calculated result.
CARGO_NET_GIT_FETCH_WITH_CLI uses the `git` executable instead of the rust
git2 crate/lib, which speeds things up and is known to resolve some issues
fetching the registry or individual crates.
This is to work around a specific issue with git-resident Cargo.toml
dependencies (e.g. terminfo) that keep randomly failing to download under macOS
CI.
We use this fallback value for FISH_BUILD_DIR when `cargo` is not
invoked from `cmake`, but we already have a cargo-defined build
directory and we shouldn't just decide to use $TARGET_MANIFEST_DIR/build
instead.
Tests pass locally!
We will continue to use the "normal" fish base directory detection when using
the CMake test harness which properly sets up a sandboxed $HOME for fish to use,
but when running source code tests with a bare `cargo test` we don't want to
write to the actual user's profile.
This also works around test failures when running `cargo test` under CI with a
locked-down $HOME directory (see #10474).
Prior to this change, signals.py attempted to generate Ctrl-C (SIGINT) by
sending \x03 to stdin. But with the change to use the CSI U sequence, Ctrl-C no
longer generates SIGINT.
Switch to sending SIGINT directly. Also switch up some of the sleep constants so
that a sleep command can't be confused with another one.
The test_history_formats test was reading from build/tests/ which is an artifact
of the cmake test runner. The source code tests should not depend on the cmake
test harness at all, so this is changed to read from the original test source in
the ./tests/ directory instead.
As documented in #10474, there are issues with 64-bit floating point rounding
under x86 targets without SSE2 extensions, where x87 floating point math causes
imprecise results.
Document the shortcoming and provide some version of the test that passes
regardless of architecture.
FISH_BUILD_DIR (nominally, ./build) is created by cmake. If you only check out
the project via git and then run `cargo build`, this directory won't exist and
many of the tests will fail.
%ld expects a 4-byte parameter on 32-bit architectures and an 8-byte parameter
on 64-bit architectures, but we supplied are trying to supply a 64-bit parameter
that would overflow 32-bit storage.
Use %lld instead which expects a `long long` parameter, which should be 8-bytes
under both architectures.
See #10474
I think given a local terminal running fish on a remote system, we can't
assume that an input sequence like \ea is sent all in one packet. (If we
could that would be perfect.)
Let's readd the default escape delay, to avoid a potential regression, but
make it only apply to raw escape bindings like "bind \e123". Treat sequences
like "bind escape,1,2,3" like regular sequences, so they can be bound on
all terminals.
This partially reverts commit b815319607.
Given "abbr foo something", the input sequence
foo<space><ctrl-z><space>
would re-expand the abbreviation on the second space which is surprising
because the cursor is not at or inside the command token. This looks to be
a regression from 00432df42 (Trigger abbreviations after inserting process
separators, 2024-04-13)
Happily, 69583f303 (Allow restricting abbreviations to specific commands
(#10452), 2024-04-24) made some changes that mean the bad commit seems no
longer necessary. Not sure why it works but I'll take it.
I think we can now call what we have in git better than the last
C++-based release, and you'll still need a C compiler to build it
because we still have some C code (libc.c).
As reported on gitter, commands like "rm (...)" sometimes want a previous
command inside the parentheses. Let's try that. If a user actually wants
to search for a command substitution they can move the cursor outside the
command substitution, or type the search string after pressing ctrl-r?
On a command with multiline quoted string like
begin
echo "line1
line2"
end
we actually indent line2 which seeems misleading because the indentation
changes the behavior when typed into a script.
This has become more prominent since commits
- a37629f86 (fish_clipboard_copy: indent multiline commands, 2024-04-13)
- 611a0572b (builtins type/functions: indent interactively-defined functions, 2024-04-12)
- 222673f33 (edit_command_buffer: send indented commandline to editor, 2024-04-12)
which add indentation to an exported commandline.
Never indent quoted strings, to make sure the rendering matches the semantics.
Note that we do need to indent the opening quote which is fine because
it's on the same line.
While at it, indent command substitutions recursively. That feature should
also be added to fish_indent's formatting mode (which is the default).
Fortunately the formatting mode already works fine with quoted strings;
it does not indent them. Not sure how that's done and whether indentation
can use the same logic.
Given "1(23)4", this function returns an inclusive range, from the opening
to the closing parenthesis. The subcommand is extracted by incrementing
the range start and interpreting the result as an exclusive range.
This is confusing, especially if we want to add multi-character quotes.
Change it to always return the full range (including parentheses) and provide
an easy way to access the command string.
While at it, switch to returning an enum.
This change is perhaps larger and more complex than necessary (sorry)
because it is mainly made with multi-character quotes in mind. Let's see
if that works out.
In addition to the native Emacs undo binding, we also support ctrl-z.
On Linux, ctrl-shift-z alias ctrl-Z is the redo binding according to
https://en.wikipedia.org/wiki/Table_of_keyboard_shortcuts Let's bind allow
that.
Unfortunately ctrl-shift and ctrl-alt modified shortcuts on Linux may be
intercepted by the windowing system or the terminal. Only alt-shift seems to be
available reliably (but the shift bit should mean "extend selection" in Emacs).
This removes IsOkAnd and the is_some_and method.
I cannot actually find is_none_or in the stdlib?
I've kept the trait name to avoid changing it now and then later, maybe this should
be moved elsewhere to avoid claiming it's an stdlib thing?
It appears we can't find a system that ships rustc >= 1.67 and < 1.70,
so keeping it at 1.67 gains nothing.
1.70 is used in Debian 13, so that will be able to build fish out of
the box (12 was on 1.63 which was already too low).
After abandoning a commandline (for example with ctrl-c) it's nice to be
able to restore it. There is little reason to discard the requisite undo
information, so keep it.
git_version_gen fails on Noble Numbat because modern Git refuses
to read repo-local config if owned by another user.
fishuser@a4263f53c93e:~/fish-build$ cd /fish-source/
fishuser@a4263f53c93e:/fish-source$ git describe --always --dirty
fatal: detected dubious ownership in repository at '/fish-source'
To add an exception for this directory, call:
Allow reading it (though that doesn't seem necessary here, it would be better
to ignore it).
vared.fish is installed at
/home/fishuser/fish-build/test/buildroot/usr/local/share/fish/functions/vared.fish
as oppposed to being sourced from share/functions/.
I'm not 100% sure why this happens but it doesn't seem wrong.
iTerm2 supports CSI u so the custom bindings are no longer needed. Sequences
like \e\eOC are Escape followed by an SS3 arrow key which we can already
decode separately.
In ImageMagick 7 or later, legacy commands have been replaced with
magick. Here a new functions, defines these completions and it is
called for `magick` and `magick convert`.
fixes#7172. Closes#10307.
Co-authored-by: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
We were inconsistent about this for no apparent reason.
Also cleaning up in ~/.config/fish/completions is
irrelevant by now since we moved to ~/.local/share/fish 8 years ago.
Now that the parent commit moved it again, cleaning up that one seems
reasonable.
These take over two minutes under ASAN (like ~40 seconds without, so
they aren't quick to begin with), and don't really give any additional
insight.
So we skip them to save time
This allows making something like
```fish
abbr --add gc --position anywhere --command git back 'reset --hard
HEAD^'
```
to expand "gc" to "reset --hard HEAD^", but only if the command is
git (including "command git gc" or "and git gc").
Fixes#9411
I have no idea why this matches the string thrice when it is entered
once and suggestions are disabled.
I've seen this fail even on my local system, I expect it works because
of some terminal integration.
Running
echo foo | vim -
gets us in a weird situation because we put the job in fish's process groups.
It causes us to not set a PGID for this job, so it can't be resumed among
other things.
Stopping the job with ctrl-z and try to exit the shell causes a crash in the
"There are still jobs active" warning because the PID for the job is still 0.
Let's remove the assertion to restore previous behavior, and hopefully fix
this later.
Remove the last non scoped place where we disable protocols (just before
exec(1)); it's not necessary with the current approach because we always
disable inside eval.
There is an edge case where we don't:
fish -ic "exec bash"
leaving bash with CSI u enabled. Disable that also in -ic mode where we
don't have a reader.
In future we should use the same approach for restore_term_mode() but I'm
not sure which one is better.
We enable terminal protocols once at startup, and disable them before exit.
Additionally, we disable them while evaluating commands (see 8164855b7 (Disable
terminal protocols throughout evaluation, 2024-04-02))..
Thirdly, we re-enable protocols inside builtin read (where it's disabled
because we are evaluating something). All of these three are scoped and
statically guaranteed to not leak into each others scopes.
There is another place where we enable protocols non-scoped: when we
receive a notification that a job is stopped. If this is ever hit, things
will be imbalanced and we'll fail to restore the right terminal state,
or (more likely) crash due the assertion in terminal_protocols_enable().
This code path used to be necessary when we disabled protocols only while
actually executing an external command but we changed that in 8164855b7,
so it should no longer be. Remove it.
I haven't been able to find a test case, I'll try to do that later.
The main reason we changed the scope of protocols was focus reporting (#10408).
We have given up on that for now (outside tmux where I can't get it to work)
so we might want to reconsider and go back to the "optimized" approach of
enabling it for as long as possible. But this is simpler, easier to verify.
Try to keep the "backwards-incompatible" section reasonably short so
people can get a quick overview of what they need to handle.
So we split the "bind" part into two.
This tries to open the given file to use as stdin, and if it fails,
for any reason, it uses /dev/null instead.
This is useful in cases where we would otherwise do either of these:
```fish
test -r /path/to/file
and string match foo < /path/to/file
cat /path/to/file 2>/dev/null | string match foo
```
This both makes it nicer and shorter, *and* helps with TOCTTOU - what if the file is removed/changed after the check?
The reason for reading /dev/null instead of a closed fd is that a closed fd will often cause an error.
In case opening /dev/null fails, it still skips the command.
That's really a last resort for when the operating system
has turned out to be a platypus and not a unix.
Fixes#4865
(cherry picked from commit df8b9b7095)
wl-copy is a daemon process that serves its stdin to any wl-paste processes.
On Wayland, we launch it from fish_clipboard_copy. It then lives in the
same process group as fish (see `ps -o pid,pgid,comm`).
For some reason pressing ctrl-c inside the VSCode integrated terminal with
fish as the default shell kills the wl-copy process, thus clearing the
clipboard. On other terminals it works fine.
This is also reproducible by running "echo foo | wl-copy" ctrl-v ctrl-c ctrl-v
(the second ctrl-v does not paste because wl-copy was killed).
Work around this for now by running wl-copy asynchronously, and disowning it.
This seems to fix it though I really don't know why. Alternatively we could
"setsid" but that's technically not available on BSD.
For some reason this works in Bash. We should strace it to figure out why.
This introduces a feature flag, "test-require-arg", that removes builtin test's zero and one argument special modes.
That means:
- `test -n` returns false
- `test -z` returns true
- `test -x` with any other option errors out with "missing argument"
- `test foo` errors out as expecting an option
`test -n` returning true is a frequent source of confusion, and so we are breaking with posix in this regard.
As always the flag defaults to off and can be turned on. In future it will default to on and then eventually be made read-only.
There is a new FLOG category "deprecated-test", run `fish -d deprecated-test` and it will show any test call that would change in future.
This seems a bit better because it's what bind uses. To makes sure that
something like :kbd:`ctrl-x` looks good in HTML, remove the border from the
kbd style. Else both "ctrl" and "x" get small boxes which looks weird.
When writing scripts for other shells, it can be confusing and annoying
that our `man` function shadows other manual pages, for example `exec(1p)`
from [Linux man-pages]. I almost never want to see the fish variant for such
contended cases (which obviuosly don't include fish-specific commands like
`string`, only widely-known shell builtins).
For the contented cases like `exec`, the POSIX documentation is more
substantial and useful, since it describes a (sub)set of languages widely
used for scripting.
Because of this I think we should stop overriding the system's man pages.
Nowadays we offer `exec -h` as intuitive way to show the documentation for
the fish-specific command (note that `help` is not a good replacement because
it uses a web browser).
Looking through the contended commands, it seems like for most of them,
the fish version is not substantially different from the system version.
A notable exception is `read` but I don't think it's a very important one.
So I think we should can sacrifice a bit of the native fish-scripting
experience in exchange for playing nicer with other shells. I think the
latter is more important because scripting is not our focus, the way I see it.
So maybe put our manpath at the end.
In lieu of that, let's at least have `exec.rst` reference the system variant.
[Linux man-pages]: https://www.kernel.org/doc/man-pages/Closes#10376
This is similar to f7dac82ed (Escape separators (colon and equals) to improve
completion, 2019-08-23) except we only escape : and = if they are the result of
file completions. This way we avoid issues with custom completions like dd.
This also means that it won't work for things like __fish_complete_suffix
[*] but that can be fixed later, once we can serialize the DONT_ESCAPE flag.
By moving the escaping step earlier, this causes some unit test changes
which should not result in actual behavior change.
See also #6099
[*]: The new \: and \= does not leak from "complete -C" because that command
unescapes its output -- unless --escape is given.
alt-d used to do that until evil merge[*] 213e90704 (Merge remote-tracking branch
'upstream/master' into bind_mode, 2014-01-15) which changed the order of
the \ed bindings such that the smart dirh version would be shadowed by the
simpler ones.
[*] git blame alone failed to find it because it skips merge commits.
Another consequence of a583fe723 ("commandline -f foo" to skip queue
and execute immediately, 2024-04-08) is that "commandline -f repaint"
will paint the prompt with the current value of $status which might be
set from a shell command in a the currently executing binding, instead of
waiting for the top-level status. This is wrong, at least historically. It
surfaces in bindings like alt-w which always paint a status value of [1]
when on single-lines commandlines.
Another regression is that a redundant repaint in a signal handler outputs
an extra prompt.
Fix both by making repaint commands go over the input queue again. This way,
they are always run with a good commandline state. There is no need to
repaint immediately because I don't think anyone has a data dependency on it
(we currently don't expose the prompt string), it's only for rendering.
We sometimes leak ^[[I and ^[[O focus reporting events when run from VSCode's
"Run python file" button in the top right corner. To reproduce I installed
the ms-python extension set the VSCode default shell to fish and repeatedly
ran a script that does "time.sleep(1)". I believe VSCode synthesizes keys
and triggers a race condition.
We can probably fix this but I'm not sure when I'll get to it (given how
relatively unimportant this feature is).
So let's go back to the old behavior of only enabling focus reporting in tmux.
I believe that tmux is affected by the same VSCode issue (also on 3.7.1 I
think) but I haven't been able to get tmux to emit focus reporting sequences
yet. Still, keep it to not regress cursor shape (#4788). So far this is
the only motivation for focus reporting and I believe it is only relevant
for terminals that can split windows (though there are a bunch that do).
Closes#10448
There seem to be versions of ssh (possibly not from OpenSSH) that don't
print the version number in -V, so make sure not to pass an empty string as
numeric arg to test.
Fixes#10445
While it does need to store the string, we also need to use the string after
storing it, so we aren't getting any advantage from passing by value. Just pass
by reference to simplify the call sites.
This is another problem that has been bothering me for years: as mentioned
in 1dd901e52 (Maintain cursor in history prefix search, 2024-04-12), up-arrow
search highlights search matches but the contrast is really bad, especially in
command position, because the search matches --background=brblack is combined
with whatever foreground syntax highlighting the command has. The history
pager had a similar problem (for the selected history item) but circumented
it by disabling syntax highlighting altogether for the selected item.
fish_color_search_match's foreground component is ignored.
Let's use it instead of syntax highlighting.
This fixes the contrast on some default colorschemes but the bryellow
foreground looks weirdly like an error/warning on some terminals. Change it
to white. This needs a hack because we don't have a canonical way to tell
if a uvar has been set by the user. Fortunately the foreground component
hasn't been used at all so far, so we're not so much changing it as much as
initializing it.
On Konsole with
function my-bindings
bind --preset --erase escape
bind escape,i 'echo escape i'
end
set fish_key_bindings my-bindings
the "escape,i" binding doesn't trigger. This is because of our special
handling of the escape key prefix. Other multi-key bindings like "bind j,k"
wait indefinitely for the second character. But not "escape,i"; that one
has historically had a low timeout (fish_escape_delay_ms). The motivation
is probably that we have a "escape" binding as well that shouldn't wait
indefinitely.
We can distinguish between the case of raw escape sequence binding like "\e123"
and a binding that talks about the actual escape key like "escape,i". For the
latter we don't need the special treatment of having a low timeout, so make it
fall back to "fish_sequence_key_delay_ms" which waits indefinitely by default.
Indented multiline commandlines look ugly in an external editor. Also,
fish doesn't properly handle the case when the editor runs fish_indent.
Fix is by indenting when exporting the commandline and un-indenting when
importing the commandline again.
Unindent only if the file is properly indented (meaning at least by the
amount fish would use). Another complication is that we need to offset
cursor positions by the indentation.
This approach exposes "fish_indent --only-indent" and "--only-unindent"
though I don't imagine they are useful for others so I'm not sure if this
is the right place and whether we should even document it.
One alternative is to add "commandline --indented" to handle indentation
transparently.
So "commandline --indented" would print a indented lines,
and "commandline --indented 'if true' ' echo'" would remove the unecessary
indentation before replacing the commandline.
That would probably simplify the logic for the cursor position offset.
When we read bytes like \xfc that don't produce a Unicode code point,
we encode them in a Unicode private use area.
This encoding should be transparent to the user.
We accidentally add it to uvar files as \uf6fc in this case. When reading
it back, read_unquoted_escape() will fail at the "fish_reserved_codepoint(c)"
check. This check is to avoid external input being misinterpreted
as one of our in-band signalling characters like ANY_CHAR (for *).
For encoded raw bytes, this check probably doesn't really matter in terms of
security because the only thing we do with these bytes is convert them back
to raw. So we could allow unescaping them at this point, thus supporting
old uvar files.
However that seems like the wrong direction. PUA encoding should never leak.
So let's instead make sure to serialize it as \xfc instead of \f6fc going
forward.
Fixes#10313
Popular operating systems support shift-delete to delete the selected item
in an autocompletion widgets. We already support this in the history pager.
Let's do the same for up-arrow history search.
Related discussion: https://github.com/fish-shell/fish-shell/pull/9515
On
a;
we don't expand the abbreviation because the cursor is right of semicolon,
not on the command token. Fix this by making sure that we call expand-abbr
with the cursor on the semicolon which is the end of the command token.
(Now that our bind command execution order is less surprising, this is doable.)
This means that we need to fix the cursor after successfully expanding
an abbreviation. Do this by setting the position explicitly even when no
--set-position is in effect.
An earlier version of this patch used
bind space self-insert backward-char expand-abbr or forward-char
The problem with that (as a failing test shows) was that given "abbr m
myabbr", after typing "m space ctrl-z", the cursor would be after the "m",
not after the space. The second space removes the space, not changing the
cursor position, which is weird. I initially tried to fix this by adding
a hack to the undo group logic, to always restore the cursor position from
when begin-undo-group was used.
bind space self-insert begin-undo-group backward-char expand-abbr end-undo-group or forward-char
However this made test_torn_escapes.py fail for mysterious reasons.
I believe this is because that test registers and triggers a SIGUSR1 handler;
since the signal handler will rearrange char events, that probably messes
with the undo group guards.
I resorted to adding a tailor-made readline cmd. We could probably remove
it and give the new behavior to expand-abbr, not sure.
Fixes#9730
File names that have lots of spaces look quite ugly when inserted as
completions because every space will have a backslash.
Add an initial heuristic to decide when to use quotes instead of
backslash escapes.
Quote when
1. it's not an autosuggestion
2. we replace the token or insert a fresh one
3. we will add a space at the end
In future we could relax some of these requirements.
Requirement 2 means we don't quote when appending to an existing token.
Need to find a natural behavior here.
Re 3, if the completion adds no space, users will probably want to add more
characters, which looks a bit weird if the token has a trailing quote.
We could relax this requirement for directory completions, so «ls so»
completes to «ls 'some dir with spaces'/».
Closes#5433
On Konsole, given
bind escape,i 'echo escape i'
bind alt-i 'echo alt-i'
pressing alt-i triggers the wrong binding. This is because we treat "escape
followed by i" as "alt-i". This is to support raw sequences like "\ei"
which are probably meant as "alt-i" -- we match such inputs to both mappings.
This double matching is not necessary for new-style bindings which
unambiguously describe the key presses, so let's activate this sequence
matching only for bindings specified as raw sequences.
Conversely, we currently fail to match an XTerm raw binding for ctrl-enter:
echo 'XTerm.vt100.formatOtherKeys: 0' | xrdb
xterm -e fish
bind \e\[27\;5\;13~ execute
because we decode this to a single char; we match the leading CSI but not
the entire sequence. So this is a raw binding where we accidentally
match full, modified keys. Fix that too (two birds with one stone).
I think commit 8386088b3 (Update commandline state changes eagerly as well,
2024-04-11) broke the alt-s binding.
This is because we update the commandline state snapshot (which is consumed
by builtin commandline and others) only at key points. This seems like a
dubious optimization. With the new streamlined bind execution semantics,
this doesn't really work anymore; any shell command can run any number of
commands like "commandline -i foo" which should synchronize.
Do the simple thing of calculating the snapshot whenever needed.
The search term highlighting looks looks really bad on the default theme
because the command is highlighted as dark blue and the search term adds
a dark background. If this new feature motivates us to finally fix this,
that would be great.
Closes#10430
Some of these handled multiline prompts but not multiline command lines. We
first need to move the cursor to the end of the commandline, then we can
print a message. Finally, we need to move the cursor back to where it was.
The new reader_execute_readline_cmd() runs apply_commandline_state_changes()
to make sure that given
bind x "commandline --insert foo; commandline -f backward-char"
the backward-char command knows about the insertion of "foo". This
causes problems when running "sleep 1&" and typing some characters -
the commandline will be cleared when the job finishes. This is because
apply_commandline_state_changes() works with stale information in this case.
Let's call it as soon as we know it's needed. This is less messy and fits
better with the new bind function semantics ("execute things in the order
they are written").
This makes them more convenient to use interactively, similar to the existing
\c and \a versions. The resulting bind output keeps using the canonical
ctrl/alt version.
Not sure about s- because that's somewhat ambiguous, it could be "super".
See the parent commit for some context. Turns out that 8bf8b10f6 (Extended &
human-friendly keys, 2024-03-30) broke this for terminals that speak CSI u.
This is pretty complex, probably not worth it.
When a terminal sends \x1ba, that could be either escape,a or alt-a.
Historically we've handled this with an escape delay that defaults to 30
milliseconds. If we read nothing for that time, it's escape. Otherwise it's
an alt modifier (or an escape sequence).
As a side effect of 8bf8b10f6 (Extended & human-friendly keys, 2024-03-30) we
added a new way of disambiguating escape: whenever we read the escape byte,
we immediately try another (nonblocking) read. If it succeeds, we treat it
as modifier, else it's escape. Before that commit, we didn't have a concept
of modifiers.
The new way works fine for disambiguating escape,a from alt-a (as pressed
by the user) because only for alt-a the data is sent in the same packet.
So we no longer need the escape delay to disambiguate the alt from the
escape key. Let's simplify things by not using it by default.
The escape delay as set by fish_escape_delay_ms also serves another purpose;
it allows to disambiguate "escape,a" from "escape (pause) a". For that use
case we want to keep it.
As mentioned in 8a7c3ceec (Don't abandon line after writing control sequences,
2024-04-06) we need to freshed stdout timestamps after writing to stdout
but before we might redraw, in particular when writing control sequences.
Commit a583fe723 ("commandline -f foo" to skip queue and execute immediately,
2024-04-08) made "commandline -f repaint" redraw immediately, while still
executing the bound shell command; at that time we have written "disabling"
sequences but not refreshed timestamps yet, so do that.
This is probably not needed for commands outside the repaint family.
Needless to say that this is messy, maybe we can simplify things in future.
Ref https://github.com/fish-shell/fish-shell/issues/10409#issuecomment-2044863817
A failing test might emit an OSC 133 prompt marking sequence, confusing
the parent terminal to think the test output contains a shell prompt. Let's
remove these.
If a key's codepoint is in the PUA1 range, it could
be either from our own named keys (like key::Space)
or from a CSI u key that we haven't assigned a name yet
https://sw.kovidgoyal.net/kitty/keyboard-protocol/#functional-key-definitions
(The latter can still be bound using the \u1234 or the equivalent \e[4660u
raw CSI u sequence.)
It doesn't make sense to insert a PUA character into the commandline when
the user presses PrintScreen; ignore them silently.
This partially reverts b77d1d0e2 (Stop crashing on invalid Unicode input,
2024-02-27). That commit did:
1. convert input byte sequences that map to a PUA codepoint into several
characters, using our on-char-per-byte PUA encoding.
2. do the same for inputs that are codepoints outside the valid Unicode range.
3. render them as replacement character (one per input byte)
In future, we should probably remove these features altogether, and simply
ignore invalid Unicode code points.
Commit c3cd68dda (Process shell commands from bindings like regular char
events, 2024-03-02) mentions a "weird ordering difference".
The issue is that "commandline -f foo" goes through the input
queue while other commands are executed directly.
For example
bind ctrl-g "commandline -f end-of-line; commandline -i x"
is executed in the wrong order. Fix that.
This doesn't yet work for "commandline -f exit" but that can be fixed easily.
It's hard to imagine anyone would rely on the existing behavior. "commandline
-f" in bindings is mostly used for repainting the commandline.
If a binding was input starting with "\e", it's usually a raw control sequence.
Today we display the canonical version like:
bind --preset alt-\[,1,\;,5,C foo
even if the input is
bind --preset \e\[1\;5C foo
Make it look like the input again. This looks more familiar and less
surprising (especially since we canonicalize CSI to "alt-[").
Except that we use the \x01 representation instead of \ca because the
"control" part can be confusing. We're inside an escape sequence so it seems
highly unlikely that an ASCII control character actually comes from the user
holding the control key.
The downside is that this hides the canonical version; it might be surprising
that a raw-escape-sequence binding can be erased using the new syntax and
vice versa.
We don't yet support all keys from
https://sw.kovidgoyal.net/kitty/keyboard-protocol/#functional-key-definitions
Instead of displaying a private-use character, show the character code;
this can be used to map the key even if we don't know a name for it.
bind \uE011 'echo print screen'
bind ctrl-\uE011 'echo do control + print screen'
Note that it's also possible to mape the raw CSI u sequence, like
bind \e\[57361u 'echo print screen'
but we should not encourage that syntax because it does not allow adding
the modifiers like ctrl.
Of course leaking the PUA character code is not ideal.
As implied by the changelog.
Unfortunately it's not obvious how to access the RefCell value in spite
of a potential (albeit unlikely) present mutable borrow. We need to use a
different type to make it work in such cases, hopefully doing that in future.
In future we could even use panic=abort and use this style of cleanup for
panics (instead of RAII).
For numpad 1 with nulock, Alacritty sends
escape,[,5,7,4,0,0,u
which is codepoint \x31, key "1". We have a terminfo mapping for "sright"
which translates to
escape,[,1,;,2,C
The first two characters, escape and [ match. Then we accidentally match the
"1" from the mapping against the entire sequence, because that sequence is
canonicalized to codepoint "1" . The most blatant problem is that we discard
the rest of the sequence. Fix that.
This allows us to re-enable raw CSI u mappings like "bind \e[1u ..."
which is what kitty uses for shell integration.
This allows terminals like foot and kitty to
* scroll to the previous/next prompt with ctrl-shift-{z,x}
* pipe the last command's output to a pager with ctrl-shift-g
Kitty has existing fish shell integration
shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish which we
can simplify now. They keep a state variable to decide which of prompt start,
command start or command end to output. I think with our implementation
this is no longer necessary, at least I couldn't reproduce any difference.
We also don't need to hook into fish_cancel or fish_posterror like they do;
only in the one place where we actually draw the prompt.
As mentioned in the above shell integration script, kitty disables reflow
when it sees an OSC 133 marker, so we need to do it ourselves,
otherwise the prompt will go blank after a terminal resize.
Closes#10352
If I type
$ echo $SOME_VARIABLE_WIHT_A_TYPO
$ set -S SOME_VARIABLE_WIHT
and press tab, I'm always extremely surprised that this completes to
$ set -S fish_history
which is because $history[1] contains the typo'd variable name. I don't
think anyone intends to filter by that last 3-4 history items, so let's
remove this pitfall.
Note that I usually hit this scenario with undefined variables, not necessarily
typos.. "set -S" is usually redundant but it's still quite nice in this case,
to rule out any weird empty strings/empty lists.
Commit 8164855b7 (Disable terminal protocols throughout evaluation, 2024-04-02)
changed where we output control sequences (to enable bracketed paste and CSI).
Likewise, f285e85b0 (Enable focus reporting only just before reading from
stdin, 2024-04-06) added control sequence output just before we read().
This output causes problems because it invalidates our stdout/stderr
timestamps, which causes us to think that a rogue background process wrote
to the terminal; we react by abandoning the current line and redrawing the
prompt below. Our fix was to refresh the TTY timestamps after we run a bind
command that might add stdout (#3481).
Since commit c3cd68dda (Process shell commands from bindings like regular
char events, 2024-03-02), this timestamp refresh logic is in the wrong place;
shell commands are run later now; we could move it but wait -
... we also need to make sure to refresh timestamps after outputting control
sequences. Since bracketed paste is enabled after CSI u, we can skip the
latter. Additionally, since we currently output control sequences before
every single top-level interactive command, we no longer need to separately
refresh timestamps in between commands.
Fixes#10409
Some terminals send the focus-in sequences ("^[I") whenever focus reporting is
enabled. We enable focus reporting whenever we are finished running a command.
If we run two commands without reading in between, the focus sequences
will show up on the terminal.
Fix this by enabling focus-reporting as late as possible.
This fixes the problem with `^[I` showing up when running "cat" in
gnome-terminal https://github.com/fish-shell/fish-shell/issues/10411.
This begs the question if we should do the same for CSI u and bracketed paste.
It's difficult to answer that; let's hope we find motivating test cases.
If we enable CSI u too late, we might misinterpret key presses, so for now
we still enable those as early as possible.
Also, since we now read immediately after enabling focus events, we can get
rid of the hack where we defer enabling them until after the first prompt.
When I start a fresh terminal, the ^[I no longer shows up.
It's not clear whether builtin read should be able to do everything
that the normal prompt does but I guess we haven't found a problem yet.
Given that read could be used to read a single character at a type,
it's a bit odd to toggle terminal protocols all the time.
But that's not the typical case (at least not for when stdin is a TTY),
and it seems fine.
Teste with
bind ctrl-4 'echo yay'
Regressed in 8164855b7 (Disable terminal protocols throughout evaluation,
2024-04-02).
Apparently VTE terminals send the "focus in" event whenever we re-enable
focus reporting. That's probably a sensible thing to do.
Anyway, our problem is simply that we accidentally end history search on these
focus events which are implemented as anonymous (unmappable) readline cmds.
Perhaps there should be a separate cmd category.
Focus events show up as key::Invalid which is a weird private use code point;
probably we can get rid of this key..
Fixes#10411
Similar to 20bbdb68f (Set terminal title unconditionally, 2024-03-30).
While at it, get rid of a few unnecessary guards (we are never called from
a command substitution, so the check only adds confusion).
I'm not sure if it's worth supporting a terminal that mishandles unknown OSC
and CSI sequences. Better to fix the terminal. Note that there are Emacs
terminals available that don't have this problems; for example "vterm".
See the changelog additions for user-visible changes.
Since we enable/disable terminal protocols whenever we pass terminal ownership,
tests can no longer run in parallel on the same terminal.
For the same reason, readline shortcuts in the gdb REPL will not work anymore.
As a remedy, use gdbserver, or lobby for CSI u support in libreadline.
Add sleep to some tests, otherwise they fall (both in CI and locally).
There are two weird failures on FreeBSD remaining, disable them for now
https://github.com/fish-shell/fish-shell/pull/10359/checks?check_run_id=23330096362
Design and implementation borrows heavily from Kakoune.
In future, we should try to implement more of the kitty progressive
enhancements.
Closes#10359
To do so add an ad-hoc "commandline --search-field" to operate on pager
search field.
This is primarily motivated because a following commit reuses the
fish_clipboard_paste logic for bracketed paste. This avoids a regression.
Terminal titles are set with an OSC 0 sequence. I don't think we want to
support terminals that react badly to unknown OSC (or CSI) sequences.
So let's remove our feature detection.
This will fix future false negatives along the lines of
https://github.com/fish-shell/fish-shell/pull/10037
This binding is akin to ForwardSingleChar but it is "passive" in that is not
intended to affect the meta state of the shell: autocompletions are not accepted
if the cursor is at the end of input and it does not have any effect in the
completions pager.
Currently, we expand command-abbrs (those with `--position command`) after `if`, but not after `command` or `builtin` or `time`:
```fish
abbr --add gc "git checkout"
```
will expand as `if gc` but not as `command gc`.
This was explicitly tested, but I have no idea why it shouldn't be?
The incorrect order of operations was being used since && binds tighter than ||
in rust (as with most sane languages).
Under Linux, EAGAIN == EWOULDBLOCK so this would always succeed in the case of a
non-blocking fd without making the call to make_fd_nonblocking().
Comparing to the 3.7.0 C++ code, it looks like this was an oversight introduced
in the migration to rust.
In particular, this allows restoring the terminal on crashes, which is
feasible now that we have the panic handler. Since std::process::exit() skips
destructors, we need to reshuffle some code. The "exit_without_destructors"
semantics (which std::process::exit() als has) was mostly necessary for C++
since Rust leaks global variables by default.
When fish crashes due to a panic, the terminal window is closed. Some
terminals keep the window around when the crash is due to a fatal signal,
but today we don't exit via fatal signal on panic.
There is the option to set «panic = "abort"» in Cargo.toml, which
would give us coredumps but also worse stacktraces on stderr.
More importantly it means that we don't unwind, so destructors are skipped
I don't think we want that because we should use destructors to
restore the terminal state.
On crash in interactive fish, read one more line before exiting, so the
stack trace is always visible.
In future, we should move this "read one line before exiting" logic to where
we call "panic!", so I can attach a debugger and see the stacktrace.
Looks like "add_custom_command(OUTPUT ...)" assumes the dependencies are
correct which is not always true. We can use "add_custom_target" to always
re-run Cargo.
Unfortunately on Debian "open" is a symlink to "openvt", and there's
no way from outside to tell.
This prevents fish from failing because no browser could be found.
Today fish_cursor_selection_mode controls whether selection mode includes
the cursor. Since it's by default only used for Vi mode, perhaps use it to
also decide whether it should be allowed to select one-past the last character.
Not allowing to select to select one-past the last character is much nicer
in Vi mode. Unfortunately Vi mode sometimes needs to temporarily select
past end (using forward-single-char and such), so reset fish_cursor_selection_mode
for the duration of the binding.
Also fix other things like cursor placement after yank/yank-pop.
Closes#10286Closes#3299
We have
bind --preset -M $mode --sets-mode paste \e\[200~ __fish_start_bracketed_paste
Commit c3cd68dda (Process shell commands from bindings like regular char
events, 2024-03-02) made it so __fish_start_bracketed_paste is no longer
executed before the bind mode is updated.
This is a long-awaited fix but it broke __fish_start_bracketed_paste's
assumption that $fish_bind_mode is the mode before we entered paste mode.
This means we never exit paste mode.
Work around that. I forgot about this issue because I already replaced our
bracketed paste handling on my fork.
This was a misunderstanding, the OBS tumbleweed builds build from a tarball that's pushed manually.
We no longer use corrosion so this dependency is unused.
This reverts commit bdde2b2b35.
Fixes#10391
The current version of serial_test we use (0.4.0)
depends on parking_lot 0.10.2 which in turn
depends on lock_api 0.3.4.
This version of lock_api is vulnerable to [RUSTSEC-2020-0070](https://rustsec.org/advisories/RUSTSEC-2020-0070)
This was patched in lock_api 0.4.2 but we need to update serial_test
to get the update.
Today,
bind foo "commandline -f expand-abbr; commandline -i \n"
does not work because this
1. enqueues an expand-abbr readline event
2. "commandline -i" inserts \n
3. processes the expand-abbr readline event
Since there is no abbreviation on the new line, this doesn't do anything.
PR https://github.com/fish-shell/fish-shell/pull/9398 would fix this
particular instance however it does not fix the issue that "commandline -i"
is run before the expand-abbr is processed by the reader. This is harmless
here but there would be a problem if "commandline" tried to read commandline
state that was created by a preceding command.
It's not super clear to me whether the above binding should work as one
would naively expect. That would imply that "commandline" would need to
drain all input events (at least all synthetic ones) from the input queue,
to ensure it sees the current state.
Fortunately the parent commit makes it so if we separate them
bind foo "commandline -f expand-abbr" "commandline -i \n"
both will be separate events and the commandline state will be synced after
each of them. This fixes abbreviation expansion here.
Also, we can now mix readline cmds and shell commands, which makes it shorter.
A long standing issue is that bindings cannot mix special input functions
and shell commands. For example,
bind x end-of-line "commandline -i x"
silently does nothing. Instead we have to do lift everything to shell commands
bind x "commandline -f end-of-line; commandline -i x"
for no good reason.
Additionally, there is a weird ordering difference between special input
functions and shell commands. Special input functions are pushed into the
the queue whereas shell commands are executed immediately.
This weird ordering means that the above "bind x" still doesn't work as
expected, because "commandline -i" is processed before "end-of-line".
Finally, this is all implemented via weird hack to allow recursive use of
a mutable reference to the reader state.
Fix all of this by processing shell commands the same as both special input
functions and regular chars. Hopefully this doesn't break anything.
Fixes#8186Fixes#10360Closes#9398
Most chat programs I found use Shift+Return to insert a newline while plain
Return sends the message. One user reported having only tried Shift+Return
and not knowing about Alt+Return.
No release notes yet because this only works on a very small number of
terminals. Once we enable CSI u, this should work on most modern terminals.
Multiline search strings are weirdly broken (inserting control characters
in the command line) and probably not very useful anyway.
On the other hand I often want to compose a multi-line command
from single-line commands I ran previously.
Let's support this case by limiting the initial search string to the current
line; and replace only that line.
Alternatively this could operate on jobs (that is, replace a surrounding
"foo | bar") instead of using line boundaries.
This is resistant to misuse by including O_DIRECTORY in the open flags and it is
a separate function from {w,}open_cloexec() in preparation for making that one
return a `File` instead of an `OwnedFd`.
`intersects()` is "any of" while `contains()` is "all of" and while it makes no
difference when testing a single bit, I believe `contains()` is less brittle
for future maintenance and updates as its meaning is clearer.
</pedantic>
More work in prep for having wopen_cloexec() return `File` directly.
This eliminates checking for an invalid fd and makes both ownership and
mutability clear (some more operations that involve changes to the underlying
state of the fd now require `&mut File` instead of just a `RawFd`).
Code that clearly does not use non-blocking IO is ported to use
`Write::write_all()` directly instead of our rusty port of the `write_loop()`
function (which handles EAGAIN/EWOULDBLOCK in addition to EINTR, while
`write_all()` only handles the latter).
Add git as a build requirement. Package name guessed then confirmed by searching
on rpm.pbone.net against openSUSE Tumbleweed.
Log excerpt:
[ 14s] CMake Error at /usr/share/cmake/Modules/ExternalProject.cmake:2910 (message):
[ 14s] error: could not find git for clone of corrosion-populate
The %{_docdir} macro is defined, but due to an oversight is not passed
to CMake in some versions of openSUSE where it should be.
Use doc directives to avoid mucking around with cp.
This is a step towards converting `wopen_cloexec()` to return `File` instead of
`OwnedFd`/`AutocloseFd`.¹
In addition to letting us use native standard library functions instead of
unsafe libc calls, we gain additional semantic safety because `File` operations
that manipulate the state of the fd (e.g. `File::seek()`) require a `&mut`
reference to the `File`, whereas using `RawFd` or `OwnedFd` everywhere leaves us
in a position where it's not clear whether or not other references to the same
fd will manipulate its underlying state.
¹ We actually wouldn't even need `wopen_cloexec()` at all (just a widechar
wrapper) as Rust's native `File::open()`/`File::create()` functionality uses
`FD_CLOEXEC` internally.
I used below script to list all GitHub issues and PRs that are not yet
mentioned in the changelog. It's almost empty now.
While at it, curate the "notable" section and move some entries around,
notably from "interactive improvements" to "bindings".
```shell
ms="fish next-3.x"
{
gh issue list --state closed --milestone "$ms" -L 500
gh pr list --state all --search "milestone:\"$ms\"" -L 500
} | sort -n | while IFS='
' read line; do
set -- $line
grep -qE '\W'$1 CHANGELOG.rst ||
echo https://github.com/fish-shell/fish-shell/issues/$1 "$line"
done
```
* builtin/test: Split Token enum into 2-level hierarchy
* builtin/test: Rearrange the Token enum hierarchy
* builtin/test: Separate Token into Unary and Binary
* builtin/test: import IsOkAnd polyfill
* builtin/test: Rename enum variants one more time
I was able to trigger this by flipping around the history pager.
Since the only applicable caller here already stops if it gets None,
just don't assert.
Unless the editor changed to a different file for some reason.
Note that the Kakoune integration uses -always to export the cursor even if
the user temporarily suppressed hooks - possibly a "fish_indent" hook.
I don't think the existing logic is correct, as the comment says, our internal
state is only matched if we *actually* wrote out the file. But if we ran into an
error, it doesn't match, does it?
The incompatible_msrv one is a false positive because we have polyfills for
is_some_and() and is_ok_or() which are Rust 1.74. I'm not yet sure how to
communicate that to Clippy.
Call fish_should_add_to_history to see if a command should be saved
If it returns 0, it will be saved, if it returns anything else, it
will be ephemeral.
It gets the right-trimmed text as the argument.
If it doesn't exist, we do the historical behavior of checking for a
leading space.
That means you can now turn that off by defining a
`fish_should_add_to_history` that just doesn't check it.
documentation based on #9298
This is absolutely disgusting code, but it works out okay-ish.
The problem is xgettext has no rust support (it's stuck in review
limbo). So we use cargo-expand to extract all invocations of
gettext, and massage all that to generate a
messages.pot ourselves.
We also assume any string constant could be translated.
One of the things that keep me from using Vi mode is that it doesn't define an
insert-mode shortcut to accept autosuggestions. Let's use Control-N because
that Vim key is the closest equivalent.
Closes#10339
The existing logic did not work because:
- Path::new("/foo/bar").ends_with("/bar") does not return true.
- PathBuf::shrink_to() only (potentially) reallocates the backing
storage, and won't have an effect on the stored value.
It appears that the shift-delete key escape sequence is not being generated
because there's no mapping for it in screen-256color, causing the test to fail.
Switch to using f1 for the test.
We are no longer C++, we no longer support xcode
Note: This will remove a warning "DO NOT EDIT" comment from __fish_build_paths.fish, but
that's unnecessary. The file is typically in /usr or another
package-manager-owned location, so people don't typically edit it.
And if it did we don't actually *care*, it'll work fine.
As mentioned in the comment the historical behavior is because pressing unknown
control characters like Ctrl+4 inserts confusing characters, so let's back
out that part of b77d1d0e2 (Stop crashing on invalid Unicode input, 2024-02-27).
We still have the code for rendering control characters, for pasted text,
or text recalled from history. It is unclear whether we should strip those.
Some terminals already strip control characters from pasted text -- but not
all of them: see https://codeberg.org/dnkl/foot/pulls/312 for example which
has a follow up called "Don't strip HT when pasting in non-bracketed mode".
Don't force the internal use of `RefCell<T>`, let the caller place that into
`MainThread<>` manually. This lets us remove the reference to `MainThread<>`
from the definition of `Screen` again and reduces the number of
`assert_is_main_thread()` calls.
Fairly straightforward, with the only unfortunate part of this being that
`Screen` isn't as pure and now encodes the facte that we use it with
main-thread-only stdout `Outputter`.
The regex struct is pretty large at 560 bytes, with the entire
Abbreviation being 664 bytes.
If it's an "Option<Regex>", any abbr gets to pay the price. Boxing it
means abbrs without a regex are over 500 bytes smaller.
IfStatement is 680 bytes, much larger than the other
variants (SwitchStatement is next at 232). An enum is as large as its
largest variant, so this saves a bunch, especially since
DecoratedStatement is much more likely than IfStatement.
This will speed up the no-execute benchmark by 1.07x.
Unlike C++, Rust requires "char" to be a valid Unicode code point. As a
workaround, we take the raw (probably UTF-8-encoded) input and convert each
input byte to a char representation from the private use area (see commit
3b15e995e (str2wcs: encode invalid Unicode characters in the private use
area, 2023-04-01)). We convert back whenever we output the string, which
is correct as long as the encoding didn't change since the data was input.
We also need to convert keyboard input; do that.
Quick testing shows that our reader drops PUA characters. Since this patch
converts both invalid Unicode input as well as PUA input into a safe PUA
representation, there's no longer a reason to not add PUA characters to
the commandline, so let's do that to restore traditional behavior.
Render them as � (REPLACEMENT CHARACTER); unfortunately we show one per
input byte instead of one per code point. To fix this we probably need our
own char type.
While at it, remove some special cases that try to prevent insertion of
control characters. I don't think they are necessary. Could be wrong..
This makes it so code like
```fish
echo foo
echo bar
```
is collapsed into
```fish
echo foo
echo bar
```
One empty line is allowed, more is overkill.
We could also allow more than one for e.g. function endings.
We don't need to know that it tried these five before finally getting
one, the list is *right there*.
It is also very unlikely that someone has "xterm" or "ansi" but not "xterm-256color"
For xterm-256color, we don't warn *at all* because we have that one hardcoded.
This allows us to get the terminfo information without linking against curses.
That means we can get by without a bunch of awkward C-API trickery.
There is no global "cur_term" kept by a library for us that we need to invalidate.
Note that it still requires a "unhashed terminfo database", and I don't know how well it handles termcap.
I am not actually sure if there are systems that *can't* have terminfo, everything I looked at
has the ncurses terminfo available to install at least.
... even if the file hasn't changed. This addresses an oddity in the following
case:
* Shell is started,
* function `foo` is sourced from foo.fish
* foo.fish is *externally* edited and saved
* <Loaded definition of `foo` is now stale, but fish is unaware>
* `funced foo` loads `type -p foo` showing changed definition, user exits
$EDITOR saving no changes (or with $status 0, more generally).
* Stale definition of `foo` remains
If a hostname starts with a dash `-` character, the prompt_hostname function
fails because the `string` function interprets it as an option instead
of an argument.
We still don't support tabs but as of the parent commit, there are no more
weird glitches, so it should be fine to recall those lines?
This reverts commit cc0e366037.
Inserting Tab or Backspace characters causes weird glitches. Sometimes it's
useful to paste tabs as part of a code block.
Render tabs as "␉" and so on for other ASCII control characters, see
https://unicode-table.com/en/blocks/control-pictures/. This fixes the
width-related glitches.
You can see it in action by inserting some control characters into the
command line:
set chars
for x in (seq 1 0x1F)
set -a chars (printf "%02x\\\\x%02x" $x $x)
end
eval set chars $chars
commandline -i "echo '" $chars
Fixes#6923Fixes#5274Closes#7295
We could extend this approach to display a fallback symbol for every unknown
nonprintable character, not just ASCII control characters.
In future we might want to support tab properly.
This reserved 64, which is *gigantic*.
Over all of share/**.fish, 75% of lists are empty, 99.97% are 16
elements or fewer.
Reducing this to 16 reduces memory usage for a gigantic example
script (git.fish pasted a bunch of times for a total of almost 100k
lines) by ~10% and speeds up "--no-execute" time by the same amount.
For smaller scripts it's less noticeable simply because parse time
matters less.
There are other options, like creating the vec ::with_capacity, or
using 8 instead of 16, or even letting the vec just grow
naturally (rust's vec currently grows from 0 to 4 and then doubles,
which isn't terrible for this use), but the point is that 64 is
wasteful and never comes out on top, always in the last two places
comparing a bunch of choices.
Makes it possible to use the sanitizers again.
Note that this requires RUSTFLAGS to be set when running CMake, and will not be
updated when running the build system if the environment variable changes.
Fish functions are great for configuring fish but they don't integrate
seamlessly with the rest of the system. For tasks that can run outside fish,
writing scripts is the natural approach.
To edit my scripts I frequently run
$EDITOR (which my-script)
Would be great to reduce the amount typing for this common case (the names
of editor and scripts are usually short, so that's a lot of typing spent on
the boring part).
Our Alt+o binding opens the file at the cursor in a pager. When the cursor
is in command position, it doesn't do anything (unless the command is actually
a valid file path). Let's make it open the resolved file path in an editor.
In future, we should teach this binding to delegate to "funced" upon seeing
a function instead of a script. I didn't do it yet because funced prints
messages, so it will mess with the commandline rendering if used from
a binding. (The fact that funced encourages overwriting functions that
ship with fish is worrysome. Also I'm not sure why funced doesn't open the
function's source file directly (if not sourced from stdin). Persisting the
function should probably be the default.)
Alternative approach: I think other shells expand "=my-script" to
"/path/to/my-script". That is certainly an option -- if we do that we'd want
to teach fish to complete command names after "=". Since I don't remember
scenarios where I care about the full path of a script beyond opening it in
my editor, I didn't look further into this.
Closes#10266
Commit e5b34d5cd (Suppress autosuggesting during backspacing like browsers do,
2012-02-06) disabled autosuggestion when backspacing. Autosuggestions are
re-enabled whenever we insert anything in the command line. Undo uses a
different code path to insert into the command line, which does not re-enable
autosuggestion.
Fix that.
Also re-enable autosuggestion when undo erases from the command line.
This seems like the simplest approach. It's not clear if there's a better
behavior; browsers don't agree on one in any case.
This is the last remnant of the old percent expansion.
It has the downsides of it, in that it is annoying to combine with
anything:
```fish
echo %self/foo
```
prints "%self/foo", not fish's pid.
We have introduced $fish_pid in 3.0, which is much easier to use -
just like a variable, because it is one.
If you need backwards-compatibility for < 3.0, you can use the
following shim:
```fish
set -q fish_pid
or set -g fish_pid %self
```
So we introduce a feature-flag called "remove-percent-self" to turn it
off.
"%self" will simply not be special, e.g. `echo %self` will print
"%self".
This stops you from doing e.g.
```fish
set pager command less
echo foo | $pager
```
Currently, it would run the command *builtin*, which can only do
`--search` and similar, and would most likely end up printing its own
help.
That means it very very likely won't work, and the code is misguided -
it is trying to defeat function resolution in a way that won't do what
the author wants it to.
The alternative would be to make the command *builtin* execute the
command, *but*
1. That would require rearchitecting and rewriting a bunch of it and
the parser
2. It would be a large footgun, in that `set EDITOR command foo` will
only ever work inside fish, but $EDITOR is also used outside.
I don't want to add a feature that we would immediately have to discourage.
Currently, if you enter `echo` and press up-arrow, it might select
e.g. `echo foo`.
You can then enter text, making it `echo foobar` and press up-arrow
again, but the search string is *still* `echo`.
Many *other* input functions will end history search, including e.g.
expand-abbr, so pressing space by default will already end it.
So this ends the history search once you input something.
Incidentally this allows suggestions to work in this case, so it
Fixes#10287
Note that autosuggestions have been disabled while history search is
active since a08450bcb6, I'm not sure
it's actually *needed*, so it would also be possible to enable it in
that case.
But since this is already awkward (history search is *active* but with
the old search string) and I'm not sure if e.g. suggestions during
history search would be too busy, let's do this first.
With LTO, Release builds are now a lot slower.
For development debug builds are much nicer.
We'll ask packagers to pass Release when building a package.
Unfortunately ninja does not want to be tricked.
I tried `touch`ing a file and writing the date to a file,
and even removing that file before cargo runs, it doesn't work.
So instead we'll do the imperfect solution of enumerating sources.
And yes, we use a GLOB because listing source files is terrible.
Any build system that wants you not to glob is a build system made for
build system people who like touching build systems, not me.
The default codegen units is 16 but we set it to 1*. On my system, this
saves 0.1 MB (2%) in the unstripped binary, while adding 10s (20%) to the
build time. This doesn't seem worth, better stick to the defaults.
[*] along enabling fat LTO which is debatable too
gpg's --use-embedded-filename is a dangerous option that can cause gpg
to write arbitrary content to arbitrary files.
According to the GnuPG maintainer, this is not an option recommended
for use (https://dev.gnupg.org/T4500). Fish shouldn't encourage users
to supply it.
I've offered https://dev.gnupg.org/T6972 to upstream to make it even
more clear that this option is a bad idea.
While removing it, we might as well also remove
--no-use-embedded-filename, since it is effectively a no-op.
This reduces the test time by ~33% on my system (23s to 15s)
Given that it takes ~180-240s on Github Actions, if we get a reduction
like that we can save over a minute.
These are dog-slow at building, and the tests themselves are barely
sped up running as release.
Given that we have ~10 minute build and ~3 minute test time on Github
Actions on macOS, let's see if this speeds it up
(we can also do it for the others, but the most important is the
slowest test because that's what stops the checkmark appearing)
We only use this
1. if we have localeconv_l
2. to get the decimal point / thousands separator for numbers
So we can ignore all this and directly create a purely LC_NUMERIC locale.
This *was* more useful when we were in C++ and the printing functions
all relied on locale, but we only use this in printf and that only
extracts the number stuff.
Commit b768b9d3f (Use fuzzy subsequence completion for options names as well,
2024-01-27) allowed completing "oa" to "--foobar", which is a false positive,
especially because it hides other valid completions of non-option arguments.
Let's at least require a leading dash again before completing option names.
The lines of code I commented on in #10254 were meant to serve only as examples
of the changes I was requesting, not the only instances.
Also just use `Mode::from_bits_truncate()` instead of unsafe or unwrapping since
we know the modes are correct.
* Fix build on NetBSD
Notably:
1. A typo in `f_flag` vs `f_flags` - this was probably never tested
2. Some pointless name differences - `st_mtimensec` vs
`st_mtime_nsec`
3. The big one: This said that LC_GLOBAL_LOCALE() was -1 "everywhere".
Well, not on NetBSD.
* ifdef for macos
Instead of skipping for non-interactive shells, skip when stdin is not a tty.
This allows the cursor to be set for scripts that use the `read` command.
We use this so you can run fish from the build directory and it picks
up its data files.
If this wasn't canonicalized, that would break if you're building with
a $PWD through a symlink.
* Update just.fish to handle descriptions for completions
This change updates fish completions to also include descriptions for justfile recipes. It has been tested with descriptions for recipes with arguments as well
* rely on fish only (avoid sed)
Version 2.1.0 introduced subsequence matching for completions but as the
changelog entry mentions, "This feature [...] is not yet implemented for
options (like ``--foobar``)". Add it. Seems like a strict improvement,
pretty much.
.unwrap() is in effect an assert(). If it is applied mistakenly, the
program crashes and there isn't a good error.
I would like it to be used as a last resort. In these cases there are
nicer ways to do it that handle a missing result properly.
Fix cases like
eval my-cmd (commandline -o)
complete -C "my-cmd $(commandline -o)"
In both cases, we spuriously evaluate tokens like "(inside-quoted-string)"
as command substitutions. Fix this by escaping the strings. The momentarily
regresses the intended purpose of "eval" -- to expand variables -- but the
next commit will fix that.
Issue #10194 reports Cobra completions do
set -l args (commandline -opc)
eval $args[1] __complete $args[2..] (commandline -ct | string escape)
The intent behind "eval" is to expand variables and tildes in "$args".
Fair enough. Several of our own completions do the same, see the next commit.
The problem with "commandline -o" + "eval" is that the former already
removes quotes that are relevant for "eval". This becomes a problem if $args
contains quoted () or {}, for example this command will wrongly execute a
command substituion:
git --work-tree='(launch-missiles)' <TAB>
It is possible to escape the string the tokens before running eval, but
then there will be no expansion of variables etc. The problem is that
"commandline -o" only unescapes tokens so they end up in a weird state
somewhere in-between what the user typed and the expanded version.
Remove the need for "eval" by introducing "commandline -x" which expands
things like variables and braces. This enables custom completion scripts to
be aware of shell variables without eval, see the added test for completions
to "make -C $var/some/dir ".
This means that essentially all third party scripts should migrate from
"commandline -o" to "commandline -x". For example
set -l tokens
if commandline -x >/dev/null 2>&1
set tokens (commandline -xpc)
else
set tokens (commandline -opc)
end
Since this is mainly used for completions, the expansion skips command
substitutions. They are passed through as-is (instead of cancelling or
expanding to nothing) to make custom completion scripts work reasonably well
in the common case. Of course there are cases where we would want to expand
command substitutions here, so I'm not sure.
Move all qmark tests to `scoped_test()` sections with explicitly set feature
flags. We already test the default qmark behavior in the functionality tests.
This prefers `-s` to `-v` - we have a *lot* more uses of `command -s`, it's the easier
mnemonic *and* the more compatible-with-fish option.
Also we don't really need the separate section that explains what
these options do *again*.
It seems the logic for calculating the cursor position was not ported correctly,
because the correct place to insert it is at the cursor_pos regardless of
range.start, going by the parameters submitted to the function and the expected
result.
This allows running a fish built from `cargo build` *and* built via
cmake.
In future, we should make this an optional thing that's removed from
installed builds.
We're already moving them, we can remove the awkward dot that hides
them, and while we're doing that remove the useless $USER as well.
Most systems will have only one of these files - it's rare to run a
second package manager (especially for anything more than
bootstrapping a container).
These take a *lot* of time - `pip3` takes 180ms, `pipenv` takes 320ms
on my system.
Note that this removes a number of obsolete workarounds - pip's was
fixed in 2017 (and pip2 is less and less of a thing), pipenv's change
was in 2019.
Since these are packaging tools with access to the internet they
should really be kept up-to-date, so it is unlikely someone still uses
these old versions.
We have a lot of completions that look like
```fish
pip completion --fish 2>/dev/null | source
```
That's *fine*, upstream gives us some support.
However, the scripts they provide change very rarely, usually not even
every release, and so running them again for every shell is extremely
wasteful.
In particular the python tools are very slow, `pip completion --fish`
takes about 180ms on my system with a hot cache, which is quite
noticeable.
So what we do is we run them once, store them in a file in our cache
directory, and then serve from that.
We store the mtime of the command we ran, and compare against that for
future runs. If the mtime differs - so if the command was up or
downgraded, we run it again.
This will move all current cache uses to e.g. ~/.cache/fish/
That's better anyway because it makes it easier to remove.
Also it allows supplying a subdir so you can do `__fish_make_cache_dir
completions`
to get ~/.cache/fish/completions.
NCurses headers contain this conditional "#define cur_term":
print "#elif @cf_cv_enable_reentrant@"
print "NCURSES_WRAPPED_VAR(TERMINAL *, cur_term);"
print "#define cur_term NCURSES_PUBLIC_VAR(cur_term())"
print "#else"
OpenSUSE Tumbleweed uses this configuration option; For reentrancy, cur_term
is a function. If the NCurses autoconf variable @NCURSES_WRAP_PREFIX@
is not changed from its default, the function is called _nc_cur_term.
I'm not sure if we have a need to support non-default @NCURSES_WRAP_PREFIX@
but if we do there are various ways;
- search for the symbol with the cur_term suffix
- figure out the prefix based on the local curses installation,
for example by looking at the header files.
Fixes#10243
If I alias "e" to "emacsclient" it will probably accept the same options.
Let's dereference the alias so we can detect support for passing the cursor
position in more cases.
This does not solve the problem for recursive cases (e.g. alias of another
alias). If we want to handle that we would need cycle detection.
This is run in the current locale, without resetting to en_US.UTF-8
like our integration tests do.
So if you want to check for a specific message you need to check the
localized version.
This is awkward because some systems really want $SHELL to be
sh-compatible, it's also duplicated with the actual docs and not
really something you have to do in the first five minutes of using
fish.
Supersedes #10229
CMP0066: Honor per-config flags in try_compile() source-file
signature.
CMP0067: Honor language standard in try_compile() source-file signature.
We no longer have any try_compile
This was previously limited to Linux predicated on the existence
of certain headers, but Rust just exposes those functions unconditionally. So
remove the check and just perform the mtime hack on Linux and Android.
Make sure to also look for the error part that occurs after the last format
specifier.
Still not great because it won't fail if there's unexpected output at the
beginning or end of the string.
Commit 5f849d0 changed control-C to print an inverted ^C and then a newline.
The original motivation was
> In bash if you type something and press ctrl-c then the content of the line
> is preserved and the cursor is moved to a new line. In fish the ctrl-c just
> clears the line. For me the behaviour of bash is a bit better, because it
> allows me to type something then press ctrl-c and I have the typed string
> in the log for further reference.
This sounds like a valid use case in some scenarios but I think that most
abandoned commands are noise. After all, the user erased them. Also, now that
we have undo that can be used to get back a limited set of canceled commands.
I believe the original motivation for existing behavior (in other shells) was
that TERM=dumb does not support erasing characters. Similarly, other shells
like to leave behind other artifacts, for example when using tab-completion
or in their interactive menus but we generally don't.
Control-C is the obvious way to quickly clear a multi-line commandline.
IPython does the same. For the other behavior we have Alt-# although that's
probably not very well-known.
Restore the old Control-C behavior of simply clearing the command line.
Our unused __fish_cancel_commandline still prints the ^C. For folks who
have explicitly bound ^C to that, it's probably better to keep the existing
behavior, so let's leave this one.
Previous attempt at #4713 fizzled.
Closes#10213
This function is a hotspot, but it has inefficient codegen:
1. For whatever reason, the chars() iterator of wstr is slower
than that of a slice. Use the slice.
2. Unnecessary overflow checks were preventing vectorization.
Switch to a more optimized implementation.
This improves aliases benchmark time by about 9%.
This was used in CMake to detect invalid mbrtowc implementations. The only known
case was on SnowLeopard, which is no longer supported. Remove this file.
Since none of the compiles(xxx) calls are to particularly complex code, we can
just use `rsconf` directly to test for the presence of the symbols or headers as
needed.
Note that it seems at least some of the previous detection was not working
correctly; in particular HAVE_PIPE2 was evaluating to false on my WSL install
where pipe2(2) was available (caught because it revealed some compilation errors
in that conditional compilation path after porting).
I kept the cfg names and the tests themselves mostly as-is, though we might want
to change that to conform with the rust convention of lowercase cfg names and
decide whether we want to prefix all these with have_, fish_, or nothing at all.
Also the posix_spawn() test should probably check for the symbol `posix_spawn()`
rather than the header `spawn.h` since we don't use it via the header but rather
via the symbol (but in reality they're almost certainly going to give the same
result).
NB: I only encountered this when rewriting the cfg detection, which means that
the previous detection wasn't correct since I have pipe2 on Linux but didn't run
into this build error before.
I had originally created a safe `set_locale()` wrapper and clippy-disallowed
`libc::setlocale()` but almost all our uses of `libc::setlocale()` are in a loop
where it makes much more sense to just obtain the lock outright then call
`setlocale()` repeatedly rather than lock it in the wrapper function each time.
No need to use cfg_attr and have to worry about syncing the preconditions for
the cfg_attr with the preconditions for where `slice_contains_slice()` is used
in the codebase, just mark it as `allow(unused)` with a comment.
pcre2-sys includes a vendored copy of PCRE2, which allows for
statically-linked PCRE2. Hook this up to the CMake build variable, and
remove the C++ integration for PCRE2.
They are probably not terribly useful for us but let's see what happens.
Unfortunately cargo does not properly forward the combination of "RUSTFLAGS"
and "--target" that is currently required to build with ASan [1]. Hence doctests
will fail to link on ASan builds. Let's disable doctests when ASan is active.
[1]: https://github.com/rust-lang/cargo/issues/10666 et al
Use Rust for executables
Drops the C++ entry points and restructures the Rust package into a
library and three binary crates.
Renames the fish-rust package to fish.
At least on Ubuntu, "fish_indent" is built before "fish".
Make sure export CURSES_LIBRARY_LIST to all binaries to make sure
that "cached-curses-libnames" is populated.
Closes#10198
With the next commit, if I run
docker/docker_run_tests.sh --shell-after docker/jammy-asan-clang.Dockerfile
I get this in test_string.fish and test_git.fish:
=================================================================
==8339==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 72 byte(s) in 1 object(s) allocated from:
#0 0x55a8a637eb45 in realloc /rustc/llvm/src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:85:3
#1 0x7facb841b6cc in _nc_doalloc (/lib/x86_64-linux-gnu/libtinfo.so.6+0x106cc) (BuildId: e22ba7829a55a0dec2201a0b6dac7ba236118561)
SUMMARY: AddressSanitizer: 72 byte(s) leaked in 1 allocation(s).
Strangely there is no tparm in the call stack. It does not seem to happen
in CI.
This makes "ninja test" write only to the build directory, not to the source
tree. This enables our docker script which mounts the source as read-only.
Some tests create files like "./test/test-home". Traditionally the did so
in the first parent directory that contained tests/test.fish; so either a
build directory or the root.
The new rust version always changes directory to the root. This blows up
when running with our docker/ files, which mount the source as read-only.
Fix this by always changing directory to the build directory.
In future we could extend this to not chdir if FISH_BUILD_DIR was not
specified, to match traditional behavior. No strong opinions here.
Update the pydoctheme.css file to add support for print media.
The code was adapted from the existing support for screens that are less than
700px wide, with the following changes:
- Remove the documents and sections index
- Remove the quick search
- Remove dead CSS code
Additionally, add section numbers and ensure that code blocks are never split
across multiple pages.
GNUInstallDirs is what defines CMAKE_INSTALL_FULL_BINDIR and such, so
the setting in Rust.cmake didn't work.
This also makes build.rs error out if any of these aren't defined
This would highlight `$var["foo"]` as an error because
parse_util_slice_length didn't advance the iterator.
There's got to be a nicer way to write this.
The C++ code implicitly relied on wrapping behavior.
There are probably more cases like this. Maybe we should disable
"overflow-checks" in release mode.
This would crash from the highlighter for something like
`PATH={$PATH[echo " "`
The underlying cause is that we use "char_at" which panics on
overread.
So instead this implements try_char_at and then just returns None.
This is more correct - we don't want to change how we encode this
string in the middle of encoding it, and also happens to be a bit
faster in my benchmarks because this is actually a function call
according to valgrind.
We assume that you use something like hyperfine to run warmups, like
our driver script does.
This allows the script to be run e.g. in valgrind without being too
much of a pain in the gluteus.
Iterator::last() consumes the entire iterator, even for DoubleEndedIterator,
see https://github.com/rust-lang/rust/pull/28125#issuecomment-145070161
Because of this, "at_line_start()" took 90% of
fish_indent share/completions/git.fish
making it take 1000ms instead of 30 ms. Fix that.
Keep running tests serially to avoid breaking assumptions.
I think many of these tests can run in parallel and/or don't need test_init().
Use the safe variant everywhere, to get it done faster.
Here are the differences to the C++ version in fish_tests:
1. we don't need to chdir to repo root, cargo test already does.
2. we don't need srandom because we already use deterministic RNGs for tests.
3. we don't yet call asan_before_exit(). Not yet sure how to hook into
"cargo test" before exit.
This will allow to use "cargo test" for unit tests that depend on our
curses.rs.
This means that Rust.cmake depends on ConfigureChecks, so move that one to
the front.
Today, debounce-style work items are only created from the main thread.
The work to compute the result is done in a background thread but the
completion callback is called on the main thread again.
The completion callbacks used by the reader capture a shared reference to
ReaderData, which includes a Parser. Neither of those types needs to be
sent across threads.
The debounce machinery moves the completion callback into a function object
that is moved to the background thread and back again. Because of this
there is a Send requirement on the completion callback.
Since we already synchronize on MAIN_THREAD_QUEUE, we don't need Send from
the function object. Lift the requirement.
This removes an awkward hack from ParseError::describe_with_prefix,
where it added errors for two error codes.
andor_in_pipeline was already there, so we just need bare_variable_assignment.
Some of the completions recently introduced called Blender itself to query some
arguments, and Blender sometimes prints messages to stderr. This output was not
filtered, resulting in the shell printing irrelevant messages during completion.
This would misname `\e\x7F` as "backspace":
bind -k backspace 'do something'
bind \e\x7F 'do something'
because it would check if there was any key *in there*.
This was probably meant for continuous mode, but it simply doesn't
work right. It's preferable to not give a key when one would work over
giving one when it's not correct.
This file uses the questionable "self.somemethod(self.somefield)" pattern.
We should either set the functions free or stop passing redundant parameters.
Not sure.
For now fix one of them to avoid a string clone.
This implements input and input_common FFI pieces in input_ffi.rs, and
simultaneously ports bind.rs. This was done as a single commit because
builtin_bind would have required a substantial amount of work to use the input
ffi.
This will support rewriting the input machinery in Rust.
Note that while there are a lot of keys here, in practice this is very fast -
taking on the order of microseconds to populate.
We run __fish_enable_bracketed_paste on every shell prompt, and inside
edit_command_buffer. This protects from accidents when pasting control
characters, and makes sure the paste results in a single undo group.
Let's do the same for builtin read.
Found while doing the research for #10101
- Replace short options with old-style options: even though they are
single-letter, Blender's options cannot be combined.
- Add comments to separate blocks of options, mirroring Blender's help message.
- Add missing options: render-frame, python-use-system-env, register-allusers,
unregister, unregister-allusers.
- Remove options: debug-gpu-disable-ssbo, debug-gpu-renderdoc, -R.
- Fix typos:
- debug-depsgraph-eval (was -evel)
- debug-depsgraph-pretty (was -time)
- app-template (was open-last)
- Update output formats:
- Add descriptions.
- Add HDR, TIFF, OpenEXR, OpenEXR Multilayer, FFmpeg, Cineon, DPX, JPEG 2000,
and WebP, which are optional but generally available.
- Remove IRIZ, which is no longer available.
- Fix arguments for --use-extension: they should be 0 or 1, not true or false.
- Make env-system-* options require a parameter.
- Improve --add-ons by querying the list of add-ons inside Blender rather than a
hardcoded path. This is because Blender's add-on modules may come from many
different paths which depend on platform.
- Fix __blender_echo_input_file_name, by relying on extension.
- Fix listing of scene datablocks inside Blend file.
- Add listing of Python text datablocks to execute inside Blend file.
Closes#10150
Adhere as best as possible to the style guidelines at
https://www.nordtheme.com/docs/colors-and-palettes. Some adaptations were made
so that `functions <function>` is also syntax highlighted per the upstream
recommendations.
Additionally, the theme file has been reordered to follow the order of variables
defined in interactive syntax-highlighting-variables documentation.
This was an issue with "--no-execute", which has no variables and
therefore no $HOME:
```fish
fish --no-execute /path/to/file
```
would say the error is in `~/path/to/file`.
Instead, since this is just for a message, we simply return the
filename without doing the replacement.
Fixes#10171
The existing subsequence search commonly returns false positives.
Support globs, to allow searching for disconnected substrings in a better way.
Closes#10143Closes#10131
When working on a C or C++ projects, it is often handy to compile a
single file (e.g. large refactoring where many files fail to compile so
compiling a single file results in less compiler errors making the compiler
output significantly easier to read and navigate). Current completion offers
only ninja targets which are usually just top level binaries. This commit makes
object files and library files to be offered in the ninja completion.
The change is inspired by the zsh ninja completion [1], but aims to reduce noise
by only matching for entries ending in ".o", ".so" or ".a".
[1] c828f06e08/src/zsh/_ninja (L30)
The "#[bench]" attribute is not allowed in stable Rust, so keep it behind
a new feature flag. Run on nightly Rust with
$ cargo bench --features=bechmark
test tests::encoding::bench::bench_convert_ascii ... bench: 125,988 ns/iter (+/- 1,128) = 1040 MB/s
Repeated
CARGO_LOG=cargo::core::compiler::fingerprint=trace cargo b
show that we always rebuild because of "compat.c". Not sure why.
Let's disable this for now so we can use the cache (for test targets etc.).
We rarely attach trait methods to stdlib types so this warning is unlikely to
be a true positive It is a false positive for the methods defined in future.rs.
It's not always obvious which method is selected when it's available in the
stdlib but I haven't seen a build failure yet. So let's disable the warning.
In future we might be able suppress it per method, see Rust issue 48919.
We often want to format and print a string to a fd, usually stdout/stderr.
In general we can't use "format!", "print!", "eprint!" etc. because they don't
know about our use of WString where we encode of invalid Unicode characters
in the private use area.
Instead we use "wwrite_to_fd()".
Since we unfortunately don't have a "wformat!()" yet, we use "sprintf!()"
to create a formatted wstring to pass to "wwrite_to_fd()".
Add "printf!" and "eprintf!" to stand in for "print!" and "eprint!".
For printing to files other than stdout and stderr, keep "fwprintf!" but
drop the "w" since our "sprintf!" always produces wide strings.
Replace "fputws" with "fprintf" though we could also use "wwrite_to_fd"
if performance matters.
Unlike std::io::stdout(), we don't use locking yet.
Remaining work:
- There are more places where we use \be?print(ln)?!
Usually we print strings that are guaranteed to be valid UTF-8, but not
always. We should probably make all of them respect our WString semantics
but preferrably keep using the native Rust format strings (#9948).
- I think flog.rs currently uses String so it won't handle invalid Unicode
characters. We should probably fix this as well.
These compile checks are expected to produce compiler errors on some systems.
The errors show up when there is an unrelated error, this is probably quite
confusing so fix that. Should revisit this later.
Like FLOGF!, this now needs at least one argument to format.
This avoids some issues with missing variables and broken format
strings - it is how I found 13ba5bd405 -
where disown had a format string, with two placeholders, but no
arguments to fill them with.
For use in e.g. macros, where it's otherwise hard to tell if we have
something to format or not, this adds a wgettext_maybe_fmt! version to
"maybe" format, if necessary.
In LastC++11, an empty history item means we either reached the end of history,
or the item is actually empty. The second meaning is still true. We never
append empty history items but the history file might have been modified.
Fixes#10129
Recall that universal notifiers are used to report changes to universal
variables to other shell instances. This adds a new strategy based on using
inotify to directly monitor the universal variables
file.
We have tried this in the past and abandoned it because it doesn't properly
work on some CI systems - let's try again.
This
1. Skips access() if we only have "special" permissions like the owner
that need stat
2. Does the geteuid()/getegid() *once* outside of filter_path, if we
need it
In the extreme case of `path filter --perm user,group` it will remove
3 syscalls per file.
This makes it easier to get *any pager* in the number of places we do.
Unfortunately:
1. It can't just execute the pager because that might block
2. We can't really set the necessary options for less here
so they still need to be set outside.
This
Fixes#10074
by falling back to `cat` in that case. We could also decide to abort
instead of using a non-pager, but for history that's probably fine.
Drop support for history file version 1.
ParseExecutionContext no longer contains an OperationContext because in my
first implementation, ParseExecutionContext didn't have interior mutability.
We should probably try to add it back.
Add a few to-do style comments. Search for "todo!" and "PORTING".
Co-authored-by: Xiretza <xiretza@xiretza.xyz>
(complete, wildcard, expand, history, history/file)
Co-authored-by: Henrik Hørlück Berg <36937807+henrikhorluck@users.noreply.github.com>
(builtins/set)
This reduces noise in the upcoming "Port execution" commit.
I accidentally made IoStreams a "class" instead of a "struct". Would be
easy to correct that but this will be deleted soon, so I don't think we care.
These printed "Unknown error while evaluating command substitution".
Now they print something like
```
fish: for: status: cannot overwrite read-only variable
for status in foo; end
^~~~~^
in command substitution
fish: Invalid arguments
echo (for status in foo; end)
^~~~~~~~~~~~~~~~~~~~~~~^
```
for `echo (for status in foo; end)`
This is, of course, still not *great*. Mostly the `fish: Invalid
arguments` is basically entirely redundant.
An alternative is to simply skip the error message, but that requires some
more scaffolding (describe_with_prefix adds some error messages on its
own, so we can't simply say "don't add the prefix if we don't have a
message")
(cherry picked from commit 1b5eec2af6)
Refresh some stale CSS, improve some rendering, and fix some bugs.
Some of the CSS no longer applied. Remove the bright red X in history
and use a tamer color. Fix the prev/next paginator buttons from moving
for large paginations. Fix the calculation about disabling prev/next.
* wildcard: Remove file size from the description
We no longer add descriptions for normal file completions, so this was
only ever reached if this was a command completion, and then it was
only added if the file wasn't a regular file... in which case it can't
be an executable.
So this was dead.
* Make possible_link() a maybe
This gives us the full information, not just "no" or "maybe"
* wildcard: Rationalize file/command completions
This keeps the entry_t as long as possible, and asks it, so especially
on systems with working d_type we can get by without a single stat in
most cases.
Then it guts file_get_desc, because that is only used for command
completions - we have been disabling file descriptions for *years*,
and so this is never called there.
That means we have no need to print descriptions about e.g. broken symlinks, because those are not executable.
Put together, what this means is that we, in most cases, only do
an *access(2)* call instead of a stat, because that might be checking
more permissions.
So we have the following constellations:
- If we have d_type:
- We need a stat() for every _symlink_ to get the type (e.g. dir or regular)
(this is for most symlinks, if we want to know if it's a dir or executable)
- We need an access() for every file for executables
- If we do not have d_type:
- We need a stat() for every file
- We need an lstat() for every file if we do descriptions
(i.e. just for command completion)
- We need an access() for every file for executables
As opposed to the current way, where every file gets one lstat whether
with d_type or not, and an additional stat() for links, *and* an
access.
So we go from two syscalls to one for executables.
* Some more comments
* rust link option
* rust remove size
* rust accessovaganza
* Check for .dll first for WSL
This saves quite a few checks if e.g. System32 is in $PATH (which it
is if you inherit windows paths, IIRC).
Note: Our WSL check currently fails for WSL2, where this would
be *more* important because of how abysmal the filesystem performance
on that is.
This is off by one from the C++ version.
It wasn't super obvious why this worked in the first place.
Looks like args[0] is "-" because we are invoked like
fish -c 'exec "${@}"' - "${@}"
and it looks like "-" is treated like "--" by bash, so we emulate that.
See https://github.com/fish-shell/fish-shell/issues/367#issuecomment-11740812
This function only ever returns true if target_os=linux, so we need to invert
the OS check.
In the first invocation, this function may allocate heap memory.
Clarify that this is safe.
[ja: I don't have the original commit handy so I made up the log message]
The following "Port execution" commit will use RefCell for the wait handle
store. If we hold a borrow while we are running an event (which may run
script code) there will be a borrowing conflict. Avoid this by returning
the borrow earlier.
Given an env like
foo
bar=baz
we would set "foo" to empty due to a typo.
The typo is pointed out by a PORTING comment.
Luckily I don't think we ever hit this case because that would mean our
parent process has a serious bug. Rust's std::env::vars_os() skips env
lines that don't contain a "=" char. This seems like a reasonable behavior
for us too. Do that.
This makes it so expand_intermediate_segment knows about the case
where it's last, only followed by a "/".
When it is, it can do without the file_id for finding links (we don't
resolve the files we get here), which allows us to remove a stat()
call.
This speeds up the case of `...*/` by quite a bit.
If that last component was a directory with 1000 subdirectories we
could skip 1000 stat calls!
One slight weirdness: We refuse to add links to directories that we already visited, even if they are the last component and we don't actually follow them. That means we can't do the fast path here either, but we do know if something is a link (if we get d_type), so it still works in common cases.
This can be bound like `bind \cl clear-screen`, and is, by default
In contrast to the current way it doesn't need the external `clear`
command that was always awkward.
Also it will clear the screen and first draw the old prompt to remove
flicker.
Then it will immediately trigger a repaint, so the prompt will be overwritten.
This fixes the following deadlock. The C++ functions path_get_config and
path_get_data lazily determine paths and then cache those in a C++ static
variable. The path determination requires inspecting the environment stack.
If these functions are first called while the environment stack is locked
(in this case, when fetching the $history variable) we can get a deadlock.
The fix is to call them eagerly during env_init. This can be removed once
the corresponding C++ functions are removed.
This issue caused fish_config to fail to report colors and themes.
Add a test.
This was pretty annoying on rust release day, because it introduced
new warnings.
Specifically 1.73 introduced a spurious one about PartialOrd and Ord
disagreeing when both were in fact #derive-d.
Unlike our C++ tests, our Rust tests fail as soon as an assertion fails.
Whether this is desired is debatable; it seems fine for
most cases and is easier to implement.
This means that Rust tests usually don't need to print anything besides
what assert!/assert_eq! already provide.
One exception is the history merge test. Let's add a simple err!() macro to
support this. Unlike the C++ err() it does not yet print colors.
Currently all of our macros live in common.rs, to keep the import graph simple.
Notably this exposes config.h to Rust (for UVAR_FILE_SET_MTIME_HACK).
In future we should move the CMake checks into build.rs so we can potentially
get rid of CMake.
On the following "Port execution" commit, ASan will complain if we read
beyond a terminating null byte in get_autosuggestion_performer(). This is
actually working as intended but we need to appease ASan somehow..
get_pwd_slash() uses "if var.is_empty()" but it should be "if !var.is_empty()".
This wasn't a problem so far because in practice most code paths use the
get_pwd_slash() override from EnvStackImpl. The generic one is used in the
upcoming unit tests.
This uses "screen.reset_line" to move the cursor without informing the
reader's machinery (because that deals with positions *in the
commandline*), but then only repainted "if needed" - meaning if the
reader thought anything changed.
That could lead to a situation where the cursor stays at column 0
until you do something, e.g. in
```fish
bind -m insert u undo
```
when you press alt+u - because the *escape* calls repaint-mode, which
puts the cursor in column 0, and then the undo doesn't, which keeps it
there.
Of course this binding should also `repaint-mode`, because it changes
the mode.
Some changes might be ergonomic:
1. Make repaint-mode the default if the mode changed (we would need to
skip it for bracketed-paste)
2. Make triggering the repaint easier - do we need to set
force_exec_prompt_and_repaint to false here as well?
Anyway, this
Fixes#7910
This strips the newline from "code_context" (which is really just the
called function), and from the unescaped output.
Rather, in case the output doesn't end with a newline it'll mark it
with an explicit message "(no trailing newline)".
This was introduced as a workaround to #7215 - xdg-open's generic path
wouldn't background graphical apps.
This has been fixed a month ago in xdg-open, so we can stop doing it.
The good news is this also allows terminal apps to be used again, so
it
Fixes#10045
This is a sensible thing to do, and fixes some cases where we're
state-dependent.
E.g. this fixes the case in the pager where some things are bold and
some aren't, because that bolding is (rather awkwardly) implicitly
triggered when we have a background, and so we don't notice we need to
re-do that bolding after we moved to the next line because we think we
still have the same color.
Fixes#9617
This adopts the Rust postfork code, bridging it from C++ exec module.
We use direct function calls for the bridge, rather than cxx/autocxx, so that we
can be sure that no memory allocations or other shenanigans are happening.
This implements the "postfork" code in Rust, including calling fork(),
exec(), and all the bits that have to happen in between. postfork lives
in the fork_exec module.
It is not yet adopted.
This introduces a new module called fork_exec, which will be for posix_spawn,
postfork, and flog_safe - stuff concerned with actually executing binaries,
and error reporting.
Add a FLOG_SAFE! macro which writes errors to the flog fd in an
async-signal-safe way. This implementation differs from the C++ in that we
allow printing integers directly - no requiring them to be converted to a
buffer first.
This makes it so
```fish
if -e foo
# do something
end
```
complains about `-e` not being a command instead of `end` being used
outside of an if-block.
That means both that `-e` could now be used as a command name (it
already can outside of `if`!) *and* that we get a better error!
The only way to get `if` to be a decorated statement now is to use `if
-h` or `if --help` specifically (with a literal option).
The same goes for switch, while and begin.
It would be possible, alternatively, to disallow `if -e` and point
towards using `test` instead, but the "unknown command" message should
already point towards using `test` more than pointing at the
"end" (that might be quite far away).
- This is untested and unused, string ownership is very much subject to change
- Ports the minimally necessary parts of complete.rs as well
- This should fix an infinite loop in `create_directory` in `path.rs`, the first
`wstat` loop only breaks if it fails with an error that's different from
EAGAIN
- wildcard_match is now closer to the original that is linked in a comment, as
pointer-arithmetic translates very poorly. The act of calling wildcard
patterns wc or wildcard is kinda confusing when wc elsewhere is widechar.
This was already supposed to handle `--foo=bar<TAB>` cases, except it
printed the `--foo=` again, causing fish to take that as part of the
token.
See #9538 for a similar thing with __fish_complete_directories.
Fixes#10011
This is the most common and sensible env var, we check it outside,
so we can skip loading the function at all if we already know it's not
gonna do anything.
This is done on every startup of every single fish, and it saves ~0.2ms.
I sometimes find myself doing something like this:
- Look for a commandline that includes "echo" (as an example)
- Type echo, press up a few times
- I can't immediately find what I'm looking for
- Press ctrl-r to open up the history pager
- It uses the current commandline as the search string,
so now I'm looking for "echo foobar"
This makes it so if the search string already is in use, that's what
the history-pager picks as the initial search string.
This was the remaining immediately actionable part of #7375.
It's not definitely the last word, but a change here would require a
bigger plan.
Fixes#7375
Apparently this is actually a point of confusion.
Unfortunately we can't use `which` here because 1. it might not be
installed, 2. it might be trash.
So we give instructions from inside fish, and explain that they
should *typically* work.
See #10002
Without this, a recipe containing a trailing backslash followed by a line not
beginning with tab (like any non-continued recipe lines would) would result in
the continuation showing up in completions.
Whenever a line ends in a backslash, consider the next line invalid as a target.
Regex explanation:
^([^#]*[^#\\])? -- optional prefix not containing comment character and not
ending in backslash
(\\\\)*\\$ -- 2n+1 backslashes at end of line (handles escaped backslashes)
This is in regards to a comment on 290d07a833, which resulted in 46c967903d.
Those commits handled the default path when it is unset on startup.
DEFAULT_PATH is used when PATH is unset at runtime as far as I can tell.
As far as I can tell this has had the non-overidding ordering behavior since inception
(or at least 17 years ago ea998b03f2).
We don't change anything about compilation-setup, we just immediately jump to
Rust, making the eventual final swap to a Rust entrypoint very easy.
There are some string-usage and format-string differences that are generally
quite messy.
In CMake this used a `version` file in the CARGO_MANIFEST_DIR, but
relying on that is problematic due to change-detection, as if we add
`cargo-rerun-if-changed:version`, cargo would rerun every time if the file does
not exist, since cargo would expect the file to be generated by the
build-script. We could generate it, but that relies on the output of `git
describe`, whose dependencies we can only limit to anything in the
`.git`-folder, again causing unnecessary build-script runs.
Instead, this reads the `FISH_BUILD_VERSION`-env-variable at compile time
instead of the `version`-file, and falls back to calling git-describe through
the `git_version`-proc-macro. We thus do not need to deal with extraneous
build-script running.
- `libc::setlinebuf` is not available through Rust's libc it appears.
- autocxx fails to generate bindings using `*mut FILE`, instead go through
`void*`
- rust_main needs `parse_util_detect_errors_in_ast`, which is _partially_
ported, instead add FFI interop for C++.
- We need to set the filename if we are sourcing a file
C++ main used getopt (no w!), which appears to internally print
error-messages. The Rust version will use `wgetopter_t`, and therefore needs to
print this itself.
- It is currently never set, but will be set once `main` is ported
- `should_suppress_stderr_for_tests` used to be PROGRAM_NAME !=
TESTS_PROGRAM_NAME, but the equivalent C++ code was
`!std::wcscmp(program_name, TESTS_PROGRAM_NAME)`, and `wcsmp` returns
zero if they are equal, thus is equivalent to `==` in Rust
- https://github.com/ATiltedTree/setup-rust has not been committed to since May
2022, I am uncertain about how widely used it is.
- It appears to have a bug with restoring its internal cache whenever there
comes a new stable version (immediate guess would be the cache-key does not
resolve `stable` to a specific version, which somehow breaks rustup, but I have not investigated)
- https://github.com/dtolnay/rust-toolchain is a more sensible take of https://github.com/actions-rs/toolchain,
where the original repo appears to be unmaintained.
It is implemented in one file of yaml/bash
https://github.com/dtolnay/rust-toolchain/blob/master/action.yml, we could
easily fork it if it becomes unmainted, unlike the other actions which uses
unnecessary javascript
* Some temporary change until compose - commit
* First draft
* Fix an error that prints double completion
* Fix completion errors. Add rpm-ostree alias.
Fix cimpletion where it trigger by multiple commands.
Add update and remove, which are aliases for upgrade and uninstall.
* Remove -r when it is unnecessary
Some command need path completion for arguments no matter what,
which makes -r flag useless
* Remove -x for compose image
-x does not block the path anyway
* Add missing short otpion in compose image
Revert the last change to block -l completion
* Fix description
Fix multiple description.
This used to be assigned to the job, but that was removed in
f30ce21aaa.
Since then this was vestigial. It could have technically errored out,
but we should be catching that where we use the actual modes, not here.
Similar to `time`, except that one is more common as a command.
Note that this will also allow `builtin and`, which is somewhat
useless, but then it is also useless outside of a pipeline.
Addition to #9985
This used to print all codepoints outside of the ASCII range (i.e.
above 0x80) in \uXXXX or \UYYYYYYYY notation.
That's quite awkward, considering that this is about keys that are
being pressed, and many keyboards have actual symbols for these on
them - I have an "ö" key, so I would like to use `bind ö` and not
`bind \u00F6`. So we go by iswgraph.
On a slightly different note, `\e` was written as `\c[ (or \e)`. I do
not believe anyone really uses `\c[` (the `[` would need to
be escaped!), and it's confusing and unnecessary to even mention that.
This allows e.g. `foo | command time`, while still rejecting `foo | time`.
(this should really be done in the ast itself, but tbh most of
parse_util kinda should)
Fixes#9985
This cleans up the CSS, reduces the number of different colors and special settings we use.
It increases contrast so we now pass WCAG AAA (according to chromium), and switches to css variables for colors to make dark mode simpler to implement.
- "1.6.0" now supports formatting let-else statements which we use liberally,
and appears to have some fixes in regards to long-indented-lines with macros
like `wgettext_ft!`
- This commit updates the formatting so that devs with the latest stable don't
see random format-fixes upon running `cargo fmt`
During development, for a while `path change-extension` would return 0
when it found an extension to change.
This was later changed to returning 0 if there are any path arguments.
Neither of which is *super* useful, I admit, but we've picked one and
the docs shouldn't contradict it.
Unfortunately, /var/lib/dpkg/status on recent-ish Debian versions at
least only contains the *installed* packages, rendering this solution
broken.
What we do instead is:
1. Remove a useless newline from each package, so our limit would now
let more full package data sets through
2. Increase the limit by 5x
This yields a completion that runs in ~800ms instead of ~700ms on a
raspberry pi, but gives ~10x the candidates, compared to the old
apt-cache version.
This partially reverts 96deaae7d8
This was accidentally changed in 3.2.0, when type was made a builtin.
Since it's been 4 releases and nobody has noticed, rather than
breaking things again let's leave it as it is, especially because the
option is named "--no-functions", not "--no-functions-or-builtins".
Note: This *requires* an argument after the format string:
```rust
FLOGF!(debug, "foo");
```
won't compile. I think that's okay, because in that case you should
just use FLOG.
An alternative is to make it skip the sprintf.
"FLOGF!" is supposed to treat its first argument as a format
string (but doesn't because that part isn't implemented currently).
That means running something like
```rust
FLOGF!(term_support, "curses var", var_name, "=", value);
```
That would rightly just print "curses var", ignoring the other
arguments.
By contrast, FLOG! is the literal "just join these as a string"
version.
- Make CMake use the correct target-path
- Make build.rs use the correct target dir
Workspaces place it in the project root by default, the alternative to making
this change is to add a `.cargo/config.toml` file with
```toml
[build]
target-dir = "fish-rust/target"
```
Which I think is unnecessary, as we likely want to use the new location anyways.
- This allows running `cargo fmt/clippy/test/etc` from root
- Ideally the root should be the fish-rust package instead of being virtual, but
that requires changed to CMake/Corrosion. This change should instead be
completely compatible with our existing setup.
- This also means we will only have on `Cargo.lock` for all current and future
crates.
This was "function", needs to be "function*s*".
It was only an issue in the option parsing because we set cmd there
again instead of passing it. Maybe these should just be file-level constants?
This is an alternative to the very common pattern of
```rust
streams.err.append(output);
streams.err.append1('\n');
```
Which has negative performance implications, see https://github.com/fish-shell/fish-shell/pull/9229
It takes `Into<WString>` to hopefully avoid allocating anew when the argument is
a WString with leftover capacity
This used expect_re with a regex ending in `.*`, followed by an
`expect_prompt`.
This meant that, depending on the timing, the regex could swallow the
prompt marker, which caused extremely confusing output like
>Testing file pexpects/generic.py:Failed to match pattern: prompt 14
> ...
> OUTPUT +1.33 ms (Line 70): \rprompt 13>functions\r\nN_, abbr,
> alias, bg, cd, [SNIP], up-or-search, vared, wait\r\n⏎
> \r⏎ \r\rprompt 14>
Yeah - it shows that "prompt 14" was in the output and it can't find
"prompt 14".
I could reproduce the failure locally when running the tests
repeatedly. I got one after 17 attempts and so far haven't been able
to reproduce it with this change applied.
This removes some spurious unsafe and some imports.
Note: We don't use it in `test`, because that can be asked to check
arbitrary file descriptors, while this only checks stdout specifically.
Turns out doing `==` on Enums with values will do a deep comparison,
including the values.
So EventDescription::Signal(SIGTERM) is !=
EventDescription::Signal(SIGWINCH).
That's not what we want here, so this does a bit of a roundabout thing.
* Simplify and fix `__fish_is_zfs_feature_enabled`
Previously `__fish_is_zfs_feature_enabled` was doing
`<whitespace>$queried_feature<whitespace>` pattern matching which
was skipping the state part expected in the follow-up checking code.
Passing the dataset/snapshot in a `target` argument is pointless. As
none of the existing code attempts to do this plus it is also a
private function (`__` prefix), rename of the argument and removal
of extra text replacement should not be considered a breaking change.
* Changed the `&& \` into `|| return`
* Run `fish_indent`
The `impl<T> Hash for &T` hashes the string itself[^1].
It is unclear if that is actually faster than just calling `keyfunc` multiple times (they should all be linear).
For context, Rust by default uses SipHash 1-3 db1b1919ba
An alternative would be to store it as raw pointers aka `*const T`, which have a cheaper hash impl.
That has a more complicated implementation + removes lifetimes.
This commit rather removes the premature optimization.
[^1]: Source: https://doc.rust-lang.org/std/ptr/fn.hash.html
- The Err-variants will be used by e.g. wildcard, so might as well change it
now.
- `create_directory` should now not infinitely loop until it fails with an
error message that isn't `EAGAIN`
These are both clearly behind early returns, there is no need to check it again.
This isn't a case where we're doing logic gymnastics to see that it
can't be run without no_exec() being handled, this is
```c++
if (no_exec()) return;
// ..
// ..
// ..
if (no_exec()) foo;
```
We have already run waccess with X_OK. We already *know* the file is
executable.
There is no reason to check again.
Restores some of the speedup from the fast_waccess hack that was
removed to fix#9699.
Corrosion does not forward the `CMAKE_OSX_DEPLOYMENT_TARGET` to cargo.
As a result we end up building the Rust-libraries for the default target,
which is usually current macOS-version. But CMake links using the set
target, so we link for a version older than we built for.
To properly build for older macOS versions, the env variable
`MACOSX_DEPLOYMENT_TARGET` should instead be set, which cargo,
cmake and friends read by default. This can then lead to
warnings if you have libraries (e.g. PCRE2) built for newer
than our minimum version. Therefore we do not set a min-target
by default.
Padding with an unprintable character is now disallowed, like it was for other
zero-length characters.
`string shorten` now ignores escape sequences and non-printable characters
when calculating the visible width of the ellipsis used (except for `\b`,
which is treated as a width of -1).
Previously `fish_wcswidth` returned a length of -1 when the ellipsis-str
contained any non-printable character, causing the command to poentially
print a larger width than expected.
This also fixes an integer overflows in `string shorten`'s
`max` and `max2`, when the cumulative sum of character widths turned negative
(e.g. with any non-printable characters, or `\b` after the changes above).
The overflow potentially caused strings containing non-printable characters
to be truncated.
This adds test that verify the fixed behaviour.
- Add test to verify piped string replace exit code
Ensure fields parsing error messages are the same.
Note: C++ relied upon the value of the parsed value even when `errno` was set,
that is defined behaviour we should not rely on, and cannot easilt be replicated from Rust.
Therefore the Rust version will change the following error behaviour from:
```shell
> string split --fields=a "" abc
string split: Invalid fields value 'a'
> string split --fields=1a "" abc
string split: 1a: invalid integer
```
To:
```shell
> string split --fields=a "" abc
string split: a: invalid integer
> string split --fields=1a "" abc
string split: 1a: invalid integer
```
* feat(completions): support Krita
* feat(completions): support summary options for Krita
* feat(completions): support remaining options for Krita
* feat(completions): remove debug instructions
* feat(completions): hide completions for sizes for Krita
* feat(completions): fix Krita
* feat(changelog): mention new completion
* fix(completions): refactor Krita
* fix(completion): reformat
* feat(completion): dynamically generate workspace list
* fix(completion): refactor
* fix(completion): krita
* fix(completions): use printf
This gives us the biggest chance that these are *visible* in the
terminal, which allows people to choose something nicer.
It changes two colors - the autosuggestion and the pager
description (i.e. the completion descriptions in the pager).
In a bunch of terminals I've tested these are pretty similar - for the
most part brblack for the suggestions is a bit brighter than 555, and
yellow for the descriptions is less blue
than the original.
We could also make the descriptions brblack, but that's for later.
Technically we are a bit naughty in having a few foreground and
background pairs that might not be visible,
but there's nothing we can do if someone makes white invisible on brblack.
Fixes#9913Fixes#3443
Empty hash maps muck around with TLS. Per code review, use a boxed slice
of a tuple instead. This has the nice benefit of printing inherited vars
in sorted order.
This adopts the new function store, replacing the C++ version.
It also reimplements builtin_function in Rust, as these was too coupled to
the function store to handle in a separate commit.
This didn't work for something like `pactl set-card-profile foo
<TAB>`,
because it didn't allow for the card name, as it would just print the
index again and again.
We could end up overflowing if we print out something that's a multiple of the
chunk size, which would then finish printing in the chunk-printing, but not
break out early.
DirIter had a serious bug where it would crash on an invalid path. Make it more
robust and rationalize its error handling. Move it into its own module and add
tests.
Prior to this change, we had a silly wrapper type EventDescription which wrapped
EventType, which actually described the event.
Remove this wrapper and rename EventType to EventDescription (since it describes
more than just the type of event).
The RETURN_IN_ORDER argparse mode (enabled via leading '-') causes non-options
(i.e. positionals) to be returned intermixed with options in the original order,
instead of being permuted to the end. Such positionals are identified via the
option sentinel of char code 1. Use a real named constant for this return,
rather than weird stuff like '\u{1}'
This had a weird, unnecessary and terrible backwards-incompatibility
in how you get the completions out.
I do not like it but I am in a good enough mood to work around it.
See #9878.
This confirmed that a file existed via access(file, F_OK).
But we already *know* that it does because this is the expansion for
the "trailing slash" - by definition all wildcard components up to
here have already been checked.
And it's not checking for directoryness either because it does F_OK.
This will remove one `access()` per result, which will cut the number
of syscalls needed for a glob that ends in a "/" in half.
This brings us on-par with e.g. `ls` (which uses statx while we use
newfstatat, but that should have about the same results)
Fixes#9891.
Remove the following C++ functions/methods, which have no callers:
fallback.cpp:
- wcstod_l
proc.cpp:
- job_t::get_processes
wutil.cpp:
- fish_wcstoll
- fish_wcstoull
Also drop unused configure checks/defines:
- HAVE_WCSTOD_L
- HAVE_USELOCALE
Remove the following C++ functions/methods, which have all been ported to Rust and no longer have any callers in C++:
common.cpp:
- assert_is_locked/ASSERT_IS_LOCKED
path.cpp:
- path_make_canonical
wutil.cpp:
- wreadlink
- fish_iswgraph
- file_id_t::older_than
It's super easy to get a lot of these and they'll otherwise slow down
the completions a lot.
This makes `git add <TAB>` ~5-6x faster with about 4000 untracked
files (a copy of the fish build directory). It goes from 1.5 seconds to
250ms.
This is just for the git >= 2.11 path, but the other one would require
more checking and since git 2.11 is almost 7 years old now that's not
worth it.
This makes `fish -c begin` fail with a status of 127 - it already
printed a syntax error so that was weird. (127 was the status for
syntax errors when piping to fish, so we stay consistent with that)
We allow multiple `-c` commands, and this will return the regular
status if the last `-c` succeeded.
This is fundamentally an extremely weird situation but this is the
simple targeted fix - we did nothing, unsuccessfully, so we should
fail.
Things to consider in future:
1. Return something better than 127 - that's the status for "unknown
command"!
2. Fail after a `-c` failed, potentially even checking all of them
before executing the first?
Fixes#9888
This also allows scoped feature tests that makes testing feature flags thread-safe.
As in you can guarantee that the test actually has the correct feature flag
value, regardless of which other tests are running in parallell.
This also cleans up and removes unnecessary usage of FFI-oriented `feature_metadata_t`,
which is only used from Rust code after `builtins/status` was ported.
This ran two `test`s a `count` and one `echo`, which is a bit wasteful.
So instead, for the common case where you pass one argument, this will
run one `set -q`.
This can save off ~160 microseconds for each ordinary `cd`, which
speeds it up by a factor of ~2 (so 1000 runs of cd might take 260ms
instead of 550ms).
Ideally the cd function would just be incorporated into the builtin,
but that's a bigger change.
Note this is slightly incomplete - the FD is not moved into the parser, and so
will be freed at the end of each directory change. The FD saved in the parser is
never actually used in existing code, so this doesn't break anything, but will
need to be corrected once the parser is ported.
This shaves about 9 seconds off of the runtime, and makes the test
deterministic.
We do not touch the test_convert test because there is a known failure and we
need to track it down before making it deterministic.
Get some stuff out of the common module, which is growing large.
Also migrate the tests into "native" Rust tests so they will run in parallel.
We have to use an explicit setlocale() call to get a multibyte locale, for the
"crazy" tests.
Prior to this commit, FLOG used the ffi bridge to get the output fd. Invert
this: have fish set the output fd within main. This allows FLOG to be used in
pure Rust tests.
After accidentally running a command that includes a pasted password, I want
to delete command from history. Today we need to recall or type (part of)
that command and type "history delete". Let's maybe add a shortcut to do
this from the history pager.
The current shortcut is Shift+Delete. I don't think that's very discoverable,
maybe we should use Delete instead (but only if the cursor is at the end of
the commandline, otherwise delete a char).
Closes#9454
The tentative binding for the upcoming "history-pager-delete" is
bind -k sdc history-pager-delete or backward-delete-char
When Shift+Delete is pressed while the history pager is active,
"history-pager-delete" succeeds. In this case, the "or" needs to kick the
"backward-delete-char" out of the input queue.
After doing so, it continues reading, but interprets the input as
single-char binding. This breaks when the next key emits a multi-char sequence,
like the arrow keys.
Fix this by reading a full sequence, which means we need to run "read_char()"
instead of "read_ch()" (confusing, right?).
I'm still working on writing a test. Somehow this only reproduces in the
history pager where Shift+Delete followed by down arrow emits "[B" (since
we swallowed the leading escape char). Confusingly, it doesn't do that in
the commandline or the completion search field.
Two small fixes:
1. ParsedSourceRef, if present, should not be None; express that in the type.
2. ParsedSourceRef is intended to be shareable across threads; make it so.
Use as_wstr() instead of from_ffi() in a few places to avoid an allocation,
and make job_control_t work in &wstr instead of &str to reduce complexity at
the call sites.
- Using an option makes it much clearer that the check for empty args is
redundant.
- Also prefer implementing TryFrom only for &str, to not hide the string
conversion and allocation happening.
This was present in the C++ version for command, though never for type.
Checking over all elements of PATH can be slow on some platforms eg
WSL2, so only do that when used with `--all`.
Based on discussion in
https://github.com/fish-shell/fish-shell/pull/9856
This restores the status quo where builtins are like external commands
in that they can't see anything after a 0x00, because that's the c-style
string terminator.
* Make NULs work for builtins
This switches from passing a c-string to output_stream_t::append to
passing a proper string.
That means a builtin that prints a NUL no longer crashes with "thread '' panicked
at 'String contained intermediate NUL character: ".
Instead, it will actually handle the NUL, even as an argument.
That means something like
`echo foo\x00bar` will now actually print a NUL instead of truncating
after the `foo` because we passed c-strings around everywhere.
The former is *necessary* for e.g. `string`, the latter is a change
that on the whole makes dealing with NULs easier, but it is a
behavioral change.
To restore the c-string behavior we would have to truncate arguments
at NUL.
See #9739.
* Use AsRef instead of trait bound
* docs: Add "Writing your own prompt" doc
* Remove a space from the "output"
* some teensy adjustments
* Address feedback
* envvar one more PWD
* More html warning
Prior to this change, parser_t exposed an environment_t, and Rust had to go
through that. But because we have implemented Environment in Rust, it is
better to just expose the native Environment from parser_t. Make that
change and update call sites.
The writembs macro was ported from C++, which attempted to detect when a NULL
termcap was used. However we have never gotten a bug report from this. Bravely
remove it.
The outputter code has a lot of checks that string capabilities are non-empty;
just enforce that at the curses layer so we can remove those checks.
Also remove some types and traits, replacing them with simple functions.
Per code review, we think that tparm does nothing when there are no parameters,
and it is safe to remove it, even though this is a break from C++. This
simplifies some code.
This commit introduces a fishconfig_print.css that contains special CSS styles that only apply when printing the fishconfig page. This is especially useful when the user wants to print out the key bindings.
This makes some simplifications to scoped_push and ScopeGuard:
1. ScopeGuard no longer uses ManuallyDrop; the memory management is now
trivial and no longer requires `unsafe`.
2. The functions `cancel` and `rollback` have been removed, as
these were unused. They can be added back later if needed.
3. `scoped_push` has been simplified in both signature and implementation.
4. `Projection` is no longer required and has been removed.
Also add some tests.
This should include the important info from the wiki.
We should try to find some recommendation for tools, or even an online
platform where people can submit translations without having to go
through all this setup
Mostly this tries to give logical header levels, so the "Fish Style
Guide" section is in the "Code Style" section
Also remove a few unimportant C++-centric sections - I'm not sure iwyu
even runs anymore, and cppcheck isn't great in my experience.
We can't just call the Rust version of `fish_setlocale()` without also either
calling the C++ version of `fish_setlocale()` or removing all `src/complete.cpp`
variables that are initialized and aliasing them to their new rust counterparts.
Since we're not interested in keeping the C++ code around, just call the C++
version of the function via ffi until we don't have *any* C++ code referencing
`src/common.h` at all.
Note that *not* doing this and then calling the rust version of
`fish_setlocale()` instead of the C++ version will cause errant behavior and
random segfaults as the C++ code will try to read and use uninitialized values
(including uninitialized pointers) that have only had their rust counterparts
init.
This is not yet used but will take eventually take the place of all (n)curses
access. The curses C library does a lot of header file magic with macro voodoo
to make it easier to perform certain tasks (such as access or override string
capabilities) but this functionality isn't actually directly exposed by the
library's ABI.
The rust wrapper eschews all of that for a more straight-forward implementation,
directly wrapping only the basic curses library calls that are required to
perform the tasks we care about. This should let us avoid the subtle
cross-platform differences between the various curses implementations that
plagued the previous C++ implementation.
All functionality in this module that requires an initialized curses TERMINAL
pointer (`cur_term`, traditionally) has been subsumed by the `Term` instance,
which once initialized with `curses::setup()` can be obtained at any time with
`curses::Term()` (which returns an Option that evaluates to `None` if `cur_term`
hasn't yet been initialized).
Either add rust wrappers for C++ functions called via ffi or port some pure code
from C++ to rust to provide support for the upcoming `env_dispatch` rewrite.
The global variables are moved (not copied) from C++ to rust and exported as
extern C integers. On the rust side they are accessed only with atomic semantics
but regular int access is preserved from the C++ side (until that code is also
ported).
It's not clear whether or not `system_wcwidth()` was picked solely because of
the namespace conflict (which is easily remedied) but using the most obvious
name for this function should be the way to go.
We already have our own overload of `wcwidth()` (`fish_wcwidth()`) so it should
be more obvious which is the bare system call and which isn't.
(I do want to move this w/ some of the other standalone extern C wrappers to the
unix module later.)
Pull in the correct descriptions merged from across the various C++ header and
source files and get rid of the getter function that's only used in one place
but causes us to split the documentation for FISH_EMOJI_WIDTH across multiple
declarations.
This can be used for functions that accept non-Unicode content (i.e. &CStr or
CString) but are often used in our code base with a UTF-8 or UTF-32 string
on-hand.
When such a function is passed a CString, it's passed through as-is and
allocation-free. But when, as is often the case, we have a static string we can
now pass it in directly with all the nice ergonomics thereof instead of having
to manually create and unwrap a CString at the call location.
There's an upstream request to add this functionality to the standard library:
https://github.com/rust-lang/rust/issues/71448
This is more complicated than it needs to be thanks to the presence of CMake and
the C++ ffi in the picture. rsconf can correctly detect the required libraries
and instruct rustc to link against them, but since we generate a static rust
library and have CMake link it against the C++ binaries, we are still at the
mercy of CMake picking up the symbols we want.
Unfortunately, we could detect the gettext symbols but discover at runtime that
they weren't linked in because CMake was compiled with `-DWITH_GETTEXT=0` or
similar (as the macOS CI runner does). This means we also need to pass state
between CMake and our build script to communicate which CMake options were
enabled.
Delegate the `view` and `view_mut` to the newly added `Projection<T>`, which
makes everything oh so much clearer and cleaner. Add comments to clarify what is
happening.
This can be used when you primarily want to return a reference but in order for
that reference to live long enough it must be returned with an object.
i.e. given `Mutex<Foo { bar }>` you want a function to lock the mutex and return
a reference to `bar` but you can't return that reference since it has a lifetime
dependency on `MutexGuard` (which only derefs to all of `Foo` and not just
`bar`). You can return a `Projection` owning the `MutexGuard<Foo>` and set it up
to deref to `&bar`.
This was always extremely weasel-wordy and I have no idea which one
here is a good choice.
OMF is basically inactive at this point, so we might be doing people a
disservice by linking to it.
This wasn't providing a lot of value, and the license compatibility is iffy.
There's a bit of weirdness in that this now uses a `Box<dyn Error>`,
but since currently nothing actually errors out let's punt that for
later.
This is a terrible way of going about things,
and means we're currently broken on any unix that isn't specifically listed.
But at least it'll build and allow us to keep the FreeBSD CI running.
Historically fish has used the functions `fish_wcstol`, `fish_wcstoi`, and
`fish_wcstoul` (and some long long variants) for most integer conversions.
These have semantics that are deliberately different from the libc
functions, such as consuming trailing whitespace, and disallowing `-` in
unsigned versions.
fish has started to drift away from these semantics; some divergence from
C++ has crept in.
Rename the existing `fish_wcs*` functions in Rust to remove the fish
prefix, to express that they attempt to mirror libc semantics; then
introduce `fish_` wrappers which are ported from C++. Also fix some
miscellaneous bugs which have crept in, such as missing range checks.
This also skips the 192 git- and 64 npm- pages that
1. have better completions already (for the most part)
2. don't have the same name as a command typically in $PATH
In doing so it reduces the runtime on my system from 9s to 7s. Granted
I have all of these, so that's the best case.
This implements the primary environment stack, and other environments such
as the null and snapshot environments, in Rust. These are used to implement
the push and pop from block scoped commands such as `for` and `begin`, and
also function calls.
owning_null_terminated_array is used for environment variables, where we need to
provide envp for child processes. This switches the implementation from C++ to
Rust.
We retain the C++ owning_null_terminated_array_t; it simply wraps the Rust
version now.
The `u64::from(buf.f_flag)` was needed in two places. The existing handled macOS
which always has a 32-bit statfs::f_flag, but statvfs::f_flag is an `unsigned
long` which means it needs to be coerced to 64-bits on 32-bit targets.
It completes identical to `fg` and `bg` w/ this change. I'm not aware of any
reason why it shouldn't, but feel free to enlighten me if I've missed something.
[ci skip]
There's no reason to inject prefix into our newly allocated str after storing
pattern in there. Just allocate with the needed capacity up front and then
insert in the correct order.
There's no reason to inject prefix into our newly allocated str after storing
pattern in there. Just allocate with the needed capacity up front and then
insert in the correct order.
Suppress TLS variable leaks caused by outstanding background threads by
suppressing the ASAN interposer functions. This is possible because because
we're now using use_tls=1.
-----------------------
Direct leak of 64 byte(s) in 2 object(s) allocated from:
#0 0x5627a1f0cc86 in __interceptor_realloc (/home/runner/work/fish-shell/fish-shell/build/fish_tests+0xb9fc86) (BuildId: da87d16730727369ad5fa46052d10337d6941fa9)
#1 0x7f04d8800f79 in pthread_getattr_np (/lib/x86_64-linux-gnu/libc.so.6+0x95f79) (BuildId: 69389d485a9793dbe873f0ea2c93e02efaa9aa3d)
#2 0x5627a1f2f664 in __sanitizer::GetThreadStackTopAndBottom(bool, unsigned long*, unsigned long*) (/home/runner/work/fish-shell/fish-shell/build/fish_tests+0xbc2664) (BuildId: da87d16730727369ad5fa46052d10337d6941fa9)
#3 0x5627a1f2fb83 in __sanitizer::GetThreadStackAndTls(bool, unsigned long*, unsigned long*, unsigned long*, unsigned long*) (/home/runner/work/fish-shell/fish-shell/build/fish_tests+0xbc2b83) (BuildId: da87d16730727369ad5fa46052d10337d6941fa9)
#4 0x5627a1f19a0d in __asan::AsanThread::SetThreadStackAndTls(__asan::AsanThread::InitOptions const*) (/home/runner/work/fish-shell/fish-shell/build/fish_tests+0xbaca0d) (BuildId: da87d16730727369ad5fa46052d10337d6941fa9)
#5 0x5627a1f19615 in __asan::AsanThread::Init(__asan::AsanThread::InitOptions const*) (/home/runner/work/fish-shell/fish-shell/build/fish_tests+0xbac615) (BuildId: da87d16730727369ad5fa46052d10337d6941fa9)
#6 0x5627a1f19b01 in __asan::AsanThread::ThreadStart(unsigned long long) (/home/runner/work/fish-shell/fish-shell/build/fish_tests+0xbacb01) (BuildId: da87d16730727369ad5fa46052d10337d6941fa9)
#7 0x7f04d87ffb42 (/lib/x86_64-linux-gnu/libc.so.6+0x94b42) (BuildId: 69389d485a9793dbe873f0ea2c93e02efaa9aa3d)
#8 0x7f04d88919ff (/lib/x86_64-linux-gnu/libc.so.6+0x1269ff) (BuildId: 69389d485a9793dbe873f0ea2c93e02efaa9aa3d)
init_curses() is/can be called more than once, in which case the previous
ncurses terminal state is leaked and a new one is allocated.
`del_curterm(cur_term)` is supposed to be called prior to calling `setupterm()`
if `setupterm()` is being used to reinit the default `TERMINAL *cur_term`.
The new asan exit handlers are called to get proper ASAN leak reports (as
calling _exit(0) skips the LSAN reporting stage and exits with success every
time).
They are no-ops when not compiled for ASAN.
Set use_tls back to its default of 1.
This is required to work around an ASAN/LSAN virtualization bug but seems to be
behind the random __cxa_thread_atexit_impl() leaks?
This ports some signal setup and handling bits to Rust.
The signal handling machinery requires walking over the list of known signals;
that's not supported by the Signal type. Rather than duplicate the list of
signals yet again, switch back to a table, as we had in C++.
This also adds two further pieces which were neglected by the Signal struct:
1. Localize signal descriptions
2. Support for integers as the signal name
This allows the rust code to free up C++ resources allocated for a callback even
when the callback isn't executed (as opposed to requiring the callback to run
and at the end of the callback cleaning up all allocated resources).
Also add type-erased destructor registration to callback_t. This allows for
freeing variables allocated by the callback for debounce_t's
perform_with_callback() that don't end up having their completion called due to
a timeout.
Largely routine but for the trampolines in iothread.h and iothread.cpp which
were a real PITA to get correct w/ all their variants.
Integration is complete with all old code ripped out and the tests using the
rust version of the code.
Like the WSL check, this was incorrectly assuming WSL implies
cfg(windows) when it's actually picked up as Linux.
Also, improve over the C++ code by not relying on the build-time WSL
status to determine if we are running on WSL at runtime since it's often
the case that the fish binaries are built on a non-WSL host (for
packaging) then executed on a WSL only at runtime.
(But it's ok to assume if fish has been built for Windows or not Linux
that it will either be run or not run on top of a Win32 character device
system.)
Also, port of the comment and relevant WSL and fish issue links over
from the CPP codebase for posterity.
* Since we already have an allocation of length wstr.len(), it's
probably better to allocate the result (which is strictly less than or
equal to the input length) up-front rather than risk thrashing the Vec
allocation,
* There's no need to compare c2 against '\0' since that will just cause
to_digit(16) to return None anyway,
* Our convert_hex() specialization of to_digit(16) that only checks
capital letters A-F without also checking lowercase a-f isn't
significantly faster than just use to_digit(16), and we already assert
that the input *wasn't* a lowercase a-f before making the call, so
there's no point in using a special function to handle that.
Prior to this change, wstr::split had two weird behaviors:
1. Splitting an empty string would yield nothing, rather than an empty
string.
2. Splitting a string with the separator character as last character
would not yield an empty string.
For example L!("x:y:").split(':') would return ["x", "y"] instead of
what it does in C++, which is ["x", "y", ""].
Fix these.
This reverts commit 76dc849fca.
The warning added in that commit is incorrect. The functions
unescape_string_url and unescape_string_var will not panic, because
char_at() return 0 if the index is equal to its length.
This reverts commit f9c92753c4.
This commit attempted to replace exit_without_destructors() with
std::process::exit; however this is wrong for two reasons:
1. std::process::exit() runs Rust runtime cleanup stuff we don't want
2. std::process::exit() invokes destructors, meaning atexit handlers,
which we don't want.
The type system no longer guarantees that the input string is nul-terminated,
meaning accessing beyond the range-checked `i` a char-at-a-time is no longer
safe. (In C++, we would either be using a plain C string which is always
nul-terminated or we would be using (w)string::cstr() which similarly grants
access to its nul-terminated buffer.)
Aside from that, there's no need to explicitly check `if c2 == '\0'` because
'\0' is not a valid hex digit so the `?` tacked on to `convert_hex_digit(c2)?`
will abort and return `None` anyway.
convert_hex_digit() is not appreciably faster than char::to_digit(16) and makes
the code less maintainable since it encodes certain assumptions; since it's also
not used consistently just drop it in favor of the std fn.
Since the output string (per the decode logic) is always shorter than or equal
to the input string, just reserve the input string size upfront to prevent vec
reallocations.
* Add rpm-ostree completion
Add basic command completion for rpm-ostree. This should improve the
user experience for fish users using rpm-ostree.
* Shorten rpm-ostree descriptions
---------
Co-authored-by: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
* completions: updated jq completions
* completions: added completions for gojq
* Shorten jq completion descriptions
* Update gojq.fish
Capitalize first letter of descriptions to match other completions.
---------
Co-authored-by: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
Somewhat counter-intuitively, this code is active when compiling under *Linux*
and is always false when compiling under Windows. The logic was incorrectly
reversed before (it's easier to reason about when you realize that fish doesn't
even compile under Windows because it uses tons of libc functions).
As the code was actually never compiled, it wasn't actually tested for validity
either and there were some issues that prevented it from compiling that have
since been fixed. The logic has also been adjusted a bit to make it possible to
use the rust-native int parsing instead of `libc::strtod()`.
The code has been changed to use `once_cell::race::OnceBool` instead of
`once_cell::sync::Lazy<T>` which imposes a greater runtime burden with locking
and other overhead. We don't care if the code runs more than once on init (if
calls were to race, though they probably don't) - just that the code isn't
subsequently executed on each call. The `once_cell::race` module is a better fit
here, though it doesn't expose the ergonomic `Lazy<T>` façade around its types.
is_main_thread() and co were previously ported to threads.rs, so remove the
duplicate code and move everything else related to threads there as well. No
need for common.rs to be as long as our old common.cpp!
I left #[deprecated] stubs in common.rs to help redirect anyone porting code
over that we can remove after the port has finished.
Additionally, the fork guards had previously been left as a todo!() item but I
ported that over. They're all called from the now-central threads::init()
function so there isn't a need to call each individual thread-management-fn
manually.
The decision was made a while back to try and embrace/use the native rust thread
functionality and utilities so the manual thread management code has been ripped
out and was replaced with code that marshals the native rust values instead. The
values won't line up with what the C++ code sees, but it never lined up anyway
since each was using a separate counter to keep track of the values.
There are many places where we want to treat a missing variable the same as
a variable with an empty value.
In C++ we handle this by branching on maybe_t<env_var_t>::missing_or_empty().
If it returns false, we go on to access maybe_t<env_var_t>::value() aka
operator*.
In Rust, Environment::get() will return an Option<EnvVar>.
We could define a MissingOrEmpty trait and implement it for Option<EnvVar>.
However that will still leave us with ugly calls to Option::unwrap()
(by convention Rust does use shorthands like *).
Let's add a variable getter that returns none for empty variables.
This isn't the same as "join"/"join0", where one is just a special
case of the other.
These are two different, if basically opposite commands.
But more importantly this was a huge mess and the formatting was broken.
Except for the indent visitor bits.
Tests for parse_util_detect_errors* are not ported yet because they depend
on expand.h (and operation_context.h which depends on env.h).
This caused math to assert out because it never wrote into the buffer.
Now, presumably it wrote somewhere but I don't know where, so fixing
this seems like a good idea.
Fixes#9735.
The translation is fairly direct though it adds some duplication, for example
there are multiple "match" statements that mimic function overloading.
Rust has no overloading, and we cannot have generic methods in the Node trait
(due to a Rust limitation, the error is like "cannot be made into an object")
so we include the type name in method names.
Give clients like "indent_visitor_t" a Rust companion ("IndentVisitor")
that takes care of the AST traversal while the AST consumption remains
in C++ for now. In future, "IndentVisitor" should absorb the entirety of
"indent_visitor_t". This pattern requires that "fish_indent" be exposed
includable header to the CXX bridge.
Alternatively, we could define FFI wrappers for recursive AST traversal.
Rust requires we separate the AST visitors for "mut" and "const"
scenarios. Take this opportunity to concretize both visitors:
The only client that requires mutable access is the populator. To match the
structure of the C++ populator which makes heavy use of function overloading,
we need to add a bunch of functions to the trait. Since there is no other
mutable visit, this seems acceptable.
The "const" visitors never use "will_visit_fields_of()" or
"did_visit_fields_of()", so remove them (though this is debatable).
Like in the C++ implementation, the AST nodes themselves are largely defined
via macros. Union fields like "Statement" and "ArgumentOrRedirection"
do currently not use macros but may in future.
This commit also introduces a precedent for a type that is defined in one
CXX bridge and used in another one - "ParseErrorList". To make this work
we need to manually define "ExternType".
There is one annoyance with CXX: functions that take explicit lifetime
parameters require to be marked as unsafe. This makes little sense
because functions that return `&Foo` with implicit lifetime can be
misused the same way on the C++ side.
One notable change is that we cannot directly port "find_block_open_keyword()"
(which is used to compute an error) because it relies on the stack of visited
nodes. We cannot modify a stack of node references while we do the "mut"
walk. Happily, an idiomatic solution is easy: we can tell the AST visitor
to backtrack to the parent node and create the error there.
Since "node_t::accept_base" is no longer a template we don't need the
"node_visitation_t" trampoline anymore.
The added copying at the FFI boundary makes things slower (memcpy dominates
the profile) but it's not unusable, which is good news:
$ hyperfine ./fish.{old,new}" -c 'source ../share/completions/git.fish'"
Benchmark 1: ./fish.old -c 'source ../share/completions/git.fish'
Time (mean ± σ): 195.5 ms ± 2.9 ms [User: 190.1 ms, System: 4.4 ms]
Range (min … max): 193.2 ms … 205.1 ms 15 runs
Benchmark 2: ./fish.new -c 'source ../share/completions/git.fish'
Time (mean ± σ): 677.5 ms ± 62.0 ms [User: 665.4 ms, System: 10.0 ms]
Range (min … max): 611.7 ms … 805.5 ms 10 runs
Summary
'./fish.old -c 'source ../share/completions/git.fish'' ran
3.47 ± 0.32 times faster than './fish.new -c 'source ../share/completions/git.fish''
Leftovers:
- Enum variants are still snakecase; I didn't get around to changing this yet.
- "ast_type_to_string()" still returns a snakecase name. This could be
changed since it's not user visible.
A JobId is not supposed to convert to other types.
Since this type is defined as NonZeroU32 (which cannot be -1), we need to
add some conversion functions to match the C++ behavior.
Overall, it would have been better to keep using the C++ type.
The conversion to usize is used for array accesses, so negative values
would cause crashes either way. Let's do it earlier so we can get rid of
the suspect C-style cast.
This allows us to use the scoped push in more scenarios by appeasing the
borrow checker.
Use it in a couple of places instead of ScopeGuard. Hopefully this is makes
porting easier.
Even though we generally dont' want to use this type (because it's immutable),
it can be advantageous when working with the std::fs API. This is because
it implements "AsRef<Path>" which neither of CString and Vec<u8> do.
This is basically a subset of type, so we might as well.
To be clear this is `command -s` and friends, if you do `command grep` that's
handled as a keyword.
One issue here is that we can't get "one path or not" because I don't
know how to translate a maybe_t? Do we need to make it a shared_ptr instead?
While it is true that `git switch <remote-branch>` errors to disallow a detached
head without the `-d` option, it is valid to use any starting point (commit or
reference) in conjunction with the `-c` option. Additionally, the starting point
can occur before any option.
This enables the following completions:
* `git switch -c <local-name> <any-branch>`
* `git switch <any-branch> -c <local-name>`
* `git switch -d <any-starting-point>`
* `git switch <any-branch> -d`
The trade-off is this does allow for `git switch <remote-branch>` to be
completed with an error.
Note that this logically reverts 7e3d3cc30f.
Vi visual mode selection highlighting behaves unexpectedly when the selection
foreground and background in the highlight spec don't match. The following
unexpected behaviors are:
* The foreground color is not being applied when defined by the
`fish_color_selection` variable.
* `set_color` options (e.g., `--bold`) would not be applied under the cursor
when selection begins in the middle of the command line or when the cursor
moves forward after visually selecting text backward.
With this change, visual selection respects the foreground color and any
`set_color` options are applied consistently regardless of where visual
selection begins and the position of the cursor during selection.
Most of it is duplicated, hence untested.
Functions like mbrtowc are not exposed by the libc crate, so declare them
ourselves.
Since we don't know the definition of C macros, add two big hacks to make
this work:
1. Replace MB_LEN_MAX and mbstate_t with values (resp types) that should
be large enough for any implementation.
2. Detect the definition of MB_CUR_MAX in the build script. This requires
more changes for each new libc. We could also use this approach for 1.
Additionally, this commit brings a small behavior change to
read_unquoted_escape(): we cannot decode surrogate code points like \UDE01
into a Rust char, so use � (\UFFFD, replacement character) instead.
Previously, we added such code points to a wcstring; looks like they were
ignored when printed.
wcs2string converts a wide string to a narrow one. The result is
null-terminated and may also contain interior null-characters.
std::string allows this.
Rust's null-terminated string, CString, does not like interior null-characters.
This means we will need to use Vec<u8> or OsString for the places where we
use interior null-characters.
On the other hand, we want to use CString for places that require a
null-terminator, because other Rust types don't guarantee the null-terminator.
Turns out there is basically no overlap between the two use cases, so make
it two functions. Their equivalents in Rust will have the same name, so
we'll only need to adjust the type when porting.
Existing C++ code didn't use a function for this but simply added
ENCODE_DIRECT_BASE. In Rust that's more verbose because char won't do
arithmetics, hence the function.
We'll add a dual function for decoding, so let's rename this.
BTW we should get rid of the "wchar" naming, it's just "char" in Rust.
This prevents leaking the escape sequence by printing nonsense, and it
also allows disabling cursor setting by just setting the variable to
e.g. empty.
And if we ever added any shapes, it would allow them to be used on new
fish and ignored on old
Fixes#9698
Use a "cmake-vendored" directory if it exists, to avoid accessing the
network if it's available, and a target to create an appropriate tarball
to create that directory.
Otherwise this would complete
`git --exec-path=foo`, by running `complete -C"'' --exec-path=foo"`,
which would print "--exec-path=foo", and so it would end as
`git --exec-path=--exec-path=foo` because the "replaces token" bit was
lost.
I'm not sure how to solve it cleanly - maybe an additional option to
`complete`?
Anyway, for now this
Fixes#9538.
Prior to this change, wcstoi("0x") would fail with missing digits.
However strtoul will "backtrack" to return just the 0 and leave the x as
the remainder. Implement this behavior.
Prior to this change, wcstoi() would return an error if the requested
type were unsigned, and the input had a leading minus sign. However this
causes problems for printf, which expects strtoul behavior.
Add "modulo base" behavior which wraps the negative value to positive.
Factor this into an option; the default is False (but code which
previously used strtoull directly should set it to true).
fish_wcstoi_partial is like fish_wcstoi: it converts from a string to an
int optionally inferring the radix. fish_wcstoi_partial also returns the
number of characters consumed.
Unfortunately we cannot use wide string literals in match statements
(not sure if there's an easy fix).
Because of this, I converted the input to UTF-8 so we could use the match
statement. This conversion is confusing, let's skip it.
This can be triggered on linux with:
```js
import { spawn } from 'child_process';
const shell = spawn('/home/alfa/dev/fish-shell/build-c++/fish', []);
```
Under node 19.8.1.
*No clue* how that happens, but since this is a workaround we shall
skip it.
Everything but signal handlers has been changed to use `Signal` instead of
`c_int` or `i32` signal values.
Event handlers are using `usize` to match C++, at least for now.
Signal is a newtype around NonZeroI32. We could use NonZeroU8 since all signal
values comfortably fit, but using i32 lets us avoid a fallible attempt at
narrowing values returned from the system as integers to the narrower u8 type.
Known signals are explicitly defined as constants and can be matched against
with equality or with pattern matching in a `match` block. Unknown signal values
are passed-through without causing any issues.
We're using per-OS targeting to enable certain libc SIGXXX values - we could
change this to dynamically detecting what's available in build.rs but then it
might not match what libc exposes, still giving us build failures.
This should be used in lieu of manually targeting individual operating systems
when using features shared by all BSD families.
e.g. instead of
#[cfg(any(target_os = "freebsd", target_os = "dragonflybsd", ...))]
fn foo() { }
you would use
#[cfg(feature = "bsd")]
fn foo() { }
This feature is automatically detected at build-time (see build.rs changes) and
should *not* be enabled manually. Additionally, this feature may not be used to
conditionally require any other dependency, as that isn't supported for
auto-enabled features.
Another from the "why are we asserting instead of doing something
sensible" department.
The alternative is to make exit() and return() compute their own exit
code, but tbh I don't want any *other* builtin to hit this either?
Fixes#9659
Just address two clippy lints that are fallout from changing the signal type.
There's no longer any need to convert these (which gets rid of an unwrap).
Due to limitations imposed by the borrow checker, there are very few places
where we will be able to use the `ScopedPush` class ported over from the C++
codebase (once you capture the value w/ a `ScopedPush` you can't access the
value - or the mutable reference you used to reach it! - until the `ScopedPush`
object goes out of scope).
This alternative requires binding the previous values to a variable and manually
restoring them in the callback passed to the `ScopeGuard` constructor, but will
work with rust's borrow and `&mut` paradigm.
Currently the `autocxx` generated code does not produce any code intelligence
because `rust-analyzer` can't find the generated code since it's not in the
workspace. Here, we detect `rust-analyzer` by checking for a `RUSTC_WRAPPER`
environment variable containing `rust-analyzer` and changing (or avoid changing)
the output directory accordingly.
Closes#9654.
This was added to support signals; however we are unlikely to use this
for anything else. Remove it; just use a u64 to report signals that have
been set.
The test passes but only if executed on its own. It's not the most perfect test,
but I can basically never get `make test` to pass under WSL while that's not the
case on all my other machines.
This optimizes over both the rust rewrite and the original C++ code. The rust
rewrite saw `std::bitset` replaced with `[bool; 65]` which could result in a
lot of memory copy bandwidth each time we checked for and received no signals.
The original C++ code would iterate over all signal slots to see if any were
set. The code now returns a single u64 and only checks slots that are known to
have signals via an intelligent `Iterator` impl.
You can now use a reference to CxxWString or an allocated UniquePtr<CxxWString>
to get an &wstr temporary to use without having to allocate again (e.g. via
`from_ffi()`).
Rust has multiple sanitizers available (with llvm integration).
-Zsanitizer=address catches the most likely culprits but we may want to set up a
separate job w/ -Zsanitizer=memory to catch uninitialized reads.
It might be necessary to execute `cargo build` as `cargo build -Zbuild-std` to
get full coverage.
When we're linking against the hybrid C++ codebase, the sanitizer library is
injected into the binary by also include `-fsanitize=address` in CXXFLAGS - we
do *not* want to manually opt-into `-lasan`. We also need to manually specify
the desired target triple as a CMake variable and then explicitly pass it to all
`cargo` invocations if building with ASAN.
Corrosion has been patched to make sure it follows these rules.
The `cargo-test` target is failing to link under ASAN. For some reason it has
autocxx/ffi dependencies even though only rust-native, ffi-free code should be
tested (and one would think the situation wouldn't change depending on the
presence of the sanitizer flag). It's been disabled under ASAN for now.
wchar.rs should not import let alone reexport FFI strings.
Stop re-exporting utf32str! because we use L! instead.
In wchar_ffi.rs, stop re-exporting cxx::CxxWString because that hasn't
seen adoption.
I think we should use re-exports only for aliases like "wstr" or for aliases
into internal modules.
So I'd probably remove `pub use wchar_ffi::wcharz_t = crate::ffi::wcharz_t`
as well.
bool_assert_comparison is stupid, the reason they give is "it's shorter". Well,
`assert!(!foo)` is nowhere near as readable as `assert_eq!(foo, false)` because
of the ! noise from the macro.
Uninlined format args is a stupid lint that Rust actually walked back when they
made it an official warning because you still have to use a mix of inlined and
un-inlined format args (the latter of which won't complain) since only idents
can be inlined.
This shows some of the ugliness of the rust borrow checker when it comes to
safely implementing any sort of recursive access and the need to be overly
explicit about which types are actually used across threads and which aren't.
We're forced to use an `Arc` for `ItemMaker` (née `item_maker_t`) because
there's no other way to make it clear that its lifetime will last longer than
the FdMonitor's. But once we've created an `Arc<T>` we can't call
`Arc::get_mut()` to get an `&mut T` once we've created even a single weak
reference to the Arc (because that weak ref could be upgraded to a strong ref at
any time). This means we need to finish configuring any non-atomic properties
(such as `ItemMaker::always_exit`) before we initialize the callback (which
needs an `Arc<ItemMaker>` to do its thing).
Because rust doesn't like self-referential types and because of the fact that we
now need to create both the `ItemMaker` and the `FdMonitorItem` separately
before we set the callback (at which point it becomes impossible to get a
mutable reference to the `ItemMaker`), `ItemMaker::item` is dropped from the
struct and we instead have the "constructor" for `ItemMaker` take a reference to
an `FdMonitor` instance and directly add itself to the monitor's set, meaning we
don't need to move the item out of the `ItemMaker` in order to add it to the
`FdMonitor` set later.
We were only using their ffi implementations which are automatically
exported/public, but the actual functions we would need if we were to use
FdMonitor and co. in native rust code were either private or missing convenient
wrappers.
The existing code is kept, but a rusty version of these functions is added for
code that needs them.
These should only be temporarily used when porting 1-to-1 from C++; we should
use the std library's `read()` and `write_all()` methods instead in the future.
By extracting the equivalent of i32::cmp() into its own const function,
it becomes a lot easier to see what is happening and the logic can be
more direct.
These will be used in the parser.
Maybe this type should be a struct with boolean fields. The current way has
the upside that the usage is exactly the same as in C++.
CXX does not allow generic types like maybe_t. When porting a C++ function
that returns maybe_t to Rust, we return std::unique_ptr instead. Let's make
the transition more seamless by allowing to convert back to maybe_t implicitly.
For some reason this error is triggered by tests after the Rust port of
ast.cpp. Might want to get to the bottom of this but moving it back
to match the original C++ logic fixes it.
This is one of the few warnings we disable due to false positives. Let's also
disable it in the preprocessing steps needed for the Rust build.
Other warnings we ignore are -Wno-address -Wunused-local-typedefs and
-Wunused-macros. I didn't add them here because I don't expect that they
will be triggered by the headers we give to cxx.
After deleting a history item with
history delete --exact --case-sensitive the-item
it is still reachable by history search until the shell is restarted.
Let's fix this by saving history after each deletion. The non-exact variants
of "history delete" already do this. I think this was just an oversight
owed to the fact that hardly anyone uses "--exact" (else we would surely
have changed it to not require an explicit "--case-sensitive").
Prior to this fix, the Rust FLOG output was regressed from C++, because
it put quotes around strings. However if we used Display, we would fail
to FLOG non-display types like ThreadIDs.
There is apparently no way in Rust to write a function which formats a
value preferentially using Display, falling back to Debug.
Fix this by introducing two new traits, FloggableDisplay and
FloggableDebug. FloggableDisplay is implemented for all Display types,
and FloggableDebug can be "opted into" for any Debug type:
impl FloggableDebug for MyType {}
Both traits have a 'to_flog_str' function. FLOG brings them both into
scope, and Rust figures out which 'to_flog_str' gets called.
`xbps-query` actually parses `-Rsl` as `-Rs l`, which means that packages
without the letter "l" in their names or descriptions are not included in
`__fish_print_xbps_packages`'s output.
* wutil: Rewrite `wrealpath` in Rust
* Reduce use of FFI types in `wrealpath`
* Addressed PR comments regarding allocation
* Replace let binding assignment with regular comparison
More ugliness with types that cxx bridge can't recognize as being POD. Using
pointers to get/set `termios` values with an assert to make sure we're using
identical definitions on both sides (in cpp from the system headers and in rust
from the libc crate as exported).
I don't know why cxx bridge doesn't allow `SharedPtr<OpaqueRustType>` but we can
work around it in C++ by converting a `Box<T>` to a `shared_ptr<T>` then convert
it back when it needs to be destructed. I can't find a clean way of doing it
from the cxx bridge wrapper so for now it needs to be done manually in the C++
code.
Types/values that are drop-in ready over ffi are renamed to match the old cpp
names but for types that now differ due to ffi difficulties I've left the `_ffi`
in the function names to indicate that this isn't the "correct" way of using the
types/methods.
We want to keep the cast because tv_sec is not always 64 bits, see b5ff175b4
(Fix timer.rs cross-platform compilation, 2023-02-14).
It would be nice to avoid the clippy exemption, perhaps using something like
#[cfg(target_pointer_width = "32")]
let seconds = val.tv_sec as i64;
#[cfg(not(target_pointer_width = "32"))]
let seconds = val.tv_sec;
but I'm not sure if "target_pointer_width" is the right criteria.
The FISH_RUST_TARGET_DIR is not set for Tests.cmake, the target_dir will set to
$CARGO_MANIFEST_DIR/target. But if build.target-dir or CARGO_TARGET_DIR is set,
the real target_dir doesn't at the $CARGO_MANIFEST_DIR/target. It causes failure
in cargo test. Then, set --target-dir for cargo test.
Closes#9600
Upsizing to `usize` from `i32` doesn't work if `usize` is only 32-bits.
I changed the code to use the `FromStr` impl on `i32`, but we could have also
just used `u64` instead of `i32`.
Also, we should get in the habit of using the appropriate type aliases where
possible (`i32` should be `RawFd`).
We want to try and catch as much unexpected/non-deterministic behavior as we
can. We could run the CI explicitly in debug mode, but I think it makes sense to
always have overflow checks on in both debug/release modes everywhere, at least
for the duration of the codebase transition.
The mutex was being locked from the very start, before it was needed and
possibly before it would be needed.
Also rename the static global to stick to rust naming conventions.
Note that `once_cell::sync::Lazy<T>` actually internally uses its own lock
around the value, but in this case it's insufficient because `SmallRng` doesn't
implement `SeedableRng` so we can't reseed it with only an `&mut` reference and
must instead replace its value.
We probably *could* still use `Lazy<SmallRng>` directly and then rely on
`std::mem::swap()` to replace the contents of the shared global static without
reassigning the variable directly with a new `SmallRng` instance, but I'm not
sure that's a great idea. This is just a built-in, there's no real harm in
locking twice (especially while fish remains essentially single-threaded).
The old comments about using i128 logic were still there even though we are no
longer using that approach and the output type was very much misleadingly a u64
printed to the console (but via `%d` so it was ultimately shown as an i64). Be
explicit about the resulting being a valid i64 value before passing it to the
sprintf!() macro.
Also add comments about the safety of the final `unwrap()` operation.
Rust doesn't have __FUNCTION__ or __func__ (though you can hack around it with a
proc macro, but that will require a separate crate and slowing down compilation
times with heavy proc macro dependencies), so these are just regular functions
(at least for now). Rust's default stack trace on panic (even in release mode)
should be enough (and the functions themselves are inlined so the calling
function should be the second frame from the top, after the #[cold] panic
functions).
This is to allow us to verify some implementation details that aren't explicitly
documented in the rust standard library's documentation.
std::thread uses `pthread_create()` underneath the hood on *nix platforms, so
this *should* merely be a formality.
The way cxx bridge works, it doesn't recognize any types from another module as
being shared cxx bridge types with generations native to both C++ and Rust,
meaning every module that was going to use function pointers would have to
define its own `c_void` type (because cxx bridge doesn't recognize any of
libc::c_void, std::ffi::c_void, or autocxx::c_void).
FFI on other platforms has long used the equivalent of `uint8_t *` as an
alternative to `void *` for code where `void` was not available or was
undesirable for some reason. We can join the club - this way we can always use
`* {const|mut} u8` in our rust code and `uint8_t *` in our C++ code to pass
around parameters or values over the C abi.
I needed to rename some types already ported to rust so they don't clash with
their still-extant cpp counterparts. Helper ffi functions added to avoid needing
to dynamically allocate an FdMonitorItem for every fd (we use dozens per basic
prompt).
I ported some functions from cpp to rust that are used only in the backend but
without removing their existing cpp counterparts so cpp code can continue to use
their version of them (`wperror` and `make_detached_pthread`).
I ran into issues porting line-by-line logic because rust inverts the behavior
of `std::remove_if(..)` by making it (basically) `Vec::retain_if(..)` so I
replaced bools with an explict enum to make everything clearer.
I'll port the cpp tests for this separately, for now they're using ffi.
Porting closures was ugly. It's nothing hard, but it's very ugly as now each
capturing lambda has been changed into an explicit struct that contains its
parameters (that needs to be dynamically allocated), a standalone callback
(member) function to replace the lambda contents, and a separate trampoline
function to call it from rust over the shared C abi (not really relevant to
x86_64 w/ its single calling convention but probably needed on other platforms).
I don't like that `fd_monitor.rs` has its own `c_void`. I couldn't find a way to
move that to `ffi.rs` but still get cxx bridge to consider it a shared POD.
Every time I moved it to a different module, it would consider it to be an
opaque rust type instead. I worry this means we're going to have multiple
`c_void1`, `c_void2`, etc. types as we continue to port code to use function
pointers.
Also, rust treats raw pointers as foreign so you can't do `impl Send for * const
Foo` even if `Foo` is from the same module. That necessitated a wrapper type
(`void_ptr`) that implements `Send` and `Sync` so we can move stuff between
threads.
The code in fd_monitor_t has been split into two objects, one that is used by
the caller and a separate one associated with the background thread (this is
made nice and clean by rust's ownership model). Objects not needed under the
lock (i.e. accessed by the background thread exclusively) were moved to the
separate `BackgroundFdMonitor` type.
* Improve prompt execution time
* Change status to changes
* Remove grep/awk/sort
* Remove calls to grep/awk/sort
* Don't overwrite user defined colors
* Make look more consistent with git
This removes a weird `ls` call (that just decorates directories), and
makes it behave like normal path completion.
(really, this should be a proper option to complete)
Fixes#9285
Add completions for trash-cli commands:
trash, trash-empty, trash-list, trash-put and trash-restore.
``trash --help`` are used to identify the executable in trash cli completion.
Keeps the location of original function definition, and also stores
where it was copied. `functions` and `type` show both locations,
instead of none. It also retains the line numbers in the stack trace.
Rewrite completions for meson to expose meson commands with their
options and subcommands. New completions are based on the meson 1.0.
Subcommands were introduced in meson 0.42.0 (August 2017), so new
completions will only work for versions after 0.42.0. At this moment,
even oldstable Debian (buster) has meson 0.49.2 -- which means it is
unlikely someone will be affected.
---------
Co-authored-by: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
By default, fish does not complete files that have leading dots, unless the
wildcard itself has a leading dot. However this also affected completions;
for example `git add` would not offer `.gitlab-ci.yml` because it has a
leading dot.
Relax this for custom completions. Default file expansion still
suppresses leading dots, but now custom completions can create
leading-dot completions and they will be offered.
Fixes#3707.
When we draw the prompt, we move the cursor to the actual
position *we* think it is by issuing a carriage return (via
`move(0,0)`), and then going forward until we hit the spot.
This helps when the terminal and fish disagree on the width of the
prompt, because we are now definitely in the correct place, so we can
only overwrite a bit of the prompt (if it renders longer than we
expected) or leave space after the prompt. Both of these are benign in
comparison to staircase effects we would otherwise get.
Unfortunately, midnight commander ("mc") tries to extract the last
line of the prompt, and does so in a way that is overly naive - it
resets everything to 0 when it sees a `\r`, and doesn't account for
cursor movement. In effect it's playing a terminal, but not committing
to the bit.
Since this has been an open request in mc for quite a while, we hack
around it, by checking the $MC_SID environment variable.
If we see it, we skip the clearing. We end up most likely doing
relative movement from where we think we are, and in most cases it
should be *fine*.
This removes a possibility of an infinite loop where something in
__fish_config_interactive triggers a fish_prompt or fish_read event,
which calls __fish_on_interactive which calls
__fish_config_interactive again, ...
Fixes#9564
This wanted to get the default priority, and it ran a thing *at source
time*.
This can lead to a variety of errors and I don't believe it's all that
useful, so we remove it.
This is an additional tool, and this function is executed on source
time so we'd spew errors.
(also remove an ineffective line - it's probably *nicer* with the
read, but that's not what's currently effectively doing anything)
We should fix this warning eventually. Silence it for now to make Clippy
pass without warnings, which makes it much more useful.
Compiling fish-rust v0.1.0 (/home/johannes/git/fish-riir/fish-rust)
error: mutable borrow from immutable input(s)
--> src/ffi.rs:79:32
|
79 | pub fn get_procs(&self) -> &mut [UniquePtr<process_t>] {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: immutable borrow here
--> src/ffi.rs:79:22
|
79 | pub fn get_procs(&self) -> &mut [UniquePtr<process_t>] {
| ^^^^^
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#mut_from_ref
= note: `#[deny(clippy::mut_from_ref)]` on by default
error: could not compile `fish-rust` due to previous error
A following commit will pass global string constants to the gettext macro.
This is not ideal because we might accidentally use the constants without
gettext (which we should never do). To fix that we might need to define a
macro per constant, or use a proc macro which is maybe not worth it.
warning: deref which would be done by auto-deref
--> src/wchar_ffi.rs:81:5
|
81 | &*EMPTY_WSTRING
| ^^^^^^^^^^^^^^^ help: try this: `&EMPTY_WSTRING`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#explicit_auto_deref
= note: `#[warn(clippy::explicit_auto_deref)]` on by default
Separate the neovim completions from the vim ones, as their supported
options have diverged considerably.
Some documented options are not yet implemented, these are added but
commented out.
Closes#9535.
---------
Co-authored-by: Mahmoud Al-Qudsi <mqudsi@neosmart.net>
This is an easy win for `git add ` completion time if we have multiple descriptions.
What happened was we did things once per description string, but the
things included a bunch of computation (including multiple `string`
calls and even a `realpath`!). Because these don't change, we can
simply do them once.
And it turns out we can just use a cartesian product:
for d in $desc
printf '%s\t%s\n' $file $d
end
becomes
printf '%s\n' $file\t$desc
lazy_static has better ergonomics at the call/access sites (it returns a
reference to the type directly, whereas with once_cell we get a static Lazy<T>
that we must dereference instead) but the once_cell api is slated for
integration into the standard library [0] and has been the "preferred" way to
declare static global variables w/ deferred initialization. It's also less
opaque and easier to comprehend how it works, I guess?
(Both `once_cell` and `lazy_static` are already in our dependency tree, so this
should have no detrimental effect on build times. It actually negligibly
*improves* build times by not using macros, reducing the amount of expansion the
compiler has to do by a miniscule amount.)
[0]: https://github.com/rust-lang/rust/issues/74465
I have no idea why `apt-cache --no-generate show` is so slow since it basically
dumps the contents of the cache file located at `/var/lib/dpkg/status`. We are
technically bypassing any waits on the cache lock file so this may produce
incorrect results if the cache is being regenerated in the moment, but that's a
small price to pay and the results are likely confined to simply not generating
comprehensive results.
With this change, we no longer need to truncate results to the first n matches
and we no longer only print packages beginning with the commandline argument
enabling fish's partial completions logic to offer less-perfect suggestions when
no better options are available.
Even though we are generating more usable completions, we still trounce the old
performance by leaps and bounds:
```
Benchmark #1: fish -c "complete -C\"apt install ac\""
Time (mean ± σ): 2.165 s ± 0.033 s [User: 267.0 ms, System: 1932.2 ms]
Range (min … max): 2.136 s … 2.256 s 10 runs
Benchmark #2: build/fish -c "complete -C\"apt install ac\""
Time (mean ± σ): 111.1 ms ± 1.8 ms [User: 38.9 ms, System: 72.9 ms]
Range (min … max): 108.2 ms … 114.9 ms 26 runs
Summary
'build/fish -c "complete -C\"apt install ac\""' ran
19.49 ± 0.44 times faster than 'fish -c "complete -C\"apt install ac\""'
```
I think this should be preferred for all subcommand completions because it
handles typos or subcommands we don't recognize better (`apt foo <TAB>` no
longer suggests subcommands since the subcommand position has been taken).
It's debatable whether is_ascii_digit() is better than (0..=9).contains().
(Probably we want to go with the mainstream Rust choice eventually.)
Let's disable the warning for now since it's not terribly important.
We should only be dealing with wcharz_t at the language boundary.
Rust callers should prefer the equivalent &wstr.
Since wcsfilecmp() is no longer exposed directly it can take &wstr only.
- Added phx completions. These are very common completions for the Elixir Phoenix Framework.
Documentation can be found here: https://hexdocs.pm/phoenix/1.7.0-rc.2/Mix.Tasks.Local.Phx.html#content
- Added argument completions
- Made all descriptions start with an uppercase for better consistency
- Update CHANGELOG.rst
This is early work but I guess there's no harm in pushing it?
Some thoughts on the conventions:
Types that live only inside Rust follow Rust naming convention
("FeatureMetadata").
Types that live on both sides of the language boundary follow the existing
naming ("feature_flag_t").
The alternative is to define a type alias ("using feature_flag_t =
rust::FeatureFlag") but that doesn't seem to be supported in "[cxx::bridge]"
blocks. We could put it in a header ("future_feature_flags.h").
"feature_metadata_t" is a variant of "FeatureMetadata" that can cross
the language boundary. This has the advantage that we can avoid tainting
"FeatureMetadata" with "CxxString" and such. This is an experimental approach,
probably not what we should do in general.
The initial port of feature flags requires a global initialization. Since
fish_indent accesses feature flags, let's make sure to initialize them here.
In future, we can stop initializing things fish_indent doesn't need (like
the topic monitor) but that's no big deal. Global initialization should
always be a benign addition.
The original implementation without the test took me 3 hours (first time
seriously looking into this)
The functions take "wcharz_t" for smooth integration with existing C++ callers.
This is at the expense of Rust callers, which would prefer "&wstr". Would be
nice to declare a function parameter that accepts both but I don't think
that really works since "wcharz_t" drops the lifetime annotation.
rustfmt removes the "::" prefix from qualifiers. This breaks the build because
I think a later "pub use ffi::*" results in "std" being an ambiguous reference.
We can re-enable these once we're nearing a RIIR release (or if someone thinks
it's a good use of their time to fix them before then). Otherwise we're just
going to have GitHub reporting CI failure for all commits instead of just the
ones that actually broke something.
(I'm mainly trying to get the branch in a good state to merge into master.)
Use rustup to install the latest version of rust. The latest version of rust
available from pkg is 1.66.0 while the code currently needs 1.67.0 or later.
The nix crate had all its default features enabled, which included features that
are not present under BSD. We should only enable the select subset of crate
features that we know are available cross-platform (or else use conditional
targeting in Cargo.toml to only enable Linux-only features when compiling for
Linux targets).
For now, it seems we can just use the nix crate with all features disabled as it
still builds under Linux and FreeBSD in this state.
The `cmake` meta package pulls in `cmake-core`, `cmake-docs`, and `cmake-man` -
we don't need the latter two.
(It seems to be available on all the versions/architectures we target.)
The git-lite flavor, being significantly smaller and downloading/installing much
faster with fewer dependencies, is much better suited for CI environments (at
the cost of not supporting interactive git commands).
By default /etc/pkg/FreeBSD.conf uses either the /quarterly or /latest pkg
builds, which are built against the latest minor release of FreeBSD for the
given ${ABI} string at the time they were last updated.
The nature of the shared binary packages means everyone (across all minor
versions of the same major version on the same architecture, all of which share
the same stable ABI) gets the same binary build.
There are however packages which depend on symbols exported by system-provided
libraries (rather than by other packages, which are always going to be in sync)
that *aren't* stable across minor releases, leaving packages like llvm
broken if you install the latest llvm from pkg's binary repos built against,
say, FreeBSD 13.1 while running FreeBSD 13.0.
The other option is to use the "snapshots" of the binary packages available upon
the release of each minor version, by using /release_0, /release_1, etc instead
of /quarterly or /latest, but then you're limited to the ports that were
available at that specific date and those old versions.
tl;dr just make sure we're always using the latest minor release for each major
version of FreeBSD we intend to support.
This works around an autocxx limitations where different types cannot
have the same name even if they live in different namespace.
ast::job_t conflicts with job_t.
This adds an implementation of fish_wcstoi in Rust, mirroring the one in
fish. As Rust does not have a string to number which infers the radix
(i.e. looks for leading 0x or 0), we add that manually.
In v3 several input parameters where renamed and since v4 it requires Node.js 16.
This resolves warnings about Node.js 12 and `set-output` being deprecated and
slated for removal in the `Lock threads` workflow.
This addresses the node v12 deprecation warning in the GitHub CI, caused by the
dependency on actions/checkout@v2.
While actions/checkout@v3 introduces some new features and changes some
defaults, the subset of features that we use should not be affected by this
migration.
The "breaking change" from v2 to v3 can be seen at [0]. Since we are tracking
only v2 without a dot release specified, we are already opting into any breakage
across minor versions, so really the only change of note is the node version
upgrade.
[0]: https://github.com/actions/checkout/compare/v2.4.2...v3.0.0
This translated ctrl-k to "\v", which is a "vertical tab", and ctrl-l
to "\f" and ctrl-g to "\a".
There is no "vertical tab" or "alarm" or "\f" *key*, so these
shouldn't be translated. Just drop these and call them `\ck` and such.
(vertical tab specifically is utterly useless and I would be okay with
dropping it entirely, I have never seen it used anywhere)
That commit did way too many things, making it hard to see the 5 regressions
it introduced. Let's revert it and its stragglers. In future, we could redo
some of the changes.
Reverts changes to share/completions/git.fish from
- 3548aae55 (completions/git: Don't leak submodule subcommands, 2023-01-23)
- 905f788b3 (completions/git: Remove awkward newline symbol, 2023-01-10)
- 2da1a4ae7 (completions/git: Fix git-foo commands, 2023-01-09)
- e9bf8b9a4 (Run fish_indent on share/completions/*.fish, 2022-12-08)
- d31847b1d (Fix apparent dyslexia, 2022-11-12)
- 054d0ac0e (git completions: undo mistaken `set -f` usage, 2022-10-28)
- f5711ad5e (git.fish: collapse repeat complete cmds, set -f, rm unneeded funcs, 2022-10-27)
Bracketed paste adds one undo entry unless the pasted text contains a '
or \. This is because the "paste" bind-mode has bindings for those keys,
so they effectively start a new undo entry.
Let's fix this by adding an explicit undo group (our first use of this
feature!).
@@ -8,7 +8,7 @@ Please tell us which operating system and terminal you are using. The output of
Please tell us if you tried fish without third-party customizations by executing this command and whether it affected the behavior you are reporting:
Please tell us if you tried fish without third-party customizations by executing this command and whether it affected the behavior you are reporting:
sh -c 'env HOME=$(mktemp -d) fish'
sh -c 'env HOME=$(mktemp -d) XDG_CONFIG_HOME= XDG_DATA_DIRS= fish'
Tell us how to reproduce the problem. Including an asciinema.org recording is useful for problems that involve the visual display of fish output such as its prompt.
Tell us how to reproduce the problem. Including an asciinema.org recording is useful for problems that involve the visual display of fish output such as its prompt.
fish's core code has been ported from C++ to Rust (:issue:`9512`). This means a large change in dependencies and how to build fish. However, there should be no direct impact on users. Packagers should see the :ref:`For Distributors <rust-packaging>` section at the end.
Notable backwards-incompatible changes
--------------------------------------
- As part of a larger binding rework, ``bind`` gained a new key notation.
In most cases the old notation should keep working, but in rare cases you may have to change a ``bind`` invocation to use the new notation.
See :ref:`below <changelog-new-bindings>` for details.
-:kbd:`ctrl-c` now calls a new bind function called ``clear-commandline``. The old behavior, which leaves a "^C" marker, is available as ``cancel-commandline`` (:issue:`10935`)
-``random`` will produce different values from previous versions of fish when used with the same seed, and will work more sensibly with small seed numbers.
The seed was never guaranteed to give the same result across systems,
so we do not expect this to have a large impact (:issue:`9593`).
- Variables in command position that expand to a subcommand keyword are now forbidden to fix a likely user error.
For example, ``set editor command emacs; $editor`` is no longer allowed (:issue:`10249`).
-``functions --handlers`` will now list handlers in a different order.
Now it is definition order, first to last, where before it was last to first.
This was never specifically defined, and we recommend not relying on a specific order (:issue:`9944`).
- The ``qmark-noglob`` feature, introduced in fish 3.0, is enabled by default. That means ``?`` will no longer act as a single-character glob.
You can, for the time being, turn it back on by adding ``no-qmark-noglob`` to :envvar:`fish_features` and restarting fish::
set -Ua fish_features no-qmark-noglob
The flag will eventually be made read-only, making it impossible to turn off.
- Terminals that fail to ignore unrecognized OSC or CSI sequences may display garbage. We know cool-retro-term and emacs' ansi-term are affected, but most mainstream terminals are not.
- fish no longer searches directories from the Windows system/user ``$PATH`` environment variable for Linux executables. To execute Linux binaries by name (i.e. not with a relative or absolute path) from a Windows folder, make sure the ``/mnt/c/...`` path is explicitly added to ``$fish_user_paths`` and not just automatically appended to ``$PATH`` by ``wsl.exe`` (:issue:`10506`).
- Under Microsoft Windows Subsystem for Linux 1 (not WSL 2), backgrounded jobs that have not been disowned and do not terminate on their own after a ``SIGHUP`` + ``SIGCONT`` sequence will be explicitly killed by fish on exit (after the usual prompt to close or disown them) to work around a WSL 1 deficiency that sees backgrounded processes that run into ``SIGTTOU`` remain in a suspended state indefinitely (:issue:`5263`). The workaround is to explicitly ``disown`` processes you wish to outlive the shell session.
Notable improvements and fixes
------------------------------
.._changelog-new-bindings:
- fish now requests XTerm's ``modifyOtherKeys`` keyboard encoding and `kitty keyboard protocol's <https://sw.kovidgoyal.net/kitty/keyboard-protocol/>`_ progressive enhancements (:issue:`10359`).
Depending on terminal support, this allows to binding more key combinations, including arbitrary combinations of modifiers :kbd:`ctrl`, :kbd:`alt` and :kbd:`shift`, and distinguishing (for example) :kbd:`ctrl-i` from :kbd:`tab`.
Additionally, ``bind`` now supports a human-readable syntax in addition to byte sequences.
This includes modifier names, and names for keys like :kbd:`enter` and :kbd:`backspace`.
For example
-``bind up 'do something'`` binds the up-arrow key instead of a two-key sequence ("u" and then "p")
-``bind ctrl-x,alt-c 'do something'`` binds a sequence of two keys.
Any key argument that starts with an ASCII control character (like ``\e`` or ``\cX``) or is up to 3 characters long, not a named key, and does not contain ``,`` or ``-`` will be interpreted in the old syntax to keep compatibility for the majority of bindings.
Keyboard protocols can be turned off by disabling the "keyboard-protocols" feature flag::
set -Ua fish_features no-keyboard-protocols
This is a temporary measure to work around buggy terminals (:issue:`11056`), which appear to be relatively rare.
Use this if something like "=0" or "=5u" appears in your commandline mysteriously.
- fish can now be built as a self-installing binary (:issue:`10367`). That means it can be easily built on one system and copied to another, where it can extract supporting files.
To do this, run::
cargo install --path . # in a clone of the fish repository
# or `cargo build --release` and copy target/release/fish{,_indent,_key_reader} wherever you want
The first time it runs interactively, it will extract all the data files to ``~/.local/share/fish/install/``. A specific path can be used for the data files with ``fish --install=PATH`` To uninstall, remove the fish binaries and that directory.
This build system is experimental; the main build system, using ``cmake``, remains the recommended approach for packaging and installation to a prefix.
- A new function ``fish_should_add_to_history`` can be overridden to decide whether a command should be added to the history (:issue:`10302`).
- Bindings can now mix special input functions and shell commands, so ``bind ctrl-g expand-abbr "commandline -i \n"`` works as expected (:issue:`8186`).
- Special input functions run from bindings via ``commandline -f`` are now applied immediately, instead of after the currently executing binding (:issue:`3031`, :issue:`10126`).
For example, ``commandline -i foo; commandline | grep foo`` succeeds now.
- Undo history is no longer truncated after every command, but kept for the lifetime of the shell process.
- The :kbd:`ctrl-r` history search now uses glob syntax (:issue:`10131`).
- The :kbd:`ctrl-r` history search now operates only on the line or command substitution at cursor, making it easier to combine commands from history (:issue:`9751`).
- Abbreviations can now be restricted to specific commands. For instance::
abbr --add --command git back 'reset --hard HEAD^'
will expand "back" to ``reset --hard HEAD^``, but only when the command is ``git`` (:issue:`9411`).
Deprecations and removed features
---------------------------------
-``commandline --tokenize`` (short option ``-o``) has been deprecated in favor of ``commandline --tokens-expanded`` (short option ``-x``) which expands variables and other shell syntax, removing the need to use :doc:`eval <cmds/eval>` in completion scripts (:issue:`10212`).
- Two new feature flags:
-``remove-percent-self`` (see ``status features``) disables PID expansion of ``%self``, which has been supplanted by ``$fish_pid`` (:issue:`10262`).
-``test-require-arg`` disables ``test``'s one-argument mode. That means ``test -n`` without an additional argument will return false, ``test -z`` will keep returning true. Any other option without an argument, anything that is not an option and no argument will be an error. This also goes for ``[``, test's alternate name.
This is a frequent source of confusion and so we are breaking with POSIX explicitly in this regard.
In addition to the feature flag, there is a debug category "deprecated-test". Running fish with ``fish -d deprecated-test`` will show warnings whenever a ``test`` invocation that would change is used. (:issue:`10365`).
These can be enabled with::
set -Ua fish_features remove-percent-self test-require-arg
We intend to enable them by default in future, and after that eventually make them read-only.
- Specifying key names as terminfo names (using the ``bind -k`` syntax) is deprecated and may be removed in a future version.
- When a terminal pastes text into fish using bracketed paste, fish used to switch to a special ``paste`` bind mode.
This bind mode has been removed. The behavior on paste is no longer configurable.
- When an interactive fish is stopped or terminated by a signal that cannot be caught (SIGSTOP or SIGKILL), it may leave the terminal in a state where keypresses with modifiers are sent as CSI u sequences, instead of traditional control characters or escape sequences that are recognized by Readline and compatible programs, such as bash and python.
If this happens, you can use the ``reset`` command from ``ncurses`` to restore the terminal state.
-``fish_key_reader --verbose`` no longer shows timing information.
- Terminal information is no longer read from hashed terminfo databases, or termcap databases (:issue:`10269`). The vast majority of systems use a non-hashed terminfo database, which is still supported.
-``source`` returns an error if used without a filename or pipe/redirection (:issue:`10774`).
Scripting improvements
----------------------
-``for`` loops will no longer remember local variables from the previous iteration (:issue:`10525`).
- A new ``history append`` subcommand appends a command to the history, without executing it (:issue:`4506`).
- A new redirection: ``<? /path/to/file`` will try opening the file as input, and if it doesn't succeed silently uses ``/dev/null`` instead.
This can help with checks like ``test -f /path/to/file; and string replace foo bar < /path/to/file``. (:issue:`10387`)
- A new option ``commandline --tokens-raw`` prints a list of tokens without any unescaping (:issue:`10212`).
- A new option ``commandline --showing-suggestion`` tests whether an autosuggestion is currently displayed (:issue:`10586`).
-``functions`` and ``type`` now show that a function was copied and its source, rather than solely ``Defined interactively`` (:issue:`6575`).
- Stack trace now shows line numbers for copied functions (:issue:`6575`).
-``foo & && bar`` is now a syntax error, like in other shells (:issue:`9911`).
-``if -e foo; end`` now prints a more accurate error (:issue:`10000`).
-``cd`` into a directory that is not readable but accessible (permissions ``--x``) is now possible (:issue:`10432`).
- An integer overflow in ``string repeat`` leading to a near-infinite loop has been fixed (:issue:`9899`).
-``string shorten`` behaves better in the presence of non-printable characters, including fixing an integer overflow that shortened strings more than intended (:issue:`9854`).
-``string pad`` no longer allows non-printable characters as padding (:issue:`9854`).
-``string repeat`` now allows omission of ``-n`` when the first argument is an integer (:issue:`10282`).
-``string match`` and ``replace`` have a new ``--max-matches`` option to return as soon as the specified number of matches have been identified, which can improve performance in scripts (:issue:`10587`).
-``functions --handlers-type caller-exit`` once again lists functions defined as ``function --on-job-exit caller``, rather than them being listed by ``functions --handlers-type process-exit``.
- A new ``set --no-event`` option sets or erases variables without triggering a variable event. This can be useful to change a variable in an event handler (:issue:`10480`).
- Commas in command substitution output are no longer used as separators in brace expansion, preventing a surprising expansion in some cases (:issue:`5048`).
- Universal variables can now store strings containing invalid UTF-8 (:issue:`10313`).
- A new ``path basename -E`` option that causes it to return the basename ("filename" with the directory prefix removed) with the final extension (if any) also removed. This is a shorter version of ``path change-extension "" (path basename $foo)`` (:issue:`10521`).
- A new ``math --scale-mode`` option to select ``truncate``, ``round``, ``floor``, ``ceiling`` as you wish; the default value is ``truncate``. (:issue:`9117`).
-``random`` is now less strict about its arguments, allowing a start larger or equal to the end. (:issue:`10879`)
-``function --argument-names`` now produces an error if a read-only variable name is used, rather than simply ignoring it (:issue:`10842`).
- Tilde expansion in braces (that is, ``{~,}``) works correctly (:issue:`10610`).
Interactive improvements
------------------------
- Autosuggestions were sometimes not shown after recalling a line from history, which has been fixed (:issue:`10287`).
- Up-arrow search matches -- which are highlighted in reverse colors -- are no longer syntax-highlighted, to fix bad contrast with the search match highlighting.
- Command abbreviations (those with ``--position command`` or without a ``--position``) now also expand after decorators like ``command`` (:issue:`10396`).
- Abbreviations now expand after process separators like ``;`` and ``|``. This fixes a regression in version 3.6 (:issue:`9730`).
- When exporting interactively defined functions (using ``type``, ``functions`` or ``funcsave``) the function body is now indented, to match the interactive command line editor (:issue:`8603`).
-:kbd:`ctrl-x` (``fish_clipboard_copy``) on multiline commands now includes indentation (:issue:`10437`).
-:kbd:`ctrl-v` (``fish_clipboard_paste``) now strips ASCII control characters from the pasted text.
This is consistent with normal keyboard input (:issue:`5274`).
- When a command like ``fg %2`` fails to find the given job, it no longer behaves as if no job spec was given (:issue:`9835`).
- Redirection in command position like ``>echo`` is now highlighted as error (:issue:`8877`).
-``fish_vi_cursor`` now works properly inside the prompt created by builtin ``read`` (:issue:`10088`).
- fish no longer fails to open a FIFO if interrupted by a terminal resize signal (:issue:`10250`).
-``read --help`` and friends no longer ignore redirections. This fixes a regression in version 3.1 (:issue:`10274`).
- Measuring a command with ``time`` now considers the time taken for command substitution (:issue:`9100`).
-``fish_add_path`` now automatically enables verbose mode when used interactively (in the command line), in an effort to be clearer about what it does (:issue:`10532`).
- fish no longer adopts TTY modes of failed commands (:issue:`10603`).
-``complete -e cmd`` now prevents autoloading completions for ``cmd`` (:issue:`6716`).
- fish's default color scheme no longer uses the color "blue", as it has bad contrast against the background in a few terminal's default palettes (:issue:`10758`, :issue:`10786`)
The color scheme will not be upgraded for existing installs. If you want, you should select it again via ``fish_config``.
- Command lines which are larger than the terminal are now displayed correctly, instead of multiple blank lines being displayed (:issue:`7296`).
- Prompts that use external commands will no longer produce an infinite loop if the command crashes (:issue:`9796`).
- Undo (:kbd:`ctrl-z`) restores the cursor position too (:issue:`10838`).
- The output of ``jobs`` shows "-" for jobs that have the same process group ID as the fish process, rather than "-2" (:issue:`10833`).
- Job expansion (``%1`` syntax) works properly for jobs that are a mixture of external commands and functions (:issue:`10832`).
- Command lines which have more lines than the terminal can be displayed and edited correctly (:issue:`10827`).
- Functions that have been erased are no longer highlighted as valid commands (:issue:`10866`).
-``not``, ``time``, and variable assignments (that is ``not time a=b env``) is correctly recognized as valid syntax (:issue:`10890`).
- The Web-based configuration removes old right-hand-side prompts again, fixing a regression in fish 3.4.0 (:issue:`10675`).
- Further protection against programs which crash and leave the terminal in an inconsistent state (:issue:`10834`, :issue:`11038`).
- A workaround for git being very slow on macOS has been applied, improving performance after a fresh boot (:issue:`10535`).
New or improved bindings
^^^^^^^^^^^^^^^^^^^^^^^^
- When the cursor is on a command that resolves to an executable script, :kbd:`alt-o` will now open that script in your editor (:issue:`10266`).
- During up-arrow history search, :kbd:`shift-delete` will delete the current search item and move to the next older item. Previously this was only supported in the history pager.
-:kbd:`shift-delete` will also remove the currently-displayed autosuggestion from history, and remove it as a suggestion.
-:kbd:`ctrl-Z` (also known as :kbd:`ctrl-shift-z`) is now bound to redo.
- Some improvements to the :kbd:`alt-e` binding which edits the command line in an external editor:
- The editor's cursor position is copied back to fish. This is currently supported for Vim and Kakoune.
- Cursor position synchronization is only supported for a set of known editors, which are now also detected in aliases which use ``complete --wraps``. For example, use ``complete --wraps my-vim vim`` to synchronize cursors when ``EDITOR=my-vim``.
- Multiline commands are indented before being sent to the editor, which matches how they are displayed in fish.
- The ``...-path-component`` bindings, like ``backward-kill-path-component``, now treat ``#`` as part of a path component (:issue:`10271`).
- Bindings like :kbd:`alt-l` that print output in between prompts now work correctly with multiline commandlines.
-:kbd:`alt-d` on an empty command line lists the directory history again. This restores the behavior of version 2.1.
-``history-prefix-search-backward`` and ``-forward`` now maintain the cursor position, instead of moving the cursor to the end of the command line (:issue:`10430`).
- The following keys have refined behavior if the terminal supports :ref:`the new keyboard encodings <changelog-new-bindings>`:
- :kbd:`shift-enter` now inserts a newline instead of executing the command line.
- :kbd:`ctrl-backspace` now deletes the last word instead of only one character (:issue:`10741`).
- :kbd:`ctrl-delete` deletes the next word (same as :kbd:`alt-d`).
- New special input functions:
- ``forward-char-passive`` and ``backward-char-passive`` are like their non-passive variants but do not accept autosuggestions or move focus in the completion pager (:issue:`10398`).
- ``forward-token``, ``backward-token``, ``kill-token``, and ``backward-kill-token`` are similar to the ``*-bigword`` variants but for the whole argument token (which includes escaped spaces) (:issue:`2014`).
- ``clear-commandline``, which merely clears the command line, as an alternative to ``cancel-commandline`` which prints ``^C`` and a new prompt (:issue:`10213`).
- The ``accept-autosuggestion`` special input function now returns false when there was nothing to accept (:issue:`10608`).
- Vi mode has seen some improvements but continues to suffer from the lack of people working on it.
- New default cursor shapes for insert and replace mode.
- :kbd:`ctrl-n` in insert mode accepts autosuggestions (:issue:`10339`).
- Outside insert mode, the cursor will no longer be placed beyond the last character on the commandline.
- When the cursor is at the end of the commandline, a single :kbd:`l` will accept an autosuggestion (:issue:`10286`).
- The cursor position after pasting (:kbd:`p`) has been corrected.
- Added an additional binding, :kbd:`_`, for moving to the beginning of the line (:issue:`10720`).
- When the cursor is at the start of a line, escaping from insert mode no longer moves the cursor to the previous line.
- Added bindings for clipboard interaction, like :kbd:`",+,p` and :kbd:`",+,y,y`.
- Deleting in visual mode now moves the cursor back, matching vi (:issue:`10394`).
- The :kbd:`;`, :kbd:`,`, :kbd:`v`, :kbd:`V`, :kbd:`I`, and :kbd:`gU` bindings work in visual mode (:issue:`10601`, :issue:`10648`).
- Support :kbd:`%` motion (:issue:`10593`).
- :kbd:`ctrl-k` to remove the contents of the line beyond the cursor in all modes (:issue:`10648`).
- Support `ab` and `ib` vi text objects. New input functions are introduced ``jump-{to,till}-matching-bracket`` (:issue:`1842`).
- The :kbd:`E` binding now correctly handles the last character of the word, by jumping to the next word (:issue:`9700`).
Completions
^^^^^^^^^^^
- Command-specific tab completions may now offer results whose first character is a period. For example, it is now possible to tab-complete ``git add`` for files with leading periods. The default file completions hide these files, unless the token itself has a leading period (:issue:`3707`).
- Option completion now uses fuzzy subsequence filtering, just like non-option completion (:issue:`830`).
This means that ``--fb`` may be completed to ``--foobar`` if there is no better match.
- Completions that insert an entire token now use quotes instead of backslashes to escape special characters (:issue:`5433`).
- Normally, file name completions start after the last ``:`` or ``=`` in a token.
This helps commands like ``rsync --files-from=``.
This special meaning can now disabled by escaping these separators as ``\:`` and ``\=``.
This matches Bash's behavior.
Note that this escaping is usually not necessary since the completion engine already tries
to guess whether the separator is actually part of a file name.
- Various new completion scripts and numerous updates to existing ones.
- Completions could hang if the ``PAGER`` environment variable was sent to certain editors on macOS, FreeBSD and some other platforms. This has been fixed (:issue:`10820`).
- Generated completions are now stored in ``$XDG_CACHE_HOME/fish`` or ``~/.cache/fish`` by default (:issue:`10369`)
- A regression in fish 3.1, where completing a command line could change it completely, has been fixed (:issue:`10904`).
Improved terminal support
^^^^^^^^^^^^^^^^^^^^^^^^^
- fish now marks the prompt and command-output regions (via OSC 133) to enable terminal shell integration (:issue:`10352`).
Shell integration shortcuts can scroll to the next/previous prompt or show the last command output in a pager.
- fish now reports the working directory (via OSC 7) unconditionally instead of only for some terminals (:issue:`9955`).
- fish now sets the terminal window title (via OSC 0) unconditionally instead of only for some terminals (:issue:`10037`).
- Focus reporting in tmux is no longer disabled on the first prompt.
- Focus reporting is now disabled during commands run inside key bindings (:issue:`6942`).
- Cursor changes are applied to all terminals that support them, and the list of specifically-supported terminals has been removed (:issue:`10693`).
- If it cannot find the terminfo entry given by :envvar:`TERM` environment variable, fish will now use an included ``xterm-256color`` definition to match the vast majority of current terminal emulators (:issue:`10905`). If you need to have a specific terminfo profile for your terminal's ``TERM`` variable, install it into the terminfo database.
- Further improvements to the correct display of prompts which fill the width of the terminal (:issue:`8164`).
Other improvements
------------------
-``status`` gained a ``buildinfo`` subcommand, to print information on how fish was built, to help with debugging (:issue:`10896`).
-``fish_indent`` will now collapse multiple empty lines into one (:issue:`10325`).
-``fish_indent`` now preserves the modification time of files if there were no changes (:issue:`10624`).
- Performance in launching external processes has been improved for many cases (:issue:`10869`).
- Performance and interactivity under Windows Subsystem for Linux has been improved, with a workaround for Windows-specific locations being appended to ``$PATH`` by default (:issue:`10506`).
- On macOS, paths from ``/etc/paths`` and ``/etc/manpaths`` containing colons are handled correctly (:issue:`10684`).
- Additional filesystems such as AFS are properly detected as remote, which avoids certain hangs due to expensive filesystem locks (:issue:`10818`).
- A spurious error when launching multiple instances of fish for the first time has been removed (:issue:`10813`).
.._rust-packaging:
For distributors
----------------
fish has been ported to Rust. This means a significant change in dependencies, which are listed in the README. In short, Rust 1.70 or greater is required, and a C++ compiler is no longer needed (although a C compiler is still required, for some C glue code and the tests).
CMake remains the recommended build system, because of cargo's limited support for installing support files. Version 3.5 remains the minimum supported version. The Xcode generator for CMake is not supported any longer (:issue:`9924`). CMake builds default to optimized release builds (:issue:`10799`).
fish no longer depends on the ncurses library, but still uses a terminfo database. When packaging fish, please add a dependency on the package containing your terminfo database instead of curses.
The ``test`` target was removed as it can no longer be defined in new CMake versions. Use ``make fish_run_tests``. Any existing test target will not print output if it fails (:issue:`11116`).
The Web-based configuration has been rewritten to use Alpine.js (:issue:`9554`).
--------------
fish 4.0b1 (released December 17, 2024)
=======================================
A number of improvements were included in fish 4.0.0 following the beta release of 4.0b1. These include fixes for regressions, improvements to completions and documentation, and the removal of a small number of problematic changes.
The full list of fixed issues can be found on the `GitHub milestone page for 4.0-final <https://github.com/fish-shell/fish-shell/milestone/43>`_.
--------------
fish 3.7.1 (released March 19, 2024)
fish 3.7.1 (released March 19, 2024)
====================================
====================================
@@ -33,7 +299,7 @@ Notable improvements and fixes
- Improvements to the history pager, including:
- Improvements to the history pager, including:
- The history pager will now also attempt subsequence matches (:issue:`9476`), so you can find a command line like ``git log 3.6.1..Integration_3.7.0`` by searching for ``gitInt``.
- The history pager will now also attempt subsequence matches (:issue:`9476`), so you can find a command line like ``git log 3.6.1..Integration_3.7.0`` by searching for ``gitInt``.
- Opening the history pager will now fill the search field with a search string if you're already in a search (:issue:`10005`). This makes it nicer to search something with :kbd:`↑` and then later decide to switch to the full pager.
- Opening the history pager will now fill the search field with a search string if you're already in a search (:issue:`10005`). This makes it nicer to search something with :kbd:`up` and then later decide to switch to the full pager.
- Closing the history pager with enter will now copy the search text to the commandline if there was no match, so you can continue editing the command you tried to find right away (:issue:`9934`).
- Closing the history pager with enter will now copy the search text to the commandline if there was no match, so you can continue editing the command you tried to find right away (:issue:`9934`).
- Performance improvements for command completions and globbing, where supported by the operating system, especially on slow filesystems such as NFS (:issue:`9891`, :issue:`9931`, :issue:`10032`, :issue:`10052`).
- Performance improvements for command completions and globbing, where supported by the operating system, especially on slow filesystems such as NFS (:issue:`9891`, :issue:`9931`, :issue:`10032`, :issue:`10052`).
@@ -63,21 +329,21 @@ Interactive improvements
- Vi mode now uses :envvar:`fish_cursor_external` to set the cursor shape for external commands (:issue:`4656`).
- Vi mode now uses :envvar:`fish_cursor_external` to set the cursor shape for external commands (:issue:`4656`).
- Opening the history search in vi mode switches to insert mode correctly (:issue:`10141`).
- Opening the history search in vi mode switches to insert mode correctly (:issue:`10141`).
- Vi mode cursor shaping is now enabled in iTerm2 (:issue:`9698`).
- Vi mode cursor shaping is now enabled in iTerm2 (:issue:`9698`).
- Working directory reporting is enabled for iTerm2 (:issue:`9955`).
- Completing commands as root includes commands not owned by root, fixing a regression introduced in fish 3.2.0 (:issue:`9699`).
- Completing commands as root includes commands not owned by root, fixing a regression introduced in fish 3.2.0 (:issue:`9699`).
- Selection uses ``fish_color_selection`` for the foreground and background colors, as intended, rather than just the background (:issue:`9717`).
- Selection uses ``fish_color_selection`` for the foreground and background colors, as intended, rather than just the background (:issue:`9717`).
- The completion pager will no longer sometimes skip the last entry when moving through a long list (:issue:`9833`).
- The completion pager will no longer sometimes skip the last entry when moving through a long list (:issue:`9833`).
- The interactive ``history delete`` interface now allows specifying index ranges like "1..5" (:issue:`9736`), and ``history delete --exact`` now properly saves the history (:issue:`10066`).
- The interactive ``history delete`` interface now allows specifying index ranges like "1..5" (:issue:`9736`), and ``history delete --exact`` now properly saves the history (:issue:`10066`).
- Command completion will now call the stock ``manpath`` on macOS, instead of a potential Homebrew version. This prevents awkward error messages (:issue:`9817`).
- Command completion will now call the stock ``manpath`` on macOS, instead of a potential Homebrew version. This prevents awkward error messages (:issue:`9817`).
-A new bind function ``history-pager-delete``, bound to :kbd:`Shift` + :kbd:`Delete` by default, will delete the currently-selected history pager item from history (:issue:`9454`).
-the ``redo`` special input function restores the pre-undo cursor position.
- A new bind function ``history-pager-delete``, bound to :kbd:`shift-delete` by default, will delete the currently-selected history pager item from history (:issue:`9454`).
-``fish_key_reader`` will now use printable characters as-is, so pressing "ö" no longer leads to it telling you to bind ``\u00F6`` (:issue:`9986`).
-``fish_key_reader`` will now use printable characters as-is, so pressing "ö" no longer leads to it telling you to bind ``\u00F6`` (:issue:`9986`).
-``open`` can be used to launch terminal programs again, as an ``xdg-open`` bug has been fixed and a workaround has been removed (:issue:`10045`).
-``open`` can be used to launch terminal programs again, as an ``xdg-open`` bug has been fixed and a workaround has been removed (:issue:`10045`).
- The ``repaint-mode`` binding will now only move the cursor if there is repainting to be done. This fixes :kbd:`Alt` combination bindings in vi mode (:issue:`7910`).
- The ``repaint-mode`` binding will now only move the cursor if there is repainting to be done. This fixes :kbd:`alt` combination bindings in vi mode (:issue:`7910`).
- A new ``clear-screen`` bind function is used for :kbd:`Ctrl` + :kbd:`l` by default. This clears the screen and repaints the existing prompt at first,
- A new ``clear-screen`` bind function is used for :kbd:`ctrl-l` by default. This clears the screen and repaints the existing prompt at first,
so it eliminates visible flicker unless the terminal is very slow (:issue:`10044`).
so it eliminates visible flicker unless the terminal is very slow (:issue:`10044`).
- The ``alias`` convenience function has better support for commands with unusual characters, like ``+`` (:issue:`8720`).
- The ``alias`` convenience function has better support for commands with unusual characters, like ``+`` (:issue:`8720`).
- A longstanding issue where items in the pager would sometimes display without proper formatting has been fixed (:issue:`9617`).
- A longstanding issue where items in the pager would sometimes display without proper formatting has been fixed (:issue:`9617`).
- The :kbd:`Alt` + :kbd:`l` binding, which lists the directory of the token under the cursor, correctly expands tilde (``~``) to the home directory (:issue:`9954`).
- The :kbd:`alt-l` binding, which lists the directory of the token under the cursor, correctly expands tilde (``~``) to the home directory (:issue:`9954`).
- Various fish utilities that use an external pager will now try a selection of common pagers if the :envvar:`PAGER` environment variable is not set, or write the output to the screen without a pager if there is not one available (:issue:`10074`).
- Various fish utilities that use an external pager will now try a selection of common pagers if the :envvar:`PAGER` environment variable is not set, or write the output to the screen without a pager if there is not one available (:issue:`10074`).
- Command-specific tab completions may now offer results whose first character is a period. For example, it is now possible to tab-complete ``git add`` for files with leading periods. The default file completions hide these files, unless the token itself has a leading period (:issue:`3707`).
- Command-specific tab completions may now offer results whose first character is a period. For example, it is now possible to tab-complete ``git add`` for files with leading periods. The default file completions hide these files, unless the token itself has a leading period (:issue:`3707`).
@@ -181,6 +447,7 @@ This release of fish contains a number of fixes for problems identified in fish
Notable improvements and fixes
Notable improvements and fixes
------------------------------
------------------------------
-``abbr --erase`` now also erases the universal variables used by the old abbr function. That means::
-``abbr --erase`` now also erases the universal variables used by the old abbr function. That means::
abbr --erase (abbr --list)
abbr --erase (abbr --list)
can now be used to clean out all old abbreviations (:issue:`9468`).
can now be used to clean out all old abbreviations (:issue:`9468`).
@@ -203,10 +470,10 @@ Interactive improvements
- Variables that were set while the locale was C (the default ASCII-only locale) will now properly be encoded if the locale is switched (:issue:`2613`, :issue:`9473`).
- Variables that were set while the locale was C (the default ASCII-only locale) will now properly be encoded if the locale is switched (:issue:`2613`, :issue:`9473`).
- Escape during history search restores the original command line again (fixing a regression in 3.6.0).
- Escape during history search restores the original command line again (fixing a regression in 3.6.0).
- Using ``--help`` on builtins now respects the ``$MANPAGER`` variable, in preference to ``$PAGER`` (:issue:`9488`).
- Using ``--help`` on builtins now respects the ``$MANPAGER`` variable, in preference to ``$PAGER`` (:issue:`9488`).
-:kbd:`Control-G` closes the history pager, like other shells (:issue:`9484`).
-:kbd:`ctrl-g` closes the history pager, like other shells (:issue:`9484`).
- The documentation for the ``:``, ``[`` and ``.`` builtin commands can now be looked up with ``man`` (:issue:`9552`).
- The documentation for the ``:``, ``[`` and ``.`` builtin commands can now be looked up with ``man`` (:issue:`9552`).
- fish no longer crashes when searching history for non-ASCII codepoints case-insensitively (:issue:`9628`).
- fish no longer crashes when searching history for non-ASCII codepoints case-insensitively (:issue:`9628`).
- The :kbd:`Alt-S` binding will now also use ``please`` if available (:issue:`9635`).
- The :kbd:`alt-s` binding will now also use ``please`` if available (:issue:`9635`).
- Themes that don't specify every color option can be installed correctly in the Web-based configuration (:issue:`9590`).
- Themes that don't specify every color option can be installed correctly in the Web-based configuration (:issue:`9590`).
- Compatibility with Midnight Commander's prompt integration has been improved (:issue:`9540`).
- Compatibility with Midnight Commander's prompt integration has been improved (:issue:`9540`).
- A spurious error, noted when using fish in Google Drive directories under WSL 2, has been silenced (:issue:`9550`).
- A spurious error, noted when using fish in Google Drive directories under WSL 2, has been silenced (:issue:`9550`).
@@ -252,7 +519,7 @@ fish 3.6.0 (released January 7, 2023)
Notable improvements and fixes
Notable improvements and fixes
------------------------------
------------------------------
- By default, :kbd:`Control-R` now opens the command history in the pager (:issue:`602`). This is fully searchable and syntax-highlighted, as an alternative to the incremental search seen in other shells. The new special input function ``history-pager`` has been added for custom bindings.
- By default, :kbd:`ctrl-r` now opens the command history in the pager (:issue:`602`). This is fully searchable and syntax-highlighted, as an alternative to the incremental search seen in other shells. The new special input function ``history-pager`` has been added for custom bindings.
- Abbrevations are more flexible (:issue:`9313`, :issue:`5003`, :issue:`2287`):
- Abbrevations are more flexible (:issue:`9313`, :issue:`5003`, :issue:`2287`):
- They may optionally replace tokens anywhere on the command line, instead of only commands
- They may optionally replace tokens anywhere on the command line, instead of only commands
@@ -348,15 +615,15 @@ Interactive improvements
- If the terminal definition for :envvar:`TERM` can't be found, fish now tries using the "xterm-256color" and "xterm" definitions before "ansi" and "dumb". As the majority of terminal emulators in common use are now more or less xterm-compatible (often even explicitly claiming the xterm-256color entry), this should often result in a fully or almost fully usable terminal (:issue:`9026`).
- If the terminal definition for :envvar:`TERM` can't be found, fish now tries using the "xterm-256color" and "xterm" definitions before "ansi" and "dumb". As the majority of terminal emulators in common use are now more or less xterm-compatible (often even explicitly claiming the xterm-256color entry), this should often result in a fully or almost fully usable terminal (:issue:`9026`).
- A new variable, :envvar:`fish_cursor_selection_mode`, can be used to configure whether the command line selection includes the character under the cursor (``inclusive``) or not (``exclusive``). The new default is ``exclusive``; use ``set fish_cursor_selection_mode inclusive`` to get the previous behavior back (:issue:`7762`).
- A new variable, :envvar:`fish_cursor_selection_mode`, can be used to configure whether the command line selection includes the character under the cursor (``inclusive``) or not (``exclusive``). The new default is ``exclusive``; use ``set fish_cursor_selection_mode inclusive`` to get the previous behavior back (:issue:`7762`).
- fish's completion pager now fills half the terminal on first tab press instead of only 4 rows, which should make results visible more often and save key presses, without constantly snapping fish to the top of the terminal (:issue:`9105`, :issue:`2698`).
- fish's completion pager now fills half the terminal on first tab press instead of only 4 rows, which should make results visible more often and save key presses, without constantly snapping fish to the top of the terminal (:issue:`9105`, :issue:`2698`).
- The ``complete-and-search`` binding, used with :kbd:`Shift-Tab` by default, selects the first item in the results immediately (:issue:`9080`).
- The ``complete-and-search`` binding, used with :kbd:`shift-tab` by default, selects the first item in the results immediately (:issue:`9080`).
-``bind`` output is now syntax-highlighted when used interacively.
-``bind`` output is now syntax-highlighted when used interacively.
-:kbd:`Alt-H` (the default ``__fish_man_page`` binding) does a better job of showing the manual page of the command under cursor (:issue:`9020`).
-:kbd:`alt-h` (the default ``__fish_man_page`` binding) does a better job of showing the manual page of the command under cursor (:issue:`9020`).
- If :envvar:`fish_color_valid_path` contains an actual color instead of just modifiers, those will be used for valid paths even if the underlying color isn't "normal" (:issue:`9159`).
- If :envvar:`fish_color_valid_path` contains an actual color instead of just modifiers, those will be used for valid paths even if the underlying color isn't "normal" (:issue:`9159`).
- The key combination for the QUIT terminal sequence, often :kbd:`Control-Backslash` (``\x1c``), can now be sused as a binding (:issue:`9234`).
- The key combination for the QUIT terminal sequence, often :kbd:`ctrl-\\` (``\x1c``), can now be used as a binding (:issue:`9234`).
- fish's vi mode uses normal xterm-style sequences to signal cursor change, instead of using the iTerm's proprietary escape sequences. This allows for a blinking cursor and makes it work in complicated scenarios with nested terminals. (:issue:`3741`, :issue:`9172`)
- fish's vi mode uses normal xterm-style sequences to signal cursor change, instead of using the iTerm's proprietary escape sequences. This allows for a blinking cursor and makes it work in complicated scenarios with nested terminals. (:issue:`3741`, :issue:`9172`)
- When running fish on a remote system (such as inside SSH or a container), :kbd:`Control-X` now copies to the local client system's clipboard if the terminal supports OSC 52.
- When running fish on a remote system (such as inside SSH or a container), :kbd:`ctrl-x` now copies to the local client system's clipboard if the terminal supports OSC 52.
-``commandline`` gained two new options, ``--selection-start`` and ``--selection-end``, to set the start/end of the current selection (:issue:`9197`, :issue:`9215`).
-``commandline`` gained two new options, ``--selection-start`` and ``--selection-end``, to set the start/end of the current selection (:issue:`9197`, :issue:`9215`).
- fish's builtins now handle keyboard interrupts (:kbd:`Control-C`) correctly (:issue:`9266`).
- fish's builtins now handle keyboard interrupts (:kbd:`ctrl-c`) correctly (:issue:`9266`).
Completions
Completions
^^^^^^^^^^^
^^^^^^^^^^^
@@ -466,9 +733,9 @@ This release of fish introduces the following small enhancements:
This release also fixes a number of problems identified in fish 3.5.0.
This release also fixes a number of problems identified in fish 3.5.0.
- Completing ``git blame`` or ``git -C`` works correctly (:issue:`9053`).
- Completing ``git blame`` or ``git -C`` works correctly (:issue:`9053`).
- On terminals that emit a ``CSI u`` sequence for :kbd:`Shift-Space`, fish inserts a space instead of printing an error. (:issue:`9054`).
- On terminals that emit a ``CSI u`` sequence for :kbd:`shift-space`, fish inserts a space instead of printing an error. (:issue:`9054`).
-``status fish-path`` on Linux-based platforms could print the path with a " (deleted)" suffix (such as ``/usr/bin/fish (deleted)``), which is now removed (:issue:`9019`).
-``status fish-path`` on Linux-based platforms could print the path with a " (deleted)" suffix (such as ``/usr/bin/fish (deleted)``), which is now removed (:issue:`9019`).
- Cancelling an initial command (from fish's ``--init-command`` option) with :kbd:`Control-C` no longer prevents configuration scripts from running (:issue:`9024`).
- Cancelling an initial command (from fish's ``--init-command`` option) with :kbd:`ctrl-c` no longer prevents configuration scripts from running (:issue:`9024`).
- The job summary contained extra blank lines if the prompt used multiple lines, which is now fixed (:issue:`9044`).
- The job summary contained extra blank lines if the prompt used multiple lines, which is now fixed (:issue:`9044`).
- Using special input functions in bindings, in combination with ``and``/``or`` conditionals, no longer crashes (:issue:`9051`).
- Using special input functions in bindings, in combination with ``and``/``or`` conditionals, no longer crashes (:issue:`9051`).
@@ -566,7 +833,7 @@ Interactive improvements
- The ``vared`` command can now successfully edit variables named "tmp" or "prompt" (:issue:`8836`, :issue:`8837`).
- The ``vared`` command can now successfully edit variables named "tmp" or "prompt" (:issue:`8836`, :issue:`8837`).
-``time`` now emits an error if used after the first command in a pipeline (:issue:`8841`).
-``time`` now emits an error if used after the first command in a pipeline (:issue:`8841`).
-``fish_add_path`` now prints a message for skipped non-existent paths when using the ``-v`` flag (:issue:`8884`).
-``fish_add_path`` now prints a message for skipped non-existent paths when using the ``-v`` flag (:issue:`8884`).
- Since fish 3.2.0, pressing :kbd:`Control-D` while a command is running would end up inserting a space into the next commandline, which has been fixed (:issue:`8871`).
- Since fish 3.2.0, pressing :kbd:`ctrl-d` while a command is running would end up inserting a space into the next commandline, which has been fixed (:issue:`8871`).
- A bug that caused multi-line prompts to be moved down a line when pasting or switching modes has been fixed (:issue:`3481`).
- A bug that caused multi-line prompts to be moved down a line when pasting or switching modes has been fixed (:issue:`3481`).
- The Web-based configuration system no longer strips too many quotes in the abbreviation display (:issue:`8917`, :issue:`8918`).
- The Web-based configuration system no longer strips too many quotes in the abbreviation display (:issue:`8917`, :issue:`8918`).
- Fish started with ``--no-config`` will now use the default keybindings (:issue:`8493`)
- Fish started with ``--no-config`` will now use the default keybindings (:issue:`8493`)
@@ -577,10 +844,10 @@ Interactive improvements
New or improved bindings
New or improved bindings
^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^
- The :kbd:`Alt-S` binding will now insert ``doas`` instead of ``sudo`` if necessary (:issue:`8942`).
- The :kbd:`alt-s` binding will now insert ``doas`` instead of ``sudo`` if necessary (:issue:`8942`).
- The ``kill-whole-line`` special input function now kills the newline preceeding the last line. This makes ``dd`` in vi-mode clear the last line properly.
- The ``kill-whole-line`` special input function now kills the newline preceeding the last line. This makes ``dd`` in vi-mode clear the last line properly.
- The new ``kill-inner-line`` special input function kills the line without any newlines, allowing ``cc`` in vi-mode to clear the line while preserving newlines (:issue:`8983`).
- The new ``kill-inner-line`` special input function kills the line without any newlines, allowing ``cc`` in vi-mode to clear the line while preserving newlines (:issue:`8983`).
- On terminals that emit special sequences for these combinations, :kbd:`Shift-Space` is bound like :kbd:`Space`, and :kbd:`Ctrl-Return` is bound like :kbd:`Return` (:issue:`8874`).
- On terminals that emit special sequences for these combinations, :kbd:`shift-space` is bound like :kbd:`space`, and :kbd:`ctrl-enter` is bound like :kbd:`return` (:issue:`8874`).
Improved prompts
Improved prompts
^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^
@@ -626,7 +893,7 @@ This release of fish fixes the following problems identified in fish 3.4.0:
- An error printed after upgrading, where old instances could pick up a newer version of the ``fish_title`` function, has been fixed (:issue:`8778`)
- An error printed after upgrading, where old instances could pick up a newer version of the ``fish_title`` function, has been fixed (:issue:`8778`)
- fish builds correctly on NetBSD (:issue:`8788`) and OpenIndiana (:issue:`8780`).
- fish builds correctly on NetBSD (:issue:`8788`) and OpenIndiana (:issue:`8780`).
-``nextd-or-forward-word``, bound to :kbd:`Alt-Right Arrow` by default, was inadvertently changed to move like ``forward-bigword``. This has been corrected (:issue:`8790`).
-``nextd-or-forward-word``, bound to :kbd:`alt-right` by default, was inadvertently changed to move like ``forward-bigword``. This has been corrected (:issue:`8790`).
-``funcsave -q`` and ``funcsave --quiet`` now work correctly (:issue:`8830`).
-``funcsave -q`` and ``funcsave --quiet`` now work correctly (:issue:`8830`).
- Issues with the ``csharp`` and ``nmcli`` completions were corrected.
- Issues with the ``csharp`` and ``nmcli`` completions were corrected.
@@ -732,10 +999,10 @@ Scripting improvements
Interactive improvements
Interactive improvements
------------------------
------------------------
- Vi mode cursors are now set properly after :kbd:`Control-C` (:issue:`8125`).
- Vi mode cursors are now set properly after :kbd:`ctrl-c` (:issue:`8125`).
-``funced`` will try to edit the whole file containing a function definition, if there is one (:issue:`391`).
-``funced`` will try to edit the whole file containing a function definition, if there is one (:issue:`391`).
- Running a command line consisting of just spaces now deletes an ephemeral (starting with space) history item again (:issue:`8232`).
- Running a command line consisting of just spaces now deletes an ephemeral (starting with space) history item again (:issue:`8232`).
- Command substitutions no longer respect job control, instead running inside fish's own process group (:issue:`8172`). This more closely matches other shells, and improves :kbd:`Control-C` reliability inside a command substitution.
- Command substitutions no longer respect job control, instead running inside fish's own process group (:issue:`8172`). This more closely matches other shells, and improves :kbd:`ctrl-c` reliability inside a command substitution.
-``history`` and ``__fish_print_help`` now properly support ``less`` before version 530, including the version that ships with macOS. (:issue:`8157`).
-``history`` and ``__fish_print_help`` now properly support ``less`` before version 530, including the version that ships with macOS. (:issue:`8157`).
-``help`` now knows which section is in which document again (:issue:`8245`).
-``help`` now knows which section is in which document again (:issue:`8245`).
- fish's highlighter will now color options (starting with ``-`` or ``--``) with the color given in the new $fish_color_option, up to the first ``--``. It falls back on $fish_color_param, so nothing changes for existing setups (:issue:`8292`).
- fish's highlighter will now color options (starting with ``-`` or ``--``) with the color given in the new $fish_color_option, up to the first ``--``. It falls back on $fish_color_param, so nothing changes for existing setups (:issue:`8292`).
@@ -748,7 +1015,7 @@ Interactive improvements
- Propagation of universal variables from a fish process that is closing is faster (:issue:`8209`).
- Propagation of universal variables from a fish process that is closing is faster (:issue:`8209`).
- The command line is drawn in the correct place if the prompt ends with a newline (:issue:`8298`).
- The command line is drawn in the correct place if the prompt ends with a newline (:issue:`8298`).
-``history`` learned a new subcommand ``clear-session`` to erase all history from the current session (:issue:`5791`).
-``history`` learned a new subcommand ``clear-session`` to erase all history from the current session (:issue:`5791`).
- Pressing :kbd:`Control-C` in ``fish_key_reader`` will no longer print the incorrect "Press [ctrl-C] again to exit" message (:issue:`8510`).
- Pressing :kbd:`ctrl-c` in ``fish_key_reader`` will no longer print the incorrect "Press [ctrl-C] again to exit" message (:issue:`8510`).
- The default command-not-found handler for Fedora/PackageKit now passes the whole command line, allowing for functionality such as running the suggested command directly (:issue:`8579`).
- The default command-not-found handler for Fedora/PackageKit now passes the whole command line, allowing for functionality such as running the suggested command directly (:issue:`8579`).
- When looking for locale information, the Debian configuration is now used when available (:issue:`8557`).
- When looking for locale information, the Debian configuration is now used when available (:issue:`8557`).
- Pasting text containing quotes from the clipboard trims spaces more appropriately (:issue:`8550`).
- Pasting text containing quotes from the clipboard trims spaces more appropriately (:issue:`8550`).
@@ -761,8 +1028,8 @@ Interactive improvements
New or improved bindings
New or improved bindings
^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^
-:kbd:`Escape` can now bound without breaking arrow key bindings (:issue:`8428`).
-:kbd:`escape` can now bound without breaking arrow key bindings (:issue:`8428`).
- The :kbd:`Alt-H` binding (to open a command’s manual page) now also ignores ``command`` (:issue:`8447`).
- The :kbd:`alt-h` binding (to open a command’s manual page) now also ignores ``command`` (:issue:`8447`).
Improved prompts
Improved prompts
^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^
@@ -828,7 +1095,7 @@ Improved terminal support
- Vi mode cursors are enabled in Apple Terminal.app (:issue:`8167`).
- Vi mode cursors are enabled in Apple Terminal.app (:issue:`8167`).
- Vi cursor shaping and $PWD reporting is now also enabled on foot (:issue:`8422`).
- Vi cursor shaping and $PWD reporting is now also enabled on foot (:issue:`8422`).
-``ls`` will use colors also on newer versions of Apple Terminal.app (:issue:`8309`).
-``ls`` will use colors also on newer versions of Apple Terminal.app (:issue:`8309`).
- The :kbd:`Delete` and :kbd:`Shift-Tab` keys work more reliably under ``st`` (:issue:`8352`, :issue:`8354`).
- The :kbd:`delete` and :kbd:`shift-tab` keys work more reliably under ``st`` (:issue:`8352`, :issue:`8354`).
Other improvements
Other improvements
------------------
------------------
@@ -855,7 +1122,7 @@ This release of fish fixes the following problems identified in fish 3.3.0:
- The prompt and command line are redrawn correctly in response to universal variable changes (:issue:`8088`).
- The prompt and command line are redrawn correctly in response to universal variable changes (:issue:`8088`).
- A superfluous error that was produced when setting the ``PATH`` or ``CDPATH`` environment variables to include colon-delimited components that do not exist was removed (:issue:`8095`).
- A superfluous error that was produced when setting the ``PATH`` or ``CDPATH`` environment variables to include colon-delimited components that do not exist was removed (:issue:`8095`).
- The Vi mode indicator in the prompt is repainted correctly after :kbd:`Ctrl-C` cancels the current command (:issue:`8103`).
- The Vi mode indicator in the prompt is repainted correctly after :kbd:`ctrl-c` cancels the current command (:issue:`8103`).
- fish builds correctly on platforms that do not have a ``spawn.h`` header, such as old versions of OS X (:issue:`8097`).
- fish builds correctly on platforms that do not have a ``spawn.h`` header, such as old versions of OS X (:issue:`8097`).
A number of improvements to the documentation, and fixes for completions, are included as well.
A number of improvements to the documentation, and fixes for completions, are included as well.
@@ -925,15 +1192,15 @@ Interactive improvements
New or improved bindings
New or improved bindings
^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^
- Pasting in Vi mode puts text in the right place in normal mode (:issue:`7847`).
- Pasting in Vi mode puts text in the right place in normal mode (:issue:`7847`).
- Vi mode's :kbd:`u` is bound to ``undo`` instead of ``history-search-backward``, following GNU readline's behavior. Similarly, :kbd:`Control-R` is bound to ``redo`` instead of ``history-search-backward``, following Vim (:issue:`7908`).
- Vi mode's :kbd:`u` is bound to ``undo`` instead of ``history-search-backward``, following GNU readline's behavior. Similarly, :kbd:`ctrl-r` is bound to ``redo`` instead of ``history-search-backward``, following Vim (:issue:`7908`).
-:kbd:`s` in Vi visual mode now does the same thing as :kbd:`c` (:issue:`8039`).
-:kbd:`s` in Vi visual mode now does the same thing as :kbd:`c` (:issue:`8039`).
- The binding for :kbd:`"*y` now uses ``fish_clipboard_copy``, allowing it to support more than just ``xsel``.
- The binding for :kbd:`",*,y` now uses ``fish_clipboard_copy``, allowing it to support more than just ``xsel``.
- The :kbd:`Control-Space` binding can be correctly customised (:issue:`7922`).
- The :kbd:`ctrl-space` binding can be correctly customised (:issue:`7922`).
-``exit`` works correctly in bindings (:issue:`7967`).
-``exit`` works correctly in bindings (:issue:`7967`).
- The :kbd:`F1` binding, which opens the manual page for the current command, now works around a bug in certain ``less`` versions that fail to clear the screen (:issue:`7863`).
- The :kbd:`f1` binding, which opens the manual page for the current command, now works around a bug in certain ``less`` versions that fail to clear the screen (:issue:`7863`).
- The binding for :kbd:`Alt-S` now toggles whether ``sudo`` is prepended, even when it took the commandline from history instead of only adding it.
- The binding for :kbd:`alt-s` now toggles whether ``sudo`` is prepended, even when it took the commandline from history instead of only adding it.
- The new functions ``fish_commandline_prepend`` and ``fish_commandline_append`` allow toggling the presence of a prefix/suffix on the current commandline. (:issue:`7905`).
- The new functions ``fish_commandline_prepend`` and ``fish_commandline_append`` allow toggling the presence of a prefix/suffix on the current commandline. (:issue:`7905`).
-``backward-kill-path-component``:kbd:`Control-W`) no longer erases parts of two tokens when the cursor is positioned immediately after ``/``. (:issue:`6258`).
-``backward-kill-path-component``:kbd:`ctrl-w`) no longer erases parts of two tokens when the cursor is positioned immediately after ``/``. (:issue:`6258`).
Improved prompts
Improved prompts
^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^
@@ -1049,8 +1316,8 @@ Notable improvements and fixes
…h-shell/build (makepkg)>
…h-shell/build (makepkg)>
It is still possible to react to the ``COLUMNS`` variable inside the prompt to implement smarter behavior.
It is still possible to react to the ``COLUMNS`` variable inside the prompt to implement smarter behavior.
-**fish completes ambiguous completions** after pressing :kbd:`Tab` even when they
-**fish completes ambiguous completions** after pressing :kbd:`tab` even when they
have a common prefix, without the user having to press :kbd:`Tab` again
have a common prefix, without the user having to press :kbd:`tab` again
(:issue:`6924`).
(:issue:`6924`).
- fish is less aggressive about resetting terminal modes, such as flow control, after every command.
- fish is less aggressive about resetting terminal modes, such as flow control, after every command.
Although flow control remains off by default, enterprising users can now enable it with
Although flow control remains off by default, enterprising users can now enable it with
@@ -1176,7 +1443,7 @@ Interactive improvements
- The interactive reader now allows ending a line in a logical operators (``&&`` and ``||``) instead of complaining about a missing command. (This was already syntactically valid, but interactive sessions didn't know about it yet).
- The interactive reader now allows ending a line in a logical operators (``&&`` and ``||``) instead of complaining about a missing command. (This was already syntactically valid, but interactive sessions didn't know about it yet).
- The prompt is reprinted after a background job exits (:issue:`1018`).
- The prompt is reprinted after a background job exits (:issue:`1018`).
- fish no longer inserts a space after a completion ending in ``.``, ``,`` or ``-`` is accepted, improving completions for tools that provide dynamic completions (:issue:`6928`).
- fish no longer inserts a space after a completion ending in ``.``, ``,`` or ``-`` is accepted, improving completions for tools that provide dynamic completions (:issue:`6928`).
- If a filename is invalid when first pressing :kbd:`Tab`, but becomes valid, it will be completed properly on the next attempt (:issue:`6863`).
- If a filename is invalid when first pressing :kbd:`tab`, but becomes valid, it will be completed properly on the next attempt (:issue:`6863`).
-``help string match/replace/<subcommand>`` will show the help for string subcommands (:issue:`6786`).
-``help string match/replace/<subcommand>`` will show the help for string subcommands (:issue:`6786`).
-``fish_key_reader`` sets the exit status to 0 when used with ``--help`` or ``--version`` (:issue:`6964`).
-``fish_key_reader`` sets the exit status to 0 when used with ``--help`` or ``--version`` (:issue:`6964`).
-``fish_key_reader`` and ``fish_indent`` send output from ``--version`` to standard output, matching other fish binaries (:issue:`6964`).
-``fish_key_reader`` and ``fish_indent`` send output from ``--version`` to standard output, matching other fish binaries (:issue:`6964`).
@@ -1213,15 +1480,15 @@ Interactive improvements
When it can't find a command, fish now just executes a function called ``fish_command_not_found``
When it can't find a command, fish now just executes a function called ``fish_command_not_found``
instead of firing an event, making it easier to replace and reason about.
instead of firing an event, making it easier to replace and reason about.
Previously-defined ``__fish_command_not_found_handler`` functions with an appropriate event listener will still work (:issue:`7293`).
Previously-defined ``__fish_command_not_found_handler`` functions with an appropriate event listener will still work (:issue:`7293`).
-:kbd:`Control-C` handling has been reimplemented in C++ and is therefore quicker (:issue:`5259`), no longer occasionally prints an "unknown command" error (:issue:`7145`) or overwrites multiline prompts (:issue:`3537`).
-:kbd:`ctrl-c` handling has been reimplemented in C++ and is therefore quicker (:issue:`5259`), no longer occasionally prints an "unknown command" error (:issue:`7145`) or overwrites multiline prompts (:issue:`3537`).
-:kbd:`Control-C` no longer kills background jobs for which job control is
-:kbd:`ctrl-c` no longer kills background jobs for which job control is
- Autosuggestions work properly after :kbd:`Control-C` cancels the current commmand line (:issue:`6937`).
- Autosuggestions work properly after :kbd:`ctrl-c` cancels the current commmand line (:issue:`6937`).
- History search is now case-insensitive unless the search string contains an uppercase character (:issue:`7273`).
- History search is now case-insensitive unless the search string contains an uppercase character (:issue:`7273`).
-``fish_update_completions`` gained a new ``--keep`` option, which improves speed by skipping completions that already exist (:issue:`6775`, :issue:`6796`).
-``fish_update_completions`` gained a new ``--keep`` option, which improves speed by skipping completions that already exist (:issue:`6775`, :issue:`6796`).
- Aliases containing an embedded backslash appear properly in the output of ``alias`` (:issue:`6910`).
- Aliases containing an embedded backslash appear properly in the output of ``alias`` (:issue:`6910`).
-``open`` no longer hangs indefinitely on certain systems, as a bug in ``xdg-open`` has been worked around (:issue:`7215`).
-``open`` no longer hangs indefinitely on certain systems, as a bug in ``xdg-open`` has been worked around (:issue:`7215`).
- Long command lines no longer add a blank line after execution (:issue:`6826`) and behave better with :kbd:`Backspace` (:issue:`6951`).
- Long command lines no longer add a blank line after execution (:issue:`6826`) and behave better with :kbd:`backspace` (:issue:`6951`).
-``functions -t`` works like the long option ``--handlers-type``, as documented, instead of producing an error (:issue:`6985`).
-``functions -t`` works like the long option ``--handlers-type``, as documented, instead of producing an error (:issue:`6985`).
- History search now flashes when it found no more results (:issue:`7362`)
- History search now flashes when it found no more results (:issue:`7362`)
- fish now creates the path in the environment variable ``XDG_RUNTIME_DIR`` if it does not exist, before using it for runtime data storage (:issue:`7335`).
- fish now creates the path in the environment variable ``XDG_RUNTIME_DIR`` if it does not exist, before using it for runtime data storage (:issue:`7335`).
@@ -1258,27 +1525,27 @@ Interactive improvements
New or improved bindings
New or improved bindings
^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^
- As mentioned above, new special input functions ``undo`` (:kbd:`Control+\_` or :kbd:`Control+Z`) and ``redo`` (:kbd:`Alt-/`) can be used to revert changes to the command line or the pager search field (:issue:`6570`).
- As mentioned above, new special input functions ``undo`` (:kbd:`ctrl-_` or :kbd:`ctrl-z`) and ``redo`` (:kbd:`alt-/`) can be used to revert changes to the command line or the pager search field (:issue:`6570`).
-:kbd:`Control-Z` is now available for binding (:issue:`7152`).
-:kbd:`ctrl-z` is now available for binding (:issue:`7152`).
- Additionally, using the ``cancel`` special input function (bound to :kbd:`Escape` by default) right after fish picked an unambiguous completion will undo that (:issue:`7433`).
- Additionally, using the ``cancel`` special input function (bound to :kbd:`escape` by default) right after fish picked an unambiguous completion will undo that (:issue:`7433`).
-``fish_clipboard_paste`` (:kbd:`Control+V`) trims indentation from multiline commands, because fish already indents (:issue:`7662`).
-``fish_clipboard_paste`` (:kbd:`ctrl-v`) trims indentation from multiline commands, because fish already indents (:issue:`7662`).
- Vi mode bindings now support ``dh``, ``dl``, ``c0``, ``cf``, ``ct``, ``cF``, ``cT``, ``ch``, ``cl``, ``y0``, ``ci``, ``ca``, ``yi``, ``ya``, ``di``, ``da``, ``d;``, ``d,``, ``o``, ``O`` and Control+left/right keys to navigate by word (:issue:`6648`, :issue:`6755`, :issue:`6769`, :issue:`7442`, :issue:`7516`).
- Vi mode bindings now support ``dh``, ``dl``, ``c0``, ``cf``, ``ct``, ``cF``, ``cT``, ``ch``, ``cl``, ``y0``, ``ci``, ``ca``, ``yi``, ``ya``, ``di``, ``da``, ``d;``, ``d,``, ``o``, ``O`` and Control+left/right keys to navigate by word (:issue:`6648`, :issue:`6755`, :issue:`6769`, :issue:`7442`, :issue:`7516`).
- Vi mode bindings support :kbd:`~` (tilde) to toggle the case of the selected character (:issue:`6908`).
- Vi mode bindings support :kbd:`~` (tilde) to toggle the case of the selected character (:issue:`6908`).
- Functions ``up-or-search`` and ``down-or-search`` (:kbd:`Up` and :kbd:`Down`) can cross empty lines, and don't activate search mode if the search fails, which makes them easier to use to move between lines in some situations.
- Functions ``up-or-search`` and ``down-or-search`` (:kbd:`up` and :kbd:`down`) can cross empty lines, and don't activate search mode if the search fails, which makes them easier to use to move between lines in some situations.
- If history search fails to find a match, the cursor is no longer moved. This is useful when accidentally starting a history search on a multi-line commandline.
- If history search fails to find a match, the cursor is no longer moved. This is useful when accidentally starting a history search on a multi-line commandline.
- The special input function ``beginning-of-history`` (:kbd:`Page Up`) now moves to the oldest search instead of the youngest - that's ``end-of-history`` (:kbd:`Page Down`).
- The special input function ``beginning-of-history`` (:kbd:`pageup`) now moves to the oldest search instead of the youngest - that's ``end-of-history`` (:kbd:`pagedown`).
- A new special input function ``forward-single-char`` moves one character to the right, and if an autosuggestion is available, only take a single character from it (:issue:`7217`, :issue:`4984`).
- A new special input function ``forward-single-char`` moves one character to the right, and if an autosuggestion is available, only take a single character from it (:issue:`7217`, :issue:`4984`).
- Special input functions can now be joined with ``or`` as a modifier (adding to ``and``), though only some commands set an exit status (:issue:`7217`). This includes ``suppress-autosuggestion`` to reflect whether an autosuggestion was suppressed (:issue:`1419`)
- Special input functions can now be joined with ``or`` as a modifier (adding to ``and``), though only some commands set an exit status (:issue:`7217`). This includes ``suppress-autosuggestion`` to reflect whether an autosuggestion was suppressed (:issue:`1419`)
- A new function ``__fish_preview_current_file``, bound to :kbd:`Alt+O`, opens the
- A new function ``__fish_preview_current_file``, bound to :kbd:`alt-o`, opens the
current file at the cursor in a pager (:issue:`6838`, :issue:`6855`).
current file at the cursor in a pager (:issue:`6838`, :issue:`6855`).
-``edit_command_buffer`` (:kbd:`Alt-E` and :kbd:`Alt-V`) passes the cursor position
-``edit_command_buffer`` (:kbd:`alt-e` and :kbd:`alt-v`) passes the cursor position
to the external editor if the editor is recognized (:issue:`6138`, :issue:`6954`).
to the external editor if the editor is recognized (:issue:`6138`, :issue:`6954`).
-``__fish_prepend_sudo`` (:kbd:`Alt-S`) now toggles a ``sudo`` prefix (:issue:`7012`) and avoids shifting the cursor (:issue:`6542`).
-``__fish_prepend_sudo`` (:kbd:`alt-s`) now toggles a ``sudo`` prefix (:issue:`7012`) and avoids shifting the cursor (:issue:`6542`).
-``__fish_prepend_sudo`` (:kbd:`Alt-S`) now uses the previous commandline if the current one is empty,
-``__fish_prepend_sudo`` (:kbd:`alt-s`) now uses the previous commandline if the current one is empty,
to simplify rerunning the previous command with ``sudo`` (:issue:`7079`).
to simplify rerunning the previous command with ``sudo`` (:issue:`7079`).
-``__fish_toggle_comment_commandline`` (:kbd:`Alt-#`) now uncomments and presents the last comment
-``__fish_toggle_comment_commandline`` (:kbd:`alt-#`) now uncomments and presents the last comment
from history if the commandline is empty (:issue:`7137`).
from history if the commandline is empty (:issue:`7137`).
-``__fish_whatis_current_token`` (:kbd:`Alt-W`) prints descriptions for functions and builtins (:issue:`7191`, :issue:`2083`).
-``__fish_whatis_current_token`` (:kbd:`alt-w`) prints descriptions for functions and builtins (:issue:`7191`, :issue:`2083`).
- The definition of "word" and "bigword" for movements was refined, fixing (eg) vi mode's behavior with :kbd:`e` on the second-to-last char, and bigword's behavior with single-character words and non-blank non-graphical characters (:issue:`7353`, :issue:`7354`, :issue:`4025`, :issue:`7328`, :issue:`7325`)
- The definition of "word" and "bigword" for movements was refined, fixing (eg) vi mode's behavior with :kbd:`e` on the second-to-last char, and bigword's behavior with single-character words and non-blank non-graphical characters (:issue:`7353`, :issue:`7354`, :issue:`4025`, :issue:`7328`, :issue:`7325`)
- fish's clipboard bindings now also support Windows Subsystem for Linux via PowerShell and clip.exe (:issue:`7455`, :issue:`7458`) and will properly copy newlines in multi-line commands.
- fish's clipboard bindings now also support Windows Subsystem for Linux via PowerShell and clip.exe (:issue:`7455`, :issue:`7458`) and will properly copy newlines in multi-line commands.
- Using the ``*-jump`` special input functions before typing anything else no longer crashes fish.
- Using the ``*-jump`` special input functions before typing anything else no longer crashes fish.
@@ -2370,7 +2637,7 @@ Interactive improvements
key both on its own and as part of a control sequence, was applied to
key both on its own and as part of a control sequence, was applied to
all control characters; this has been reduced to just the escape key.
all control characters; this has been reduced to just the escape key.
- Completing a function shows the description properly (:issue:`5206`).
- Completing a function shows the description properly (:issue:`5206`).
-`commandline` can now be used to set the commandline for the next command, restoring a behavior in 3.4.1 (:issue:`8807`).
-``commandline`` can now be used to set the commandline for the next command, restoring a behavior in 3.4.1 (:issue:`8807`).
- Added completions for
- Added completions for
-``ansible``, including ``ansible-galaxy``, ``ansible-playbook``
-``ansible``, including ``ansible-galaxy``, ``ansible-playbook``
@@ -3191,8 +3458,8 @@ Other notable fixes and improvements
- Directory autosuggestions will now descend as far as possible if
- Directory autosuggestions will now descend as far as possible if
there is only one child directory (:issue:`2531`)
there is only one child directory (:issue:`2531`)
- Add support for bright colors (:issue:`1464`)
- Add support for bright colors (:issue:`1464`)
- Allow Ctrl-J (`\cj`) to be bound separately from Ctrl-M
- Allow Ctrl-J (``\cj``) to be bound separately from Ctrl-M
(`\cm`) (:issue:`217`)
(``\cm``) (:issue:`217`)
- psub now has a “-s”/“–suffix” option to name the temporary file with
- psub now has a “-s”/“–suffix” option to name the temporary file with
that suffix
that suffix
- Enable 24-bit colors on select terminals (:issue:`2495`)
- Enable 24-bit colors on select terminals (:issue:`2495`)
@@ -3336,7 +3603,7 @@ Other notable fixes and improvements
-``type`` has a new ``-q`` option to suppress output (:issue:`1540` and, like
-``type`` has a new ``-q`` option to suppress output (:issue:`1540` and, like
other shells, ``type -a`` now prints all matches for a command
other shells, ``type -a`` now prints all matches for a command
(:issue:`261`).
(:issue:`261`).
- Pressing F1 now shows the manual page for the current command
- Pressing :kbd:`f1` now shows the manual page for the current command
(:issue:`1063`).
(:issue:`1063`).
-``fish_title`` functions have access to the arguments of the
-``fish_title`` functions have access to the arguments of the
currently running argument as ``$argv[1]`` (:issue:`1542`).
currently running argument as ``$argv[1]`` (:issue:`1542`).
This will create a copy of the fish repository in the directory fish-shell in your current working directory.
Also, for most changes you want to run the tests and so you'd get a setup to compile fish.
For that, you'll require:
- Rust - when in doubt, try rustup
- CMake
- PCRE2 (headers and libraries) - optional, this will be downloaded if missing
- gettext (headers and libraries) - optional, for translation support
- Sphinx - optional, to build the documentation
Of course not everything is required always - if you just want to contribute something to the documentation you'll just need Sphinx,
and if the change is very simple and obvious you can just send it in. Use your judgement!
Once you have your changes, open a pull request on https://github.com/fish-shell/fish-shell/pulls.
Guidelines
==========
In short:
In short:
- Be conservative in what you need (``C++11``, few dependencies)
- Be conservative in what you need (keep to the agreed minimum supported Rust version, limit new dependencies)
- Use automated tools to help you (including ``make test``,``build_tools/style.fish`` and ``make lint``)
- Use automated tools to help you (including ``make fish_run_tests`` and``build_tools/style.fish``)
Contributing completions
Contributing completions
------------------------
========================
Completion scripts are the most common contribution to fish, and they are very welcome.
Completion scripts are the most common contribution to fish, and they are very welcome.
@@ -42,57 +77,21 @@ Put your completion script into share/completions/name-of-command.fish. If you h
If you want to add tests, you probably want to add a littlecheck test. See below for details.
If you want to add tests, you probably want to add a littlecheck test. See below for details.
Contributing to fish's C++ core
Contributing documentation
-------------------------------
==========================
Fish uses C++11. Newer C++ features should not be used to make it possible to use on older systems.
The documentation is stored in ``doc_src/``, and written in ReStructured Text and built with Sphinx.
It does not use exceptions, they are disabled at build time with ``-fno-exceptions``.
To build it locally, run from the main fish-shell directory::
Don't introduce new dependencies unless absolutely necessary, and if you do,
sphinx-build -j 8 -b html -n doc_src/ /tmp/fish-doc/
please make it optional with graceful failure if possible.
Add any new dependencies to the README.rst under the *Running* and/or *Building* sections.
Linters
which will build the docs as html in /tmp/fish-doc. You can open it in a browser and see that it looks okay.
-------
Automated analysis tools like cppcheck can point out
The builtins and various functions shipped with fish are documented in doc_src/cmds/.
potential bugs or code that is extremely hard to understand. They also
help ensure the code has a consistent style and that it avoids patterns
that tend to confuse people.
To make linting the code easy there are two make targets: ``lint``,
to lint any modified but not committed ``*.cpp`` files, and
``lint-all`` to lint all files.
Fish has custom cppcheck rules in the file ``.cppcheck.rule``. These
help catch mistakes such as using ``wcwidth()`` rather than
``fish_wcwidth()``. Please add a new rule if you find similar mistakes
being made.
Suppressing Lint Warnings
~~~~~~~~~~~~~~~~~~~~~~~~~
Once in a while the lint tools emit a false positive warning. For
example, cppcheck might suggest a memory leak is present when that is
not the case. To suppress that cppcheck warning you should insert a line
like the following immediately prior to the line cppcheck warned about:
::
// cppcheck-suppress memleak // addr not really leaked
The explanatory portion of the suppression comment is optional. For
other types of warnings replace “memleak” with the value inside the
parenthesis (e.g., “nullPointerRedundantCheck”) from a warning like the
following:
::
[src/complete.cpp:1727]: warning (nullPointerRedundantCheck): Either the condition 'cmd_node' is redundant or there is possible null pointer dereference: cmd_node.
Code Style
Code Style
----------
==========
To ensure your changes conform to the style rules run
To ensure your changes conform to the style rules run
@@ -102,7 +101,7 @@ To ensure your changes conform to the style rules run
before committing your change. That will run our autoformatters:
before committing your change. That will run our autoformatters:
-``git-clang-format`` for c++
-``rustfmt`` for Rust
-``fish_indent`` (shipped with fish) for fish script
-``fish_indent`` (shipped with fish) for fish script
-``black`` for python
-``black`` for python
@@ -122,6 +121,20 @@ If you want to check the style of the entire code base run
That command will refuse to restyle any files if you have uncommitted
That command will refuse to restyle any files if you have uncommitted
changes.
changes.
Fish Script Style Guide
-----------------------
1. All fish scripts, such as those in the *share/functions* and *tests*
directories, should be formatted using the ``fish_indent`` command.
2. Function names should be in all lowercase with words separated by
underscores. Private functions should begin with an underscore. The
first word should be ``fish`` if the function is unique to fish.
3. The first word of global variable names should generally be ``fish``
for public vars or ``_fish`` for private vars to minimize the
possibility of name clashes with user defined vars.
Configuring Your Editor for Fish Scripts
Configuring Your Editor for Fish Scripts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -158,65 +171,13 @@ made to run fish_indent via e.g.
1. All fish scripts, such as those in the *share/functions* and *tests*
Use ``cargo fmt`` and ``cargo clippy``. Clippy warnings can be turned off if there's a good reason to.
directories, should be formatted using the ``fish_indent`` command.
2. Function names should be in all lowercase with words separated by
underscores. Private functions should begin with an underscore. The
first word should be ``fish`` if the function is unique to fish.
3. The first word of global variable names should generally be ``fish``
for public vars or ``_fish`` for private vars to minimize the
possibility of name clashes with user defined vars.
C++ Style Guide
---------------
1. The `Google C++ Style
Guide <https://google.github.io/styleguide/cppguide.html>`__ forms
the basis of the fish C++ style guide. There are two major deviations
for the fish project. First, a four, rather than two, space indent.
Second, line lengths up to 100, rather than 80, characters.
2. The ``clang-format`` command is authoritative with respect to
indentation, whitespace around operators, etc.
3. All names in code should be ``small_snake_case``. No Hungarian
notation is used. The names for classes and structs should be
followed by ``_t``.
4. Always attach braces to the surrounding context.
5. Indent with spaces, not tabs and use four spaces per indent.
6. Document the purpose of a function or class with doxygen-style
comment blocks. e.g.:
::
/**
* Sum numbers in a vector.
*
* @param values Container whose values are summed.
* @return sum of `values`, or 0.0 if `values` is empty.
*/
double sum(std::vector<double> & const values) {
...
}
*/
or
::
/// brief description of somefunction()
void somefunction() {
Testing
Testing
-------
=======
The source code for fish includes a large collection of tests. If you
The source code for fish includes a large collection of tests. If you
are making any changes to fish, running these tests is a good way to make
are making any changes to fish, running these tests is a good way to make
@@ -230,28 +191,26 @@ regressions in the future (i.e., we don’t reintroduce the bug).
The tests can be found in three places:
The tests can be found in three places:
- src/fish_tests.cpp for tests to the core C++ code
- src/tests for unit tests.
- tests/checks for script tests, run by `littlecheck <https://github.com/ridiculousfish/littlecheck>`__
- tests/checks for script tests, run by `littlecheck <https://github.com/ridiculousfish/littlecheck>`__
- tests/pexpects for interactive tests using `pexpect <https://pexpect.readthedocs.io/en/stable/>`__
- tests/pexpects for interactive tests using `pexpect <https://pexpect.readthedocs.io/en/stable/>`__
When in doubt, the bulk of the tests should be added as a littlecheck test in tests/checks, as they are the easiest to modify and run, and much faster and more dependable than pexpect tests. The syntax is fairly self-explanatory. It's a fish script with the expected output in ``# CHECK:`` or ``# CHECKERR:`` (for stderr) comments.
When in doubt, the bulk of the tests should be added as a littlecheck test in tests/checks, as they are the easiest to modify and run, and much faster and more dependable than pexpect tests. The syntax is fairly self-explanatory. It's a fish script with the expected output in ``# CHECK:`` or ``# CHECKERR:`` (for stderr) comments.
fish_tests.cpp is mostly useful for unit tests - if you wish to test that a function does the correct thing for given input, use it.
The pexpects are written in python and can simulate input and output to/from a terminal, so they are needed for anything that needs actual interactivity. The runner is in build_tools/pexpect_helper.py, in case you need to modify something there.
The pexpects are written in python and can simulate input and output to/from a terminal, so they are needed for anything that needs actual interactivity. The runner is in build_tools/pexpect_helper.py, in case you need to modify something there.
Local testing
Local testing
~~~~~~~~~~~~~
-------------
The tests can be run on your local computer on all operating systems.
The tests can be run on your local computer on all operating systems.
::
::
cmake path/to/fish-shell
cmake path/to/fish-shell
make test
make fish_run_tests
Git hooks
Git hooks
~~~~~~~~~
---------
Since developers sometimes forget to run the tests, it can be helpful to
Since developers sometimes forget to run the tests, it can be helpful to
use git hooks (see githooks(5)) to automate it.
use git hooks (see githooks(5)) to automate it.
@@ -276,7 +235,7 @@ One possibility is a pre-push hook script like this one:
done
done
if["x$isprotected"= x1 ];then
if["x$isprotected"= x1 ];then
echo"Running tests before push to master"
echo"Running tests before push to master"
make test
make fish_run_tests
RESULT=$?
RESULT=$?
if[$RESULT -ne 0];then
if[$RESULT -ne 0];then
echo"Tests failed for a push to master, we can't let you do that" >&2
echo"Tests failed for a push to master, we can't let you do that" >&2
@@ -286,7 +245,7 @@ One possibility is a pre-push hook script like this one:
exit0
exit0
This will check if the push is to the master branch and, if it is, only
This will check if the push is to the master branch and, if it is, only
allow the push if running ``make test`` succeeds. In some circumstances
allow the push if running ``make fish_run_tests`` succeeds. In some circumstances
it may be advisable to circumvent this check with
it may be advisable to circumvent this check with
``git push --no-verify``, but usually that isn’t necessary.
``git push --no-verify``, but usually that isn’t necessary.
@@ -294,7 +253,7 @@ To install the hook, place the code in a new file
``.git/hooks/pre-push`` and make it executable.
``.git/hooks/pre-push`` and make it executable.
Coverity Scan
Coverity Scan
~~~~~~~~~~~~~
-------------
We use Coverity’s static analysis tool which offers free access to open
We use Coverity’s static analysis tool which offers free access to open
source projects. While access to the tool itself is restricted,
source projects. While access to the tool itself is restricted,
@@ -304,56 +263,75 @@ with their GitHub account. Currently, tests are triggered upon merging
the ``master`` branch into ``coverity_scan_master``. Even if you are not
the ``master`` branch into ``coverity_scan_master``. Even if you are not
a fish developer, you can keep an eye on our statistics there.
a fish developer, you can keep an eye on our statistics there.
Installing the Required Tools
Contributing Translations
-----------------------------
=========================
Installing the Linting Tools
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To install the lint checkers on Mac OS X using Homebrew:
::
brew install cppcheck
To install the lint checkers on Debian-based Linux distributions:
::
sudo apt-get install clang
sudo apt-get install cppcheck
Installing the Formatting Tools
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mac OS X:
::
brew install clang-format
Debian-based:
::
sudo apt-get install clang-format
Message Translations
--------------------
Fish uses the GNU gettext library to translate messages from English to
Fish uses the GNU gettext library to translate messages from English to
other languages.
other languages.
Creating and updating translations requires the Gettext tools, including
``xgettext``, ``msgfmt`` and ``msgmerge``. Translation sources are
stored in the ``po`` directory, named ``LANG.po``, where ``LANG`` is the
two letter ISO 639-1 language code of the target language (eg ``de`` for
German).
To create a new translation:
* generate a ``messages.pot`` file by running ``build_tools/fish_xgettext.fish`` from
the source tree
* copy ``messages.pot`` to ``po/LANG.po``
To update a translation:
* generate a ``messages.pot`` file by running
``build_tools/fish_xgettext.fish`` from the source tree
The ``--no-fuzzy-matching`` is important as we have had terrible experiences with gettext's "fuzzy" translations in the past.
Many tools are available for editing translation files, including
command-line and graphical user interface programs. For simple use, you can just use your text editor.
Open up the po file, for example ``po/sv.po``, and you'll see something like::
msgid "%ls: No suitable job\n"
msgstr ""
The ``msgid`` here is the "name" of the string to translate, typically the english string to translate. The second line (``msgstr``) is where your translation goes.
For example::
msgid "%ls: No suitable job\n"
msgstr "%ls: Inget passande jobb\n"
Any ``%s`` / ``%ls`` or ``%d`` are placeholders that fish will use for formatting at runtime. It is important that they match - the translated string should have the same placeholders in the same order.
Also any escaped characters, like that ``\n`` newline at the end, should be kept so the translation has the same behavior.
Our tests run ``msgfmt --check-format /path/to/file``, so they would catch mismatched placeholders - otherwise fish would crash at runtime when the string is about to be used.
Be cautious about blindly updating an existing translation file. Trivial
changes to an existing message (eg changing the punctuation) will cause
existing translations to be removed, since the tools do literal string
matching. Therefore, in general, you need to carefully review any
recommended deletions.
Setting Code Up For Translations
--------------------------------
All non-debug messages output for user consumption should be marked for
All non-debug messages output for user consumption should be marked for
translation. In C++, this requires the use of the ``_`` (underscore)
translation. In Rust, this requires the use of the ``wgettext!`` or ``wgettext_fmt!``
macro:
macros:
::
::
streams.out.append_format(_(L"%ls: There are no jobs\n"), argv[0]);
streams.out.append(wgettext_fmt!("%ls: There are no jobs\n", argv[0]));
All messages in fish script must be enclosed in single or double quote
All messages in fish script must be enclosed in single or double quote
characters. They must also be translated via a subcommand. This means
characters for our message extraction script to find them.
They must also be translated via a command substitution. This means
that the following are **not** valid:
that the following are **not** valid:
::
::
@@ -368,82 +346,15 @@ Above should be written like this instead:
echo (_ "hello")
echo (_ "hello")
echo (_ "goodbye")
echo (_ "goodbye")
Note that you can use either single or double quotes to enclose the
You can use either single or double quotes to enclose the
message to be translated. You can also optionally include spaces after
message to be translated. You can also optionally include spaces after
the opening parentheses and once again before the closing parentheses.
the opening parentheses or before the closing parentheses.
Creating and updating translations requires the Gettext tools, including
``xgettext``, ``msgfmt`` and ``msgmerge``. Translation sources are
stored in the ``po`` directory, named ``LANG.po``, where ``LANG`` is the
two letter ISO 639-1 language code of the target language (eg ``de`` for
German).
To create a new translation, for example for German:
* generate a ``messages.pot`` file by running ``build_tools/fish_xgettext.fish`` from
the source tree
* copy ``messages.pot`` to ``po/LANG.po``
To update a translation:
* generate a ``messages.pot`` file by running
``build_tools/fish_xgettext.fish`` from the source tree
fish is a smart and user-friendly command line shell for macOS, Linux,
fish is a smart and user-friendly command line shell for macOS, Linux,
and the rest of the family. fish includes features like syntax
and the rest of the family. fish includes features like syntax
@@ -62,12 +62,11 @@ Instructions for other distributions may be found at
Windows
Windows
~~~~~~~
~~~~~~~
- On Windows 10, fish can be installed under the WSL Windows Subsystem
- On Windows 10/11, fish can be installed under the WSL Windows Subsystem
for Linux with the instructions for the appropriate distribution
for Linux with the instructions for the appropriate distribution
listed above under “Packages for Linux”, or from source with the
listed above under “Packages for Linux”, or from source with the
instructions below.
instructions below.
-Fish can also be installed on all versions of Windows using
-fish (4.0 on and onwards) cannot be installed in Cygwin, due to a lack of Rust support.
`Cygwin <https://cygwin.com/>`__ (from the **Shells** category).
Building from source
Building from source
~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~
@@ -88,10 +87,11 @@ Dependencies
Running fish requires:
Running fish requires:
- curses or ncurses (preinstalled on most \*nix systems)
-A terminfo database, typically from curses or ncurses (preinstalled on most \*nix systems) - this needs to be the directory tree format, not the "hashed" database.
If this is unavailable, fish uses an included xterm-256color definition.
- some common \*nix system utilities (currently ``mktemp``), in
- some common \*nix system utilities (currently ``mktemp``), in
addition to the basic POSIX utilities (``cat``, ``cut``, ``dirname``,
addition to the basic POSIX utilities (``cat``, ``cut``, ``dirname``,
@@ -168,64 +148,50 @@ To install into ``/usr/local``, run:
mkdir build;cd build
mkdir build;cd build
cmake ..
cmake ..
make
cmake --build .
sudo make install
sudo cmake --install .
The install directory can be changed using the
The install directory can be changed using the
``-DCMAKE_INSTALL_PREFIX`` parameter for ``cmake``.
``-DCMAKE_INSTALL_PREFIX`` parameter for ``cmake``.
Building from source (macOS) - Xcode
CMake Build options
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~
Note: The minimum supported macOS version is 10.10 "Yosemite".
In addition to the normal CMake build options (like ``CMAKE_INSTALL_PREFIX``), fish's CMake build has some other options available to customize it.
..code::bash
- BUILD_DOCS=ON|OFF - whether to build the documentation. This is automatically set to OFF when Sphinx isn't installed.
mkdir build;cd build
cmake .. -G Xcode
An Xcode project will now be available in the ``build`` subdirectory.
You can open it with Xcode, or run the following to build and install in
``/usr/local``:
..code::bash
xcodebuild
xcodebuild -scheme install
The install directory can be changed using the
``-DCMAKE_INSTALL_PREFIX`` parameter for ``cmake``.
Build options
~~~~~~~~~~~~~
In addition to the normal cmake build options (like ``CMAKE_INSTALL_PREFIX``), fish has some other options available to customize it.
- BUILD_DOCS=ON|OFF - whether to build the documentation. This is automatically set to OFF when sphinx isn't installed.
- INSTALL_DOCS=ON|OFF - whether to install the docs. This is automatically set to on when BUILD_DOCS is or prebuilt documentation is available (like when building in-tree from a tarball).
- INSTALL_DOCS=ON|OFF - whether to install the docs. This is automatically set to on when BUILD_DOCS is or prebuilt documentation is available (like when building in-tree from a tarball).
- FISH_USE_SYSTEM_PCRE2=ON|OFF - whether to use an installed pcre2. This is normally autodetected.
- FISH_USE_SYSTEM_PCRE2=ON|OFF - whether to use an installed pcre2. This is normally autodetected.
- MAC_CODESIGN_ID=String|OFF - the codesign ID to use on Mac, or "OFF" to disable codesigning.
- MAC_CODESIGN_ID=String|OFF - the codesign ID to use on Mac, or "OFF" to disable codesigning.
- WITH_GETTEXT=ON|OFF - whether to build with gettext support for translations.
- WITH_GETTEXT=ON|OFF - whether to build with gettext support for translations.
- extra_functionsdir, extra_completionsdir and extra_confdir - to compile in an additional directory to be searched for functions, completions and configuration snippets
Note that fish does *not* support static linking and will attempt to error out if it detects it.
Building fish as self-installable (experimental)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Help, it didn’t build!
You can also build fish as a self-installing binary.
~~~~~~~~~~~~~~~~~~~~~~
If fish reports that it could not find curses, try installing a curses
This will include all the datafiles like the included functions or web configuration tool in the main ``fish`` binary.
development package and build again.
On Debian or Ubuntu you want:
On the first interactive run, and whenever it notices they are out of date, it will extract the datafiles to ~/.local/share/fish/install/ (currently, subject to change). You can do this manually by running ``fish --install``.
::
To install fish as self-installable, just use ``cargo``, like::
cargo install --path /path/to/fish # if you have a git clone
cargo install --git https://github.com/fish-shell/fish-shell --tag 4.0 # to build from git once 4.0 is released
cargo install --git https://github.com/fish-shell/fish-shell # to build the current development snapshot without cloning
On RedHat, CentOS, or Amazon EC2:
This will place the binaries in ``~/.cargo/bin/``, but you can place them wherever you want.
::
This build won't have the HTML docs (``help`` will open the online version) or translations.
sudo yum install ncurses-devel
It will try to build the man pages with sphinx-build. If that is not available and you would like to include man pages, you need to install it and retrigger the build script, e.g. by setting FISH_BUILD_DOCS=1::
FISH_BUILD_DOCS=1 cargo install --path .
Setting it to "0" disables the inclusion of man pages.
You can also link this build statically (but not against glibc) and move it to other computers.
Contributing Changes to the Code
Contributing Changes to the Code
--------------------------------
--------------------------------
@@ -237,8 +203,8 @@ Contact Us
Questions, comments, rants and raves can be posted to the official fish
Questions, comments, rants and raves can be posted to the official fish
mailing list at https://lists.sourceforge.net/lists/listinfo/fish-users
mailing list at https://lists.sourceforge.net/lists/listinfo/fish-users
or join us on our `gitter.im
or join us on our `matrix
channel <https://gitter.im/fish-shell/fish-shell>`__. Or use the `fish tag
channel <https://matrix.to/#/#fish-shell:matrix.org>`__. Or use the `fish tag
on Unix & Linux Stackexchange <https://unix.stackexchange.com/questions/tagged/fish>`__.
on Unix & Linux Stackexchange <https://unix.stackexchange.com/questions/tagged/fish>`__.
There is also a fish tag on Stackoverflow, but it is typically a poor fit.
There is also a fish tag on Stackoverflow, but it is typically a poor fit.
These is a proposed port of fish-shell from C++ to Rust, and from CMake to cargo or related. This document is high level - see the [Development Guide] for more details.
## Why Port
- Gain access to more contributors and enable easier contributions. C++ is becoming a legacy language.
- Free us from the annoyances of C++/CMake, and old toolchains.
- Ensure fish continues to be perceived as modern and relevant.
- Unlock concurrent mode (see below).
## Why Rust
- Rust is a systems programming language with broad platform support, a large community, and a relatively high probability of still being relevant in a decade.
- Rust has a unique strength in its thread safety features, which is the missing piece to enable concurrent mode - see below.
- Other languages considered:
- Java, Python and the scripting family are ruled out for startup latency and memory usage reasons.
- Go would be an awkward fit. fork is [quite the problem](https://stackoverflow.com/questions/28370646/how-do-i-fork-a-go-process/28371586#28371586) in Go.
- Other system languages (D, Nim, Zig...) are too niche: fewer contributors, higher risk of the language becoming irrelevant.
## Risks
- Large amount of work with possible introduction of new bugs.
- Long period of complicated builds.
- Existing contributors will have to learn Rust.
- As of yet unknown compatibility story for Tier 2+ platforms (Cygwin, etc).
## Approach
We will do an **incremental port** in the span of one release. We will have a period of using both C++ and Rust, and both cargo and CMake, leveraging FFI tools (see below).
The work will **proceed on master**: no long-lived branches. Tests and CI continue to pass at every commit for recent Linux and Mac. Centos7, \*BSD, etc may be temporarily disabled if they prove problematic.
The Rust code will initially resemble the replaced C++. Fidelity to existing code is more important than Rust idiomaticity, to aid review and bisecting. But don't take this to extremes - use judgement.
The port will proceed "outside in." We'll start with leaf components (e.g. builtins) and proceed towards the core. Some components will have both a Rust and C++ implementation (e.g. FLOG), in other cases we'll change the existing C++ to invoke the new Rust implementations (builtins).
After porting the C++, we'll replace CMake.
We will continue to use wide chars, locales, gettext, printf format strings, and PCRE2. We will not change the fish scripting language at all. We will _not_ use this as an opportunity to fix existing design flaws, with a few carefully chosen exceptions. See [Strings](#strings).
We will not use tokio, serde, async, or other fancy Rust frameworks initially.
### FFI
Rust/C++ interop will use [autocxx](https://github.com/google/autocxx), [Cxx](https://cxx.rs), and possibly [bindgen](https://rust-lang.github.io/rust-bindgen/). I've forked these for fish (see the [Development Guide]). Once the port is done, we will stop using them, except perhaps bindgen for PCRE2.
We will use [corrosion](https://github.com/corrosion-rs/corrosion) for CMake integration.
Inefficiencies (e.g. extra string copying) at the FFI layer are fine, since it will all get thrown away.
Tests can stay in fish_tests.cpp or be moved into Rust .rs files; either is fine.
### Strings
Rust's `String` / `&str` types cannot represent non-UTF8 filenames or data using the default encoding scheme. That's why all string conversions must go through fish's encoding scheme (using the private-use area to encode invalid sequences). For example, fish cannot use `File::open` with a `&str` because the decoding will be incorrect.
So instead of `String`, fish will use its own string type, and manage encoding and decoding as it does today. However we will make some specific changes:
1. Drop the nul-terminated requirement. When passing `const wchar_t*` back to C++, we will allocate and copy into a nul-terminated buffer.
2. Drop support for 16-bit wchar. fish will use UTF32 on all platforms, and manage conversions itself.
After the port we can consider moving to UTF-8, for memory usage reasons.
See the [Rust Development Guide][Development Guide] for more on strings.
### Thread Safety
Allowing [background functions](https://github.com/fish-shell/fish-shell/issues/238) and concurrent functions has been a goal for many years. I have been nursing [a long-lived branch](https://github.com/ridiculousfish/fish-shell/tree/concurrent_even_simpler) which allows full threaded execution. But though the changes are small, I have been reluctant to propose them, because they will make reasoning about the shell internals too complex: it is difficult in C++ to check and enforce what crosses thread boundaries.
This is Rust's bread and butter: we will encode thread requirements into our types, making it explicit and compiler-checked, via Send and Sync. Rust will allow turning on concurrent mode in a safe way, with a manageable increase in complexity, finally enabling this feature.
## Timeline
Handwaving, 6 months? Frankly unknown - there's 102 remaining .cpp files of various lengths. It'll go faster as we get better at it. Peter (ridiculous_fish) is motivated to work on this, other current contributors have some Rust as well, and we may also get new contributors from the Rust community. Part of the point is to make contribution easier.
## Links
- [Packaging Rust projects](https://wiki.archlinux.org/title/Rust_package_guidelines) from Arch Linux
This describes how to build macOS artifacts as part of a release. These artifacts are uploaded to the GitHub release page, where they are discovered by the web site build script.
Artifacts may be built locally or in CI. Using CI is preferred.
> **Note**
> Only fish-shell administrations may create releases. Released macOS packages require code signing and notarization via private Apple developer keys, which are owned by @ridiculous_fish. These keys are stored in GitHub secrets.
## Building in CI (GitHub Actions)
macOS packages may be built in CI through a GitHub workflow. This requires a fish-shell administrator as it requires invoking secret code signing keys.
Steps:
1. Go to https://github.com/fish-shell/fish-shell/actions
2. On the left side, click on the "macOS build and codesign" Action.
3. On the right, click on the "Run workflow" button, select the branch or tag, and click Run Workflow.
4.**Reload the page**. This is necessary because the workflow will not appear until the page is reloaded.
5. Click on the new workflow. It should be in a Waiting state.
6. Click on Review Deployments, and approve and start the "deployment."
7. Once the workflow completes, expand the `actions/upload-artifact@v4` step in the logs. This should have an "Artifact download URL" - click it and download!
## Building locally (no code signing)
To build locally without notarizing and code signing, use the `build_tools/make_pkg.sh` script:
```
> ./build_tools/make_pkg.sh
```
Packages will be placed in `~/fish_built` by default.
Note these packages will result in loud warnings or errors when others try to install them, because of the lack of code signing.
## Building locally with code signing and notarization
You will need the following:
- The ".p12" certificate files for both "Developer ID Application" and "Developer ID Installer".
- (These can be generated via Export Certificate in Xcode)
- The password for these files (by convention, the same password is used for both).
- The JSON file generated via `rcodesign encode-app-store-connect-api-key`.
This describes how to get started building fish-shell in its partial Rust state, and how to contribute to the port.
## Overview
fish is in the process of transitioning from C++ to Rust. The fish project has a Rust crate embedded at path `fish-rust`. This crate builds a Rust library `libfish_rust.a` which is linked with the C++ `libfish.a`. Existing C++ code will be incrementally migrated to this crate; then CMake will be replaced with cargo and other Rust-native tooling.
Important tools used during this transition:
1. [Corrosion](https://github.com/corrosion-rs/corrosion) to invoke cargo from CMake.
2. [cxx](http://cxx.rs) for basic C++ <-> Rust interop.
3. [autocxx](https://google.github.io/autocxx/) for using C++ types in Rust.
We use forks of the last two - see the [FFI section](#ffi) below. No special action is required to obtain these packages. They're downloaded by cargo.
## Building
### Build Dependencies
fish-shell currently depends on Rust 1.70 or later. To install Rust, follow https://rustup.rs.
### Build via CMake
It is recommended to build inside `fish-shell/build`. This will make it easier for Rust to find the `config.h` file.
Build via CMake as normal (use any generator, here we use Ninja):
```shell
$ cd fish-shell
$ mkdir build &&cd build
$ cmake -G Ninja ..
$ ninja
```
This will create the usual fish executables.
### Build just libfish_rust.a with Cargo
The directory `fish-rust` contains the Rust sources. These require that CMake has been run to produce `config.h` which is necessary for autocxx to succeed.
Follow the "Build from CMake" steps above, and then:
```shell
$ cd fish-shell/fish-rust
$ cargo build
```
This will build only the library, not a full working fish, but it allows faster iteration for Rust development. That is, after running `cmake` you can open the `fish-rust` as the root of a Rust crate, and tools like rust-analyzer will work.
## Development
The basic development loop for this port:
1. Pick a .cpp (or in some cases .h) file to port, say `util.cpp`.
2. Add the corresponding `util.rs` file to `fish-rust/`.
3. Reimplement it in Rust, along with its dependencies as needed. Match the existing C++ code where practical, including propagating any relevant comments.
- Do this even if it results in less idiomatic Rust, but avoid being super-dogmatic either way.
- One technique is to paste the C++ into the Rust code, commented out, and go line by line.
4. Decide whether any existing C++ callers should invoke the Rust implementation, or whether we should keep the C++ one.
- Utility functions may have both a Rust and C++ implementation. An example is `FLOG` where interop is too hard.
- Major components (e.g. builtin implementations) should _not_ be duplicated; instead the Rust should call C++ or vice-versa.
5. Remember to run `cargo fmt` and `cargo clippy` to keep the codebase somewhat clean (otherwise CI will fail). If you use rust-analyzer, you can run clippy automatically by setting `rust-analyzer.checkOnSave.command = "clippy"`.
You will likely run into limitations of [`autocxx`](https://google.github.io/autocxx/) and to a lesser extent [`cxx`](https://cxx.rs/). See the [FFI sections](#ffi) below.
## Type Mapping
### Constants & Type Aliases
The FFI does not support constants (`#define` or `static const`) or type aliases (`typedef`, `using`). Duplicate them using their Rust equivalent (`pub const` and `type`/`struct`/`enum`).
### Non-POD types
Many types cannot currently be passed across the language boundary by value or occur in shared structs. As a workaround, use references, raw pointers or smart pointers (`cxx` provides `SharedPtr` and `UniquePtr`). Try to keep workarounds on the C++ side and the FFI layer of the Rust code. This ensures we will get rid of the workarounds as we peel off the FFI layer.
### Strings
Fish will mostly _not_ use Rust's `String/&str` types as these cannot represent non-UTF8 data using the default encoding.
fish's primary string types will come from the [`widestring` crate](https://docs.rs/widestring). The two main string types are `WString` and `&wstr`, which are renamed [Utf32String](https://docs.rs/widestring/latest/widestring/utfstring/struct.Utf32String.html) and [Utf32Str](https://docs.rs/widestring/latest/widestring/utfstr/struct.Utf32Str.html). `WString` is an owned, heap-allocated UTF32 string, `&wstr` a borrowed UTF32 slice.
In general, follow this mapping when porting from C++:
-`wcstring` -> `WString`
-`const wcstring &` -> `&wstr`
-`const wchar_t *` -> `&wstr`
None of the Rust string types are nul-terminated. We're taking this opportunity to drop the nul-terminated aspect of wide string handling.
#### Creating strings
One may create a `&wstr` from a string literal using the `wchar::L!` macro:
```rust
usecrate::wchar::prelude::*;
// This imports wstr, the L! macro, WString, a ToWString trait that supplies .to_wstring() along with other things
fnget_shell_name()-> &'staticwstr{
L!("fish")
}
```
There is also a `widestrs` proc-macro which enables L as a _suffix_, to reduce the noise. This can be applied to any block, including modules and individual functions:
```rust
usecrate::wchar::{wstr,widestrs}
// also imported by the prelude
#[widestrs]
fnget_shell_name()-> &'staticwstr{
"fish"L// equivalent to L!("fish")
}
```
#### The wchar prelude
We have a prelude to make working with these string types a whole lot more ergonomic. In particular `WExt` supplies the null-terminated-compatible `.char_at(usize)`,
and a whole lot more methods that makes porting C++ code easier. It is also preferred to use char-based-methods like `.char_count()` and `.slice_{from,to}()`
of the `WExt` trait over directly calling `.len()` and `[usize..]/[..usize]`, as that makes the code compatible with a potential future change to UTF8-strings.
`WString` and `&wstr` are the common strings used by Rust components. At the FII boundary there are some additional strings for interop. _All of these are temporary for the duration of the port._
-`CxxWString` is the Rust binding of `std::wstring`. It is the wide-string analog to [`CxxString`](https://cxx.rs/binding/cxxstring.html) and is [added in our fork of cxx](https://github.com/ridiculousfish/cxx/blob/fish/src/cxx_wstring.rs). This is useful for functions which return e.g. `const wcstring &`.
-`W0String` is renamed [U32CString](https://docs.rs/widestring/latest/widestring/ucstring/struct.U32CString.html). This is basically `WString` except it _is_ nul-terminated. This is useful for getting a nul-terminated `const wchar_t *` to pass to C++ implementations.
-`wcharz_t` is an annoying C++ struct which merely wraps a `const wchar_t *`, used for passing these pointers from C++ to Rust. We would prefer to use `const wchar_t *` directly but `autocxx` refuses to generate bindings for types such as `std::vector<const wchar_t *>` so we wrap it in this silly struct.
Note C++ `wchar_t`, Rust `char`, and `u32` are effectively interchangeable: you can cast pointers to them back and forth (except we check upon u32->char conversion). However be aware of which types are nul-terminated.
These types should be confined to the FFI modules, in particular `wchar_ffi`. They should not "leak" into other modules. See the `wchar_ffi` module.
### Format strings
Rust's builtin `std::fmt` modules do not accept runtime-provided format strings, so we mostly won't use them, except perhaps for FLOG / other non-translated text.
Instead we'll continue to use printf-style strings, with a Rust printf implementation.
### Vectors
See [`Vec`](https://cxx.rs/binding/vec.html) and [`CxxVector`](https://cxx.rs/binding/cxxvector.html).
In many cases, `autocxx` refuses to allow vectors of certain types. For example, autocxx supports `std::vector` and `std::shared_ptr` but NOT `std::vector<std::shared_ptr<...>>`. To work around this one can create a helper (pointer, length) struct. Example:
```cpp
structRustFFIJobList{
std::shared_ptr<job_t>*jobs;
size_tcount;
};
```
This is just a POD (plain old data) so autocxx can generate bindings for it. Then it is trivial to convert it to a Rust slice:
Another workaround is to define a struct that contains the shared pointer, and create a vector of that struct.
## Development Tooling
The [autocxx guidance](https://google.github.io/autocxx/workflow.html#how-can-i-see-what-bindings-autocxx-has-generated) is helpful:
1. Install cargo expand (`cargo install cargo-expand`). Then you can use `cargo expand` to see the generated Rust bindings for C++. In particular this is useful for seeing failed expansions for C++ types that autocxx cannot handle.
2. In rust-analyzer, enable Proc Macro and Proc Macro Attributes.
## FFI
The boundary between Rust and C++ is referred to as the Foreign Function Interface, or FFI.
`autocxx` and `cxx` both are designed for long-term interop: C++ and Rust coexisting for years. To this end, both emphasize safety: requiring lots of `unsafe`, `Pin`, etc.
fish plans to use them only temporarily, with a focus on getting things working. To this end, both cxx and autocxx have been forked to support fish:
1. Relax the requirement that all functions taking pointers are `unsafe` (this just added noise).
2. Add support for `wchar_t` as a recognized type, and `CxxWString` analogous to `CxxString`.
See the `Cargo.toml` file for the locations of the forks.
Only typed-in commands use abbreviations. Abbreviations are not expanded in scripts.
Only typed-in commands use abbreviations. Abbreviations are not expanded in scripts.
For example, a frequently-run command like ``git checkout`` can be abbreviated to ``gco``.
For example, a frequently-run command like ``git checkout`` can be abbreviated to ``gco``.
After entering ``gco`` and pressing :kbd:`Space` or :kbd:`Enter`, the full text ``git checkout`` will appear in the command line.
After entering ``gco`` and pressing :kbd:`space` or :kbd:`enter`, the full text ``git checkout`` will appear in the command line.
To avoid expanding something that looks like an abbreviation, the default :kbd:`Control`\ +\ :kbd:`Space` binding inserts a space without expanding.
To avoid expanding something that looks like an abbreviation, the default :kbd:`ctrl-space` binding inserts a space without expanding.
An abbreviation may match a literal word, or it may match a pattern given by a regular expression. When an abbreviation matches a word, that word is replaced by new text, called its *expansion*. This expansion may be a fixed new phrase, or it can be dynamically created via a fish function. This expansion occurs after pressing space or enter.
An abbreviation may match a literal word, or it may match a pattern given by a regular expression. When an abbreviation matches a word, that word is replaced by new text, called its *expansion*. This expansion may be a fixed new phrase, or it can be dynamically created via a fish function. This expansion occurs after pressing space or enter.
@@ -49,6 +49,13 @@ Combining these features, it is possible to create custom syntaxes, where a regu
> abbr >> ~/.config/fish/config.fish
> abbr >> ~/.config/fish/config.fish
> abbr --erase (abbr --list)
> abbr --erase (abbr --list)
Alternatively you can keep them in a separate :ref:`configuration file <configuration>` by doing something like the following::
> abbr > ~/.config/fish/conf.d/myabbrs.fish
This will save all your abbreviations in "myabbrs.fish", overwriting the whole file so it doesn't leave any duplicates,
or restore abbreviations you had erased.
Of course any functions will have to be saved separately, see :doc:`funcsave <funcsave>`.
"add" subcommand
"add" subcommand
--------------------
--------------------
@@ -56,12 +63,14 @@ Combining these features, it is possible to create custom syntaxes, where a regu
``abbr --add`` creates a new abbreviation. With no other options, the string **NAME** is replaced by **EXPANSION**.
``abbr --add`` creates a new abbreviation. With no other options, the string **NAME** is replaced by **EXPANSION**.
With **--position command**, the abbreviation will only expand when it is positioned as a command, not as an argument to another command. With **--position anywhere** the abbreviation may expand anywhere in the command line. The default is **command**.
With **--position command**, the abbreviation will only expand when it is positioned as a command, not as an argument to another command. With **--position anywhere** the abbreviation may expand anywhere in the command line. The default is **command**.
With **--command COMMAND**, the abbreviation will only expand when it is used as an argument to the given COMMAND. Multiple **--command** can be used together, and the abbreviation will expand for each. An empty **COMMAND** means it will expand only when there is no command. **--command** implies **--position anywhere** and disallows **--position command**. Even with different **COMMANDS**, the **NAME** of the abbreviation needs to be unique. Consider using **--regex** if you want to expand the same word differently for multiple commands.
With **--regex**, the abbreviation matches using the regular expression given by **PATTERN**, instead of the literal **NAME**. The pattern is interpreted using PCRE2 syntax and must match the entire token. If multiple abbreviations match the same token, the last abbreviation added is used.
With **--regex**, the abbreviation matches using the regular expression given by **PATTERN**, instead of the literal **NAME**. The pattern is interpreted using PCRE2 syntax and must match the entire token. If multiple abbreviations match the same token, the last abbreviation added is used.
With **--set-cursor=MARKER**, the cursor is moved to the first occurrence of **MARKER** in the expansion. The **MARKER** value is erased. The **MARKER** may be omitted (i.e. simply ``--set-cursor``), in which case it defaults to ``%``.
With **--set-cursor=MARKER**, the cursor is moved to the first occurrence of **MARKER** in the expansion. The **MARKER** value is erased. The **MARKER** may be omitted (i.e. simply ``--set-cursor``), in which case it defaults to ``%``.
@@ -115,6 +124,12 @@ This first creates a function ``vim_edit`` which prepends ``vim`` before its arg
This creates an abbreviation "4DIRS" which expands to a multi-line loop "template." The template enters each directory and then leaves it. The cursor is positioned ready to enter the command to run in each directory, at the location of the ``!``, which is itself erased.
This creates an abbreviation "4DIRS" which expands to a multi-line loop "template." The template enters each directory and then leaves it. The cursor is positioned ready to enter the command to run in each directory, at the location of the ``!``, which is itself erased.
::
abbr --command git co checkout
Turns "co" as an argument to "git" into "checkout". Multiple commands are possible, ``--command={git,hg}`` would expand "co" to "checkout" for both git and hg.
NOTE: This page documents the fish builtin ``alias``.
To see the documentation on any non-fish versions, use ``command man alias``.
``alias`` is a simple wrapper for the ``function`` builtin, which creates a function wrapping a command. It has similar syntax to POSIX shell ``alias``. For other uses, it is recommended to define a :doc:`function <function>`.
``alias`` is a simple wrapper for the ``function`` builtin, which creates a function wrapping a command. It has similar syntax to POSIX shell ``alias``. For other uses, it is recommended to define a :doc:`function <function>`.
If you want to ease your interactive use, to save typing, consider using an :doc:`abbreviation <abbr>` instead.
If you want to ease your interactive use, to save typing, consider using an :doc:`abbreviation <abbr>` instead.
@@ -49,9 +54,11 @@ The following code will create ``rmi``, which runs ``rm`` with additional argume
rm -i $argv
rm -i $argv
end
end
``alias`` sometimes requires escaping, as you can see here::
# This needs to have the spaces escaped or "Chrome.app..."
# This needs to have the spaces escaped or "Chrome.app..."
# will be seen as an argument to "/Applications/Google":
# will be seen as an argument to "/Applications/Google":
alias chrome='/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome banana'
alias chrome='/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome'
If ``$argv`` is empty then there is nothing to parse and ``argparse`` returns zero to indicate success. If ``$argv`` is not empty then it is checked for flags ``-h``, ``--help``, ``-n`` and ``--name``. If they are found they are removed from the arguments and local variables called ``_flag_OPTION`` are set so the script can determine which options were seen. If ``$argv`` doesn't have any errors, like a missing mandatory value for an option, then ``argparse`` exits with a status of zero. Otherwise it writes appropriate error messages to stderr and exits with a status of one.
If ``$argv`` is empty then there is nothing to parse and ``argparse`` returns zero to indicate success. If ``$argv`` is not empty then it is checked for flags ``-h``, ``--help``, ``-n`` and ``--name``. If they are found they are removed from the arguments and local variables called ``_flag_OPTION`` are set so the script can determine which options were seen. If ``$argv`` doesn't have any errors, like an unknown option or a missing mandatory value for an option, then ``argparse`` exits with a status of zero. Otherwise it writes appropriate error messages to stderr and exits with a status of one.
The ``or return`` means that the function returns ``argparse``'s status if it failed, so if it goes on ``argparse`` succeeded.
The ``or return`` means that the function returns ``argparse``'s status if it failed, so if it goes on ``argparse`` succeeded.
To use the flags argparse has extracted::
# Checking for _flag_h and _flag_help is equivalent
and set myname $_flag_name[-1] # here we use the *last* --name=
Any characters in the flag name that are not valid in a variable name (like ``-`` dashes) will be replaced with underscores.
The ``--`` argument is required. You do not have to include any option specifications or arguments after the ``--`` but you must include the ``--``. For example, this is acceptable::
The ``--`` argument is required. You do not have to include any option specifications or arguments after the ``--`` but you must include the ``--``. For example, this is acceptable::
set -l argv foo
set -l argv foo
@@ -235,6 +250,13 @@ After this it figures out which variable it should operate on according to the `
A background job is executed simultaneously with fish, and does not have access to the keyboard. If no job is specified, the last job to be used is put in the background. If ``PID`` is specified, the jobs containing the specified process IDs are put in the background.
A background job is executed simultaneously with fish, and does not have access to the keyboard. If no job is specified, the last job to be used is put in the background. If ``PID`` is specified, the jobs containing the specified process IDs are put in the background.
For compatibility with other shells, job expansion syntax is supported for ``bg``. A PID of the format ``%1`` will be interpreted as the PID of job 1. Job numbers can be seen in the output of :doc:`jobs <jobs>`.
A PID of the format ``%n``, where n is an integer, will be interpreted as the PID of job number n. Job numbers can be seen in the output of :doc:`jobs <jobs>`.
When at least one of the arguments isn't a valid job specifier,
When at least one of the arguments isn't a valid job specifier,``bg`` will print an error without backgrounding anything.
``bg`` will print an error without backgrounding anything.
When all arguments are valid job specifiers, ``bg`` will background all matching jobs that exist.
When all arguments are valid job specifiers, ``bg`` will background all matching jobs that exist.
@@ -29,10 +28,20 @@ The **-h** or **--help** option displays help about using this command.
Example
Example
-------
-------
The typical use is to run something, stop it with ctrl-z, and then continue it in the background with bg::
> find / -name "*.js" >/tmp/jsfiles 2>/dev/null # oh no, this takes too long, let's press Ctrl-z!
fish: Job 1, 'find / -name "*.js" >/tmp/jsfil…' has stopped
It can add bindings if given a SEQUENCE of characters to bind to. These should be written as :ref:`fish escape sequences <escapes>`. The most important of these are ``\c`` for the control key, and``\e``for escape, and because of historical reasons also the Alt key (sometimes also called "Meta").
If both ``KEYS`` and ``COMMAND`` are given,``bind``adds (or replaces) a binding in ``MODE``.
If only ``KEYS`` is given, any existing binding in the given ``MODE`` will be printed.
For example, :kbd:`Alt`\ +\ :kbd:`W` can be written as ``\ew``, and :kbd:`Control`\ +\ :kbd:`X` (^X) can be written as ``\cx``. Note that Alt-based key bindings are case sensitive and Control-based key bindings are not. This is a constraint of text-based terminals, not ``fish``.
``KEYS`` is a comma-separated list of key names.
Modifier keys can be specified by prefixing a key name with a combination of ``ctrl-``, ``alt-`` and ``shift-``.
For example, pressing :kbd:`w` while holding the Alt modifier is written as ``alt-w``.
Key names are case-sensitive; for example ``alt-W`` is the same as ``alt-shift-w``.
``ctrl-x,ctrl-e`` would mean pressing :kbd:`ctrl-x` followed by :kbd:`ctrl-e`.
The generic key binding that matches if no other binding does can be set by specifying a ``SEQUENCE`` of the empty string (that is, ``''`` ). For most key bindings, it makes sense to bind this to the ``self-insert`` function (i.e. ``bind '' self-insert``). This will insert any keystrokes not specifically bound to into the editor. Non-printable characters are ignored by the editor, so this will not result in control sequences being inserted.
Some keys have names, usually because they don't have an obvious printable character representation.
They are:
If the ``-k`` switch is used, the name of a key (such as 'down', 'up' or 'backspace') is used instead of a sequence. The names used are the same as the corresponding curses variables, but without the 'key\_' prefix. (See ``terminfo(5)`` for more information, or use ``bind --key-names`` for a list of all available named keys). Normally this will print an error if the current``$TERM``entry doesn't have a given key, unless the ``-s`` switch is given.
- the arrow keys ``up``, ``down``,``left``and ``right``,
-``backspace``,
-``comma`` (``,``),
-``delete``,
-``end``,
-``enter``,
-``escape``,
-``f1`` through ``f12``.
-``home``,
-``insert``,
-``minus`` (``-``),
-``pageup``,
-``pagedown``,
-``space`` and
-``tab``,
To find out what sequence a key combination sends, you can use :doc:`fish_key_reader <fish_key_reader>`.
These names are case-sensitive.
``COMMAND`` can be any fish command, but it can also be one of a set of special input functions. These include functions for moving the cursor, operating on the kill-ring, performing tab completion, etc. Use ``bind --function-names`` for a complete list of these input functions.
An empty value (``''``) for ``KEYS`` designates the generic binding that will be used if nothing else matches. For most bind modes, it makes sense to bind this to the ``self-insert`` function (i.e. ``bind '' self-insert``). This will insert any keystrokes that have no bindings otherwise. Non-printable characters are ignored by the editor, so this will not result in control sequences being inserted.
When ``COMMAND`` is a shellscript command, it is a good practice to put the actual code into a :ref:`function <syntax-function>` and simply bind to the function name. This way it becomes significantly easier to test the function while editing, and the result is usually more readable as well.
To find the name of a key combination you can use :doc:`fish_key_reader <fish_key_reader>`.
``COMMAND`` can be any fish command, but it can also be one of a set of special input functions. These include functions for moving the cursor, operating on the kill-ring, performing tab completion, etc. Use ``bind --function-names`` or :ref:`see below <special-input-functions>` for a list of these input functions.
..note::
..note::
Special input functions cannot be combined with ordinary shell script commands. The commands must be entirely a sequence of special input functions (from ``bind -f``) or all shell script commands (i.e., valid fish script). To run special input functions from regular fish script, use ``commandline -f`` (see also :doc:`commandline <commandline>`). If a script produces output, it should finish by calling ``commandline -f repaint`` to tell fish that a repaint is in order.
If a script changes the commandline, it should finish by calling the ``repaint`` special input function.
If no ``SEQUENCE`` is provided, all bindings (or just the bindings in the given ``MODE``) are printed. If ``SEQUENCE`` is provided but no ``COMMAND``, just the binding matching that sequence is printed.
If no ``KEYS`` argument is provided, all bindings (in the given ``MODE``) are printed. If ``KEYS`` is provided but no ``COMMAND``, just the binding matching that sequence is printed.
Key bindings may use "modes", which mimics vi's modal input behavior. The default mode is "default". Every key binding applies to a single mode; you can specify which one with ``-M MODE``. If the key binding should change the mode, you can specify the new mode with ``-m NEW_MODE``. The mode can be viewed and changed via the ``$fish_bind_mode`` variable. If you want to change the mode from inside a fish function, use ``set fish_bind_mode MODE``.
To save custom key bindings, put the ``bind`` statements into :ref:`config.fish <configuration>`. Alternatively, fish also automatically executes a function called ``fish_user_key_bindings`` if it exists.
To save custom key bindings, put the ``bind`` statements into :ref:`config.fish <configuration>`. Alternatively, fish also automatically executes a function called ``fish_user_key_bindings`` if it exists.
Key bindings may use "modes", which mimics Vi's modal input behavior. The default mode is "default". Every key binding applies to a single mode; you can specify which one with ``-M MODE``. If the key binding should change the mode, you can specify the new mode with ``-m NEW_MODE``. The mode can be viewed and changed via the ``$fish_bind_mode`` variable. If you want to change the mode from inside a fish function, use ``set fish_bind_mode MODE``.
Options
Options
-------
-------
The following options are available:
The following options are available:
**-k** or **--key**
Specify a key name, such as 'left' or 'backspace' instead of a character sequence
**-K** or **--key-names**
Display a list of available key names. Specifying **-a** or **--all** includes keys that don't have a known mapping
**-f** or **--function-names**
**-f** or **--function-names**
Display a list of available input functions
Display a list of available input functions
@@ -72,7 +87,7 @@ The following options are available:
Specifying **-a** or **--all** without **-M** or **--mode** erases all binds in all modes regardless of sequence.
Specifying **-a** or **--all** without **-M** or **--mode** erases all binds in all modes regardless of sequence.
**-a** or **--all**
**-a** or **--all**
See **--erase** and **--key-names**
See **--erase**
**--preset** and **--user**
**--preset** and **--user**
Specify if bind should operate on user or preset bindings.
Specify if bind should operate on user or preset bindings.
@@ -87,6 +102,8 @@ The following options are available:
**-h** or **--help**
**-h** or **--help**
Displays help about using this command.
Displays help about using this command.
.._special-input-functions:
Special input functions
Special input functions
-----------------------
-----------------------
The following special input functions are available:
The following special input functions are available:
@@ -95,21 +112,31 @@ The following special input functions are available:
only execute the next function if the previous succeeded (note: only some functions report success)
only execute the next function if the previous succeeded (note: only some functions report success)
``accept-autosuggestion``
``accept-autosuggestion``
accept the current autosuggestion
accept the current autosuggestion. Returns false when there was nothing to accept.
``backward-char``
``backward-char``
move one character to the left.
move one character to the left.
If the completion pager is active, select the previous completion instead.
If the completion pager is active, select the previous completion instead.
``backward-char-passive``
move one character to the left, but do not trigger any non-movement-related operations. If the cursor is at the start of
the commandline, does nothing. Does not change the selected item in the completion pager UI when shown.
``backward-bigword``
``backward-bigword``
move one whitespace-delimited word to the left
move one whitespace-delimited word to the left
``backward-token``
move one argument to the left
``backward-delete-char``
``backward-delete-char``
deletes one character of input to the left of the cursor
deletes one character of input to the left of the cursor
``backward-kill-bigword``
``backward-kill-bigword``
move the whitespace-delimited word to the left of the cursor to the killring
move the whitespace-delimited word to the left of the cursor to the killring
``backward-kill-token``
move the argument to the left of the cursor to the killring
``backward-kill-line``
``backward-kill-line``
move everything from the beginning of the line to the cursor to the killring
move everything from the beginning of the line to the cursor to the killring
@@ -135,7 +162,7 @@ The following special input functions are available:
start selecting text
start selecting text
``cancel``
``cancel``
cancel the current commandline and replace it with a new empty one
close the pager if it is open, or undo the most recent completion if one was just inserted, or otherwise cancel the current commandline and replace it with a new empty one
``cancel-commandline``
``cancel-commandline``
cancel the current commandline and replace it with a new empty one, leaving the old one in place with a marker to show that it was cancelled
cancel the current commandline and replace it with a new empty one, leaving the old one in place with a marker to show that it was cancelled
@@ -143,6 +170,9 @@ The following special input functions are available:
``capitalize-word``
``capitalize-word``
make the current word begin with a capital letter
make the current word begin with a capital letter
``clear-commandline``
empty the entire commandline
``clear-screen``
``clear-screen``
clears the screen and redraws the prompt. if the terminal doesn't support clearing the screen it is the same as ``repaint``.
clears the screen and redraws the prompt. if the terminal doesn't support clearing the screen it is the same as ``repaint``.
@@ -188,10 +218,18 @@ The following special input functions are available:
``forward-bigword``
``forward-bigword``
move one whitespace-delimited word to the right
move one whitespace-delimited word to the right
``forward-token``
move one argument to the right
``forward-char``
``forward-char``
move one character to the right; or if at the end of the commandline, accept the current autosuggestion.
move one character to the right; or if at the end of the commandline, accept the current autosuggestion.
If the completion pager is active, select the next completion instead.
If the completion pager is active, select the next completion instead.
``forward-char-passive``
move one character to the right, but do not trigger any non-movement-related operations. If the cursor is at the end of the
commandline, does not accept the current autosuggestion (if any). Does not change the selected item in the completion pager,
if shown.
``forward-single-char``
``forward-single-char``
move one character to the right; or if at the end of the commandline, accept a single char from the current autosuggestion.
move one character to the right; or if at the end of the commandline, accept a single char from the current autosuggestion.
@@ -203,7 +241,7 @@ The following special input functions are available:
invoke the searchable pager on history (incremental search); or if the history pager is already active, search further backwards in time.
invoke the searchable pager on history (incremental search); or if the history pager is already active, search further backwards in time.
``history-pager-delete``
``history-pager-delete``
permanently delete the history item selected in the history pager
permanently delete the current history item, either from the history pager or from an active up-arrow history search
``history-search-backward``
``history-search-backward``
search the history for the previous match
search the history for the previous match
@@ -224,17 +262,32 @@ The following special input functions are available:
search the history for the next matching argument
search the history for the next matching argument
``forward-jump`` and ``backward-jump``
``forward-jump`` and ``backward-jump``
read another character and jump to its next occurence after/before the cursor
read another character and jump to its next occurrence after/before the cursor
``forward-jump-till`` and ``backward-jump-till``
``forward-jump-till`` and ``backward-jump-till``
jump to right *before* the next occurence
jump to right *before* the next occurrence
``repeat-jump`` and ``repeat-jump-reverse``
``repeat-jump`` and ``repeat-jump-reverse``
redo the last jump in the same/opposite direction
redo the last jump in the same/opposite direction
``jump-to-matching-bracket``
jump to matching bracket if the character under the cursor is bracket;
otherwise, jump to the next occurrence of *any right* bracket after the cursor.
The following brackets are considered: ``([{}])``
``jump-till-matching-bracket``
the same as ``jump-to-matching-bracket`` but offset cursor to the right for left bracket, and offset cursor to the left for right bracket.
The offset is applied for both the position we jump from and position we jump to.
In other words, the cursor will continuously jump inside the brackets but won't reach them by 1 character.
The input function is useful to emulate ``ib`` vi text object.
The following brackets are considered: ``([{}])``
``kill-bigword``
``kill-bigword``
move the next whitespace-delimited word to the killring
move the next whitespace-delimited word to the killring
``kill-token``
move the next argument to the killring
``kill-line``
``kill-line``
move everything from the cursor to the end of the line to the killring
move everything from the cursor to the end of the line to the killring
@@ -242,7 +295,7 @@ The following special input functions are available:
move the selected text to the killring
move the selected text to the killring
``kill-whole-line``
``kill-whole-line``
move the line (including the following newline) to the killring. If the line is the last line, its preceeding newline is also removed
move the line (including the following newline) to the killring. If the line is the last line, its preceding newline is also removed
``kill-inner-line``
``kill-inner-line``
move the line (without the following newline) to the killring
move the line (without the following newline) to the killring
@@ -267,7 +320,7 @@ The following special input functions are available:
reexecutes the prompt functions and redraws the prompt (also ``force-repaint`` for backwards-compatibility)
reexecutes the prompt functions and redraws the prompt (also ``force-repaint`` for backwards-compatibility)
``repaint-mode``
``repaint-mode``
reexecutes the :doc:`fish_mode_prompt <fish_mode_prompt>` and redraws the prompt. This is useful for vi-mode. If no ``fish_mode_prompt`` exists or it prints nothing, it acts like a normal repaint.
reexecutes the :doc:`fish_mode_prompt <fish_mode_prompt>` and redraws the prompt. This is useful for vimode. If no ``fish_mode_prompt`` exists or it prints nothing, it acts like a normal repaint.
``self-insert``
``self-insert``
inserts the matching sequence into the command line
inserts the matching sequence into the command line
@@ -339,22 +392,22 @@ The following functions are included as normal functions, but are particularly u
Examples
Examples
--------
--------
Exit the shell when :kbd:`Control`\ +\ :kbd:`D` is pressed::
Exit the shell when :kbd:`ctrl-d` is pressed::
bind \cd 'exit'
bind ctrl-d 'exit'
Perform a history search when :kbd:`Page Up` is pressed::
Perform a history search when :kbd:`pageup` is pressed::
bind -k ppage history-search-backward
bind pageup history-search-backward
Turn on :ref:`Vi key bindings <vi-mode>` and rebind :kbd:`Control`\ +\ :kbd:`C` to clear the input line::
Turn on :ref:`vi key bindings <vi-mode>` and rebind :kbd:`ctrl-c` to clear the input line::
set -g fish_key_bindings fish_vi_key_bindings
set -g fish_key_bindings fish_vi_key_bindings
bind -M insert \cc kill-whole-line repaint
bind -M insert ctrl-c kill-whole-line repaint
Launch ``git diff`` and repaint the commandline afterwards when :kbd:`Control`\ +\ :kbd:`G` is pressed::
Launch ``git diff`` and repaint the commandline afterwards when :kbd:`ctrl-g` is pressed::
bind \cg 'git diff; commandline -f repaint'
bind ctrl-g 'git diff' repaint
.._cmd-bind-termlimits:
.._cmd-bind-termlimits:
@@ -363,23 +416,33 @@ Terminal Limitations
Unix terminals, like the ones fish operates in, are at heart 70s technology. They have some limitations that applications running inside them can't workaround.
Unix terminals, like the ones fish operates in, are at heart 70s technology. They have some limitations that applications running inside them can't workaround.
For instance, the control key modifies a character by setting the top three bits to 0. This means:
For instance, historically the control key modifies a character by setting the top three bits to 0. This means:
- Many characters + control are indistinguishable from other keys.:kbd:`Control`\ +\ :kbd:`I`*is* tab,:kbd:`Control`\ +\:kbd:`J`*is* newline (``\n``).
- Many characters + control are indistinguishable from other keys::kbd:`ctrl-i`*is*:kbd:`tab`,:kbd:`ctrl-j`*is* newline (``\n``).
- Control and shift don't work simultaneously
- Control and shift don't work simultaneously - :kbd:`ctrl-X` is the same as :kbd:`ctrl-x`.
Other keys don't have a direct encoding, and are sent as escape sequences. For example :kbd:`→` (Right) often sends ``\e\[C``. These can differ from terminal to terminal, and the mapping is typically available in `terminfo(5)`. Sometimes however a terminal identifies as e.g. ``xterm-256color`` for compatibility, but then implements xterm's sequences incorrectly.
Other keys don't have a direct encoding, and are sent as escape sequences. For example :kbd:`right` (``→``) usually sends ``\e\[C``.
Some modern terminals support newer encodings for keys, that allow distinguishing more characters and modifiers, and fish enables as many of these as it can, automatically.
When in doubt, run :doc:`fish_key_reader`. If that tells you that pressing :kbd:`ctrl-i` sends tab, your terminal does not support these better encodings, and so fish is limited to what it sends.
.._cmd-bind-escape:
.._cmd-bind-escape:
Special Case: The Escape Character
Key timeout
----------------------------------
-----------
The escape key can be used standalone, for example, to switch from insertion mode to normal mode when using Vi keybindings. Escape can also be used as a "meta" key, to indicate the start of an escape sequence, like for function or arrow keys. Custom bindings can also be defined that begin with an escape character.
When you've bound a sequence of multiple characters, there is always the possibility that fish has only seen a part of it, and then it needs to disambiguate between the full sequence and part of it.
Holding alt and something else also typically sends escape, for example holding alt+a will send an escape character and then an "a".
For example::
fish waits for a period after receiving the escape character, to determine whether it is standalone or part of an escape sequence. While waiting, additional key presses make the escape key behave as a meta key. If no other key presses come in, it is handled as a standalone escape. The waiting period is set to 30 milliseconds (0.03 seconds). It can be configured by setting the ``fish_escape_delay_ms`` variable to a value between 10 and 5000 ms. This can be a universal variable that you set once from an interactive session.
bind j,k 'commandline -i foo'
So the escape character has its own timeout configured with :envvar:`fish_escape_delay_ms`.
# or `bind jk`
will bind the sequence ``jk`` to insert "foo" into the commandline. When you've only pressed "j", fish doesn't know if it should insert the "j" (because of the default self-insert), or wait for the "k".
You can enable a timeout for this, by setting the :envvar:`fish_sequence_key_delay_ms` variable to the timeout in milliseconds. If the timeout elapses, fish will no longer wait for the sequence to be completed, and do what it can with the characters it already has.
The escape key is a special case, because it can be used standalone as a real key or as part of a longer escape sequence, like function or arrow keys. Holding alt and something else also typically sends escape, for example holding alt+a will send an escape character and then an "a". So the escape character has its own timeout configured with :envvar:`fish_escape_delay_ms`.
See also :ref:`Key sequences <interactive-key-sequences>`.
See also :ref:`Key sequences <interactive-key-sequences>`.
``block``prevents events triggered by ``fish`` or the :doc:`emit <emit>` command from being delivered and acted upon while the block is in place.
``block``delays delivery of all events triggered by ``fish`` or the :doc:`emit <emit>`, thus delaying the execution of any function registered ``--on-event``, ``--on-process-exit``, ``--on-job-exit``, ``--on-variable`` and ``--on-signal`` until after the block is removed.
In functions, ``block`` can be useful while performing work that should not be interrupted by the shell.
The block can be removed. Any events which triggered while the block was in place will then be delivered.
Event blocks should not be confused with code blocks, which are created with ``begin``, ``if``, ``while`` or ``for``
Event blocks should not be confused with code blocks, which are created with ``begin``, ``if``, ``while`` or ``for``
Without options, the``block``command acts with function scope.
Without options, ``block``sets up a block that is released automatically at the end of the current function scope.
The following options are available:
The following options are available:
@@ -36,7 +32,7 @@ The following options are available:
Release global block.
Release global block.
**-h** or **--help**
**-h** or **--help**
Displays help about using this command.
Display help about using this command.
Example
Example
-------
-------
@@ -57,4 +53,4 @@ Example
Notes
Notes
-----
-----
Events are only received from the current fish process as there is no way to send events from one fish process to another (yet).
Events are only received from the current fish process as there is no way to send events from one fish process to another.
NOTE: This page documents the fish builtin ``command``.
To see the documentation on any non-fish versions, use ``command man command``.
**command** forces the shell to execute the program *COMMANDNAME* and ignore any functions or builtins with the same name.
**command** forces the shell to execute the program *COMMANDNAME* and ignore any functions or builtins with the same name.
In ``command foo``, ``command`` is a keyword.
The following options are available:
The following options are available:
**-a** or **--all**
**-a** or **--all**
Prints all *COMMAND* found in :envvar:`PATH`, in the order found.
Prints all *COMMAND* found in :envvar:`PATH`, in the order found.
**-q** or **--query**
**-q** or **--query**
Silence output and print nothing, setting only exit status.
Return 0 if any of the given commands could be found, 127 otherwise.
Implies **--search**.
Don't print anything.
For compatibility, this is also **--quiet** (deprecated).
For compatibility, this is also **--quiet** (deprecated).
**-v** (or **-s** or **--search**)
**-s** or **--search** (or **-v**)
Prints the external command that would be executed, or prints nothing if no file with the specified name could be found in :envvar:`PATH`.
Prints the external command that would be executed, or prints nothing if no file with the specified name could be found in :envvar:`PATH`.
**-h** or **--help**
**-h** or **--help**
Displays help about using this command.
Displays help about using this command.
With the **-v** option, ``command`` treats every argument as a separate command to look up and sets the exit status to 0 if any of the specified commands were found, or 127 if no commands could be found. **--quiet** used with **-v** prevents commands being printed, like ``type -q``.
Examples
Examples
--------
--------
|``command ls`` executes the ``ls`` program, even if an ``ls`` function also exists.
|``command ls`` executes the ``ls`` program, even if an ``ls`` function also exists.
|``command -s ls`` prints the path to the ``ls`` program.
|``command -s ls`` prints the path to the ``ls`` program.
|``command -q git; and command git log`` runs ``git log`` only if ``git`` exists.
|``command -q git; and command git log`` runs ``git log`` only if ``git`` exists.
|``command -sq git`` and ``command -q git`` and ``command -vq git`` return true (0) if a git command could be found and don't print anything.
@@ -70,24 +70,39 @@ The following options change what part of the commandline is printed or updated:
**-t** or **--current-token**
**-t** or **--current-token**
Selects the current token
Selects the current token
**--search-field**
Use the pager search field instead of the command line. Returns false if the search field is not shown.
The following options change the way ``commandline`` prints the current commandline buffer:
The following options change the way ``commandline`` prints the current commandline buffer:
**-c** or **--cut-at-cursor**
**-c** or **--cut-at-cursor**
Only print selection up until the current cursor position.
Only print selection up until the current cursor position.
If combined with ``--tokenize``, this will print up until the last completed token - excluding the token the cursor is in.
If combined with ``--tokens-expanded``, this will print up until the last completed token - excluding the token the cursor is in.
This is typically what you would want for instance in completions.
This is typically what you would want for instance in completions.
To get both, use both ``commandline --cut-at-cursor --tokenize; commandline --cut-at-cursor --current-token``,
To get both, use both ``commandline --cut-at-cursor --tokens-expanded; commandline --cut-at-cursor --current-token``,
or ``commandline -co; commandline -ct`` for short.
or ``commandline -cx; commandline -ct`` for short.
**-o** or **--tokenize**
**-x** or **--tokens-expanded**
Tokenize the selection and print one string-type token per line.
Perform argument expansion on the selection and print one argument per line.
Command substitutions are not expanded but forwarded as-is.
**--tokens-raw**
Print arguments in the selection as they appear on the command line, one per line.
**-o** or **tokenize**
Deprecated; do not use.
If ``commandline`` is called during a call to complete a given string using ``complete -C STRING``, ``commandline`` will consider the specified string to be the current contents of the command line.
If ``commandline`` is called during a call to complete a given string using ``complete -C STRING``, ``commandline`` will consider the specified string to be the current contents of the command line.
The following options output metadata about the commandline state:
The following options output metadata about the commandline state:
**-L** or **--line**
**-L** or **--line**
Print the line that the cursor is on, with the topmost line starting at 1.
If no argument is given, print the line that the cursor is on, with the topmost line starting at 1.
Otherwise, set the cursor to the given line.
**--column**
If no argument is given, print the 1-based offset from the start of the line to the cursor position in Unicode code points.
Otherwise, set the cursor to the given code point offset.
**-S** or **--search-mode**
**-S** or **--search-mode**
Evaluates to true if the commandline is performing a history search.
Evaluates to true if the commandline is performing a history search.
@@ -101,7 +116,11 @@ The following options output metadata about the commandline state:
**--is-valid**
**--is-valid**
Returns true when the commandline is syntactically valid and complete.
Returns true when the commandline is syntactically valid and complete.
If it is, it would be executed when the ``execute`` bind function is called.
If it is, it would be executed when the ``execute`` bind function is called.
If the commandline is incomplete, return 2, if erroneus, return 1.
If the commandline is incomplete, return 2, if erroneous, return 1.
**--showing-suggestion**
Evaluates to true (i.e. returns 0) when the shell is currently showing an automatic history completion/suggestion, available to be consumed via one of the `forward-` bindings.
For example, can be used to determine if moving the cursor to the right when already at the end of the line would have no effect or if it would cause a completion to be accepted (note that `forward-char-passive` does this automatically).
Example
Example
-------
-------
@@ -128,13 +147,14 @@ The most common use for something like completions is
::
::
set -l tokens (commandline -opc)
set -l tokens (commandline -xpc)
which gives the current *process* (what is being completed), tokenized into separate entries, up to but excluding the currently being completed token
which gives the current *process* (what is being completed), tokenized into separate entries, up to but excluding the currently being completed token
If you are then also interested in the in-progress token, add
If you are then also interested in the in-progress token, add
::
::
set -l current (commandline -ct)
set -l current (commandline -ct)
Note that this makes it easy to render fish's infix matching moot - if possible it's best if the completions just print all possibilities and leave the matching to the current token up to fish's logic.
Note that this makes it easy to render fish's infix matching moot - if possible it's best if the completions just print all possibilities and leave the matching to the current token up to fish's logic.
``disown`` removes the specified :ref:`job <syntax-job-control>` from the list of jobs. The job itself continues to exist, but fish does not keep track of it any longer.
``disown`` removes the specified :ref:`job <syntax-job-control>` from the list of jobs. The job itself continues to exist, but fish does not keep track of it any longer.
This will make fish lose all knowledge of the job, so functions defined with ``--on-process-exit`` or ``--on-job-exit`` will no longer fire.
Jobs in the list of jobs are sent a hang-up signal when fish terminates, which usually causes the job to terminate; ``disown`` allows these processes to continue regardless.
Jobs in the list of jobs are sent a hang-up signal when fish terminates, which usually causes the job to terminate; ``disown`` allows these processes to continue regardless.
NOTE: This page documents the fish builtin ``exec``.
To see the documentation on any non-fish versions, use ``command man exec``.
``exec`` replaces the currently running shell with a new command. On successful completion, ``exec`` never returns. ``exec`` cannot be used inside a pipeline.
``exec`` replaces the currently running shell with a new command. On successful completion, ``exec`` never returns. ``exec`` cannot be used inside a pipeline.
The **--help** or **-h** option displays help about using this command.
The **--help** or **-h** option displays help about using this command.
:program:`fish_add_path` is a simple way to add more components to fish's :envvar:`PATH`. It does this by adding the components either to $fish_user_paths or directly to :envvar:`PATH` (if the ``--path`` switch is given).
:program:`fish_add_path` is a simple way to add more directories to fish's :envvar:`PATH`. It does this by adding the directories either to :envvar:`fish_user_paths` or directly to :envvar:`PATH` (if the ``--path`` switch is given).
It is (by default) safe to use :program:`fish_add_path` in config.fish, or it can be used once, interactively, and the paths will stay in future because of :ref:`universal variables <variables-universal>`. This is a "do what I mean" style command, if you need more control, consider modifying the variable yourself.
It is (by default) safe to use :program:`fish_add_path` in config.fish, or it can be used once, interactively, and the paths will stay in future because of :ref:`universal variables <variables-universal>`. This is a "do what I mean" style command - it tries to do the right thing by default, and follow your lead on what you have already set up (e.g. by using a global :envvar:`fish_user_paths` if you have that already). If you need more control, consider modifying the variable yourself.
Components are normalized by:doc:`realpath <realpath>`. Trailing slashes are ignored and relative paths are made absolute (but symlinks are not resolved). If a component already exists, it is not added again and stays in the same place unless the ``--move`` switch is given.
Directories are normalized with:doc:`realpath <realpath>`. Trailing slashes are ignored and relative paths are made absolute (but symlinks are not resolved). If a directory is already included, it is not added again and stays in the same place unless the ``--move`` switch is given.
Components are added in the order they are given, and they are prepended to the path unless ``--append`` is given (if $fish_user_paths is used, that means they are last in $fish_user_paths, which is itself prepended to :envvar:`PATH`, so they still stay ahead of the system paths).
Directories are added in the order they are given, and they are prepended to the path unless ``--append`` is given. If $fish_user_paths is used, that means they are last in $fish_user_paths, which is itself prepended to :envvar:`PATH`, so they still stay ahead of the system paths. If the ``--path`` option is used, the paths are appended/prepended to :envvar:`PATH` directly, so this doesn't happen.
If no component is new, the variable (:envvar:`fish_user_paths` or :envvar:`PATH`) is not set again or otherwise modified, so variable handlers are not triggered.
With ``--path``, because :envvar:`PATH` must be a global variable instead of a universal one, the changes won't persist, so those calls need to be stored in :ref:`config.fish <configuration>`. This also applies to :envvar:`fish_user_paths` if you make it global (for instance by passing ``--global``).
If a component is not an existing directory, ``fish_add_path`` ignores it.
If no directory is new, the variable (:envvar:`fish_user_paths` or :envvar:`PATH`) is not set again or otherwise modified, so variable handlers are not triggered.
If an argument is not an existing directory, ``fish_add_path`` ignores it.
Options
Options
-------
-------
**-a** or **--append**
**-a** or **--append**
Add components to the *end* of the variable.
Add directories to the *end* of the variable.
**-p** or **--prepend**
**-p** or **--prepend**
Add components to the *front* of the variable (this is the default).
Add directories to the *front* of the variable (this is the default).
**-g** or **--global**
**-g** or **--global**
Use a global :envvar:`fish_user_paths`.
Use a global :envvar:`fish_user_paths`.
@@ -47,10 +49,11 @@ Options
Manipulate :envvar:`PATH` directly.
Manipulate :envvar:`PATH` directly.
**-m** or **--move**
**-m** or **--move**
Move already-existing components to the place they would be added - by default they would be left in place and not added again.
Move already-included directories to the place they would be added - by default they would be left in place and not added again.
**-v** or **--verbose**
**-v** or **--verbose**
Print the :doc:`set <set>` command used.
Print the :doc:`set <set>` command used, and some more warnings, like when a path is skipped because it doesn't exist or is not a directory.
Verbose mode is automatically enabled when fish_add_path is used interactively and the output goes to the terminal.
**-n** or **--dry-run**
**-n** or **--dry-run**
Print the ``set`` command that would be used without executing it.
Print the ``set`` command that would be used without executing it.
@@ -68,18 +71,26 @@ Example
::
::
# I just installed mycoolthing and need to add it to the path to use it.
# I just installed mycoolthing and need to add it to the path to use it.
# It is at /opt/mycoolthing/bin/mycoolthing,
# so let's add the directory: /opt/mycoolthing/bin.
> fish_add_path /opt/mycoolthing/bin
> fish_add_path /opt/mycoolthing/bin
# I want my ~/.local/bin to be checked first.
# I want my ~/.local/bin to be checked first,
# even if it was already added.
> fish_add_path -m ~/.local/bin
> fish_add_path -m ~/.local/bin
# I prefer using a global fish_user_paths
# I prefer using a global fish_user_paths
# This isn't saved automatically, I need to add this to config.fish
@@ -19,7 +19,7 @@ The ``fish_clipboard_copy`` function copies text to the system clipboard.
If stdin is not a terminal (see :doc:`isatty <isatty>`), it will read all input from there and copy it. If it is, it will use the current commandline, or the current selection if there is one.
If stdin is not a terminal (see :doc:`isatty <isatty>`), it will read all input from there and copy it. If it is, it will use the current commandline, or the current selection if there is one.
It is bound to :kbd:`Control`\ +\ :kbd:`X` by default.
It is bound to :kbd:`ctrl-x` by default.
``fish_clipboard_copy`` works by calling a system-specific backend. If it doesn't appear to work you may need to install yours.
``fish_clipboard_copy`` works by calling a system-specific backend. If it doesn't appear to work you may need to install yours.
@@ -21,7 +21,7 @@ If its stdout is not a terminal (see :doc:`isatty <isatty>`), it will output eve
If it outputs to the commandline, it will automatically escape the output if the cursor is currently inside single-quotes so it is suitable for single-quotes (meaning it escapes ``'`` and ``\\``).
If it outputs to the commandline, it will automatically escape the output if the cursor is currently inside single-quotes so it is suitable for single-quotes (meaning it escapes ``'`` and ``\\``).
It is bound to :kbd:`Control`\ +\ :kbd:`V` by default.
It is bound to :kbd:`ctrl-v` by default.
``fish_clipboard_paste`` works by calling a system-specific backend. If it doesn't appear to work you may need to install yours.
``fish_clipboard_paste`` works by calling a system-specific backend. If it doesn't appear to work you may need to install yours.
@@ -41,10 +41,46 @@ Available subcommands for the ``theme`` command:
-``save`` saves the given theme to :ref:`universal variables <variables-universal>`.
-``save`` saves the given theme to :ref:`universal variables <variables-universal>`.
-``show`` shows what the given sample theme (or all) would look like.
-``show`` shows what the given sample theme (or all) would look like.
The themes are loaded from the theme directory shipped with fish or a ``themes`` directory in the fish configuration directory (typically ``~/.config/fish/themes``).
The **-h** or **--help** option displays help about using this command.
The **-h** or **--help** option displays help about using this command.
Theme Files
-----------
``fish_config theme`` and the theme selector in the web config tool load their themes from theme files. These are stored in the fish configuration directory, typically ``~/.config/fish/themes``, with a .theme ending.
You can add your own theme by adding a file in that directory.
which will save your current theme in .theme format.
The format looks like this:
..highlight:: none
::
# name: 'Cool Beans'
# preferred_background: black
fish_color_autosuggestion 666
fish_color_cancel -r
fish_color_command normal
fish_color_comment '888' '--italics'
fish_color_cwd 0A0
fish_color_cwd_root A00
fish_color_end 009900
The two comments at the beginning are the name and background that the web config tool shows.
The other lines are just like ``set variable value``, except that no expansions are allowed. Quotes are, but aren't necessary.
Any color variable fish knows about that the theme doesn't set will be set to empty when it is loaded, so the old theme is completely overwritten.
Other than that, .theme files can contain any variable with a name that matches the regular expression ``'^fish_(?:pager_)?color.*$'`` - starts with ``fish_``, an optional ``pager_``, then ``color`` and then anything.
@@ -25,6 +25,12 @@ The following options are available:
**-i** or **--no-indent**
**-i** or **--no-indent**
Do not indent commands; only reformat to one job per line.
Do not indent commands; only reformat to one job per line.
**--only-indent**
Do not reformat, only indent each line.
**--only-unindent**
Do not reformat, only unindent each line.
**-c** or **--check**
**-c** or **--check**
Do not indent, only return 0 if the code is already indented as fish_indent would, the number of failed files otherwise. Also print the failed filenames if not reading from standard input.
Do not indent, only return 0 if the code is already indented as fish_indent would, the number of failed files otherwise. Also print the failed filenames if not reading from standard input.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.