On first run we copy the default theme to universal variables for colors
(since these defaults are not included in the binary).
Similarly, we have "fish_config theme save", which copies the given theme
to the same universal variables.
Sometimes we make changes to a default theme. Existing users won't see
those updates by default because previous defaults have been turned into
universal variables, which are indistinguishable from user-set variables.
This also means that installing fish on two systems might result in different
colors if the initially installed versions differ. This is surprising.
It feels difficult to get rid of universal variables here without breaking
features such as instant propagation on "set fish_color_normal blue"
or tab-completion on "set fish_color" showing the current value even when
that's a default.
Assuming that we don't want to stop setting these universal variables,
try a different solution: keep track of whether a variable wants to follow
future updates/removals.
This is opt-in via "--track" (e.g. "fish_config theme save --track THEME")
but crucially, enabled for the default theme when that one is saved on first launch.
(Of course this means that this enhancement only works on new installations.)
This allows customizing individual color variables (which likely means
removing --track marker) while still getting updates for other color variables.
Note that whenever we add a new color, we still need to write a migration
(see "__fish_initialized") that initializes this color in the universal
scope with the "--track" marker.
TODO:
- add a "follow future updates to this theme" checkbox to webconfig
- changelog
The first two attempts skip over empty variables and the last one doesn't.
This is fine but since we need the default case anyway, might as well reuse
it here too. (An empty color variable is treated the same way a missing
color variable is.)
I don't have a runnable test case but this does seem to have bitrotted.
Originally, we only cared about keys and the EOF and check-exit events.
Returning one of the other new events here seems totally wrong.
Try to fix this, and move the logic closer to where it's needed, so we no
longer need to update its name and we're less likely to forget to update it,
and it cannot.
DCS commands stop at ST ("\e\\"). Make sure we don't stop at just "\e". I
don't know of any command that will actually include the escape byte in its
payload but better safe than sorry.
The input queue doesn't want to be blocked, so let's decide later what to
do with a mouse click. This fixes the potential problem where a mouse click
is ignored if it is received while we're waiting for the terminal to repond
to a query.
While we are waiting for a query response from the terminal, we defer any
input processing until we receive our query response
Then that response is promoted to the front of the input queue, and
remaining inputs are processed in order.
We accidentally process focus events, which may run arbitrary code. We can't
do this; it breaks a lot of invariants (for example the it can invalidate
the cursor positions for CursorPositionQuery, or it can cause fish to exit
before fully consumeing a query response).
Make sure we only process known-safe events. We definitely need to process
CheckExit (in case we received SIGHUP). I guess we should also process Eof,
in case the terminal is buggy.
These code paths have a tiny bit of logic in common, share that.
Maybe this should be nested in ImplicitEvent, and maybe Eof and CheckExit
shouldn't be..
This object is initialized once just before we start reading from the terminal.
Once seems to be the appropriate type for this. This gets rid of an awkward
enum variant.
We never need to access this from other threads, so a Mutex is overkill.
Leave behind stale variable names like "wait_guard" to be cleaned up by the
next commit.
Since TestInputEventQueuer is used concurrently in tests,
give it its own private object, to avoid borrowing conflicts.
Same for fish_key_reader; this fixes the issue that fish_key_reader potentially
reads keyboard input before a query is finished.
Whenever config.fish runs (interactive) builtin read, we push and pop a
top-level, before the main shell's reader.
The terminal state outlives all readers, so its scope should reflect that
to avoid redundant initialization. Move it into the parser.
This is also used by a following commit that wants to access the query state
from a builtin. This should work even if no reader is active.
Note that Mutex doesn't really make sense here - the next commit will fix that.
The differences between color variables and set_color implementation have
gotten somewhat small so make them explicit by getting rid of this code clone.
Outputter::set_text_face() has clever caching logic that is not always needed
by builtin set_color -- in fact, it even needs to explicitly disable the
cache for foreground and background colros -- but this might still be worth it.
As reported in https://github.com/fish-shell/fish-shell/issues/11325, we have logic that
implicitly activates bold mode.
Even worse: the test case from https://github.com/fish-shell/fish-shell/issues/11426 shows that
we're not even consistent about that.
To reproduce, use
set -g fish_pager_color_background --background=fff
set -g fish_pager_color_prefix --underline --bold 000
set -g fish_pager_color_completion
set -g fish_pager_color_description
complete : -s a -l all -d asdf
and type ": -" <TAB>
The second prefix is underlined but not bold,
because the implicit bold mode has a subtle bug.
Now if we were to fix this, using
diff --git a/src/terminal.rs b/src/terminal.rs
index b86a7d85fe..7791d34936 100644
--- a/src/terminal.rs
+++ b/src/terminal.rs
@@ -589,7 +589,7 @@
// Lastly, we set bold, underline, italics, dim, and reverse modes correctly.
if style.is_bold()
&& !self.last.style.is_bold()
- && !bg_set
+ && !(bg_set && !last_bg_set)
&& self.write_command(EnterBoldMode)
{
self.last.style.bold = true;
that would make the description bold as well, which would probably cause chaos.
Either way, it seems wrong to expand this hack.
Let's remove it.
For better or worse, we can't safely update the default theme yet on
an existing user's machine, because we have set universal variables.
This means that fish_color_search_match and fish_pager_color_progress on
existing installations are no longer bold. That's probably acceptable.
The former was hard to read for the longest time, until 9af6a64fd2 (Fix
bad contrast in search match highlighting, 2024-04-15). The progress info
is probably not a big deal.
Attentive users may run "fish_config theme choose 'fish default'". Perhaps
we should tell them on upgrade?
Closes#11325
(As suggested in 84e7fbd466 (Make default .theme file consistent with uvars,
2022-02-03))
Historical behavior in default fish is that
1. fish_color_keyword and fish_color_option are unset, meaning they
default to their fallbacks, fish_color_command and fish_color_param.
2. colors not mentioned in the default them, such as
fish_pager_color_secondary_background, are unset
"fish_config theme save fish\ default"
- sets group 1 to a non-empty value (deactivating the fallbacks)
- sets group 2 to an empty value (which has no function change except it
changes completions for builtin set)
Both are probably fine. I guess the historical behavior is a bit nicer.
But the new behavior is simpler. We can definitely optimize it later,
for example by never redundantly setting universal color variables to an
empty value.
The foreground component of fish_color_search_match was first used in commit
9af6a64fd2 (Fix bad contrast in search match highlighting, 2024-04-15)
which also changed it from bryellow to white. Unfortunately it forgot to
update the themes. Probably all of them want to the default, so let's do that.
We only query for the cursor position if either
1. if the terminal sends an XTGETTCAP response indicating it supports scroll
forward (terminfo code indn)
2. if the terminal sends a mouse click event
In practice, the terminals that do either are also capable of reporting the
cursor position, so let's require that for now.
We could definitely make this optional, and degrade gracefully -- that's
what I originally intended.
But maybe we don't need it? Keeps things simpler. In future, we can add a
timeout, and print an error, to help debugging terminals.
Old versions of ConHost and Putty can't parse DCS sequences.
For this reason, we briefly switch to the alternate screen buffer while sending
DCS-format (e.g. XTGETTCAP) queries. For extra paranoia, we wrapped this
procedure in a synchronized update. This doesn't seem to be needed; neither
ConHost nor Putty show glitches when the synchronized update is omitted.
As of today, every terminal that implements XTGETTCAP also implements
synchronized updates but that might change.
Let's remove it, to reduce surprise for users and terminal developers.
As a bonus, this also fixes a glitch on Terminal.app which fails to parse
the synchronized-update query (`printf '\x1b[?2026$p'`) and echoes the "p"
(bug report ID FB17141059). Else we could work around this with another
alternate screen buffer.
Unfortunately, this change surfaces two issues with GNU screen. For one,
they don't allow apps to use the alternate screen features (the user may
allow it with "altscreen on"). Second, screen unconditionally echoes
the payload of DCS commands. A possible fix has been suggested at
https://lists.gnu.org/archive/html/screen-devel/2025-04/msg00010.html
I think this combination of behaviors is unique among terminals. I'm sure
there are more terminals that don't parse DCS commands yet, but I think almost
all terminals implement alternate screen buffer. Probably only terminal
multiplexers are prone to this issue. AFAICT very few multiplexers exists,
so we can work around those until they are fixed.
Disable XTGETTCAP queries for GNU screen specifically. Unfortunately screen
does not implement XTVERSION, so I don't know how to reliably identify
it. Instead, check STY and some commonly-used values TERM values.
This has false negatives in some edge cases.
But the worst thing that happens is that "+q696e646e" will be echoed once
at startup, which is easy to ignore, or work around with something like
function workaround --on-event fish_prompt
commandline -f repaint
functions --erase workaround
end
which I don't think we should apply by default, because it can mask other
issues.
We should give screen more time to respond. I guess I'll open an issue so
we don't forget. In doubt, we can always go back to the previous approach
(but implement it in fish script).
Alternative workaround: instead of the alternative screen buffer, we could
try something like clr_eol/clr_bol to erase the spuriously echoed text. I
tried to do this in various ways but (surprisingly) failed.
"set_color --background=normal" resets all attributes. I don't expect anyone
relied on this behavior. Let's remove it, to reduce surprise. This also
improves consistency with "set_color --underline-color=normal".
As suggested in
https://github.com/fish-shell/fish-shell/issues/11417#issuecomment-2825023522
For backwards compatibility reasons, "set_color normal" still resets
everything though. In future we could make "set_color --foreground=normal"
reset only foreground.
Closes#11418
Some changes fix actual problems, e.g. missing spaces in square bracket tests,
and backticks unintentionally causing code execution when intended as formatting.
Others, such as conservative quoting probably work fine in the old version in
most situations, but it's nice to have some additional safety.
Using `{ ..; }` instead of `(..)` is just a small performance enhancement.
Many of these issues were identified by shellcheck, which might be useful in CI
as well.
Given
set -g fish_color_error --background=red --background=blue
set_color --background=red --background=blue
Historically, the former would use the first color (red) while the equivalent
set_color command uses the second one (blue).
This changed in 037c1896d4 (Reuse wgetopt parsing for set_color for internal
colors, 2025-04-13) which gave set_color semantics to the former.
This seems like the wrong choice set_color is less important.
For foreground colors we already pick the best color in a way that's consistent
across both. Let's extend this approach to background and underline colors
(even though I'd not really recommend using this feature).
Fixes#11420Closes#11421
Consolidate best_color() calls because the following commit
wants to use this for background and underline colors too.
Switch to Result so we can use the "?" syntax.
Commit 6fcb418ae3 (Enable 24-bit RGB colors by default, 2025-04-11)
invalidated some documentation about fallback colors; by default we prefer
RGB unless the user has explicitly set fish_term256=0.
Note that this made fallback colors much less useful, because they are only
active if the user sets fish_term256=0. Note that setting fish_term24bit=0
is *not* enough; in that case we use the 256 color palette (and assume that
it is a subset of the 24-bit colors).
We do have some themes that use fallback colors:
fish_pager_color_description B3A06D yellow
By default, those will be less useful now.
See also https://github.com/fish-shell/fish-shell/issues/11393
Commit df3b0bd89f (Fix commandline state for custom completions with variable
overrides, 2022-01-26) made us push a transient command line for custom
completions based on a tautological null-pointer check ("var_assignments").
Commit 77aeb6a2a8 (Port execution, 2023-10-08) turned the null pointer into
a reference and replaced the check with "!ad.var_assignments.is_empty()".
This broke scenarios that relied on the transient commandline. In particular
the attached test cases rely on the transient commandline implicitly placing
the cursor at the end, irrespective of the cursor in the actual commandline.
I'm not sure if there is an easy way to identify these scenarios.
Let's restore historical behavior by always pushing the transient command line.
Fixes#11423
Commit cebc05f6c1 (Reset is not a color, 2025-04-15) tried to simpilfy
this behavior but forgot about cases like "set_color --background=normal
red --bold" where we do want to continue after resetting background.
Closes#11417
Add a new underline-color option to set_color (instead of adding an optional
color argument to --underline); this allows to set the underline color
independently of underline style (line, curly, etc.). I don't think this
flexibility is very important but this approach is probably the least hacky.
Note that there are two variants:
1. \e[58:5:1m
2. \e[58;5;1m
Variant 1 breaks:
breakage from colon-variant for colored underlines
- cool-retro-term makes text blink
- GNU screen (goes into bold mode)
- terminology (goes into bold mode)
Variant 2 would break:
- mintty (Cygwin terminal) -- it enables bold font instead.
- Windows Terminal (where it paints the foreground yellow)
- JetBrains terminals echo the colons instead of consuming them
- putty
- GNU screen (goes into bold mode)
- st
- urxvt
- xterm
- etc.
So choose variant 1.
Closes#11388Closes#7619
set_color --underline=curly outputs \e[4:3m which breaks the following
terminals:
- Terminal.app interprets it as yellow background
- abduco and dvtm interpret it as green foreground
- JetBrains terminals interprets it as yellow background
- urxvt interprets it as yellow background
terminals that interpret curly as single underline:
- tmux [1]
- emacs ansi-term [2]
- emacs vterm
- GNU screen (also wrongly turns on italic mode)
- terminology (also wrongly turns on italic mode)
- Vim's :terminal
[1]: https://github.com/orgs/tmux/discussions/4477
[2]: https://lists.gnu.org/archive/html/bug-gnu-emacs/2025-04/msg01093.htmlCloses#10957
This workaround was added in commit d66700a0e4 (Color work, 2012-02-11).
I don't understand why it would be necessary, it seems redundant. Bravely
remove it. Would be interesting to know which terminal caused the motivating
problem. Terminal.app and others seem to be unaffected by this change.
This command does not work
set_color --background=reset
These seem to work
set fish_color_normal reset
set fish_color_normal --background=reset
but I don't understand why anyone would do that, since an empty color option
gives the same behavior.
Also "reset" is totally undocumented, since "normal" is our canonical spelling.
Let's simplify things by removing support for reset everywhere except if it's
a foreground color (since there are some uses of "set_color reset" out there).
Also, simplify the set_color logic accordingly.
Our highlighting module allows different highlight roles for foreground
and background.
Other users of our color-parsing logic have no need for this.
Historically we have passed an "is_background" bool and only parsed what we're
interested in. This sort of makes sense because it's exactly what we need,
but it meant that the special behavior spread quite far.
There is no real need for spreading it; a function with the behavior "parse
a text face but honor is_background" is strictly more complex than "parse a
text face". Additionally, any performance optimization is only relevant if
the user specifies faces that won't be used, which is a very unusual case.
Let's isolate this logic in the highlighting module.
The parent commit got rid of the is_background parameter that determined
the meaning of the return value (fg/bg); since we always return both now,
give them names.
A following commit wants to add other underline styles. At most one underline
style can be active at one time. This can't be modelled well by a flat
bitset, so let's use a composable type here.
When the text face changes from bold to non-bold, we need to reset
all attributes since there is no exit_bold_mode.
The same holds for various dim and reverse mode, and future attributes.
A following commit wants to make this logic more robust to addition of future
attributes. Prepare for that by using the new type.
Not sure if this is 100% a good idea but it does remove some duplication.
While at it, change parse_color_maybe_none to actually return Option::None
and not Color::None which means something else (see a following commit).
Our "Color" type also includes text styling (bold, italics, ...). This doesn't
seem like the perfect way to model this, because the background text styles
are always unused (this is noticeable with some fish_color_* variables).
Introduce a type that represents attributes to apply to text, and nothing
else. Prefer to pass this instead of two Color values with redundant text
style is redundant.
We have a a workaround with a comment saying
> We don't know if exit_attribute_mode resets colors, so we set it to
> something known.
I'm pretty sure fish (and other software) makes this assumption.
I'd be very surprised if a relevant terminal behaves differently.
Let's remove our attempt to work around around this.
While at it, extract a function to be used in two other places
(but don't change their behavior yet).
A "None" type color means "don't change it, use the last color. So it makes
no sense to ever set "self.last_fg = NONE". The background-color code path
only sets it in the other cases. Let's copy that for the foreground one.
Also, extract this assignment to simplify both code paths.
fish -c 'set_color --print-colors --background blue' |xxd
does not print color enabling sequences but does print *disabling* sequences.
There's no need for that.
RgbColor can also be a named color, so this name is surprising to readers
who don't have the implicit assumption that named colors are the default
and that RGB support is something novel.
tl;dr reduce memory usage and ast complexity. No functional change expected.
This concerns how our ast is represented. Prior to this commit, and ever
since the new ast was introduced, each Node had a reference to its parent -
the so-called "parent pointer". This made it convenient to "walk around"
the AST - for example we could get a command and then walk up the AST to
determine if that command had a decoration (`time`, etc).
This parent pointer concept was natural in C++ for a few reasons:
1. Pointers are idiomatic in C++.
2. Parent pointers were "thin": just regular pointer-sized, e.g.
8 bytes in x86-64.
3. C++'s inheritance means that the pointer can just be stored as a field
in the base Node class. Super easy and efficient.
But these proved to have significant drawbacks when expressed in Rust:
1. Parent pointers form a cyclic data structure which is very awkward in
Rust. We had to use raw pointers and unsafe code.
2. Parent pointers were a `&dyn Node` which is necessarily "fat" (base
pointer + vtable pointer), taking up 16 bytes on a 64 bit machine. This
greatly bloated the size of the AST because our AST is quite fine (many
detailed node types).
3. The lack of inheritance means that parent pointers had to be repeated
for every node and exposed through the Node trait, which was awkward and
verbose.
In fact storing parent pointers is rather uncommon among AST
implementations. For example, LLVM does not do this; instead it dynamically
constructs a map of parent pointers on demand (see `ParentMapContext`).
fish could do this or something like it, but in fact we can do better: we
can tweak Traversal to provide parent pointers.
As a reminder, Traversal is a way of naturally iterating over all AST nodes
in a for loop:
for node in ast.walk() {...}
This is in-order ("top-down"). A parent node is yielded before its children.
Prior to this commit, this worked as follows: the Traversal maintained a
stack of next-to-be-yielded nodes. The `next()` function would pop off the
next node, push all of its children onto the stack, and then yield that
popped node.
We can easily make Traversal remember the sequence of parents of a given
Node by tweaking the Traversal to remember each Node after popping it. That
is, mark each Node in the stack as "NeedsVisit" or "Visited". Within
`next()`, check the status of the top node:
- NeedsVisit => mark it as Visited, push its children, and return that Node
- Visited => pop it, discard it, and try again
This means that, for any Node returned by `next()`, we can get the sequence
of parents as those Nodes that are marked as Visited on the stack.
The net effect of all of this is a large decrease in ast complexity and
memory usage. For example, __fish_complete_gpg.fish goes from 508 KB to 198 KB,
as measured by `fish_indent --dump-parse-tree`.
There's somewhat higher memory usage for Traversal, but these are transient
allocations, not permanent.
This removes parent back-pointers from ast nodes. Nodes no longer store
references to their parents, resulting in memory size reductions for the ast
(__fish_complete_gpg.fish goes from 508 KB to 198 KB in memory usage).
These depths are used in calculating indents for ast pretty-printing.
This moves away from parent back-pointers, so that we can ultimately remove
them.
Prior to this commit, Traversal was a convenient way to walk the nodes of
an ast in pre-order. This worked simply: it kept a stack of Nodes, and then
when a Node was visited, it was popped off and its children added.
Enhance Traversal to track whether each node on the Stack is `NeedsVisit`
or `Visited`. The idea is that, when a Node is yielded from next(), we can
reconstruct its parents as those Visited nodes on the Traversal stack.
This will allow clients to get the parents of Nodes as they are traversed
without each Node needing to explicitly save its parent.
This function hid a bug! It converted two Nodes to `*const ()` which discards
the vtable pointer, using only the data pointer; but two nodes can and do have
the same data pointer (e.g. if one node is the first item in another).
Add the (statically dispatched) is_same_node function with a warning comment,
and adopt that instead.
Now that we have more confidence in our pointers, we can allocate directly
more often, instead of always through Box. This recovers the performance
lost from the previous commit.
Prior to this commit, lists of items (e.g. an argument list to a command) would
each be Boxed, i.e. we had effectively Vec<Box<Item>>. The rationale here is
that we had raw pointers and pointer stability was important to enforce.
But we have fewer raw pointers now - only the parent pointers - and we can be
confident that the Ast will not change or move after construction. So remove
this intermediate Box, simplifying some logic and reducing ast size by ~5%.
This slows down Ast construction because we're still constructing
the Box and moving things in and out of it - that will be addressed in
subsequent commits.
This saves a decent amount of memory, both because we no longer have excess
capacity sitting around that we'll never use, but also because we no longer need
to store the "capacity" value.
Indicate the units of the durations (microseconds).
Right-align the durations for better readability.
Use `format!` instead of `fprintf` for more flexible formatting.
Write to `File` instead of raw fd.
Closes#11396
As mentioned in
https://github.com/fish-shell/fish-shell/pull/9688#discussion_r1155089596,
commit b77d1d0e2b (Stop crashing on invalid Unicode input, 2024-02-27), Rust's
char type doesn't support arbitrary 32-bit values. Out-of-range Unicode
codepoints would cause crashes. That commit addressed this by converting
the encoded bytes (e.g. UTF-8) to special private-use-area characters that
fish knows about. It didn't bother to update the code path in builtin read
that relies on mbrtowc as well.
Fix that. Move and rename parse_codepoint() and rename/reorder its input/output
parameters.
Fixes#11383
(cherry picked from commit d9ba27f58f)
This also changes the single-byte locale code path to treat keyboard input
like "\x1ba" as alt-a instead of "escape,a". I can't off-hand reproduce
a problem with "LC_ALL=C fish_key_reader", I guess we always use a UTF-8
locale if available?
(cherry picked from commit b061178606)
Two issues:
1. typing the codepoint 0x123456 into fish_key_reader:
$ fish_key_reader -cV
# decoded from: \xf4\xa3\x91
bind \xf4 'do something'
# decoded from:
bind \xa3 'do something'
# decoded from:
bind \x91 'do something'
The invalid codepoint is represented in its original encoding, which leaks
to the UI. This was more or less intentionally added by b77d1d0e2b (Stop
crashing on invalid Unicode input, 2024-02-27). That commit rendered it
as replacement byte, but that was removed for other reasons in e25a1358e6
(Work around broken rendering of pasted multibyte chars in non-UTF-8-ish
locale, 2024-08-03).
We no longer insert such (PUA) codepoints into the commandline. The "bind"
comes above would work however. I don't think this is something we want
to support. Discard invalid codepoints in the reader, so they can't be
bound and fish_key_reader shows nothing.
2. builtin read silently drops invalid encodings This builtin is not really
suited to read binary data (#11383 is an error scenario), but I guess it can
be bent to do that. Some of its code paths use str2wcstring which passes
through e.g. invalid UTF-8. The read-one-char-at-a-time code path doesn't.
Fix this.
As mentioned in
https://github.com/fish-shell/fish-shell/pull/9688#discussion_r1155089596,
commit b77d1d0e2b (Stop crashing on invalid Unicode input, 2024-02-27), Rust's
char type doesn't support arbitrary 32-bit values. Out-of-range Unicode
codepoints would cause crashes. That commit addressed this by converting
the encoded bytes (e.g. UTF-8) to special private-use-area characters that
fish knows about. It didn't bother to update the code path in builtin read
that relies on mbrtowc as well.
Fix that. Move and rename parse_codepoint() and rename/reorder its input/output
parameters.
Note that the behavior is still wrong if builtin read can't decode the
input; see the next commit.
Fixes#11383
This also changes the single-byte locale code path to treat keyboard input
like "\x1ba" as alt-a instead of "escape,a". I can't off-hand reproduce
a problem with "LC_ALL=C fish_key_reader", I guess we always use a UTF-8
locale if available?
As reported in
https://matrix.to/#/!YLTeaulxSDauOOxBoR:matrix.org/$BDVmBtBgtKCj45dVfS36rP7Y6Fo7E4uBg1vcH9IIIQg
tmux new-session -c "" fish -C 'echo $PWD'
prints
/home/fishuser/
This is because our path canonicalization function only
removes trailing slashes if there were duplicate slashes in the string.
Else (for the case above), we end up with "trailing == len"
which means we ignore trailing slashes.
I don't think this was intended by 24f1da7f30 (Add a fancy new
paths_are_equivalent function to test for equivalent paths instead of merely
equal ones, 2013-08-27). Fix it.
While at it, also document the command to reset the shape to the default,
which we should probably use. See foot commit 49034bb7 (csi: let CSI 0 q mean
"switch to user configured cursor style", 2019-07-22).
As of today, the XTerm documentation is a not clear on this; in
XTerm itself, CSI 0 q may actually change the cursor because they have an
additional default cursor is configured differently..
Things like branch and tag name can take up a lot of space on the screen. The
empty status may be useful but we're still looking for evidence. For now let's
keep only the conflict status, which is fairly familiar from the Git prompt.
See also #11183
* man: redirect stderr to /dev/null when checking for embedded files
This fixes a bug where `man status` results in "status: fish was not
built with embedded files⏎" printed.
* fish_config and status completions: redirect stderr to /dev/null when checking for embedded files
I am less sure about this commit, can get rid of it.
* status get-file/list-files: add \n to error message when not compiled with embedded files
The original only worked in the manifest directory *and* didn't even
list the right packages.
E.g. for fish it listed "printf", when the package is called
"fish-printf". So we're not keeping it because it's wrong.
Instead let's parse the actual json. It's a shame there is no
simple command to just get it line-delimited, of course.
Fixes#11384
CMake has this entire zoo of weird build types including "MinSizeRel".
I've also seen it set to empty, in distro packages no less.
Since we can't really make them all known to cargo, let's warn.
We could also error, but I'm not convinced there isn't some distro
packager out there setting it to "StrawberriesAndKittens" for some
reason,
and they'd be very cross with us if that stopped working.
See #11376
If you use `set t 10; function fish_prompt; seq $t; set t $(math $t - 1); end` and trigger a repaint, you will see 9 residual lines from the previous prompt.
Now, the right prompt will not be executed only if it is undefined `fish_right_prompt`.
This allows the use of `read -p 'echo left' -R 'echo right'`.
Also changes condition for use of `DEFAULT_PROMPT` for consistency.
I think `set_color ff0000` should default to outputting true-color sequences.
Unfortunately there is no good and widely-supported way to query for true-color
support. `COLORTERM=truecolor` doesn't work in some cases such as ssh.
Since many terminals nowadays implement the RGB sequences, let's try using
them by default.
Note that Emacs's ansi-term implements truecolor now.
See also the discussion around
https://github.com/fish-shell/fish-shell/pull/11345#issuecomment-2794920900Closes#11372
We have basically zero system tests for text coloring/formatting. I have
something in the works that will enable this without forcing tests to parse
the output of "tmux capture-pane -pe".
Fixes#11373
Fixes 17b4b39c8b (Stop reading terminfo database, 2025-03-20).
This part of the code could use some love; when we happen to clear the
selected text, we should end the selection.
But that's not how it works today. This is fine for Vi mode, because Vi
mode never deletes in visual mode.
Let's fix the crash for now.
Fixes#11367
(cherry picked from commit af3b49bf9c)
Use function names which explicitly state their flushing behavior.
When writing history items to a new file, flushing is only done at the end.
When appending items to an existing file, flushing is done for each item, in
order to keep the `first_unwritten_new_item_index` counter consistent with the
file system.
These builds do not use it, and setting it makes it possible to use
stale files.
So instead, we set it to empty. All uses I could find are either fine
with that (`set fish_function_path $__fish_data_dir/functions` - which
would also just be empty, which means it reads the embedded
functions),
or would break even if the variable was set but the directory was
empty (`source $__fish_data_dir/completions/git.fish`).
In case a completion needs a function from another script, run
`complete -C"foo "` to load it, so the full autoloading logic is used.
Otherwise these things break if the path is off. E.g. cargo's version
will fail if you override the cargo completion in
~/.config/fish/completions without also overriding the rustup
completions.
In other cases, fix for empty $__fish_data_dir, which will be coming in the next commit
This reflects better what it is - fish doesn't need to "install"
itself anymore, it just includes the data in the binary.
This also means we could include a separate "embed-man" feature that
can be turned off if you want the man pages to be shipped separately.
Also explain that in the README.
Technically the fish_update_completions files could also be piped to
python, but they'd have to be one file.
So for now, if you start a single-file fish, you'll have to run
fish_update_completions manually.
That fits the idea of having a single file that you move somewhere
better, given that it otherwise would run a script in the background
that creates a bunch of files
Because these are embedded in the fish binary,
we need to rebuild fish once they're changed.
This is only for release builds,
because rust-embed only really embeds in those
(debug builds read from the filesystem).
This is no longer useful, given that we read files from in the binary.
In the upcoming commits, this can be done with status list-files/get-file if you need it
This will load the functions and completions from inside of the fish
binary.
That means its no longer necessary to *install* a self-installable
build for basic functionality.
The functions/completions will be loaded *last*, so they are still
overridable via a file on disk (with the exception of
generated_completions, which we only use as a fallback if no
completions exist).
It still needs to extract files that are to be used by other tools,
including the man pages, fish_config.py, the man page completion
generator.
The remaining issues:
- It no longer prompts to install, but if you tried `fish_config`
after this it would fail to open the tool,
and it would be easy to forget to update those files
So: When and how should this remind you that these files need to be extracted?
Do we want e.g. a builtin that checks the version file (`status installed`)?
This could then be run by `fish_config` and `help` and tell you to run `fish --install`.
- `builtin --help` will fail - we could read these things from inside,
but we'd need groff for that.
Do we want to pre-process these and put them in the builtins themselves?
Do we want to print these on demand in `__fish_print_help` to groff?
- What directories need to still be defined? Does $__fish_data_dir need to keep existing?
Technically this *could* be the main distribution method. Maybe we
could let distro packages skip the embedded documentation and external
files,
but keep the functions/completions in the binary.
This gets the reader out of asting the source and is needed for
autoloader to get it to read a source string directly
Also add an "eval_file_wstr" method as a convenience to run a wstr as if it is a *file*, with a block and stuff
Our use of the terminfo database in /usr/share/terminfo/$TERM is both
1. a way for users to configure app behavior in their terminal (by
setting TERM, copying around and modifying terminfo files)
2. a way for terminal emulator developers to advertise support for
backwards-incompatible features that are not otherwise easily observable.
To 1: this is not ideal (it's very easy to break things). There's not many
things that realistically need configuration; let's use shell variables
instead.
To 2: in practice, feature-probing via terminfo is often wrong. There's not
many backwards-incompatible features that need this; for the ones that do
we can still use terminfo capabilities but query the terminal via XTGETTCAP
directly, skipping the file (which may not exist on the same system as
the terminal).
---
Get rid of terminfo. If anyone finds a $TERM where we need different behavior,
we can hardcode that into fish.
* Allow to override this with `fish_features=no-ignore-terminfo fish`
Not sure if we should document this, since it's supposed to be removed soon,
and if someone needs this (which we don't expect), we'd like to know.
* This is supported on a best-effort basis; it doesn't match the previous
behavior exactly. For simplicity of implementation, it will not change
the fact that we now:
* use parm_left_cursor (CSI Ps D) instead of cursor_left (CSI D) if
terminfo claims the former is supported
* no longer support eat_newline_glitch, which seems no longer present
on today's ConEmu and ConHost
* Tested as described in https://github.com/fish-shell/fish-shell/pull/11345#discussion_r2030121580
* add `man fish-terminal-compatibility` to state our assumptions.
This could help terminal emulator developers.
* assume `parm_up_cursor` is supported if the terminal supports XTGETTCAP
* Extract all control sequences to src/terminal_command.rs.
* Remove the "\x1b(B" prefix from EXIT_ATTRIBUTE_MODE. I doubt it's really
needed.
* assume it's generally okay to output 256 colors
Things have improved since commit 3669805627 (Improve compatibility with
0-16 color terminals., 2016-07-21).
Apparently almost every actively developed terminal supports it, including
Terminal.app and GNU screen.
* That is, we default `fish_term256` to true and keep it only as a way to
opt out of the the full 256 palette (e.g. switching to the 16-color
palette).
* `TERM=xterm-16color` has the same opt-out effect.
* `TERM` is generally ignored but add back basic compatiblity by turning
off color for "ansi-m", "linux-m" and "xterm-mono"; these are probably
not set accidentally.
* Since `TERM` is (mostly) ignored, we don't need the magic "xterm" in
tests. Unset it instead.
* Note that our pexpect tests used a dumb terminal because:
1. it makes fish do a full redraw of the commandline everytime, making it
easier to write assertions.
2. it disables all control sequences for colors, etc, which we usually
don't want to test explicitly.
I don't think TERM=dumb has any other use, so it would be better
to print escape sequences unconditionally, and strip them in
the test driver (leaving this for later, since it's a bit more involved).
Closes#11344Closes#11345
I think multi is always shorter unless we're only moving by one cell.
Also, we want to simplify this for a following commit where we no longer
check if it's supported.
This reverts commit 58347d494a (update PROMPT_SP heuristic, 2016-12-23)
If we write the last column of a line:
printf %0"$COLUMNS"d 0; sleep 3
most terminals will *not* move the cursor to the next line.
This behavior is indicated by the terminfo's xenl (AKA xen or
eat_newline_glitch) boolean capability.
We originally added checks for this capability because ConEmu and Windows
ConHost did not implement it, but they do now.
Also, as mentioned in
https://github.com/fish-shell/fish-shell/pull/11342#issuecomment-2769979520,
we're not aware of any present-day terminal that does not have this behavior,
but the value advertised by terminfo is sometimes wrong.
Let's get rid of this for now. A following commit will document that we
require this behavior.
I don't think we want to support terminals that implement XTGETTCAP but for
some reason don't use CSI Ps S for scroll forward; that would be a needless
complication.
Let's make ctrl-l / scrollback-push fail hard if a terminal does this.
Confusingly kitty and foot use different response formats, but happily we
no longer care.
An upcoming commit will document that we require the CSI Ps S style.
scoped_buffer borrows the screen to be able to flush buffers on drop. This is
a bit intrusive (see also 29ae571afa (Make scoped_push nicer, 2024-12-28)).
Not sure what's the best solution -- probably we should always pass the
outputter as parameter, removing the field.
For now let's at least contain the effects of this.
This part of the code could use some love; when we happen to clear the
selected text, we should end the selection.
But that's not how it works today. This is fine for Vi mode, because Vi
mode never deletes in visual mode.
Let's fix the crash for now.
Fixes#11367
`Duration::as_nanos()`
"Returns the total number of nanoseconds contained by this Duration."
https://doc.rust-lang.org/core/time/struct.Duration.html#method.as_nanos
Because we are indicating the time in milliseconds, we cannot use
`Duration::subsec_nanos()` but we need to manually get the whole duration in
nanoseconds and subtract the duration in milliseconds to get the fractional
part.
With
bind ctrl-r 'sleep 1' history-pager
typing ctrl-r,escape crashes fish in the history pager completion callback,
because the history pager has already been closed.
Prior to 55fd43d86c (Port reader, 2023-12-22), the completion callback
would not crash open a pager -- which causes weird races with the
user input.
Apparently this crash as been triggered by running "playwright",
and -- while that's running typing ctrl-r ligh escape.
Those key strokes were received while the kitty keyboard protocol
was active, possibly a race.
Fixes#11355
(cherry picked from commit c94e30293a)
With
bind ctrl-r 'sleep 1' history-pager
typing ctrl-r,escape crashes fish in the history pager completion callback,
because the history pager has already been closed.
Prior to 55fd43d86c (Port reader, 2023-12-22), the completion callback
would not crash open a pager -- which causes weird races with the
user input.
Apparently this crash as been triggered by running "playwright",
and -- while that's running typing ctrl-r ligh escape.
Those key strokes were received while the kitty keyboard protocol
was active, possibly a race.
Fixes#11355
This "SpawnedProc(env=os.environ.copy())" seems redundant but it's not, since
the default argument is initialized (with a copy of env) at module-load time.
Reshuffle the code to make it look less odd.
While at it, fix some invalid escape sequence warnings.
We canonicalize "ctrl-shift-i" to "ctrl-I".
Both when deciphering this notation (as given to builtin bind),
and when receiving it as a key event ("\e[105;73;6u")
This has problems:
A. Our bind notation canonicalization only works for 26 English letters.
For example, "ctrl-shift-ä" is not supported -- only "ctrl-Ä" is.
We could try to fix that but this depends on the keyboard layout.
For example "bind alt-shift-=" and "bind alt-+" are equivalent on a "us"
layout but not on a "de" layout.
B. While capslock is on, the key event won't include a shifted key ("73" here).
This is due a quirk in the kitty keyboard protocol[^1]. This means that
fish_key_reader's canonicalization doesn't work (unless we call toupper()
ourselves).
I think we want to support both notations.
It's recommended to match all of these (in this order) when pressing
"ctrl-shift-i".
1. bind ctrl-shift-i do-something
2. bind ctrl-shift-I do-something
3. bind ctrl-I do-something
4. bind ctrl-i do-something
Support 1 and 3 for now, allowing both bindings to coexist. No priorities
for now. This solves problem A, and -- if we take care to use the explicit
shift notation -- problem B.
For keys that are not affected by capslock, problem B does not apply. In this
case, recommend the shifted notation ("alt-+" instead of "alt-shift-=")
since that seems more intuitive.
Though if we prioritized "alt-shift-=" over "alt-+" as per the recommendation,
that's an argument against the shifted key.
Example output for some key events:
$ fish_key_reader -cV
# decoded from: \e\[61:43\;4u
bind alt-+ 'do something' # recommended notation
bind alt-shift-= 'do something'
# decoded from: \e\[61:43\;68u
bind alt-+ 'do something' # recommended notation
bind alt-shift-= 'do something'
# decoded from: \e\[105:73\;6u
bind ctrl-I 'do something'
bind ctrl-shift-i 'do something' # recommended notation
# decoded from: \e\[105\;70u
bind ctrl-shift-i 'do something'
Due to the capslock quirk, the last one has only one matching representation
since there is no shifted key. We could decide to match ctrl-shift-i events
(that don't have a shifted key) to ctrl-I bindings (for ASCII letters), as
before this patch. But that case is very rare, it should only happen when
capslock is on, so it's probably not even a breaking change.
The other way round is supported -- we do match ctrl-I events (typically
with shifted key) to ctrl-shift-i bindings (but only for ASCII letters).
This is mainly for backwards compatibility.
Also note that, bindings without other modifiers currently need to use the
shifted key (like "Ä", not "shift-ä"), since we still get a legacy encoding,
until we request "Report all keys as escape codes".
[^1]: <https://github.com/kovidgoyal/kitty/issues/8493>
This notation doesn't make sense, use either A or shift-a. We accept it
for ASCII letters only -- things like "bind shift-!" or "bind shift-Ä"
do not work as of today, we don't tolerate extra shift modifiers yet.
So let's remove it for consistency.
Note that the next commit will allow the shift-A notation again, but it will
not match shift-a events.
Our versions look like
4.0.0
4.0b1
4.0.1-535-abfef-dirty
But packagers may want to add more information here, and we don't
really care. Note that we no longer ever set the version to "unknown"
since 5abd0e46f5.
Supersedes #11173
(cherry picked from commit 411a396fa9)
This uses jj's dynamic completions when possible.
This avoids an annoying problem. After 04a4e5c4, jj's dynamic
completions (see the second paragraph of
<https://jj-vcs.github.io/jj/latest/install-and-setup/#command-line-completion>)
do not work very well in fish if the user puts `COMPLETE=fish jj |
source` in their `~/.config/fish/config.fish`. When the user types `jj
<TAB>`, they are instead overridden by fish's built-in non-dynamic
completions.
The difference is subtle. One problem I saw is that `jj new <TAB>` works
as expected (and shows revisions) while `jj new -A <TAB>` becomes broken
(and shows files).
If the user puts `COMPLETE=fish jj | source` in
`~/.config/fish/completions/jj.fish` there is no problem. However, users
might be confused if they run `COMPLETE=fish jj | source` or put it in
their config and it works in a broken fashion. I certainly was.
Meanwhile, I checked that if the user has `jj completion fish | source`
in their `config.fish`, executing `COMPLETE=fish jj
__this_command_does_not_exist | source` afterwards still works
correctly.
Let me know if there's a better approach to this problem.
(cherry picked from commit 932010cd04)
The commands 'close', 'resize', and 'status' each take 'name' as their solo argument.
Signed-off-by: memchr <memchr@proton.me>
(cherry picked from commit 5012bcb976)
This does two things:
- it stops completing cargo- tools because `cargo --list` already
includes them. This speeds up loading especially with a long $PATH
- it stops using `cargo search` for `cargo add` and install.
this removes a network call, which may be unexpected and can take a
long time
Fixes#11347
(cherry picked from commit 18371fbd4e)
This does two things:
- it stops completing cargo- tools because `cargo --list` already
includes them. This speeds up loading especially with a long $PATH
- it stops using `cargo search` for `cargo add` and install.
this removes a network call, which may be unexpected and can take a
long time
Fixes#11347
While at it, don't escape "?", I don't know why 68e167d576 (f-k-r should
use the user's locale, 2016-06-29) did that. Question mark is only special
in combination with redirections.
This parser was pretty nice but it has some issues with the new syntax.
It's not really needed when most bindings use the new syntax.
Let's remove it altogether.
I don't think there's a relevant terminal where the "bind -k" notation is
still needed. The remaining reason to keep it is backwards compatibility.
But "bind -k" is already subtly broken on terminals that implement either
of modifyOtherKeys, application keypad mode or the kitty keyboard protocol,
since those alter the byte sequences (see #11278).
Having it randomly not work might do more harm than good. Remove it.
This is meant go into 4.1, which means that users who switch back and forth
between 4.1 and 4.0 can already use the new notation.
If someone wants to use the bind config for a wider range of versions they
could use "bind -k 2>/dev/null" etc.
While at it, use the new key names in "bind --key-names", and sort it like
we do in "bind --function-names".
Closes#11342
Extract our own cfg value, to avoid noisy warnings like:
warning: unexpected `cfg` condition value: `cygwin`
--> src/fallback.rs:78:23
|
78 | #[cfg(not(target_os = "cygwin"))]
| ^^^^^^^^^^^^^^^^^^^^
|
The cygwin target will be added to Rust 1.86, so we can get rid of this
after some time.
If the kitty protcol is not supported, we still want to request modifyOtherKeys
and application keypad mode. Since 2d234bb676 (Only request keyboard protocols
once we know if kitty kbd is supported, 2025-01-26), fish_key_reader fails
to turn on those modes if the kitty keyboard protocol is not supported.
FindRust is too clever by half. It tries to do rustup's job for it.
See b38551dde9 for how that can break.
So we simplify it, and only let it check three things:
- Where's rustc? Look in $PATH and ~/.cargo/bin
- Where's cargo? Look in $PATH and ~/.cargo/bin
- What is the rust target (because we pass it explicitly)?
If any of these aren't that simple, we'll ask the user to tell us,
by setting Rust_COMPILER, Rust_CARGO or Rust_CARGO_TARGET.
None of the other things are helpful to us - we do not support windows
or whatever a "unikraft" is, and if the rust version doesn't work
it'll print its own error.
We could add a rustc version check, but that will become less and less
useful because rustc versions since 1.56 (released October 2021) will check rust-version in
Cargo.toml. So even at this point it's only pretty old rust versions already.
If anything changes in one of the listed directories or files, trigger a
rebuild.
Rebuilds are needed to update the version info built into the binaries.
The version info includes an abbreviated git commit hash, as well as information
about whether the repo was in a dirty state (uncommitted changes) when building.
Changes to files not explicitly listed will not trigger a rebuild, so to get
accurate version info upon such changes (also when checking out a different
commit which does not differ in any of the listed files), a rebuild needs to be
triggered manually (e.g. via `cargo clean` or `touch build.rs`).
It appears we're getting the correct output, but in the wrong order,
so pexpect doesn't filter it correctly:
> \r\n\x1b]133;C;cmdline_url=echo%20bar\x07bar\r\n\x1b]133;D;0\x07\x1b[?25h⏎ \r⏎ \r\rprompt 39>\x1b[?2004h
That `\x07bar` should be the \a that marks the end of the escape
sequence, followed by the actual "bar", followed by sequences marking
the end of output...
Text like "simply do" or "just press" is patronizing and unnecessary.
The prose is nicer if it's removed, and in some cases other words are
more specific.
Something like "we'll pretend your prompt is just a ``>``" can stay.
From the cargo docs (https://doc.rust-lang.org/cargo/reference/build-scripts.html#change-detection):
> By default, it takes a conservative approach of always re-running the build script if any file within the package is changed (or the list of files controlled by the exclude and include fields). For most cases, this is not a good choice, so it is recommended that every build script emit at least one of the rerun-if instructions (described below). If these are emitted, then Cargo will only re-run the script if the given value has changed
So, since we emit rerun-if-path-changed, we need to emit *all* the paths.
Failing to do this shows up most visibly as an outdated git version.
Fixes#11332
Consider command line modifications triggered from fish script via abbreviation
expansion:
function my-abbr-func
commandline -r ""
echo expanded
end
abbr -a foo --function my-abbr-func
Prior to commit 8386088b3d (Update commandline state changes eagerly as well,
2024-04-11), we'd silently ignore the command line modification.
This is because the abbreviation machinery runs something similar to
if my-abbr-func
commandline -rt expanded
end
except without running "apply_commandline_state_changes()" after
"my-abbr-func", so the «commandline -r ""» update is lost.
Commit 8386088b3d applies the commandline change immediately in the abbrevation
function callback, invalidating abbrevation-expansion state.
The abbreviation design does not tell us what should happen here. Let's ignore
commandline modifications for now. This mostly matches historical behavior.
Unlike historical behavior we also ignore modifications if the callback fails:
function my-abbr-func
commandline -r ""
false
end
Remove the resulting dead code in editable_line.
See #11324
(cherry picked from commit 11c7310f17)
Consider command line modifications triggered from fish script via abbreviation
expansion:
function my-abbr-func
commandline -r ""
echo expanded
end
abbr -a foo --function my-abbr-func
Prior to commit 8386088b3d (Update commandline state changes eagerly as well,
2024-04-11), we'd silently ignore the command line modification.
This is because the abbreviation machinery runs something similar to
if my-abbr-func
commandline -rt expanded
end
except without running "apply_commandline_state_changes()" after
"my-abbr-func", so the «commandline -r ""» update is lost.
Commit 8386088b3d applies the commandline change immediately in the abbrevation
function callback, invalidating abbrevation-expansion state.
The abbreviation design does not tell us what should happen here. Let's ignore
commandline modifications for now. This mostly matches historical behavior.
Unlike historical behavior we also ignore modifications if the callback fails:
function my-abbr-func
commandline -r ""
false
end
Remove the resulting dead code in editable_line.
See #11324
Commit 50e595503e (completions/git: fix completions for third-party git
commands, 2025-03-03) wasn't quite right, as we can see in the linked
reproduction:
$ fish_trace=1 complete -C 'git machete add --onto '
----> complete -C git-machete\ add\n--onto\
The recursive completion invocation contains a spurious newline, which means
that "--onto" is the command name. The newline is produced by "string escape
-- add --onto" inside a command substitution.
Fix this by interpreting newlines as list separators, and then joining
by spaces.
Fixes#11319
(cherry picked from commit 360cfdb7ae)
Commit 50e595503e (completions/git: fix completions for third-party git
commands, 2025-03-03) wasn't quite right, as we can see in the linked
reproduction:
$ fish_trace=1 complete -C 'git machete add --onto '
----> complete -C git-machete\ add\n--onto\
The recursive completion invocation contains a spurious newline, which means
that "--onto" is the command name. The newline is produced by "string escape
-- add --onto" inside a command substitution.
Fix this by interpreting newlines as list separators, and then joining
by spaces.
Fixes#11319
Currently fish errors out with
```fish
fish: Invalid redirection target:
rev <(ls)
^~~~^
```
This isn't very helpful in telling the user what they could be doing instead:
`rev (ls | psub)`.
Closes#11287
We can no longer have a single template that is always inserted. Instead
the web UI shows a menu allowing to select between one of our templates and
a blank one.
Commit f086bc9564 (Maintain ownership when rewriting universal variables
file, 2015-09-26) fixed an issue where "sudo -E fish" would create root-owned
~/.config/fish/fish_variables that break the users's shell.
A simlar issue exists for files in ~/.cache/fish; fix that.
Note that ~/.cache/fish is currently created on first run when we generate
completions from manpages.
See the issue described in #11292
Sometimes, the dirname of a completion is much longer than the basename.
When the dirname is the same for many completions, a long common dirname
prefix makes it hard to see the interesting differences in the basenames.
Fix this by collapsing the dirname prefix to "…/".
In future, we should find a generic way to collapse completions that don't
contain slashes.
Closes#8618Closes#11250
We incorrectly apply highlighting to trailing spaces that follow a command
or argument. This surfaces when the highlighting includes underline, which
is visible even on space characters.
Fix this by and have Claude add a unit test.
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes#11265
In our C++ implementation, these tests were run serially. As pointed out in
https://github.com/fish-shell/fish-shell/issues/11254#issuecomment-2735623229
we run them in parallel now, which means that one test could be changing
the global locale used by another.
In theory this could be fine because all tests are setting setting the
global locale to the same thing but the existence of a lock suggests that
setlocale() is not guaranteed to be atomic, so it's possible that another
thread uses a temporarily-invalid locale.
Fixes#11254
(cherry picked from commit 1d78c8bd42)
In our C++ implementation, these tests were run serially. As pointed out in
https://github.com/fish-shell/fish-shell/issues/11254#issuecomment-2735623229
we run them in parallel now, which means that one test could be changing
the global locale used by another.
In theory this could be fine because all tests are setting setting the
global locale to the same thing but the existence of a lock suggests that
setlocale() is not guaranteed to be atomic, so it's possible that another
thread uses a temporarily-invalid locale.
Fixes#11254
Commit 8bf8b10f68 (Extended & human-friendly keys, 2024-03-30)
add bindings that obsolete the terminfo-based `bind -k` invocations.
The `bind -k` variants were still left around[^*]. Unfortunately it forgot to
add the new syntax for some special keys in Vi mode. This leads to issues if
a terminal that supports the kitty keyboard protocol sends an encoding that
differs from the traditional one. As far as I can tell, this happens when
capslock or numlock is active. Let's add the new key names and consistently
mark `bind -k` invocations as deprecated.
Fixes#11303
[^*]: Support for `bind -k` will probably be removed in a future release -
it leads to issues like https://github.com/fish-shell/fish-shell/issues/11278
where it's better to fail early.
(cherry picked from commit 733f704267)
Commit 8bf8b10f68 (Extended & human-friendly keys, 2024-03-30)
add bindings that obsolete the terminfo-based `bind -k` invocations.
The `bind -k` variants were still left around[^*]. Unfortunately it forgot to
add the new syntax for some special keys in Vi mode. This leads to issues if
a terminal that supports the kitty keyboard protocol sends an encoding that
differs from the traditional one. As far as I can tell, this happens when
capslock or numlock is active. Let's add the new key names and consistently
mark `bind -k` invocations as deprecated.
Fixes#11303
[^*]: Support for `bind -k` will probably be removed in a future release -
it leads to issues like https://github.com/fish-shell/fish-shell/issues/11278
where it's better to fail early.
We have this hack where any positional arguments are taken as argument
names if "--argument-names" is given, and that didn't check for
read-only variables.
Fixes#11295
(cherry picked from commit d203ee4d53)
We have this hack where any positional arguments are taken as argument
names if "--argument-names" is given, and that didn't check for
read-only variables.
Fixes#11295
This uses jj's dynamic completions when possible.
This avoids an annoying problem. After 04a4e5c4, jj's dynamic
completions (see the second paragraph of
<https://jj-vcs.github.io/jj/latest/install-and-setup/#command-line-completion>)
do not work very well in fish if the user puts `COMPLETE=fish jj |
source` in their `~/.config/fish/config.fish`. When the user types `jj
<TAB>`, they are instead overridden by fish's built-in non-dynamic
completions.
The difference is subtle. One problem I saw is that `jj new <TAB>` works
as expected (and shows revisions) while `jj new -A <TAB>` becomes broken
(and shows files).
If the user puts `COMPLETE=fish jj | source` in
`~/.config/fish/completions/jj.fish` there is no problem. However, users
might be confused if they run `COMPLETE=fish jj | source` or put it in
their config and it works in a broken fashion. I certainly was.
Meanwhile, I checked that if the user has `jj completion fish | source`
in their `config.fish`, executing `COMPLETE=fish jj
__this_command_does_not_exist | source` afterwards still works
correctly.
Let me know if there's a better approach to this problem.
The chances that xterm-256color breaks anything are miniscule.
In the features we use, there are basically no differences,
especially when you consider that we decode keys independently.
E.g. tmux-256color has differences, but they are either just taste
questions (xterm's clear_screen will also clear scrollback),
or they're just... not actually different?
Terminfo will claim that it uses a different cursor_up and
exit_attribute_mode, but it also understands the xterm ones,
and it sends a different key_home,
but we decode that even with TERM=xterm-256color.
In some cases, terminfo is also just outright *wrong* and will claim
something does not support italics when it does.
So, since the differences are very likely to simply not matter,
throwing a warning is more confusing than it is helpful.
(cherry picked from commit 642ec399ca)
The chances that xterm-256color breaks anything are miniscule.
In the features we use, there are basically no differences,
especially when you consider that we decode keys independently.
E.g. tmux-256color has differences, but they are either just taste
questions (xterm's clear_screen will also clear scrollback),
or they're just... not actually different?
Terminfo will claim that it uses a different cursor_up and
exit_attribute_mode, but it also understands the xterm ones,
and it sends a different key_home,
but we decode that even with TERM=xterm-256color.
In some cases, terminfo is also just outright *wrong* and will claim
something does not support italics when it does.
So, since the differences are very likely to simply not matter,
throwing a warning is more confusing than it is helpful.
Commit 29dc307111 (Insert some completions with quotes instead of backslashes,
2024-04-13) breaks some workflows. Given
touch '[test] file1'
touch '[test] file2'
ls tes<Tab>
we insert completions quoted, which is inconvenient when using globs.
This implicit quoting feature is somewhat minor. But quotes look nicer,
so let's try to keep them. Either way, users can ask for it by starting a
token with «"».
Use quoting only when we insert unique completions.
Closes#11271
(cherry picked from commit 9f79fe17fc)
Prior to this commit, the WildCardExpander had one scoped variable, leading to
the annoying "zelf" pattern. Factor this into its own object and pass it around
explicitly, to clean this up.
In C++ it's easy to make an RAII-type object like "increment a counter for
the duration of this function." Such an object might accept a pointer or
reference, increment the value, and then restore it in its destructor. We
do this all the time - for example to mark a region of code as
non-interactive, etc.
Rust makes this more awkward, because now the reference is tracked by the
borrow checker: it "owns" the object for the duration of the function. This
leads to approaches like "zelf" where the object that marks the parser as
non-interactive itself becomes the new parser, but we can't call it "self"
and it's just yucky.
In this commit we introduce a notion of the "scoped data" of the Parser,
factored out of the library data. This is data which is typically set in a
scoped fashion: whether we are a subshell, are interactive, emit fish_trace
debugging info, etc. Crucially we set this as Rc: this allow the scope
itself to share data with the Parser and we can get rid of lots of "zelf"s.
Introduce a new function `Parser::push_scope` which creates a new scope and
allows modifying these variables associated with the scope. This ends up as
a nice simplification.
As part of a plan to overhaul the "scoped_set" pattern, introduce two new
"scoped" types:
ScopedCell is a trivial wrapper around Cell which exposes a function
`scoped_mod`. This allows you to modify the contents of the Cell; the
original contents are restored when the guard is dropped.
ScopedRefCell is similar, except it requires the caller to supply an
accessor which returns a &mut field, and also the new value.
These will be used to replace the rather unsightly scoped_push calls
around the fish codebase.
This concerns completions which wrap other completions. For example, if 'tig'
wraps 'git' then for the duration of the git completions, we need to make a fake
("transient") command line which contains "git" and not "tig".
Previously we had a stack of such command lines, but we never inspected anything
except the last element. Make this a single value.
This add two commands history-last-token-search-backward and
history-last-token-search-forward which behaves like bash's yank-last-arg. So
similar to history-token-search-* but only considers the last argument for
each command.
Closes#10756Closes#11258
As seen in GitHub Actions:
132/193 Test #17: check-completions.fish ...................***Failed 16.28 sec
checks/check-completions.fish..Failure:
There were no remaining checks left to match stdout:1:
OUTPUT from /home/runner/work/fish-shell/fish-shell/share/completions/pulumi.fish: warning: A new version of Pulumi is available. To upgrade from version '3.154.0' to '3.156.0', visit https://pulumi.com/docs/install/ for manual instructions and release notes.
This makes several changes:
- All panes in the current session are now show, instead of just the
current window.
- Instead of using window names when referring to panes (e.g.
"fish-dev.1"), we now use either window indicies ("3.1") or absolute
pane ids (%12). This is mainly because several windows often share the
same window name, e.g. many of my panes are automatically named "fish"
if they are currently running the shell and nothing else.
I put the window names in the descriptions. Because fish uses the
descriptions for completions, completing `fish-dev` is still helpful.
- I include the pane name into the description for a similar reason,
truncated to 15 chars.
- The panes are now ordered carefully, with panes in this window listed
first, then panes are ordered by window, and finally panes are listed
by their id (which does not change when panes are moved between windows)
Example output after `tmux selectp -t <TAB>` for a session with a few
windows. Note that windows 0, 1, and 4 are all named
`fish`. A pane in the current window can be accessed in 3 ways: `3`,
`2.3`, or `%57`.
```
0 (%4 [fish-dev] ~/d/fish-shell <active pane>) 3.1 (%58 [fish] man tmux ~/.c/f...)
1 (%8 [fish-dev] hwatch "jj.logs... <active win.>) 4.0 (%1 [sshd] tmux rename-win...)
2 (%15 [fish-dev] /U/i/d/fish-she... <active win.>) %1 (4.0 [sshd] tmux rename-win...)
3 (%57 [fish-dev] ~/d/fish-shell <active win.>) %4 (2.0 [fish-dev] ~/d/fish-shell <active pane>)
0.0 (%100 [fish] ~) %8 (2.1 [fish-dev] hwatch "jj.logs... <active win.>)
1.0 (%11 [fish] ~/d/_/nixpkgs) %11 (1.0 [fish] ~/d/_/nixpkgs)
1.1 (%38 [fish] ~/.c/f/completi...) %15 (2.2 [fish-dev] /U/i/d/fish-she... <active win.>)
2.0 (%4 [fish-dev] ~/d/fish-shell <active pane>) %38 (1.1 [fish] ~/.c/f/completi...)
2.1 (%8 [fish-dev] hwatch "jj.logs... <active win.>) %41 (3.0 [fish] ~/.c/f/conf.d)
2.2 (%15 [fish-dev] /U/i/d/fish-she... <active win.>) %57 (2.3 [fish-dev] ~/d/fish-shell <active win.>)
2.3 (%57 [fish-dev] ~/d/fish-shell <active win.>) %58 (3.1 [fish] man tmux ~/.c/f...)
3.0 (%41 [fish] ~/.c/f/conf.d) %100 (0.0 [fish] ~)
```
Compared to before:
```
0 (pane) 2 (pane) 0:fish-dev.0 (session:window.pane) 0:fish-dev.2 (session:window.pane) fish-dev (window)
1 (pane) 3 (pane) 0:fish-dev.1 (session:window.pane) 0:fish-dev.3 (session:window.pane)
```
Note that the "before" version describes the same 3 panes several times
in a row, and all the entries involving "fish-dev" are suspect since
there could be another "fish-dev" window (or, more likely, this window
and others could all be named "fish").
Closes#11115
There are some minor updates.
Also, the syntax seems to have changed in tmux 2.4 in 2017,
ef68debc8d/CHANGES (L1484)
Notably, many of the key table commands now use `-T` in place of
the correct `-t`, and the list of key binding tables has changed.
Our versions look like
4.0.0
4.0b1
4.0.1-535-abfef-dirty
But packagers may want to add more information here, and we don't
really care. Note that we no longer ever set the version to "unknown"
since 5abd0e46f5.
Supersedes #11173
Commit 29dc307111 (Insert some completions with quotes instead of backslashes,
2024-04-13) breaks some workflows. Given
touch '[test] file1'
touch '[test] file2'
ls tes<Tab>
we insert completions quoted, which is inconvenient when using globs.
This implicit quoting feature is somewhat minor. But quotes look nicer,
so let's try to keep them. Either way, users can ask for it by starting a
token with «"».
Use quoting only when we insert unique completions.
Closes#11271
This effectively disables "--help", replacing it with just a stand-in
string.
The upshot is that it makes the test suite immune to whether or not it
can find the documentation - until now it needed to *not* find it,
which is weird.
(also it saves some useless lines)
Fixes#11270
Looks like the github actions image now has ninja installed.
This causes a failure; we effectively do
$ (
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo
)
$ make VERBOSE=1
[...]
cd build; cmake .. -G "Ninja" \
-DCMAKE_INSTALL_PREFIX="/usr/local" -DCMAKE_EXPORT_COMPILE_COMMANDS=1
Re-run cmake no build system arguments
CMake Error: Error: generator : Ninja
Does not match the generator used previously: Unix Makefiles
Either remove the CMakeCache.txt file and CMakeFiles directory or choose a different binary directory.
"make" fails because it runs from top-level, with GNUMakefile's logic to
use -GNinja if available. This is at odds with the direct cmake invocation,
which defaults to -G'Unix Makefiles'.
We shouldn't mix direct cmake invocation and the top-level Makefiles, so
run make from the build directory instead.
While at it, update some test invocations missed in 8d6fdfd9de
(Remove cmake "test" target, 2025-02-02). This should
help avoid missing test failure output in CI, see
https://github.com/fish-shell/fish-shell/issues/11116#issuecomment-2629406479
(cherry picked from commit b0be53ed6a)
The new cursor-end-mode "inclusive" (which is active in Vi mode) is causing
many issues.
One of them is because cancel-commandline wants to move to the end of the
command line before printing "^C". Since "inclusive" cursor mode prevents
the cursor from moving past the last character, that one will be overwritten
with a "^". Hack around this.
Closes#11261
(cherry picked from commit b08ff33291)
The new cursor-end-mode "inclusive" (which is active in Vi mode) is causing
many issues.
One of them is because cancel-commandline wants to move to the end of the
command line before printing "^C". Since "inclusive" cursor mode prevents
the cursor from moving past the last character, that one will be overwritten
with a "^". Hack around this.
Closes#11261
Running
fish_vi_key_bindings
fish_default_key_bindings
ought to maintain cursor shape, at least in the default configuration,
so let's do that.
Fixes 9ef76860e6 (Default Vi cursor shapes for insert/replace mode, 2024-10-26).
Looks like the github actions image now has ninja installed.
This causes a failure; we effectively do
$ (
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo
)
$ make VERBOSE=1
[...]
cd build; cmake .. -G "Ninja" \
-DCMAKE_INSTALL_PREFIX="/usr/local" -DCMAKE_EXPORT_COMPILE_COMMANDS=1
Re-run cmake no build system arguments
CMake Error: Error: generator : Ninja
Does not match the generator used previously: Unix Makefiles
Either remove the CMakeCache.txt file and CMakeFiles directory or choose a different binary directory.
"make" fails because it runs from top-level, with GNUMakefile's logic to
use -GNinja if available. This is at odds with the direct cmake invocation,
which defaults to -G'Unix Makefiles'.
We shouldn't mix direct cmake invocation and the top-level Makefiles, so
run make from the build directory instead.
While at it, update some test invocations missed in 8d6fdfd9de
(Remove cmake "test" target, 2025-02-02). This should
help avoid missing test failure output in CI, see
https://github.com/fish-shell/fish-shell/issues/11116#issuecomment-2629406479
Since commit 0627c9d9af (Render control characters as Unicode Control Pictures,
2020-08-29), we render control character in the commandline as "␇" etc.
They can be inserted via either history search, or bindings such as
bind ctrl-g "commandline -i \a"
That commit incorrectly assumes that the prompt is rendered the same way as
the command line (which goes through "ScreenData" etc).
This is wrong -- prompt text is written to stdout as-is, and a prompt that
outputs \t (tab) or \a (BEL) is valid. The wrong assumption means that we
overestimate the width of prompts containing control characters.
(For some reason, after switching from Vi insert to Vi normal mode, we seem
to get the width right which means the command line jumps around)
Let's revert to the old width computation for any prompt text.
Closes#11252
(cherry picked from commit 4d81cf8af4)
Since commit 0627c9d9af (Render control characters as Unicode Control Pictures,
2020-08-29), we render control character in the commandline as "␇" etc.
They can be inserted via either history search, or bindings such as
bind ctrl-g "commandline -i \a"
That commit incorrectly assumes that the prompt is rendered the same way as
the command line (which goes through "ScreenData" etc).
This is wrong -- prompt text is written to stdout as-is, and a prompt that
outputs \t (tab) or \a (BEL) is valid. The wrong assumption means that we
overestimate the width of prompts containing control characters.
(For some reason, after switching from Vi insert to Vi normal mode, we seem
to get the width right which means the command line jumps around)
Let's revert to the old width computation for any prompt text.
Closes#11252
For unknown reasons this assertion fails. This means that 1b9b893169 (After
reading corrupted history entry, keep reading older entries, 2024-10-06)
is not fully working. Go back to historical behavior for now.
Closes#11236
(cherry picked from commit 4f80e5cb54)
See f2dde229aa (Revert changes to restore cursor position after undo,
2025-03-05).
I think there are two problems with tmux when doing a final redraw of a
larger-than-screen commandline. One is easy to trigger independent of
f2dde229aa. The other is reproduced by the broken output in the tmux test
removed by that commit. Should root-cause them later.
Use a hack for now; this also happens to fix the broken output in tmux.
For unknown reasons this assertion fails. This means that 1b9b893169 (After
reading corrupted history entry, keep reading older entries, 2024-10-06)
is not fully working. Go back to historical behavior for now.
Closes#11236
Midnight Commander 4.8.33 knows how to read the CSI u encoding of ctrl-o
(which is the only key it reads while the shell is in control). But it fails
to when numlock or capslock is active. Let's disable the kitty keyboard
protocol again until mc indicates that this is fixed.
Closes#10640
The other issue talked about in that issue is an unrelated mc issue, see
https://github.com/MidnightCommander/mc/issues/4597#issuecomment-2705900024
* completions/flatpak: don't ignore packages with uppercase in name
`[^A-Z]+` here seems to trim header section in old version flatpak (avoid one
more `tail -n -2`?) but this can ignore packages have uppercase name like
`org.gtk.Gtk3theme.Adwaita-dark`.
* completions/flatpak: use cached `__fish_print_flatpak_packages` for `flatpak install`
rustup has changed its output for 'rustup toolchain list --verbose`.
Teach FindRust.cmake about it, so that it may shamble on.
Cherry-picked from b38551dde9
rustup has changed its output for 'rustup toolchain list --verbose`.
Teach FindRust.cmake about it, so that it may shamble on.
This was reported against BSD and also affects macOS and ALSO affects Linux; our
CI just doesn't have a new enough rustup. Anyways we can't have nice things.
This feature is nice and desirable, but it was implemented in a intrusive way
by modifying the sequence of bytes we emit when running a command; this in
turn requires changing a bunch of tests.
This sequence hasn't changed in decades and the consequences of changing it
are hard to predict, given that it is likely terminal dependent; we've
already found a regression.
It's fine to reintroduce this but it should be done in a less intrusive way
(conceptually that seems straightforward - we're just remembering the cursor
position).
Revert "Fix spurious blank lines when executing scrolled commandline"
This reverts commit 0e512f8033.
Revert "On undo after execute, restore the cursor position "
This reverts commit 610338cc70.
Most versions of fish don't run any external processes at startup, except
maybe fish_vcs_prompt. This changed recently with a couple additions of uname.
This is probably fine but I guess we can reduce it down to one.
This change feels somewhat wrong. Not sure. I guess we can remove it once
we provide $OSTYPE.
Note that this is also the reason why bindings don't use
bind alt-backspace 'if test "$(uname)" = Darwin ...'
We don't want to expose a private interface in "bind" output.
This fails with:
```
CMake Warning (dev) at cmake/FindRust.cmake:349 (message):
Unexpected output from `rustc --version` for Toolchain
`stable-x86_64-unknown-freebsd`: ``.
Ignoring this toolchain.
Call Stack (most recent call first):
cmake/Rust.cmake:5 (include)
CMakeLists.txt:24 (include)
This warning is for project developers. Use -Wno-dev to suppress it.
-- Rust Toolchain:
CMake Warning at cmake/FindRust.cmake:31 (message):
The rustc executable was not found. Rust not installed or ~/.cargo/bin not
added to path?
Hint: Consider setting `Rust_COMPILER` to the absolute path of `rustc`.
```
For some reason? Disable it for now until someone figures out what's
going on
Commit 6af96a81a8 (Default bindings for token movement commands, 2024-10-05)
has been reverted but not all docs have been.
Key bindings to move by command line argument are quite intuitive, and useful
when moving across URLs or other long arguments.
We have redundant bindings like {alt,ctrl}-left, so let's use one of them
for token movement. We don't want to break the OS-native shortcut for word
movement, so use the other one on the current platform.
Note that Sublime Text does something similar: it uses the native key
binding for word movement, and the vacant one (e.g. `alt-left` on Linux)
for sub-word movement in camel case words.
While there have been 2.5 votes against making this platform dependent,
the majority of feedback was in favor.
This uses uname which seems wrong; we should rather use the OS that the
terminal is running on. I plan to implement this in future, but there's no
consensus yet on whether terminal applications should be allowed to do this.
See #10926
See #11107
Ever since 149594f974 (Initial revision, 2005-09-20), we move the
cursor to the end of the commandline just before executing it.
This is so we can move the cursor to the line below the command line,
so moving the cursor is relevant if one presses enter on say, the
first line of a multi-line commandline.
As mentioned in #10838 and others, it can be useful to restore the
cursor position when recalling commandline from history. Make undo
restore the position where enter was pressed, instead of implicitly
moving the cursor to the end. This allows to quickly correct small
mistakes in large commandlines that failed recently.
This requires a new way of moving the cursor below the command line.
Test changes include unrelated cleanup of history.py.
(cherry picked from commit 610338cc70)
(cherry picked from commit 0e512f8033)
As reported on gitter, fish running inside a qemu console randomly fails to
recognize multi-byte sequences like "\e[D" (right); it sometimes recognizes
the first two bytes as "alt-[" and the last byte as the "D" key.
This because 8bf8b10f68 (Extended & human-friendly keys, 2024-03-30) changed
our approach to reading multi-byte key sequences. Previously, we'd wait
forever (or rather fish_sequence_key_delay_ms) for the "D" byte.
As of 8bf8b10f68, we assume the entire sequence is already present in the
input buffer; and stop parsing the sequence if stdin is not readable.
It would be more technically correct to implement the VT state machine but
then we'd probably want to to figure out a timeout or a reset key, in case
of transport or terminal issues.
Returning early is also what we have historically done for multi-byte code
points. Also, other terminal programs have been using it for many years
without problems.
I don't know why this happens in qemu but it seems we can work around by
setting a 1ms timeout. This timeout should be small enough two keys "escape"
and "[" typed by a human will still be seen separate.
Refs:
https://matrix.to/#/!YLTeaulxSDauOOxBoR:matrix.org/$Cfi9wL8FGLAI6_VAQWG2mG_VxsADUPvdPB46P41Jdbshttps://matrix.to/#/!YLTeaulxSDauOOxBoR:matrix.org/$O_-LZ1W7Dk6L_4Rj0MyCry6GtO2JQlEas8fH9PrSYT8
(cherry picked from commit e1be842167)
As reported on gitter, fish running inside a qemu console randomly fails to
recognize multi-byte sequences like "\e[D" (right); it sometimes recognizes
the first two bytes as "alt-[" and the last byte as the "D" key.
This because 8bf8b10f68 (Extended & human-friendly keys, 2024-03-30) changed
our approach to reading multi-byte key sequences. Previously, we'd wait
forever (or rather fish_sequence_key_delay_ms) for the "D" byte.
As of 8bf8b10f68, we assume the entire sequence is already present in the
input buffer; and stop parsing the sequence if stdin is not readable.
It would be more technically correct to implement the VT state machine but
then we'd probably want to to figure out a timeout or a reset key, in case
of transport or terminal issues.
Returning early is also what we have historically done for multi-byte code
points. Also, other terminal programs have been using it for many years
without problems.
I don't know why this happens in qemu but it seems we can work around by
setting a 1ms timeout. This timeout should be small enough two keys "escape"
and "[" typed by a human will still be seen separate.
Refs:
https://matrix.to/#/!YLTeaulxSDauOOxBoR:matrix.org/$Cfi9wL8FGLAI6_VAQWG2mG_VxsADUPvdPB46P41Jdbshttps://matrix.to/#/!YLTeaulxSDauOOxBoR:matrix.org/$O_-LZ1W7Dk6L_4Rj0MyCry6GtO2JQlEas8fH9PrSYT8
As reported in
https://matrix.to/#/!YLTeaulxSDauOOxBoR:matrix.org/$yD_Lutaftf6ytk617kjw5vC-k_OgHRQxIiSRv89uBMI
it's weird that command name completions shadow abbreviation name
completions, given that the abbreviation will the one that will be
executed in the typical cases. Let's put abbreviation completions first;
unique_completions_retaining_order() will take care of removing any command
completions we add later.
When a command like "long-running-command &" exits, the resulting SIGCHLD
is queued in the topic monitor. We do not process this signal immediately
but only after e.g. the next command has finished. Only then do we reap the
child process.
Some terminals, such as Terminal.app, refuse to close when there are unreaped
processes associated with the terminal -- as in, having the same session ID,
see setsid(3).
In future, we might want to reap proactively.
For now, apply an isolated workaround: instead of taking care of a child
process, double-fork to create an orphaned process. Since the orphan will
be reaped by PID 1, we can eventually close Terminal.app without it asking
for confirmation.
/bin/sh -c '( "$@" ) >/dev/null 2>&1 &' -- cmd arg1 arg2
This fix confines the problem to the period during which a background process
is running. To complete the fix, we would need to call setsid to detach the
background process from a controlling terminal. That seems to be desirable
however macOS does provide a setsid utility.
setsid cmd arg1 arg2 >/dev/null 2>&1
Fixes#11181
(cherry picked from commit e015956de7)
When a command like "long-running-command &" exits, the resulting SIGCHLD
is queued in the topic monitor. We do not process this signal immediately
but only after e.g. the next command has finished. Only then do we reap the
child process.
Some terminals, such as Terminal.app, refuse to close when there are unreaped
processes associated with the terminal -- as in, having the same session ID,
see setsid(3).
In future, we might want to reap proactively.
For now, apply an isolated workaround: instead of taking care of a child
process, double-fork to create an orphaned process. Since the orphan will
be reaped by PID 1, we can eventually close Terminal.app without it asking
for confirmation.
/bin/sh -c '( "$@" ) >/dev/null 2>&1 &' -- cmd arg1 arg2
This fix confines the problem to the period during which a background process
is running. To complete the fix, we would need to call setsid to detach the
background process from a controlling terminal. That seems to be desirable
however macOS does provide a setsid utility.
setsid cmd arg1 arg2 >/dev/null 2>&1
Fixes#11181
As of 303af07, iTerm2 3.5.11 on two different machines has two different
behaviors. For unknown reasons, when pressing alt-right fish_key_reader
shows "\e\[1\;9C" on one machine and "\e\[1\;3C" on another.
Feels like iTerm2 interprets modifyOtherKeys differently, depending on
configuration.
We don't want to risk asking for the kitty
keyboard protocol until iTerm2 3.5.12 (see
https://github.com/fish-shell/fish-shell/issues/11004#issuecomment-2571494782).
So let's work around around this weirdness by adding back the legacy
bindings removed in c0bcd817ba (Remove obsolete bindings, 2024-04-28) and
plan to remove them in a few years.
Note that fish_key_reader still reports this as "left", which already has
a different binding, but it looks like literal matches of legacy sequences
have precedence.
Fixes the problem described in
https://github.com/fish-shell/fish-shell/issues/11192#issuecomment-2692247060Closes#11192
(cherry picked from commit 44d5abdc05)
Before 798527d79a (completions: fix double evaluation of tokenized commandline, 2024-01-06)
git-foo completions did something like
set -l subcommand_args (commandline -opc)
complete -C "git-foo $subcommand_args "
As mentioned in 368017905e (builtin commandline: -x for expanded tokens,
supplanting -o, 2024-01-06), the "-o" option is bad
because it produces a weird intermediate, half-expanded state.
The immediate goal of 798527d79a was to make sure we do not do any
more expansion on top of this. To that end, it changed the above to
"\$subcommand_args". The meaning is more or less the same[^*] but crucially,
the recursive completion invocation does not see through the variable,
which breaks some completions.
Fix this with the same approach as in 6b5ad163d3 (Fix double expansion of
tokenized command line, 2025-01-19).
[^*]: It wasn't semantically correct before or after -- this was later
corrected by 29f35d6cdf (completion: adopt commandline -x replacing deprecated
-o, 2024-01-22)).
Closes#11205
(cherry picked from commit 50e595503e)
As of 303af07, iTerm2 3.5.11 on two different machines has two different
behaviors. For unknown reasons, when pressing alt-right fish_key_reader
shows "\e\[1\;9C" on one machine and "\e\[1\;3C" on another.
Feels like iTerm2 interprets modifyOtherKeys differently, depending on
configuration.
We don't want to risk asking for the kitty
keyboard protocol until iTerm2 3.5.12 (see
https://github.com/fish-shell/fish-shell/issues/11004#issuecomment-2571494782).
So let's work around around this weirdness by adding back the legacy
bindings removed in c0bcd817ba (Remove obsolete bindings, 2024-04-28) and
plan to remove them in a few years.
Note that fish_key_reader still reports this as "left", which already has
a different binding, but it looks like literal matches of legacy sequences
have precedence.
Fixes the problem described in
https://github.com/fish-shell/fish-shell/issues/11192#issuecomment-2692247060Closes#11192
Before 798527d79a (completions: fix double evaluation of tokenized commandline, 2024-01-06)
git-foo completions did something like
set -l subcommand_args (commandline -opc)
complete -C "git-foo $subcommand_args "
As mentioned in 368017905e (builtin commandline: -x for expanded tokens,
supplanting -o, 2024-01-06), the "-o" option is bad
because it produces a weird intermediate, half-expanded state.
The immediate goal of 798527d79a was to make sure we do not do any
more expansion on top of this. To that end, it changed the above to
"\$subcommand_args". The meaning is more or less the same[^*] but crucially,
the recursive completion invocation does not see through the variable,
which breaks some completions.
Fix this with the same approach as in 6b5ad163d3 (Fix double expansion of
tokenized command line, 2025-01-19).
[^*]: It wasn't semantically correct before or after -- this was later
corrected by 29f35d6cdf (completion: adopt commandline -x replacing deprecated
-o, 2024-01-22)).
Closes#11205
Given
$ cat ~/.config/kitty/kitty.conf
notify_on_cmd_finish unfocused 0.1 command notify-send "job finished with status: %s" %c
kitty will send a notification whenever a long-running (>.1s) foreground
command finishes while kitty is not focused.
The %c placeholder will be replaced by the commandline.
This is passed via the OSC 133 command start marker, kitty's fish shell
integration.
That integration has been disabled for fish 4.0.0 because it's no longer
necessary since fish already prints OSC 133. But we missed the parameter for
the command string. Fix it. (It's debatable whether the shell or the terminal
should provide this feature but I think we should fix this regression?)
Closes#11203
See https://github.com/kovidgoyal/kitty/issues/8385#issuecomment-2692659161
(cherry picked from commit 4378e73fc7)
Something like
write!(f, "foo{}bar", ...)
seems to call f.write_str() thrice.
Splitting a single OSC 133 command into three calls to write(3) might result in
odd situations if one of them fails. Let's try to do it in one in most cases.
Add a new buffered output type that can be used with write!(). This is
somewhat redundant given that we have scoped_buffer(). While at it, remove
the confused error handling. This doesn't fail unless we are OOM (and this
new type makes that more obvious).
(cherry picked from commit e5e932e970)
Given
$ cat ~/.config/kitty/kitty.conf
notify_on_cmd_finish unfocused 0.1 command notify-send "job finished with status: %s" %c
kitty will send a notification whenever a long-running (>.1s) foreground
command finishes while kitty is not focused.
The %c placeholder will be replaced by the commandline.
This is passed via the OSC 133 command start marker, kitty's fish shell
integration.
That integration has been disabled for fish 4.0.0 because it's no longer
necessary since fish already prints OSC 133. But we missed the parameter for
the command string. Fix it. (It's debatable whether the shell or the terminal
should provide this feature but I think we should fix this regression?)
Closes#11203
See https://github.com/kovidgoyal/kitty/issues/8385#issuecomment-2692659161
Something like
write!(f, "foo{}bar", ...)
seems to call f.write_str() thrice.
Splitting a single OSC 133 command into three calls to write(3) might result in
odd situations if one of them fails. Let's try to do it in one in most cases.
Add a new buffered output type that can be used with write!(). This is
somewhat redundant given that we have scoped_buffer(). While at it, remove
the confused error handling. This doesn't fail unless we are OOM (and this
new type makes that more obvious).
modifyOtherKeys with non-English or other non-default keyboard layouts will
cause wrong keys to be sent by WezTerm. Let's try to disable it for now.
Proposed upstream fix: https://github.com/wezterm/wezterm/pull/6748Closes#11204
wine can be used, and is usually used for things like `wine
setup.exe`,
so it should allow for regular file completion.
Fixes#11202
(cherry picked from commit 86e531b848)
This was broken for 4.0 because it used `{}` command grouping.
Instead just do one of the things the fish_git_prompt does.
(the default isn't usable here because it gets the sha from elsewhere)
(cherry picked from commit e925eccad2)
This was broken for 4.0 because it used `{}` command grouping.
Instead just do one of the things the fish_git_prompt does.
(the default isn't usable here because it gets the sha from elsewhere)
Fix the accidental "git branch" output leaking while making sure we support:
1. unborn branch, where HEAD does not exist (`git init`)
2. detached head (`git checkout --detach`)
Notably computing the branch name should be independent of computing
a diff against HEAD.
In scenario 1 there is a branch but no HEAD,
while in scenario 2 it's the other way round.
Hence we need a separate check to see if we're in a git repo.
"git rev-parse" seems to work. Not sure what's best pracitce.
Also remove the ahead/behind logic, it was broken because it misspelled
@{upstream}.
Fixes#11179
(cherry picked from commit 7b7e744353)
Fix the accidental "git branch" output leaking while making sure we support:
1. unborn branch, where HEAD does not exist (`git init`)
2. detached head (`git checkout --detach`)
Notably computing the branch name should be independent of computing
a diff against HEAD.
In scenario 1 there is a branch but no HEAD,
while in scenario 2 it's the other way round.
Hence we need a separate check to see if we're in a git repo.
"git rev-parse" seems to work. Not sure what's best pracitce.
Also remove the ahead/behind logic, it was broken because it misspelled
@{upstream}.
Fixes#11179
As reported in
https://matrix.to/#/!YLTeaulxSDauOOxBoR:matrix.org/$CLuoHTdvcRj_8-HBBq0p-lmGWeix5khEtKEDxN2Ulfo
Running
fish -C '
fzf_key_bindings
echo fish_vi_key_bindings >>~/.config/fish/config.fish
fzf-history-widget
'
and pressing "enter" will add escape sequences like "[2 q" (cursor shape)
to fish's command line.
This is because fzf-history-widget binds "enter" to a filter
that happens to be a fish script:
set -lx FZF_DEFAULT_OPTS \
... \
"--bind='enter:become:string replace -a -- \n\t \n {2..} | string collect'" \
'--with-shell='(status fish-path)\\ -c)
The above ~/.config/fish/config.fish (redundantly) runs "fish_vi_key_bindings"
even in *noninteractive* shells, then "fish_vi_cursor" will print cursor
sequences in its "fish_exit" handler. The sequence is not printed to the
terminal but to fzf which doesn't parse CSI commands.
This is a regression introduced by a5dfa84f73 (fish_vi_cursor: skip if stdin
is not a tty, 2023-11-14). That commit wanted "fish -c read" to be able to
use Vi cursor. This is a noninteractive shell, but inside "read" we are
"effectively interactive". However "status is-interactive" does not tell
us that.
Let's use a more contained fix to make sure that we print escape sequences only
if either fish is interactive, or if we are evaluating an interactive read.
In general, "fish -c read" is prone to configuration errors, since we
recommend gating configuration (for bind etc) on "status is-interactive"
which will not run here.
(cherry picked from commit 495083249b)
As reported in
https://matrix.to/#/!YLTeaulxSDauOOxBoR:matrix.org/$CLuoHTdvcRj_8-HBBq0p-lmGWeix5khEtKEDxN2Ulfo
Running
fish -C '
fzf_key_bindings
echo fish_vi_key_bindings >>~/.config/fish/config.fish
fzf-history-widget
'
and pressing "enter" will add escape sequences like "[2 q" (cursor shape)
to fish's command line.
This is because fzf-history-widget binds "enter" to a filter
that happens to be a fish script:
set -lx FZF_DEFAULT_OPTS \
... \
"--bind='enter:become:string replace -a -- \n\t \n {2..} | string collect'" \
'--with-shell='(status fish-path)\\ -c)
The above ~/.config/fish/config.fish (redundantly) runs "fish_vi_key_bindings"
even in *noninteractive* shells, then "fish_vi_cursor" will print cursor
sequences in its "fish_exit" handler. The sequence is not printed to the
terminal but to fzf which doesn't parse CSI commands.
This is a regression introduced by a5dfa84f73 (fish_vi_cursor: skip if stdin
is not a tty, 2023-11-14). That commit wanted "fish -c read" to be able to
use Vi cursor. This is a noninteractive shell, but inside "read" we are
"effectively interactive". However "status is-interactive" does not tell
us that.
Let's use a more contained fix to make sure that we print escape sequences only
if either fish is interactive, or if we are evaluating an interactive read.
In general, "fish -c read" is prone to configuration errors, since we
recommend gating configuration (for bind etc) on "status is-interactive"
which will not run here.
Historically, up-arrow search matches have been highlighted by
1. using the usual foreground (from syntax highlighting)
2. using the background from $fish_color_search_match
Commit 9af6a64fd2 (Fix bad contrast in search match highlighting, 2024-04-15)
broke this by also applying the foreground from $fish_color_search_match.
As reported on gitter, there is a meaningful scenario where the foreground
from syntax highlighting should not be overwritten:
set fish_color_search_match --reverse
this copies the foreground from syntax highlighting to the background.
Since commit 9af6a64fd2 overwrites the foreground highlight, the resulting
background will be monocolored (black in my case) instead of whatever is
the syntax-colored foreground.
FWIW the reversed foreground will always be monocolored, because we have
always done 2.
Let's unbreak this scenario by using the foreground from
fish_color_search_match only if it's explicitly set (like we do since
9af6a64fd2).
This is hacky because an empty color is normally the same as "normal", but
it gets us closer to historical behavior. In future we should try to come
up with a better approach to color blending/transparency.
(cherry picked from commit b6269438e9)
Historically, up-arrow search matches have been highlighted by
1. using the usual foreground (from syntax highlighting)
2. using the background from $fish_color_search_match
Commit 9af6a64fd2 (Fix bad contrast in search match highlighting, 2024-04-15)
broke this by also applying the foreground from $fish_color_search_match.
As reported on gitter, there is a meaningful scenario where the foreground
from syntax highlighting should not be overwritten:
set fish_color_search_match --reverse
this copies the foreground from syntax highlighting to the background.
Since commit 9af6a64fd2 overwrites the foreground highlight, the resulting
background will be monocolored (black in my case) instead of whatever is
the syntax-colored foreground.
FWIW the reversed foreground will always be monocolored, because we have
always done 2.
Let's unbreak this scenario by using the foreground from
fish_color_search_match only if it's explicitly set (like we do since
9af6a64fd2).
This is hacky because an empty color is normally the same as "normal", but
it gets us closer to historical behavior. In future we should try to come
up with a better approach to color blending/transparency.
(This regressed in version 4 which sends OSC 7 to all terminals)
Konsole has a bug: it does not recognize file:://$hostname/path as directory.
When we send that via OSC 7, that breaks Konsole's "Open Folder With"
context menu entry.
OSC 7 producers are strongly encouraged to set a non-empty hostname, but
it's not clear if consumers are supposed to accept an empty hostname (see
https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/20).
I think it should be fine; implementations should treat it as local path.
Let's work around the Konsole bug by omitting the hostname for now. This
may not be fully correct when using a remote desktop tool to access a
system running Konsole but I guess that's unlikely and understandable.
We're using KONSOLE_VERSION, so it the workaround should not leak into SSH
sessions where a hostname component is important.
Closes#11198
Proposed upstream fix https://invent.kde.org/frameworks/kio/-/merge_requests/1820
(cherry picked from commit c926a87bdb)
Konsole has a bug: it does not recognize file:://$hostname/path as directory.
When we send that via OSC 7, that breaks Konsole's "Open Folder With"
context menu entry.
OSC 7 producers are strongly encouraged to set a non-empty hostname, but
it's not clear if consumers are supposed to accept an empty hostname (see
https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/20).
I think it should be fine; implementations should treat it as local path.
Let's work around the Konsole bug by omitting the hostname for now. This
may not be fully correct when using a remote desktop tool to access a
system running Konsole but I guess that's unlikely and understandable.
We're using KONSOLE_VERSION, so it the workaround should not leak into SSH
sessions where a hostname component is important.
Closes#11198
Proposed upstream fix https://invent.kde.org/frameworks/kio/-/merge_requests/1820
As reported in b5736c5535 (Extend iTerm CSI u workaround to < 3.5.12,
2025-02-20), iTerm 3.5.12 has resolved our issues related to the kitty
keyboard protocol. Enable it here too, matching the release branch.
The flag to gate this is set for versions of iTerm that don't have sufficient
support for the kitty keyboard protocol. CSI u is (more or less) the encoding
used by that protocol. Let's name things accordingly. My bad.
Commit 2d234bb676 (Only request keyboard protocols once we know if kitty kbd
is supported, 2025-01-26) queries support for the kitty protocol and acted
upon it after having read next character.
Unfortunately this meant that we don't turn on the kitty protocol until after
we read a character -- since the CSI ? u response does not generate a char
event. Let's query for primary DA additionally, matching what fish does.
In future, we should do a timed wait as well, to avoid terminal responses
leaking when there we exit fish_key_reader too quickly.
Whenever we add logic to print a control sequence that we hadn't printed
before, there is a nonzero risk that a terminal mishandles it.
Terminal-specific workarounds cause pain but are probably better than not
being able to use any new commands provided by terminals.
There is no universal way to identify a terminal. Device attributes (primary
through tertiary) typically get spoofed responses, likely not good enough
for working around bugs in specific versions of a terminal.
The de-facto standard for the terminal name and version is XTVERSION.
It's usually specific to the terminal, except for something like VTE-based
terminals, where we get this (which seems good enough also)
printf '\x1b[>0q'; cat
^[P>|VTE(7803)^[\
Of course querying for XTVERSION can trigger terminal bugs just as well. Let's
start querying for it now -- even without a concrete use case -- to increase
the chance we can use it during crunch time when we don't want to test
anymore. (We typically discover buggy terminals only very late in the release
cycle, most prominently after a release).
When we enable/disable terminal protocols,
we use atomic operations because of issues like
1. halfway through enabling, we might be interrupted by a signal handler.
2. our SIGTERM handler runs the (idempotent) disabling sequences,
so the operations must be async-signal safe.
The flags to keep track of whether things like kitty keyboard protocol are enabled
are "mirrored" between the enabling and disabling logic:
- the enabling logic marks it as enabled *before* enabling anything
- the disabling logic marks it as disabled *after* everything has been disabled
This ensures that we are well-behaved in issue 1; we will always (perhaps
redundantly) disable the kitty keyboard protocol.
We forgot to use the same ordering for bracketed paste.
If we get SIGTERM after this line
BRACKETED_PASTE.store(false, Ordering::Release);
we might exit with bracketed paste still turned on.
Code blocks are often written like
$ echo hello world
hello world
The "$ " is widely understood to introduce a shell command. It's often
easier to copy the whole line than copying everything after "$ ".
This gets more pronounced when there are multiple commands without interleaved
output (either due to omission or the rule of silence). Copying the whole
code block is the most natural first step.
You could argue that this is a presentation issue - the dollar prefix
should be rendered but not copied to clipboard. But in my experience there
are many cases where there is no HTML or Javascript that would allow the
copy-to-clipboard functionality to strip the prefixes.
The "$ " prefix is almost never useful when pasting; strip it automatically.
Privileged commands use "# " as prefix which overlaps with comments, so do
not strip that until we can disambiguate (another potential reason not to
do that would be safety but it's unclear if that really matters).
Add the new logic to the commandline builtin, because we don't know about the
AST in fish script. (Technically, the tokenizer already knows whether a "$
" is in command position and at the beginning of a line, but we don't
have that either (yet).)
Maybe we should move the rest of __fish_paste over as well. I'm not sure what
difference that would make; for one, pasting could no longer be cancelled
by ctrl-c (in theory), which seems like a good direction?
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
(cherry picked from commit 378f452eaa)
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)
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
These are supposed to be small, so we dump the redundant fish_indent
and fish_key_reader - the fish binary can do those jobs too (both as
builtins and if called via symlinks of that name).
We still keep tarballs instead of just compressing so that we have a
file called "fish" and not "fish-amd64-linux"
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)
Commit 82c4896809 (Fix unnecessary undo when exiting the history
pager with an empty cmd and no matches, 2025-02-02) was a nice fix
but failed to account for the code path where we switch from history
search to completion pager (and maybe also the inverse case). In this
case we don't want to undo the transient edit but commit it instead.
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.
Missed write_to_fd calls
Not in 4.0 because fish_indent isn't a builtin there.
This requires str2wcstring, which is awkward but it's not performance-sensitive.
Fixes#11146
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)
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.
e697add5b5 (Feature flag to prevent executing off buffered keys, 2025-01-02)
breaks my expectations/habits, and it breaks Midnight Commander.
Additionally, I'm not aware of any case where it actually adds security.
We generally assume that terminal echoback sequences do not contain
control characters except for well-known escape sequences.
This backs out commit e697add5b5.
See #10987, #10991
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
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
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.
Closes#11105
Add back the test from 0e512f8033 (Fix spurious blank lines when
executing scrolled commandline, 2025-01-08).
It's flaky in CI (see b8208d72f7 (Remove test for broken tmux output,
2025-01-09)) but that's not a problem for now because we disabled
the entire test CI in 2508cc9de6 (Disable some more tests under CI,
2025-01-14).
Commit c54131c8c5 (Make at least one character of the autosuggestion
always shown, 2025-01-26) draws autosuggetion until exactly the end
of the line, possibly truncated by an ellipsis. The line is "barely"
soft-wrapped; no characters or cursors are on the next line.
This means that the pager can start there (on the next line).
The calculation for available pager height fails to recognize that.
Fix that.
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
Prior to this change, wcstod_underscores would create a "pruned" string without
underscores, and then parse that. Switch instead to a filtered Iterator, which
can ignore underscores as it traverses the string.
Add a test that completes in a reasonable time only if wcstod_underscores is not
quadratic.
(cherry picked from commit b4577c10e5cf9239bc93c605f431a56d98266a1e)
Currently, when the history pager is selected, fish always one undo away from the original search term. If the search has no matches, the fish replaces the search term with itself (resulting in no visible change, but it is still treated as a transient edit). However, fish ignores undo operations where the replacement is "" by "", leading to an unnecessary undo. For example:
1. Type 'test'.
2. Do ctrl-c.
3. Open the history pager.
4. Make so there are no matches.
5. Exit - you will undo back to 'test'.
This commit also ensures that if you select a pager element that does not change the content of the commandline, it will not be added to the undo history.
Currently, if we return to the present, fish thinks that it still has a transient edit. This results in an unnecessary undo when performing a backward search. For example:
1. Type ': '.
2. Do a backward token search.
3. Do a forward token search.
4. Do another backward token search - this will result in the undo of ': '.
Currently, the search always restarts when moving from the present.
For example:
1. Do a few backward searches.
2. Use PageDown to return to the present.
3. Do another backward search.
4. Now, PageUp does nothing because the search was restarted, even if we maintained search mode.
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)
This adds the ability to complete (and therefore preview) buffer names,
and adds incomplete (aiming to maximize utility/effort, similarly to
b1064ac) bindings to the `tmux` buffer commands.
The main benefit is, IMO, is the tab completion for `tmux paste-buffer
-b` and `tmux show-buffer -b`.
Every reader gets their own wait handle which is wrong and not actually
needed - it's a singleton. We should probaly make it global. Let's
do an intermediate solution for now -- not much time this weekend ;).
Fixes#11110
There is no guarantee that Write::write() will write the entirety of the
provided buffer in one go, regardless of how short it is, because that depends
on the semantics of the underlying write handle (even if it was a
single byte, though in this case that would be because of an interrupt).
The only case I'm aware of that would guarantee a single Write::write() call
would suffice is when writing into a high-level memory-backed buffer, and we
can't make that guarantee (now or in perpetuity).
The current limit can be reached in actual use and still be a usable shell.
E.g. in #11095 someone had `git status` print over 100MiB of file
information.
This isn't propagated correctly:
If $fish_read_limit is set globally, it won't apply to the completion
command substitution, *unless* you set fish_read_limit inside of that
function.
I'm not entirely sure how that happens, but let's work around it for
now by removing that limit.
I'm going to increase the default limit in a future commit, because
it's not something supposed to be reachable in ordinary code.
See #11106
Previously, there were situations where an autosuggestion existed but was not shown at all. This commit guarantees that at least the `ellipsis_char` is shown, regardless of the situation.
This commit ensures that autosuggestions cannot soft wrap. Previous behavior:
- If the first line is not soft wrapped, the autosuggestion will be truncated and not shown on soft-wrapped lines.
- If the first line is soft-wrapped, the autosuggestion will not have any limit.
The right prompt was rendered even if scrolled.
The command line wasn't rendering on the first line, starting from 0 to the left prompt length. Steps to reproduce:
fish -C 'bind ctrl-g \'commandline $(printf %0"$(math $COLUMNS)"d0) $(seq $(math $LINES - 1))\''
# use ctrl-g
# observe that only one '0' is rendered
When drawing a soft wrapped line, the last 2 characters of the previous line are redrawn. If these 2 characters are occupied by the prompt, they are replaced with ' '.
Steps to reproduce:
fish -C 'function fish_prompt; printf %0"$(math $COLUMNS)"d 0; end'
# type anything
# observe that the last two characters of the prompt have been deleted
We need to add a line to the desired screen if the previous line was full or non-existent to prevent the pager from being drawn on empty soft wrapped or new lines.
Steps to reproduce:
fish -C '
function fish_prompt; printf \>; end
bind ctrl-g \'commandline "ls $(printf %0"$(math $COLUMNS - 5)"d 0) "\''
# use ctrl-g and tab
# observe that the pager starts on the line with the cursor
If the prompt occupies the full width of the first line, each new line will soft wrap, leaving empty lines between. This change removes the indentation that matches the start of the line to the end of the prompt if the prompt width equals the terminal width.
Steps to reproduce:
fish -C 'function fish_prompt; printf %0"$COLUMNS"d 0; end'
# type "begin" and Enter
# observe that there was a spurious empty line
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)
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)
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)
Commit f36f757fa6 (Never rewrite history file when adding ephemeral
items, 2024-10-06) has a glaring bug: when adding to history ephemeral
items that has potential paths, we fail to re-enable automatic saving,
which effectively disables automatic saving for the entire session.
Only a call to history::save_all() at exit saves us from losing data.
But until exit, other fish will see our history (unless we run history
save/merge or similar).
Fix the imbalanced enable/disable and restructure the code a bit.
Also, extend the change from f36f757fa6 (never vacuum on ephemeral
items) to private mode.
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.
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)
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.
These dynamic completions are exhaustive, but not as well-documented or
as ergonomic as the manual completions. So, any manual completions
should override them.
This used to get all the interfaces and ssids when the completions
were loaded. That's obviously wrong, given that ssids especially can, you know, change
This uses `git ls-files`, which has a simpler format (just the
filenames on separate lines), in order to print the untracked files.
This allows us to skip them in the `git status` call, which reduces
the output a lot and removes two `string match`.
In a repository with over half a million files (my home directory, if
I made it one), this improves time by a third (12s to 8s).
In a smaller repo (fish-shell) it's barely measurable.
This is consistent with what we do for highlighting history search,
see d7354880e3 (Fix regression causing crash in token history search,
2025-01-27). In future, we should try to find a better fix (and a
better test).
Fixes the other problem described in #11096
Determine if untracked files are off via `__fish_git`, so we get the
repo used on the commandline etc,
and if it isn't, at least don't error out. Yes, this *can* print a
hundred megabytes of filenames.
The two terminals Midnight Commander and dvtm are special in that
they filter requests (or perhaps responses) like
printf "\x1b[0c"
and don't implement the response themselves -- so we never get
one. Let's work around that until we can fix it.
Disable the kitty protocol in mc for now (to keep the code simple),
though we could certainly re-enable it.
Fixes 64859fc242 (Blocking wait for responses to startup queries, 2025-01-25).
`git add` may have to go through literal megabytes of file information
because of tons of untracked files.
So, if the repository is set to not show untracked files (because it's
too slow for the prompt), let's fall back on regular file completions.
(the alternative is to go back to `while read`, but that takes much
longer in repositories of a sensible size)
Fixes#11095
This was copied from C++ code but we have overflow checks, which
forces us to actually handle errors.
While at it, add some basic error logging.
Fixes#11092
Today we might
1. enable modifyOtherKeys
2. get a reply indicating the kitty keyboard protocol is supported
3. because of 2, we never turn off modifyOtherKeys again
Let's get rid of this weird issue by enabling either modifyOtherKeys
or the kitty enhancements only after we know whether the kitty protocol
is supported.
This means we need to call terminal_protocols_enable_ifn() before every
call to readch() until the querying is done. Fortunately, this is
already in place in read_normal_chars(); there are other places that
call readch() but none of those is executed until querying has completed.
At startup we query for
- the cursor position (CSI 6 n)
- kitty keyboard protocol support (CSI ? u)
- terminfo capabilities via XTGETTCAP
Since we don't wait for responses, those can leak into child processes.
Some child processes like fzf cannot decode DCS replies. Plug the
leak by ending each round of querying by asking for the Primary Device
Attribute, and resume input processing only after a response has been
received, (or ctrl-c as an escape hatch).
This is a nice simplification. Tested with the lowest common
denominator (putty, Terminal.app and st).
Fixes#11079
The st terminal wrongly parses CSI ? u as DECRC. A fix has been
proposed upstream. Let's also work around it I guess (not to mention
that querying in the first place is also sort of a workaround).
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>
This reverts commit ebdc3a0393.
Not discussed, includes a new thing that queries the terminal for the client OS
when what is really needed is just a `uname` - which would also work on Terminal.app.
Revert "README for this fork"
This reverts commit 97db461e7f.
Revert "Allow foo=bar global variable assignments"
This reverts commit 45a2017580.
Revert "Interpret () in command position as subshell"
This reverts commit 0199583435.
Revert "Allow special variables $?,$$,$@,$#"
This reverts commit 4a71ee1288.
Revert "Allow $() in command position"
This reverts commit 4b99fe2288.
Revert "Turn off full LTO"
This reverts commit b1213f1385.
Revert "Back out "bind: Remove "c-" and "a-" shortcut notation""
This reverts commit f43abc42f9.
Revert "Un-hide documentation of non-fish shell builtins"
This reverts commit 485201ba2e.
Unlike other builtins, "{" is a separate token, not a keyword-string
token.
Allow the left brace token as command string; produce it when parsing
"{ -h"/"{ --help" (and nowhere else). By using a decorated statement,
we reuse logic for redirections etc.
Other syntax elements like "and" are in the builtin list, which
- adds highlighting logic
- adds it to "builtin --names"
- makes it runnable as builtin
(e.g. "builtin '{'" would hypothetically print the man page)
These don't seem very important (highlighting for '{' needs to match
'}' anyway).
Additionally, making it a real builtin would mean that we'd need to
deactivate a few places that unescape "{" to BRACE_BEGIN.
Let's not add it to the built in list. Instead, simply synthesize
builtin_generic in the right spot.
I'm assuming we want "{ -h" to print help, but '"{" -h' to run an
external command, since the latter is historical behavior. This works
naturally with the above fake builtin approach which never tries to
unescape the left brace.
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>
If a child program crashes with some text rendered below the cursor,
we fail to clear that text. For example run vim, "pkill -9 vim" and
observe that scrollback-push fails to clean up the leftover text.
Fix that.
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
libc::getpid and getpgrp *cannot fail*, so an unsafe declaration here
is just noise.
I mean sure, if your libc is broken and these fail, but at that point
I'm comfortable declaring your computer a platypus that we do not need
to support.
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
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.
Sorry, commit 51adba6ee0 (Restore autosuggestion after corrected
typo, 2025-01-10) was pushed too early. One issue is that it saves
autosuggestions also when we edit in the middle, where we can't
restore it. We'd still restore it in some cases, even though it
doesn't apply. This breaks invariants that may cause various problems
when interacting with the autosuggestion.
Fix it by only saving the autosuggestion when we will be able to
restore it correctly.
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
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.
For compound commands we already have begin/end but
> it is long, which it is not convenient for the command line
> it is different than {} which shell users have been using for >50 years
The difference from {} can break muscle memory and add extra steps
when I'm trying to write simple commands that work in any shell.
Fix that by embracing the traditional style too.
---
Since { and } have always been special syntax in fish, we can also
allow
{ }
{ echo }
which I find intuitive even without having used a shell that supports
this (like zsh. The downside is that this doesn't work in some other
shells. The upside is in aesthetics and convenience (this is for
interactive use). Not completely sure about this.
---
This implementation adds a hack to the tokenizer: '{' is usually a
brace expansion. Make it compound command when in command position
(not something the tokenizer would normally know). We need to disable
this when parsing a freestanding argument lists (in "complete somecmd
-a "{true,false}"). It's not really clear what "read -t" should do.
For now, keep the existing behavior (don't parse compound statements).
Add another hack to increase backwards compatibility: parse something
like "{ foo }" as brace statement only if it has a space after
the opening brace. This style is less likely to be used for brace
expansion. Perhaps we can change this in future (I'll make a PR).
Use separate terminal token types for braces; we could make the
left brace an ordinary string token but since string tokens undergo
unescaping during expansion etc., every such place would need to know
whether it's dealing with a command or an argument. Certainly possible
but it seems simpler (especially for tab-completions) to strip braces
in the parser. We could change this.
---
In future we could allow the following alternative syntax (which is
invalid today).
if true {
}
if true; {
}
Closes#10895Closes#10898
Commit bdfbdaafcc (Forbid subcommand keywords in variables-as-commands
(#10249), 2024-02-06) banned "set x command; $x foo" because the
parser will not recognize "$x" as decorator.
That means that we would execute only the builtin stub,
which usually exist only for the --help argument.
This scenario does not apply for keywords that are quoted or contain
line continuations. We should not treat «"command"» differently
from «command». Fix this inconsistency to reduce confusion.
UnLike other aliases (":.["), ! is special in the grammar but in the
few cases like "! -h" where we parse it as decorated statement they
are equals. Add it to the built in list, so the help argument works.
It can still be overridden, so this should not break anything.
Other sigil-aliases ('[' and '_') are reserved words that cannot be
redefined as function. Only '!' is not.
Whereas several users define "function !!", I
found only one public occurrence of "function !":
5c7f87ed07/fish/functions/!.fish
Note that "function !" only works if invoked as "!", "! -h" or
"! --help" or "foo | !". In most other cases we parse it as negation.
We should probably make it a reserved word to reduce confusion.
If we do that, we should also add it to __fish_print_help, to make
"! -h" work.
For now let's rearrange the code so we can recognize "!" as
super-command. This fixes completion-based autosuggestions on "! ".
The commandline "and fis" rightly gets command autosuggestions whereas
"'and' fis" wrongly gets file autosuggestions. The former works via
a hack. Extend it to quoted keywords.
This file has bitrotted; for example commit bc66921ac9 (Optimize
keyword detection, 2019-04-03) removed use of SKIP_KEYWORDS but
confusingly it's still around (even after 0118eafee1 (Remove unused
functions, members (and a variable), 2022-04-09).
Also some keywords appear in multiple lists; the separate lists are
not really used today; there is a comment stating they may be useful
in future.
It would be great to add an optimization back but either way we should
present the set of reserved words in source code as a contiguous list,
to make it easy for humans to see all relevant information.
StatementVariant needs an indirection because for example NotStatement
may contain another whole statement (error[E0072]: recursive type
has infinite size).
This is dealt with by putting each StatementVariant in a Box.
This Box was also used by the AST walk implementation to implement
tagged dispatched for all variant AST nodes (see "visit_union_field").
Because of this, all other variant AST are boxed the same way, even
though they may not by cyclic themselves.
Reduce confusion by boxing only around the nodes that are actually
recursive types, and use a different tag for static dispatch.
This means that simple nodes like most normal commands and arguments
need one fewer allocation.
For better or worse, backward-token completely skips over operators
like > & |.
forward-token is (accidentally?) inconsistent with that. Fix that.
Skipping over those tokens might be wrong weird. Maybe not for
redirections since they are tighly coupled to their target. Maybe we
can improve this in future.
When pasting and executing a full line, the trailing newline character
will be included in history.
I usually manually delete the newline before executing, but sometimes
I forget. When I recall my (typically single-line) commands, it's
surprising that the cursor is on the blank second line.
The newline doesn't seem useful. Let's remove it automagically.
I wonder if anyone will be thrown off by this smart behavior.
In future, we can make this space trimming configurable, similar to
fish_should_add_to_history.
As mentioned in
https://github.com/fish-shell/fish-shell/pull/11045#discussion_r1915994998,
we need to refresh TTY timestamps to avoid timing-based issues.
For some context see
git log --grep='[Rr]efresh.* TTY'
Make things more consistent again. I don't know if all of these are
absolutely necessary, hoping to find out later (and consolidate this
logic in outputter).
tmux-commandline can fail with
```
prompt 4> commandline -i "echo $(printf %0"$COLUMNS"d)"
```
And I just can't even.
job_summary is annoyingly tight.
Also count cancel_event as a *skip*, not success.
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
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
Saturating all cores easily leads to timeouts.
The system might be doing something else, and it only leaves at most
one core per-test.
E.g. this will cause 90% of runs to fail on a raspberry pi 4.
Note that we set CTEST_PARALLEL_LEVEL on our CI machines anyway, so
this will not affect them.
The issue here is we start some short `sleep`s in the background, wait
for a prompt, and only *then* wait for jobs, and *then* check for the
job end output.
That means if the prompt takes too long, we'll read the job end
messages with the `expect_prompt`.
Instead of increasing the timeouts, just wait on the same line and
remove that prompt.
Bit of a shot in the dark, I've seen this fail and there's no real
need to match the prompt *and* the command you just ran.
(plus wc -l | string trim is unnecessary when we have count)
Commit 4f3d6427ce (Fix regression causing crash in "commandline -j",
2025-01-12) wasn't quite right; it mishandles the edge case where
the current process has no token, fix that.
Zellij 0.41.2 has a bug where it responds to
printf '\x1b[?2026$p'; cat -v
with '^[[2026;2$y' (DECRQM) instead of '^[[?2026;2$y' (DECRPM).
This is fixed by https://github.com/zellij-org/zellij/pull/3884
We fail to parse it, leading to an extra y added to the input queue.
Since it seems easy to work around for us, let's do that, I guess.
Failed on Cirrus Alpine.
The only explanation I can come up with here is that this took over
100ms to start `true | sleep 6`.
The alternative is that it started it and then did not regain control
in 6 seconds to kill that sleep.
Part of #11036
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
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.
Syntax highlighting wants to underline arguments that are files, and in other
cases do disk I/O (such as testing if a command is valid). Factor out this I/O
logic to untangle highlighting, and add some tests. No functional change
expected.
Commit 3fcc6482cb (Fix parse_util_process_extent including too much
on the left, 2024-12-24) changed the process extent based on the
observation that "A\n\n\nB" comprises three tokens with ranges 0..1,
1..2 and 4..5. Prior to that commit, the second process extent was
2..5, which seems a bit weird because it includes newlines.
Weirdness aside, the real reason for changing it was this snippet in
the autosuggestion performer, where we compute the process extent
around cursor, and check if the line at process start matches the
cached search string.
// Search history for a matching item unless this line is not a continuation line or quoted.
if range_of_line_at_cursor(
&command_line,
parse_util_process_extent(&command_line, cursor_pos, None).start,
) == search_string_range
Given "A\n\n\nB" and cursor_pos=1 commit 3fcc6482cb changed the output
from 2..5 to 4..5. This brings problems:
1. leading spaces will not be included (which is probably
inconsequential but still ugly).
2. the specified cursor position is not included in the given range.
We could paper over 2 by computing min(cursor_pos)
but that would leave 1.
For now let's revert and solve the autosuggestion issue in a less
brittle way.
This needs to work both in builtin and command mode.
We should probably clarify how we're passing FDs around, and I suspect
we may close fds in places we don't expect.
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)
Various commits have added bits to .cargo/config.toml. Unfortunately,
this file needs to be changed by the Linux package builds (debuild, RPM,
OBS etc) with the results of `cargo vendor`, to support building in
isolated environments.
These environments - especially Debian's dpkg-buildpackage/debuild - do
not make it easy to alter a file which already exists in the tarball in
an automatic way. dpkg-buildpackage in particular requires all changes
to be made in the form of patches.
Just exclude .cargo/config.toml from the tarballs for now. This means
that the stanzas it includes _will not apply_ to builds made from
tarballs, which includes releases and development builds made using the
OBS/Launchpad PPAs.
This replaces the test_driver.sh/test.fish/interactive.fish system with a test driver written in python that calls into littlecheck directly and runs pexpect in a subprocess.
This means we reduce the reliance on the fish that we're testing, and we remove a posix sh script that is a weird stumbling block (see my recent quest to make it work on directories with spaces).
To run specific tests, e.g. all the tmux tests and bind.py:
tests/test_driver.py target/release/ tests/checks/tmux*.fish tests/pexpects/bind.py
Backspace signals that the user is not happy with the commandline,
and by extension the autosuggestion.
For this reason, backspace suppresses autosuggestions until the next
text insertion.
However if I
1. type something that has an autosuggestion
2. type *one* wrong letter (removing the autosuggestion)
3. type backspace
backspace does not visibly suppress any autosuggestion but rhater
signal that the user wants to go back to the previous state of the
commandline, which does have an autosuggestion.
Enable this scenario by caching the autosuggestion when it's
invalidated. On certain edits that make the cached autosuggestion
valid again, restore it from the cache. Currently, only do this up
to a single backspace. Could extend that in future.
This implementation is really bad.. but it's a start.
Weirdly, it does not restore the cache on undo; but that's
inconsequential because undo doesn't suppress autosuggestion as
of today.
Closes#3549
My history often has erroneous single-line commands followed by
corrected versions. Sometimes the corrected versions only exist within
a multi-line commandline. This means that autosuggestion skips over
the corrected versions and return a false positive.
Fix that by splitting the commandline into lines and suggesting those,
in reverse chronological order.
One other wart: shift-delete won't delete such autosuggestions from
history; instead it will flash the screen.
Line boundaries are not the best heuristic but they are an
improvement for the most part and fits with the current approach
where autosuggestion always operates on the entire line.
In future we should operate on processes and jobs. But it may be
tricky - a backgrounding `&` should probably be included (in both?)
but `&&` or `;` probably not.
See also the discussion in
1c4e5cadf2 (diff-267c9f4da66412a9f439ac08d224356fe24265b5e1cebb6c44c2d55b96414513R59)
If there is no history search or autosuggestion, shift-delete acts
as backspace, matching native macOS behavior.
I'm not sure if we want to keep that amount of overloaded behavior,
but let's assume so for now.
If that assumption holds, it may be confusing that shift-delete
deletes the autosuggestion if the cursor is here
echo some command with autosuggstion
^
So let's only do that if the cursor is actually at the autosuggestion,
I guess.
shift-delete attempts to delete the autosuggestion from history even
if the autosuggestion is not from history.
This is weird. We probably shouldn't do this. Let's flash the
commandline instead to try to reduce confusion.
I think the dynamic detection patch ends up overriding the environment variable
set by CI (if present), because `if(NOT CTEST_PARALLEL_LEVEL)` would define to
false even if an environment variable of that name existed then we end up
explicitly assigning the environment variable by that name upon invocation with
`env`.
This is an experiment to see if it causes any of the tests to flake and/or if it
even appreciably speeds up CI to begin with.
I note that there are tests added in 8bf8b10 that mutate global terminal state
but also note that local tests without CTEST_PARALLEL_LEVEL set at all have been
running to completion just fine without any observed flakiness *and* that our
Cirrus CI tests have this hard-coded to 6.
The new 1.84 release has a new feature that makes `cargo update` MSRV-aware.
This is what it looks like in practice:
Updating crates.io index
Updating git repository `https://github.com/fish-shell/rust-pcre2`
From https://github.com/fish-shell/rust-pcre2
* [new tag] 0.2.9-utf32 -> origin/tags/0.2.9-utf32
Locking 7 packages to latest Rust 1.70 compatible versions
Updating cc v1.2.6 -> v1.2.7
Updating phf v0.11.2 -> v0.11.3
Updating phf_codegen v0.11.2 -> v0.11.3
Updating phf_generator v0.11.2 -> v0.11.3
Updating phf_shared v0.11.2 -> v0.11.3
Updating siphasher v0.3.11 -> v1.0.1
Updating syn v2.0.94 -> v2.0.95
The result of
commandline -i ": '$(seq $LINES)"\n"first scrolled line'"
is a commandline that is scrolled by one line.
Before executing that commandline, we move the cursor down by one
too many line. This is a regression from 610338cc70 (On undo after
execute, restore the cursor position, 2024-12-21). Fix that.
The test also demonstrates an unrelated problem, probably specific
to tmux.
Some terminals such as conhost and putty cannot parse DCS commands,
and will echo them back.
Work around this by making sure that this echoed text will not
be visible.
Do so by temporarily enabling the alternative screen buffer when
sending DCS queries (in this case only XTGETTCAP). The alternative
screen buffer feature seems widely supported, and easier to get right
than trying to clear individual lines etc.
The alternative screen may still be visible for a
short time. Luckily we can use [Synchronized Output](
https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036)
to make sure the screen change is never visible to the user.
Querying support for that is deemed safe since it only requires a
CSI command.
Note that it seems that every terminal that supports Synchronized
Output also parses DCS commands successfully. This means that we
could get away without the alternative screen buffer in practice.
Not sure yet.
The implementation is slightly more complex than necessary in that it
defines a redundant ImplicitEvent. This is for two reasons: 1. I have
a pending change that wants to use it, so this removes diff noise and
2. we historically have sc/input_common.rs not depend on src/output.rs.
I dont' think any are strong reasons though.
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)
Commit b6d76ae: we now use lines like "# RUN: fish=%fish %fish".
If a test exits with 127 we try to look up the command but use the
wrong name, which leads to unintelligible errors if the test exits
with 127 for other reasons.
If I run "sleep 3", type a command and hit enter, then there is no
obvious way to cancel or edit the imminent command other than ctrl-c
but that also cancels sleep, and doesn't allow editing. (ctrl-z sort
of works, but also doesn't allow editing).
Let's try to limit ourselves to inserting the buffered command
(translating enter to a newline), and only execute once the user
actually presses enter after the previous command is done.
Hide it behind a new feature flag for now.
By making things less scary, this might be more user-friendly, at
the risk of breaking expectations in some cases.
This also fixes a class of security issues where a command like
`cat malicious-file.txt` might output escape sequences, causing
the terminal to echo back a malicious command; such files can still
insert into the command line but at least not execute it directly.
(Since it's only fixed partially I'm not really sure if the security
issue is a good enough motivation for this particular change.)
Note that bracketed paste probably has similar motivation as this feature.
Part of #10987Closes#10991
Some terminals like the Linux console don't support indn (scroll
forward). Let's query for the presence of these features, and fall
back to the traditional behavior if absent.
For now, break with the tradition of using the terminfo database that
we read ourselves. Instead ask the terminal directly via XTGETTCAP.
This is a fairly young feature implemented by terminals like xterm,
foot and kitty, however xterm doesn't expose these capabilities at
this point.
This is a good opportunity to try XTGETTCAP, since these are
capabilities we haven't used before. Advantages of XTGETTCAP are that
it works across SSH and is independent of $TERM (of course ignoring
$TERM may also be breaking to some users). Let's see if it sees
adoption in practice.
Tested to work on foot and kitty, allowing the default ctrl-l binding
to work without erasing any screen content.
See #11003
The new ctrl-l implementation relies on Cursor Position Reporting (CPR)
This may not work on exotic terminals that don't support CSI 6n yet
As a workaround, probe for this feature by sending a CSI 6n (CPR)
on startup. Until the terminal responds, have scrollback-push fall
back to clear-screen.
The theoretical problem here is that we might handle scrollback-push
before we have handled the response to our feature probe. That seems
fairly unlikely; also e49dde87cc has the same characteristics.
This could query a capability instead (via XTGETTCAP or otherwise)
but I haven't found one; and this seems at least as reliable.
While at it, change the naming a bit.
See #11003
After we query kitty keyboard protocol support,
we send CSI 5n, to also receive a response if
the protocol is not supported.
However we don't bother to wait for the response, so this extra
message is not really useful (only to get better logs). Remove it.
With tmux 3.0 (from 2019) inside SSH, the CSI 5n response is echoed.
I guess with all other terminals we were just lucky. Move it to
right after where we disable ECHO I guess.
In general, asynchronous requests create a lot of potential for error,
we should try to get away from them.
These aren't typically used in the terminal but they are present on
many keyboards.
Also reorganize the named key constants a bit. Between F500 and
ENCODE_DIRECT_BASE (F600) we have space for 256 named keys.
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)
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.
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)
Testing has revealed some problems on BSD and Windows terminals and
the Linux Console, let's revert to the old implementation until these
are fixed. Leaving the changelog entry for now since it shouldn't
take long.
See #11003
The FdReadableSet api was always intended to be converted to use Duration
instead of usec/msec once the ffi was removed. This lets us be explicit about
forever/infinite timeouts and removes the (small) chance of a collision between
u64::MAX and INFINITE.
I tried this out with `type Timeout = Option<Duration>` (only without the alias)
but was unhappy with easy it is to accidentally use `None` when you meant a
timeout of zero.
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)
Commit 1c4e5cadf2 (Autosuggestions in multi-line
command lines, 2024-12-15) accidentally passed an empty
"commandline_before_suggestion" to compute_layout() when there is
no autosuggestion.
Closes#10996
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)
As reported in
https://github.com/fish-shell/fish-shell/issues/10992#issuecomment-2568954940,
the user may reset the terminal and run scrollback-push without
repainting in between. This means that the terminal will report
the cursor position y=0 x=0 which doesn't match what fish renders.
Fortunately, y=0 is a safe fallback value for the scrollback-push
use case.
While at it, fix an off-by-one error in a log.
Before 1c4e5cadf2 (Autosuggestions in multi-line command lines,
2024-12-15), the completion code path in the autosuggestion performer
used to do something weird: it used to request completions for the
entire command line (with the implied cursor at end) but try to apply
the same completion at the actual cursor.
That commit changed this to request completions only up to the cursor
position, which could in theory make us produce valid completions even
if the cursor is not at end of the line. However, that doesn't really
work since autosuggestions can only be rendered at the end of the line.
And the worst of it, that commit tries to compute
line_at_cursor(&full_line, search_string_range.end)
which crashes as out-of-bounds if the completion needs to replace the token
(like a case-correcting completion does).
Let's apply completions to the end, matching how autosuggestions work
in general.
I believe it's possible that the cursor position reported by the
terminal does not match fish's cursor. In that case, overflow. Fix
that since we should not trust the terminal.
Also rename a confusingly named variable.
Mouse-click handling has a similar issue, fix that too.
FWIW, tmux always reports cursor position zero (\x1b[1;1R) when
querying from fish (but not when querying with printf).
Will investigate that next, see the linked issue.
Fixes#10992
jj is often colocated with Git so the Git prompt also works, but
jj is always in a detached HEAD state, which is atypical for Git.
The jj prompt improves things by showing the revision ID which is
usually more useful than the commit ID.
This prompt is mostly adapted from the defaults for "jj log -r @".
Showing conflicting/empty commits seems useful.
Also perhaps bookmarks and tags, not sure.
The main problem with this prompt is that due to --ignore-working-copy,
the information may be stale. That will be rectified after every jj
command, so hopefully this doesn't cause issues.
Added in libc 0.2.163.
The constants for _CS_PATH are not implemented for some of the BSDs yet
(rust-lang/cmake#3612), so we need to keep our linking of this via the C
compiler for now.
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)
If I run
$ command A
$ command B
$ command C
and find myself wanting to re-run the same sequence of commands
multiple times, I like to join them into a single command:
$ command A &&
command B &&
command C
When composing this mega-commandline, history search can recall the
first one; the others I usually inserted with a combination of ctrl-k,
ctrl-x or the ctrl-r (since 232483d89a (History pager to only operate
on the line at cursor, 2024-03-22), which is motivated by exactly
this use case).
It's irritating that autosuggestions are missing, so try adding them.
Today, only single-line commands from history are suggested. In
future, we should perhaps also suggest any line from a multi-line
command from history.
If I type something that invalidates the autosuggestion, the
autosuggestion is still kept around in memory. This is used if
1. there is no valid autosuggestion for the new commandline
2. the user types something like "backspace backspace a"
that both makes the cached autosuggestion valid again, and does
not trigger autosuggestion suppression (hence backspace alone is
not anough)
The fact that an autosuggestion might not match the current command
line makes it more difficult to implement autosuggestions on multiline
command lines.
For now let's invalidate autosuggestions eagerly, to enable the
next commit. This heuristic invalidates too much but I don't think
that matters. We'll simply recompute the autosuggestion in those few
cases which.
This is somewhat subtle:
The #RUN line in a littlecheck file will be run by a posix shell,
which means the substitutions will also be mangled by it.
Now, we *have* shell-quoted them, but unfortunately what we need is to
quote them for inside a pre-existing layer of quotes, e.g.
# RUN: fish -C 'set -g fish %fish'
here, %fish can't be replaced with `'path with spaces/fish'`, because
that ends up as
# RUN: fish -C 'set -g fish 'path with spaces/fish''
which is just broken.
So instead, we pass it as a variable to that fish:
# RUN: fish=%fish fish...
In addition, we need to not mangle the arguments in our test_driver.
For that, because we insist on posix shell, which has only one array,
and we source a file, we *need* to stop having that file use
arguments.
Which is okay - test_env.sh could previously be used to start a test,
and now it no longer can because that is test_*driver*.sh's job.
For the interactive tests, it's slightly different:
pexpect.spawn(foo) is sensitive to shell metacharacters like space.
So we shell-quote it.
But if you pass any args to pexpect.spawn, it no longer uses a shell,
and so we cannot shell-quote it.
There could be a better way to fix this?
We:
1. Set up a nice TMPDIR for our tests to use
2. Immediately `cd` to the directory containing the test runner.
So instead we don't do (2), and stay in the temp directory, and
explicitly use all the things from the test runner directory.
I am fairly certain that cmake papered over this by adding a second
layer of temp dir.
The default is still "../test/root/bin/", but we now pass this
through,
so you *can* run
`FISHDIR=$PWD ../tests/test_driver.sh $PWD/../tests/test.fish`
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"`)
As soon as we start processing a scrollback-push readline command, we
pause execution of all other readline commands until scrollback-push
retires. This means that we never get into a situation with two
active scrollback-push commands -- unless we are executing readline
commands via a script running "commandline -f":
since the first part of scrollback-push handling returns immediately,
the script will proceed before scrollback-push retires.
A second scrollback-push fails an assertion. Work around that for now.
In future, scrollback-push should block when invoked by such a script,
just like it does when invoked from bindings.
Commit 83b0294fc9 (ctrl-l to scroll content instead of erasing screen,
2024-12-21) broke tests like tests/checks/tmux-autosuggestion.fish
on macOS CI.
I didn't get to the bottom of this but it's probably because terminfo
is broken on that CI system.
A (related?) failure mode can be observed using
TERM=linux-m ssh my-mac tmux
ctrl-l moves the cursor but fails to scroll the text.
The only reason for using terminfo here was to be consistent with
the rest of the code base. Let's use a hardcoded value instead;
I don't see why any terminal would deviate from xterm here.
This fixes macOS CI and the TERM=linux-m "misconfiguration".
It is possible that we should be using a different escape sequence
here; I'm not sure.
On ctrl-l we send `\e[2J` (Erase in Display). Some terminals interpret
this to scroll the screen content instead of clearing it. This happens
on VTE-based terminals like gnome-terminal for example.
The traditional behavior of ctrl-l erasing the screen (but not the
rest of the scrollback) is weird because:
1. `ctrl-l` is the easiest and most portable way to push the prompt
to the top (and repaint after glitches I guess). But it's also a
destructive action, truncating scrollback. I use it for scrolling
and am frequently surprised when my scroll back is missing
information.
2. the amount of lines erased depends on the window size.
It would be more intuitive to erase by prompts, or erase the text
in the terminal selection.
Let's use scrolling behavior on all terminals.
The new command could also be named "push-to-scrollback", for
consistency with others. But if we anticipate a want to add other
scrollback-related commands, "scrollback-push" is better.
This causes tests/checks/tmux-history-search.fish to fail; that test
seems pretty broken; M-d (alt-d) is supposed to delete the current
search match but there is a rogue "echo" that is supposed to invalidate
the search match. I'm not sure how that ever worked.
Also, pexepect doesn't seem to support cursor position reporting,
so work around that.
Ref: https://codeberg.org/dnkl/foot/wiki#how-do-i-make-ctrl-l-scroll-the-content-instead-of-erasing-it
as of wiki commit b57489e298f95d037fdf34da00ea60a5e8eafd6d
Closes#10934
We parse "\e\e[x" as alt-modified "Invalid" key. Due to this extra
modifier, we accidentally add it to the input queue, instead of
dropping this invalid key.
We don't really want to try to extract some valid keys from this
invalid sequence, see also the parent commit.
This allows us to remove misplaced validation that was added by
e8e91c97a6 (fish_key_reader: ignore sentinel key, 2024-04-02) but
later obsoleted by 66c6e89f98 (Don't add collateral sentinel key to
input queue, 2024-04-03).
This situation can be triggered in practice inside a terminal like tmux
3.5 by running
tmux new-session fish -C 'sleep 2' -d reader -o log-file
and typing "alt-escape x"
The log shows that we drop treat this as alt-[ and drop the x on the floor.
reader: Read char alt-\[ -- Key { modifiers: Modifiers { ctrl: false,
alt: true, shift: false }, codepoint: '[' } -- [27, 91, 120]
This input ("\e[x") is ambiguous.
It looks like it could mean "alt-[,x". However that conflicts with a
potential future CSI code, so it makes no sense to try to support this.
Returning "None" from parse_csi() causes this weird behavior of
returning "alt-[" and dropping the rest of the parsed sequence.
This is too easy; it has even crept into a bunch of places
where the input sequence is actually valid like "VT200 button released"
but where we definitely don't want to report any key.
Fix the default: report no key for all unknown sequences and
intentionally-suppressed sequences. Treat it at "alt-[" only when
there is no input byte available, which is more or less unambiguous,
hence a strong enough signal that this is a actually "alt-[".
When the user clicks somewhere in the prompt, kitty asks the shell
to move the cursor there (since there is not much else to do).
This is currently implemented by sending an array of
forward-char-passive commands. This has problems, for example it
is really slow on large command lines (probably because we repaint
everytime).
Implement kitty's `click_events=1` flag to set the
position directly. To convert from terminal-coordinates
to fish-coordinates, query [CSI 6 n Report Cursor
Position](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html)
and use it to compute the left prompt's terminal-coordinates (which
are (0, 0) in fish-coordinates).
Unfortunately this doesn't yet work correctly while the terminal
is scrolled. This is probably because the cursor position is wrong
if off-screen. To fix that we could probably record the cursor
position while not scrolled, but it doesn't seem terribly important
(the existing implementation also doesn't get it right).
We still turn off mouse reporting. If we turned it on, it
would be harder to select text in the terminal itself (not fish).
This would typically mean that mouse-drag will alter fish's
selection and shift+mouse-drag or alt+mouse-drag can be used.
To improve this, we could try to synchronize the selection: if parts
of the fish commandline are selected in the terminal's selection,
copy that to fish's selection and vice versa.
Or maybe there is an intuitive criteria, like: whenever we receive a
mouse event outside fish, turn off mouse reporting, and turn it back on
whenver we receive new keyboard input. One problem is that we lose
one event (though we could send it back to the terminal). Another
problem is we would turn it back on too late in some scenarios.
Closes#10932
Commit 01dbfb0a3f (replace writestr() with fwprintf() in reader.cpp,
2016-12-20) accidentally replaced a retry-on-EINTR write with a
non-retrying version. Commit 7f31acbf9b (Prevent fish_title output
from triggering a bel, 2022-02-02) fixed this for some cases but
not all, fix that.
This has been removed, see kitty commit cd92d50a0 (Keyboard protocol:
Remove CSI R from the allowed encodings of the F3 key as it conflicts
with the *Cursor Position Report* escape code, 2022-12-24).
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>
PR #10953 reports missing coverage for the change to update_buff_pos()
in d51f669647 (Vi mode: avoid placing cursor beyond last character,
2024-02-14).
Add a case demonstrating how $ should not move the cursor past the
last character. Goes without saying that it's really ugly that we
update_buff_pos() must be so defensive here, ideally we wouldn't pass
it out-of-bounds positions.
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.
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.
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.
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
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
[Do NOT cherry-pick to 4.0 - this needs more time to be tested]
fish sometimes needs to capture the output of a command or block of
commands. Examples include fish_prompt or any command substitution
("cmdsubs"). It does this the obvious way: by creating a pipe, using dup2
to replace stdout of the command with the write end of the pipe, and then
reading from the read end into a buffer, until EOF or the command
substitution completes. Importantly, this task also overlaps with waiting
for the process to exit; that is when executing:
set var (some_cmd)
fish needs to both wait on `some_cmd` and ALSO read its output into memory.
This is awkward to do in a portable way in a single thread (though maybe
doable on Linux with pidfd). So we wait and read on different threads.
To make things worse, command substitutions may themselves create
additional command substitutions (recursion, etc). Creating a read thread
for every command substitution would result in excessive threads. So rather
than a thread per cmdsub, we have a single dedicated thread that handles
ALL command substitutions, by multiplexing multiple file descriptors via
select/poll. This is the "fd monitor." You hand it a file descriptor and it
lets you know when it's readable, and then you can read from it (via a
callback). Also, it has a "wakeup" fd: if you write to that then the fd
monitor wakes up, figures out what it has to do, and resumes.
When the command substitution ends, we need to remove the fd from the fd
monitor, because we intend to close it. You might object "the commands in
the cmdsub have all completed so the write end of the pipe has been closed
so the fd monitor can just notice that the pipe is closed" but it's not so:
consider the horrible case of `set var (yes &)` and abandon all hope.
The current mechanism for removing the fd from the monitor is called a
"poke." We tell the fd monitor (through a "control" self-pipe) to
explicitly wake up the item. It then invokes the callback ("pokes") the
item on the dedicated fd monitor thread. The item notices that the command
substitution is complete, and it returns a value meaning "remove me" and
the fd monitor does so. The client thread is stuck waiting for this process
to complete.
So basically removing a fd from the monitor requires a round trip to its
dedicated thread. This is slow and also complicated (Rust doesn't have
futures)!
So let's not do that.
The big idea is to remove this round-trip synchronization. That is, when we
intend to remove the fd from the fd monitor, we _just do it_ and then close
the fd. Use a lock rather than a round-trip to the thread. Crucially that
lock is unlocked while the monitor thread waits in select/poll.
This invites all sorts of races:
1. fish might remove and close the fd right before the monitor polls it. It
will thus attempt to poll a closed fd.
2. fish might remove and close the fd, and then something else opens a file
and receives the same fd. Now the fd monitor will poll an fd that was
never added.
3. fish might remove and close the fd _while the fd monitor is polling it_.
What happens then? (Turns out on macOS we get EBADF, and on Linux the fd is
marked readable).
The Big Idea is that *all of these races are benign*. As long as
poll/select doesn't crash or hang, we don't care *what* it returns, because
the source of truth are the set of items stored in the fd monitor and these
item IDs are never recycled. (This also assumes that it's OK to select/poll
on random file descriptors; there ought to be no side effects).
Not only is this a large simplification since we no longer need that round
trip, it's a substantial performance improvement as well. The
"aliases.fish" benchmark goes from 164 to 154 msec on my Mac, and from 124
to 112 msec on my Linux machine - nearly 10%.
Add some tests to verify our assumptions about the behavior of closing or
replacing a file descriptor during poll. But even if these fail, all we
care about is that poll/select doesn't crash or hang.
FdMonitor is used to monitor a set of file descriptors and invoke a callback
when one becomes readable. Prior to this commit, they coudl also have the
callback invoked on timeout. fish used to use this feature but no longer does;
remove it.
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)
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*
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
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
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
__fish_cancel_commandline was unused (even before) and has some issues
on multiline commandlines. Make it use the previously active logic.
Closes#10935
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
* 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
I forgot that 610338cc70 (On undo after execute, restore the cursor
position, 2024-12-21) would cause a fallout to tests:
It makes us reuse in another place our usual cursor-movement sequences.
This causes failures like this (linebreaks added for readability):
Testing file pexpects/bind.py:Failed to match pattern: (?:\r\n|\x1b\[2 q)[^\n]*def abc\r\n
bind.py:45: timeout from expect_prompt(TO_END + "def abc\r\n") # emacs transpose words, default timeout: no delay
Escaped buffer:
\x1b[?2004h\x1b[>4;1m\x1b[=5u\x1b=\rprompt 2>echo \rprompt 2>echo abc \rprompt 2>echo def abc\r
prompt 2>echo def abc\x1b[?2004l\x1b[>4;0m\x1b[=0u\x1b>\x1b]133;C\x07def abc\r\n\x1b]133;D;0\x07\x1b[?25h⏎
\r⏎ \r\rprompt 3>\x1b[?2004h\x1b[>4;1m\x1b[=5u\x1b=
It seems that we don't print anything where we should print something
like "\r\n" or "\e[2 q" to move the cursor below the command line.
I haven't gotten to the bottom of this but it might be related to
terminfo. Once we get rid of that, we can unconditionally print
our canonical movement sequences.
This issue seems to only affect tests, since fish operates fine in
a sourcehut CI system. Let's ignore it for now.
Ever since 149594f974 (Initial revision, 2005-09-20), we move the
cursor to the end of the commandline just before executing it.
This is so we can move the cursor to the line below the command line,
so moving the cursor is relevant if one presses enter on say, the
first line of a multi-line commandline.
As mentioned in #10838 and others, it can be useful to restore the
cursor position when recalling commandline from history. Make undo
restore the position where enter was pressed, instead of implicitly
moving the cursor to the end. This allows to quickly correct small
mistakes in large commandlines that failed recently.
This requires a new way of moving the cursor below the command line.
Test changes include unrelated cleanup of history.py.
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
Please tell us which fish version you are using by executing the following:
fish --version
echo $version
Please tell us which operating system and terminal you are using. The output of `uname -a` and `echo $TERM` may be helpful in this regard although other commands might be relevant in your specific situation.
Please tell us which operating system (output of `uname`) and terminal you are using.
Please tell us if you tried fish without third-party customizations by executing this command and whether it affected the behavior you are reporting:
- Compound commands (``begin; echo 1; echo 2; end``) can now be now be abbreviated using braces (``{ echo1; echo 2 }``), like in other shells.
- Fish now supports transient prompts: if :envvar:`fish_transient_prompt` is set to 1, fish will reexecute prompt functions with the ``--final-rendering`` argument before running a commandline (:issue:`11153`).
- When tab completion results are truncated, any common directory name is omitted. E.g. if you complete "share/functions", and it includes the files "foo.fish" and "bar.fish",
the completion pager will now show "…/foo.fish" and "…/bar.fish". This will make the candidates shorter and allow for more to be shown at once (:issue:`11250`).
- The self-installing configuration introduced in fish 4.0 has been changed.
Now fish built with embedded data will just read the data straight from its own binary or write it out when necessary, instead of requiring an installation step on start.
That means it is now possible to build fish as a single file and copy it to a compatible system, including as a different user, without extracting any files.
As before this is the default when building via `cargo`, and disabled when building via `cmake`, and for packagers we continue to recommend cmake.
Note: When fish is built like this, the `$__fish_data_dir` variable will be empty because that directory no longer has meaning. If you need to load files from there,
use `status get-file` or find alternatives (like loading completions for "foo" via `complete -C"foo "`).
We're considering making data embedding mandatory in future releases because it has a few advantages even for installation from a package (like making file conflicts with other packages impossible). (:issue:`11143`)
Deprecations and removed features
---------------------------------
- Tokens like ``{ echo, echo }`` in command position are no longer interpreted as brace expansion but as compound command.
- Terminfo-style key names (``bind -k``) are no longer supported. They had been superseded by the native notation since 4.0,
and currently they would map back to information from terminfo, which does not match what terminals would send with the kitty keyboard protocol (:issue:`11342`).
- fish no longer reads the terminfo database, so its behavior is no longer affected by the :envvar:`TERM` environment variable (:issue:`11344`).
For the time being, this can be turned off via the "ignore-terminfo" feature flag::
set -Ua fish_features no-ignore-terminfo
- The ``--install`` option when fish is built as self-installable was removed. If you need to write out fish's data you can use the new ``status list-files`` and ``status get-file`` subcommands, but it should no longer be necessary. (:issue:`11143`)
- RGB colors (``set_color ff0000``) now default to using 24-bit RGB true-color commands, even if $COLORTERM is unset, because that is often lost e.g. over ssh (:issue:`11372`)
- To go back to using the nearest match from the 256-color palette, use ``set fish_term24bit 0`` or set $COLORTERM to a value that is not "24bit" or "truecolor".
To make the nearest-match logic use the 16 color palette instead, use ``set fish_term256 0``.
- Inside macOS Terminal.app, fish makes an attempt to still use the palette colors.
If that doesn't work, use ``set fish_term24bit 0``.
-``set_color --background=COLOR`` no longer implicitly activates bold mode.
To mitigate this change on existing installations that use a default theme, update your theme with ``fish_config theme choose`` or ``fish_config theme save``.
Scripting improvements
----------------------
Interactive improvements
------------------------
- Autosuggestions are now also provided in multi-line command lines. Like `ctrl-r`, autosuggestions operate only on the current line.
- Autosuggestions used to not suggest multi-line commandlines from history; now autosuggestions include individual lines from multi-line command lines.
- The history search now preserves ordering between :kbd:`ctrl-s` forward and :kbd:`ctrl-r` backward searches.
- Left mouse click (as requested by `click_events <terminal-compatibility.html#click-events>`__) can now select pager items (:issue:`10932`).
- Instead of flashing all the text to the left of the cursor, fish now flashes the matched token during history token search, the completed token during completion (:issue:`11050`), the autosuggestion when deleting it, and the full command line in all other cases.
- Pasted commands are now stripped of any ``$`` prefix.
New or improved bindings
^^^^^^^^^^^^^^^^^^^^^^^^
- On non-macOS systems, :kbd:`alt-left`, :kbd:`alt-right`, :kbd:`alt-backspace`, :kbd:`alt-delete` no longer operate on punctuation-delimited words but on whole arguments, possibly including special characters like ``/`` and quoted spaces.
On macOS, the corresponding :kbd:`ctrl-` prefixed keys operate on whole arguments.
Word operations are still available via the other respective modifier, same as in the browser.
-:kbd:`ctrl-z` (undo) after executing a command will restore the previous cursor position instead of placing the cursor at the end of the command line.
- The OSC 133 prompt marking feature has learned about kitty's ``click_events=1`` flag, which allows moving fish's cursor by clicking.
-:kbd:`ctrl-l` now pushes all text located above the prompt to the terminal's scrollback, before clearing and redrawing the screen (via a new special input function ``scrollback-push``).
For compatibility with terminals that do not provide the scroll-forward command,
this is only enabled by default if the terminal advertises support for the ``indn`` capability via XTGETTCAP.
- Bindings using shift with non-ASCII letters (such as :kbd:`ctrl-shift-ä`) are now supported.
If there is any modifier other than shift, this is the recommended notation (as opposed to :kbd:`ctrl-Ä`).
Completions
^^^^^^^^^^^
Improved terminal support
^^^^^^^^^^^^^^^^^^^^^^^^^
- Support for curly underlines in `fish_color_*` variables and :doc:`set_color <cmds/set_color>` (:issue:`10957`).
- Underlines can now be colored independent of text (:issue:`7619`).
- New documentation page `Terminal Compatibility <terminal-compatibility.html>`_ (also accessible via ``man fish-terminal-compatibility``) lists required and optional terminal control sequences used by fish.
Other improvements
------------------
-``fish_indent`` and ``fish_key_reader`` are now available as builtins, and if fish is called with that name it will act like the given tool (as a multi-call binary).
This allows truly distributing fish as a single file. (:issue:`10876`)
-``fish_indent --dump-parse-tree`` now emits simple metrics about the tree including its memory consumption.
For distributors
----------------
-``fish_indent`` and ``fish_key_reader`` are still built as separate binaries for now, but can also be replaced with a symlink if you want to save disk space (:issue:`10876`).
- The CMake system was simplified and no longer second-guesses rustup. It will run rustc and cargo via $PATH or in ~/.cargo/bin/.
If that doesn't match your setup, set the Rust_COMPILER and Rust_CARGO cmake variables (:issue:`11328`).
- Cygwin support has been reintroduced, since rust gained a Cygwin target (https://github.com/rust-lang/rust/pull/134999, :issue:`11238`).
--------------
fish 4.0.2 (released April 20, 2025)
====================================
This release of fish fixes a number of issues identified in fish 4.0.1:
- Completions are quoted, rather than backslash-escaped, only if the completion is unambiguous. Continuing to edit the token is therefore easier (:issue:`11271`). This changes the behavior introduced in 4.0.0 where all completions were quoted.
- The warning when the terminfo database can't be found has been downgraded to a log message. fish will act as if the terminal behaves like xterm-256color, which is correct for the vast majority of cases (:issue:`11277`, :issue:`11290`).
- Key combinations using the super (Windows/command) key can now (actually) be bound using the :kbd:`super-` prefix (:issue:`11217`). This was listed in the release notes for 4.0.1 but did not work correctly.
-:doc:`function <cmds/function>` is stricter about argument parsing, rather than allowing additional parameters to be silently ignored (:issue:`11295`).
- Using parentheses in the :doc:`test <cmds/test>` builtin works correctly, following a regression in 4.0.0 where they were not recognized (:issue:`11387`).
-:kbd:`delete` in Vi mode when Num Lock is active will work correctly (:issue:`11303`).
- Abbreviations cannot alter the command-line contents, preventing a crash (:issue:`11324`).
- Improvements to various completions, including new completions for ``wl-randr`` (:issue:`11301`), performance improvements for ``cargo`` completions by avoiding network requests (:issue:`11347`), and other improvements for ``btrfs`` (:issue:`11320`), ``cryptsetup`` (:issue:`11315`), ``git`` (:issue:`11319`, :issue:`11322`, :issue:`11323`), ``jj`` (:issue:`11046`), and ``systemd-analyze`` (:issue:`11314`).
- The Mercurial (``hg``) prompt can handle working directories that contain an embedded newline, rather than producing errors (:issue:`11348`).
- A number of crashes have been fixed. Triggers include prompts containing backspace characters (:issue:`11280`), history pager search (:issue:`11355`), invalid UTF-8 in :doc:`read <cmds/read>` (:issue:`11383`), and the ``kill-selection`` binding (:issue:`11367`).
- A race condition in the test suite has been fixed (:issue:`11254`), and a test for fish versioning relaxed to support downstream distributors' modifications (:issue:`11173`).
- Small improvements to the documentation (:issue:`11264`, :issue:`11329`, :issue:`11361`).
--------------
fish 4.0.1 (released March 12, 2025)
====================================
This release of fish includes the following improvements compared to fish 4.0.0:
- Key combinations using the super (Windows/command) key can be bound using the :kbd:`super-` prefix (:issue:`11217`).
- Konsole's menu shows the "Open folder with" option again (:issue:`11198`).
-``$fish_color_search_match`` will now only be applied to the foreground color if it has an explicit foreground. For example, this allows setting::
set -g fish_color_search_match --reverse
- Cursor shape commands (``\e[2 q``) are no longer sent in non-interactive shells or in redirections (:issue:`11255`).
-:doc:`status <cmds/status>` gained a ``is-interactive-read`` subcommand, to check whether the script is being called from an interactive :doc:`read <cmds/read>` invocation.
- fish's background tasks are now started in a way that avoids an error on macOS Terminal.app (:issue:`11181`).
- Using key combinations within qemu should work correctly.
- Prompts containing control characters no longer cause incorrect display of command lines (:issue:`11252`).
- Cancelling the command-line in Vi mode displays correctly again (:issue:`11261`).
- The acidhub prompt properly displays the git branch again (:issue:`11179`).
- Completions for ``wine`` correctly include files again (:issue:`11202`).
- On macOS, paths from ``/etc/paths`` and ``/etc/manpaths`` containing colons are handled correctly (:issue:`10684`). This functionality was included in the 4.0.0 release notes but was missing from the source code.
- The XTerm ``modifyOtherKeys`` keyboard encoding is no longer used under WezTerm, as it does not work correctly in all layouts (:issue:`11204`).
-:kbd:`option-left` and other similar keys should now work in iTerm versions before 3.5.12; the kitty keyboard protocol is now disabled on these versions (:issue:`11192`).
- The kitty keyboard protocol is no longer used under Midnight Commander, as it does not work correctly (:issue:`10640`).
- fish now sends the commandline along with the OSC 133 semantic prompt command start sequence. This fixes a test in the kitty terminal (:issue:`11203`).
- Git completions for third-party commands like "git-absorb" are completed correctly again (:issue:`11205`).
- Completions for ``diskutil`` no longer produce an error (:issue:`11201`).
- The output of certain error messages no longer prints newlines to standard output (:issue:`11248`).
- A number of crashes have been fixed, including file names longer than 255 bytes (:issue:`11221`), using fish on a btrfs filesystem (:issue:`11219`), history files that do not have the expected format (:issue:`11236`), and pasting into an empty command line (:issue:`11256`).
--------------
fish 4.0.0 (released February 27, 2025)
=======================================
These are the draft release notes for fish 4.0.0. Like this release of fish itself, they are in beta and are not complete. Please report any issues you find.
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.
Packagers should see the :ref:`For Distributors <rust-packaging>` section at the end.
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.
- 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.
-Terminals that fail to ignore unrecognized OSC or CSI sequences may display garbage. We know cool-retro-term and emacs' ansi-term are affected,
most mainstream terminals are not.
-:kbd:`alt-left` and :kbd:`alt-right` will now move by one argument (which may contain quoted spaces), not just one word like :kbd:`ctrl-left` and :kbd:`ctrl-right` do.
-:kbd:`alt-backspace` will delete an entire argument, not just one word (which is :kbd:`ctrl-backspace` now).
-: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`).
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.
- 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
------------------------------
@@ -51,23 +180,30 @@ Notable improvements and fixes
-``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/``. To uninstall, remove the fish binaries and that directory.
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`).
-:kbd:`ctrl-c` during command input no longer prints ``^C`` and a new prompt, but merely clears the command line. This restores the behavior from version 2.2. To revert to the old behavior, use ``bind ctrl-c __fish_cancel_commandline`` (:issue:`10213`).
- 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`).
- 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.
- 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^'
@@ -97,6 +233,7 @@ Deprecations and removed features
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
----------------------
@@ -123,6 +260,8 @@ Scripting improvements
- 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
------------------------
@@ -142,11 +281,19 @@ Interactive improvements
- 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`).
-``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`).
- 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
^^^^^^^^^^^^^^^^^^^^^^^^
@@ -154,34 +301,40 @@ New or improved bindings
- 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.
-:kbd:`alt-delete` now deletes the argument (which may contain quoted spaces) right of the cursor.
- 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:`ctrl-c` no longer cancels builtin ``read``.
-: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`).
-``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`).
@@ -191,13 +344,16 @@ Completions
- 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`).
-Historically, file name completions are provided after the last ``:`` or ``=``within a token.
-Normally, file name completions start after the last ``:`` or ``=`` in a token.
This helps commands like ``rsync --files-from=``.
If the ``=`` or ``:`` is actually part of the filename, it will be escaped as ``\:`` and ``\=``,
and no longer get this special treatment.
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
^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -213,10 +369,14 @@ Improved terminal support
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:
@@ -225,10 +385,23 @@ 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 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)
@@ -487,7 +660,7 @@ fish 3.6.0 (released January 7, 2023)
Notable improvements and fixes
------------------------------
- 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`):
- Abbreviations are more flexible (:issue:`9313`, :issue:`5003`, :issue:`2287`):
- They may optionally replace tokens anywhere on the command line, instead of only commands
- Matching tokens may be described using a regular expression instead of a literal word
@@ -583,7 +756,7 @@ Interactive improvements
- 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`).
- 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 interactively.
-: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`).
- The key combination for the QUIT terminal sequence, often :kbd:`ctrl-\\` (``\x1c``), can now be used as a binding (:issue:`9234`).
@@ -812,7 +985,7 @@ Interactive improvements
New or improved bindings
^^^^^^^^^^^^^^^^^^^^^^^^
- 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 preceding 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`).
- 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`).
@@ -921,7 +1094,7 @@ Deprecations and removed features
> set -Ua fish_features ampersand-nobg-in-token
-``$status`` is now forbidden as a command, to prevent a surprisingly common error among new users: Running ``if $status`` (:issue:`8171`). This applies *only* to ``$status``, other variables are still allowed.
-``set --query`` now returns an exit status of 255 if given no variable names. This means ``if set -q $foo`` will not enter the if-block if ``$foo`` is empty or unset. To restore the previous behavior, use ``if not set -q foo; or set -q $foo`` - but this is unlikely to be desireable (:issue:`8214`).
-``set --query`` now returns an exit status of 255 if given no variable names. This means ``if set -q $foo`` will not enter the if-block if ``$foo`` is empty or unset. To restore the previous behavior, use ``if not set -q foo; or set -q $foo`` - but this is unlikely to be desirable (:issue:`8214`).
-``_`` is now a reserved keyword (:issue:`8342`).
- The special input functions ``delete-or-exit``, ``nextd-or-forward-word`` and ``prevd-or-backward-word`` replace fish functions of the same names (:issue:`8538`).
- Mac OS X 10.9 is no longer supported. The minimum Mac version is now 10.10 "Yosemite."
@@ -944,7 +1117,7 @@ Scripting improvements
-``commandline`` gained a ``--paging-full-mode`` option to check if the pager is showing all the possible lines (no "7 more rows" message) (:issue:`8485`).
- List expansion correctly reports an error when used with all zero indexes (:issue:`8213`).
- Running ``fish`` with a directory instead of a script as argument (eg ``fish .``) no longer leads to an infinite loop. Instead it errors out immediately (:issue:`8258`)
- Some error messages occuring after fork, like "text file busy" have been replaced by bespoke error messages for fish (like "File is currently open for writing"). This also restores error messages with current glibc versions that removed sys_errlist (:issue:`8234`, :issue:`4183`).
- Some error messages occurring after fork, like "text file busy" have been replaced by bespoke error messages for fish (like "File is currently open for writing"). This also restores error messages with current glibc versions that removed sys_errlist (:issue:`8234`, :issue:`4183`).
- The ``realpath`` builtin now also squashes leading slashes with the ``--no-symlinks`` option (:issue:`8281`).
- When trying to ``cd`` to a dangling (broken) symbolic link, fish will print an error noting that the target is a broken link (:issue:`8264`).
- On MacOS terminals that are not granted permissions to access a folder, ``cd`` would print a spurious "rotten symlink" error, which has been corrected to "permission denied" (:issue:`8264`).
@@ -1450,7 +1623,7 @@ Interactive improvements
-: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:`ctrl-c` no longer kills background jobs for which job control is
- Autosuggestions work properly after :kbd:`ctrl-c` cancels the current commmand line (:issue:`6937`).
- Autosuggestions work properly after :kbd:`ctrl-c` cancels the current command line (:issue:`6937`).
- 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`).
- Aliases containing an embedded backslash appear properly in the output of ``alias`` (:issue:`6910`).
@@ -2004,7 +2177,7 @@ Interactive improvements
argument.
- Syntax highlighting works correctly with variables as commands
(:issue:`5658`) and redirections to close file descriptors (:issue:`6092`).
-``help`` works properly on Windows Subsytem for Linux (:issue:`5759`, :issue:`6338`).
-``help`` works properly on Windows Subsystem for Linux (:issue:`5759`, :issue:`6338`).
- A bug where ``disown`` could crash the shell has been fixed (:issue:`5720`).
- fish will not autosuggest files ending with ``~`` unless there are no
other candidates, as these are generally backup files (:issue:`985`).
@@ -2946,7 +3119,7 @@ Other significant changes
- Some systems’``su`` implementations do not set the ``USER``
environment variable; it is now reset for root users (:issue:`3916`).
- Under terminals which support it, bracketed paste is enabled,
escaping problematic characters for security and convience (:issue:`3871`).
escaping problematic characters for security and convenience (:issue:`3871`).
Inside single quotes (``'``), single quotes and backslashes in pasted
text are escaped (:issue:`967`). The ``fish_clipboard_paste`` function (bound
to ``C-v`` by default) is still the recommended pasting method where
@@ -3075,9 +3248,9 @@ Other significant changes
- fish no longer prints a warning when it identifies a running instance
of an old version (2.1.0 and earlier). Changes to universal variables
may not propagate between these old versions and 2.5b1.
- Improved compatiblity with Android (:issue:`3585`), MSYS/mingw (:issue:`2360`), and
- Improved compatibility with Android (:issue:`3585`), MSYS/mingw (:issue:`2360`), and
Solaris (:issue:`3456`, :issue:`3340`).
- Like other shells, the ``test`` builting now returns an error for
- Like other shells, the ``test`` built-in now returns an error for
numeric operations on invalid integers (:issue:`3346`, :issue:`3581`).
-``complete`` no longer recognises ``--authoritative`` and
``--unauthoritative`` options, and they are marked as obsolete.
- 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`` and ``build_tools/style.fish``)
- Use automated tools to help you (including ``make fish_run_tests`` and ``build_tools/style.fish``)
Contributing completions
========================
Completion scripts are the most common contribution to fish, and they are very welcome.
In general, we'll take all well-written completion scripts for a command that is publically available.
In general, we'll take all well-written completion scripts for a command that is publicly available.
This means no private tools or personal scripts, and we do reserve the right to reject for other reasons.
Before you try to contribute them to fish, consider if the authors of the tool you are completing want to maintain the script instead.
@@ -196,8 +196,14 @@ The tests can be found in three places:
- 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.
If your littlecheck test has a specific dependency, use ``# REQUIRE: ...`` with a posix sh script.
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 tests/pexpect_helper.py, in case you need to modify something there.
These tests can be run via the tests/test_driver.py python script, which will set up the environment.
It sets up a temporary $HOME and also uses it as the current directory, so you do not need to create a temporary directory in them.
If you need a command to do something weird to test something, maybe add it to the ``fish_test_helper`` binary (in tests/fish_test_helper.c), or see if it can already do it.
Local testing
-------------
@@ -207,7 +213,18 @@ The tests can be run on your local computer on all operating systems.
::
cmake path/to/fish-shell
make test
make fish_run_tests
Or you can run them on a fish, without involving cmake::
cargo build
cargo test # for the unit tests
tests/test_driver.py --cachedir=/tmp target/debug # for the script and interactive tests
Here, the first argument to test_driver.py refers to a directory with ``fish``, ``fish_indent`` and ``fish_key_reader`` in it.
In this example we're in the root of the git repo and have run ``cargo build`` without ``--release``, so it's a debug build.
The ``--cachedir /tmp`` argument means it will keep the fish_test_helper binary in /tmp instead of recompiling it for every test.
This saves some time, but isn't strictly necessary.
Git hooks
---------
@@ -235,7 +252,7 @@ One possibility is a pre-push hook script like this one:
done
if["x$isprotected"= x1 ];then
echo"Running tests before push to master"
make test
make fish_run_tests
RESULT=$?
if[$RESULT -ne 0];then
echo"Tests failed for a push to master, we can't let you do that" >&2
@@ -245,7 +262,7 @@ One possibility is a pre-push hook script like this one:
exit0
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
``git push --no-verify``, but usually that isn’t necessary.
and can be installed using the following commands:
::
sudo apt-add-repository ppa:fish-shell/release-3
sudo apt-add-repository ppa:fish-shell/release-4
sudo apt update
sudo apt install fish
@@ -75,7 +75,7 @@ If packages are not available for your platform, GPG-signed tarballs are
available from `fishshell.com <https://fishshell.com/>`__ and
`fish-shell on
GitHub <https://github.com/fish-shell/fish-shell/releases>`__. See the
`Building <#building>`__ section for instructions.
`Building <#building>`_ section for instructions.
Running fish
------------
@@ -87,8 +87,6 @@ Dependencies
Running fish requires:
- 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
addition to the basic POSIX utilities (``cat``, ``cut``, ``dirname``,
- a C compiler (for system feature detection and the test helper binary)
- PCRE2 (headers and libraries) - optional, this will be downloaded if missing
- gettext (headers and libraries) - optional, for translation support
@@ -159,6 +157,9 @@ CMake Build options
In addition to the normal CMake build options (like ``CMAKE_INSTALL_PREFIX``), fish's CMake build has some other options available to customize it.
- Rust_COMPILER=path - the path to rustc. If not set, cmake will check $PATH and ~/.cargo/bin
- Rust_CARGO=path - the path to cargo. If not set, cmake will check $PATH and ~/.cargo/bin
- Rust_CARGO_TARGET=target - the target to pass to cargo. Set this for cross-compilation.
- 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).
- FISH_USE_SYSTEM_PCRE2=ON|OFF - whether to use an installed pcre2. This is normally autodetected.
@@ -166,19 +167,19 @@ In addition to the normal CMake build options (like ``CMAKE_INSTALL_PREFIX``), f
- 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
Building fish as self-installable (experimental)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Building fish with embedded data (experimental)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can also build fish as a self-installing binary.
You can also build fish with the data files embedded.
This will include all the datafiles like the included functions or web configuration tool in the main ``fish`` binary.
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``.
Fish will then read these right from its own binary, and print them out when needed. Some files, like the webconfig tool and the manpage completion generator, will be extracted to a temporary directory on-demand. You can list the files with ``status list-files`` and print one with ``status get-file path/to/file`` (e.g. ``status get-file functions/fish_prompt.fish`` to get the default prompt).
To install fish as self-installable, just use ``cargo``, like::
To install fish with embedded files, 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 --tag 4.0.0 # to build from git with a specific version
cargo install --git https://github.com/fish-shell/fish-shell # to build the current development snapshot without cloning
This will place the binaries in ``~/.cargo/bin/``, but you can place them wherever you want.
@@ -53,7 +53,7 @@ Combining these features, it is possible to create custom syntaxes, where a regu
> abbr > ~/.config/fish/conf.d/myabbrs.fish
This will save all your abbrevations in "myabbrs.fish", overwriting the whole file so it doesn't leave any duplicates,
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>`.
@@ -125,6 +125,7 @@ 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.
::
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.
@@ -20,7 +20,7 @@ Each option specification (``OPTION_SPEC``) is written in the :ref:`domain speci
Each option that is seen in the ARG list will result in variables named ``_flag_X``, where **X** is the short flag letter and the long flag name (if they are defined). For example a **--help** option could cause argparse to define one variable called ``_flag_h`` and another called ``_flag_help``.
The variables will be set with local scope (i.e., as if the script had done ``set -l _flag_X``). If the flag is a boolean (that is, it just is passed or not, it doesn't have a value) the values are the short and long flags seen. If the option is not a boolean the values will be zero or more values corresponding to the values collected when the ARG list is processed. If the flag was not seen the flag variable will not be set.
The variables will be set with local scope (i.e., as if the script had done ``set -l _flag_X``). If the flag is a boolean (that is, it is passed or not, it doesn't have a value) the values are the short and long flags seen. If the option is not a boolean the values will be zero or more values corresponding to the values collected when the ARG list is processed. If the flag was not seen the flag variable will not be set.
Options
-------
@@ -165,7 +165,7 @@ This isn't specific to argparse but common to all things using ``getopt(3)`` (if
Flag Value Validation
---------------------
Sometimes you need to validate the option values. For example, that it is a valid integer within a specific range, or an ip address, or something entirely different. You can always do this after ``argparse`` returns but you can also request that ``argparse`` perform the validation by executing arbitrary fish script. To do so simply append an ``!`` (exclamation-mark) then the fish script to be run. When that code is executed three vars will be defined:
Sometimes you need to validate the option values. For example, that it is a valid integer within a specific range, or an ip address, or something entirely different. You can always do this after ``argparse`` returns but you can also request that ``argparse`` perform the validation by executing arbitrary fish script. To do so append an ``!`` (exclamation-mark) then the fish script to be run. When that code is executed three vars will be defined:
-``_argparse_cmd`` will be set to the value of the value of the ``argparse --name`` value.
@@ -177,7 +177,7 @@ These variables are passed to the function as local exported variables.
The script should write any error messages to stdout, not stderr. It should return a status of zero if the flag value is valid otherwise a non-zero status to indicate it is invalid.
Fish ships with a ``_validate_int`` function that accepts a ``--min`` and ``--max`` flag. Let's say your command accepts a ``-m`` or ``--max`` flag and the minimum allowable value is zero and the maximum is 5. You would define the option like this: ``m/max=!_validate_int --min 0 --max 5``. The default if you just call ``_validate_int`` without those flags is to simply check that the value is a valid integer with no limits on the min or max value allowed.
Fish ships with a ``_validate_int`` function that accepts a ``--min`` and ``--max`` flag. Let's say your command accepts a ``-m`` or ``--max`` flag and the minimum allowable value is zero and the maximum is 5. You would define the option like this: ``m/max=!_validate_int --min 0 --max 5``. The default if you call ``_validate_int`` without those flags is to check that the value is a valid integer with no limits on the min or max value allowed.
Here are some examples of flag validations::
@@ -234,7 +234,7 @@ A simple use::
return 0
end
This just wants one option - ``-h`` / ``--help``. Any other option is an error. If it is given it prints help and exits.
This supports one option - ``-h`` / ``--help``. Any other option is an error. If it is given it prints help and exits.
@@ -21,6 +22,8 @@ The block is unconditionally executed. ``begin; ...; end`` is equivalent to ``if
``begin`` does not change the current exit status itself. After the block has completed, ``$status`` will be set to the status returned by the most recent command.
Some other shells only support the ``{ [COMMANDS ...] ; }`` notation.
The **-h** or **--help** option displays help about using this command.
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.
If only ``KEYS`` is given, any existing binding for those keys in the given ``MODE`` will be printed.
If no ``KEYS`` argument is provided, all bindings (in the given ``MODE``) are printed.
``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-``.
Modifier keys can be specified by prefixing a key name with a combination of ``ctrl-``, ``alt-``,``shift-`` and ``super-`` (i.e. the "windows" or "command" key).
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`.
@@ -41,9 +43,11 @@ They are:
-``f1`` through ``f12``.
-``home``,
-``insert``,
-``menu``,
-``minus`` (``-``),
-``pageup``,
-``pagedown``,
-``printscreen``,
-``space`` and
-``tab``,
@@ -58,9 +62,7 @@ To find the name of a key combination you can use :doc:`fish_key_reader <fish_ke
..note::
If a script changes the commandline, it should finish by calling the ``repaint`` special input function.
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``.
Key bindings may use "modes", which mimics vi's modal input behavior. The default mode is "default" (in vi-mode, that's vi's "normal" mode). 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.
@@ -71,11 +73,16 @@ The following options are available:
**-f** or **--function-names**
Display a list of available input functions
**-K** or **--key-names**
Display a list of available named keys such as ``backspace``.
**-L** or **--list-modes**
Display a list of defined bind modes
**-M MODE** or **--mode***MODE*
Specify a bind mode that the bind is used in. Defaults to "default"
Specify a bind mode that the bind is used in. Defaults to "default".
If you use :ref:`vi bindings <vi-mode>`, that's the *command* mode,
what vi calls "normal" mode.
**-m NEW_MODE** or **--sets-mode***NEW_MODE*
Change the current mode to *NEW_MODE* after this binding is executed
@@ -162,7 +169,7 @@ The following special input functions are available:
start selecting text
``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
``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
@@ -170,8 +177,14 @@ The following special input functions are available:
``capitalize-word``
make the current word begin with a capital letter
``clear-commandline``
empty the entire commandline
``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.
``scrollback-push``
pushes earlier output to the terminal scrollback, positioning the prompt at the top.
``complete``
guess the remainder of the current token
@@ -237,7 +250,7 @@ The following special input functions are available:
``history-pager``
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-delete``
permanently delete the current history item, either from the history pager or from an active up-arrow history search
``history-search-backward``
@@ -258,8 +271,14 @@ The following special input functions are available:
``history-token-search-forward``
search the history for the next matching argument
``history-last-token-search-backward``
search the history for the previous matching last argument
``history-last-token-search-forward``
search the history for the next matching last argument
``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``
jump to right *before* the next occurrence
@@ -269,7 +288,7 @@ The following special input functions are available:
``jump-to-matching-bracket``
jump to matching bracket if the character under the cursor is bracket;
otherwise, jump to the next occurence of *any right* bracket after the cursor.
otherwise, jump to the next occurrence of *any right* bracket after the cursor.
The following brackets are considered: ``([{}])``
``jump-till-matching-bracket``
@@ -292,7 +311,7 @@ The following special input functions are available:
move the selected text to the killring
``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``
move the line (without the following newline) to the killring
@@ -45,8 +45,9 @@ The following options change the way ``commandline`` updates the command line bu
**-a** or **--append**
Do not remove the current commandline, append the specified string at the end of it.
**-i** or **--insert**
Do not remove the current commandline, insert the specified string at the current cursor position
**-i**, **--insert** or **--insert-smart**
Do not remove the current commandline, insert the specified string at the current cursor position.
The **--insert-smart** option turns on a Do-What-I-Mean (DWIM) mode: it strips any **$** prefix from the first command on each line.
**-r** or **--replace**
Remove the current commandline and replace it with the specified string (default)
@@ -71,7 +72,7 @@ The following options change what part of the commandline is printed or updated:
Selects the current token
**--search-field**
Use the pager search field instead of the command line. Returns false is the search field is not shown.
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:
@@ -116,7 +117,7 @@ The following options output metadata about the commandline state:
**--is-valid**
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 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.
@@ -63,7 +63,9 @@ The following options are available:
Add a description for this completion, to be shown in the completion pager.
**-w** or **--wraps***WRAPPED_COMMAND*
Causes the specified command to inherit completions from *WRAPPED_COMMAND* (see below for details).
Causes the specified command to inherit completions from *WRAPPED_COMMAND*.
This is used for "this command completes like that other command" kinds of relationships.
See below for details.
**-n** or **--condition***CONDITION*
This completion should only be used if the *CONDITION* (a shell command) returns 0. This makes it possible to specify completions that should only be used in some cases. If multiple conditions are specified, fish will try them in the order they are specified until one fails or all succeeded.
@@ -24,7 +24,8 @@ The :ref:`tutorial <tutorial>` is available as HTML via ``help tutorial`` or in
The following options are available:
**-c** or **--command=COMMAND**
Evaluate the specified commands instead of reading from the commandline, passing additional positional arguments through ``$argv``.
Evaluate the specified commands instead of reading from the commandline.
Any additional positional arguments are used as ``$argv``.
**-C** or **--init-command=COMMANDS**
Evaluate specified commands after reading the configuration but before executing command specified by **-c** or reading interactive input.
@@ -34,16 +35,12 @@ The following options are available:
See :ref:`Debugging <debugging-fish>` below for details.
**-o** or **--debug-output=DEBUG_FILE**
Specifies a file path to receive the debug output, including categories and :envvar:`fish_trace`.
The default is stderr.
Specifies a file path to receive the debug output, including categories and :envvar:`fish_trace`.
The default is standard error.
**-i** or **--interactive**
The shell is interactive.
**--install**
When built as self-installable (via cargo), this will unpack fish's datafiles and place them in ~/.local/share/fish/install/.
Fish will also ask to do this automatically when run interactively.
**-l** or **--login**
Act as if invoked as a login shell.
@@ -104,3 +101,33 @@ These options can also be changed via the :envvar:`FISH_DEBUG` and :envvar:`FISH
The categories enabled via **--debug** are *added* to the ones enabled by $FISH_DEBUG, so they can be disabled by prefixing them with **-** (**reader-*,-ast*** enables reader debugging and disables ast debugging).
The file given in **--debug-output** takes precedence over the file in :envvar:`FISH_DEBUG_OUTPUT`.
Examples
--------
To just start fish::
fish
To run a file with fish::
fish /path/to/script.fish
To run some commands with fish::
fish -c 'echo Hi there!'
You can also pass arguments to those commands::
> fish -c 'printf %s\n $argv' "first line" "second line"
first line
second line
To run a script, except read this other file first::
fish --init-cmd "source otherfile" script.fish
To :ref:`profile <profiling>` fish's startup and find what takes the most time in your configuration::
@@ -38,7 +38,7 @@ The following options are available:
Displays the current :program:`fish` version and then exits.
**--ansi**
Colorizes the output using ANSI escape sequences, appropriate for the current :envvar:`TERM`, using the colors defined in the environment (such as :envvar:`fish_color_command`).
Colorizes the output using ANSI escape sequences using the colors defined in the environment (such as :envvar:`fish_color_command`).
**--html**
Outputs HTML, which supports syntax highlighting if the appropriate CSS is defined. The CSS class names are the same as the variable names, such as ``fish_color_command``.
@@ -31,6 +31,8 @@ You can also define an empty ``fish_mode_prompt`` function to remove the vi mode
``fish_mode_prompt`` will be executed when the vi mode changes. If it produces any output, it is displayed and used. If it does not, the other prompt functions (:doc:`fish_prompt <fish_prompt>` and :doc:`fish_right_prompt <fish_right_prompt>`) will be executed as well in case they contain a mode display.
If :envvar:`fish_transient_prompt` is set to 1, ``fish_mode_prompt --final-rendering`` is run before executing the commandline.
@@ -24,6 +24,8 @@ The ``fish_prompt`` function is executed when the prompt is to be shown, and the
The exit status of commands within ``fish_prompt`` will not modify the value of :ref:`$status <variables-status>` outside of the ``fish_prompt`` function.
If :envvar:`fish_transient_prompt` is set to 1, ``fish_prompt --final-rendering`` is run before executing the commandline.
``fish`` ships with a number of example prompts that can be chosen with the ``fish_config`` command.
@@ -27,7 +27,11 @@ The following options are available:
A description of what the function does, suitable as a completion description.
**-w***WRAPPED_COMMAND* or **--wraps***WRAPPED_COMMAND*
Inherit completions from the given *WRAPPED_COMMAND*. See the documentation for :doc:`complete <complete>` for more information.
Inherit completions from the given *WRAPPED_COMMAND*.
This is used to say that this function completes like that command,
for example if you're creating an alias.
See the documentation for :doc:`complete <complete>` for more information.
If the wrapped command is the same as the function name, this will be ignored.
**-e***EVENT_NAME* or **--on-event***EVENT_NAME*
Run this function when the specified named event is emitted. Fish internally generates named events, for example, when showing the prompt. Custom events can be emitted using the :doc:`emit <emit>` command.
The following operations (sub-commands) are available:
**search**
Returns history items matching the search string. If no search string is provided it returns all history items. This is the default operation if no other operation is specified. You only have to explicitly say ``history search`` if you wish to search for one of the subcommands. The ``--contains`` search option will be used if you don't specify a different search option. Entries are ordered newest to oldest unless you use the ``--reverse`` flag. If stdout is attached to a tty the output will be piped through your pager by the history function. The history builtin simply writes the results to stdout.
Returns history items matching the search string. If no search string is provided it returns all history items. This is the default operation if no other operation is specified. You only have to explicitly say ``history search`` if you wish to search for one of the subcommands. The ``--contains`` search option will be used if you don't specify a different search option. Entries are ordered newest to oldest unless you use the ``--reverse`` flag. If stdout is attached to a tty the output will be piped through your pager by the history function. The history builtin writes the results to stdout.
**delete**
Deletes history items. The ``--contains`` search option will be used if you don't specify a different search option. If you don't specify ``--exact`` a prompt will be displayed before any items are deleted asking you which entries are to be deleted. You can enter the word "all" to delete all matching entries. You can enter a single ID (the number in square brackets) to delete just that single entry. You can enter more than one ID, or an ID range separated by a space to delete multiple entries. Just press [enter] to not delete anything. Note that the interactive delete behavior is a feature of the history function. The history builtin only supports ``--exact --case-sensitive`` deletion.
Deletes history items. The ``--contains`` search option will be used if you don't specify a different search option. If you don't specify ``--exact`` a prompt will be displayed before any items are deleted asking you which entries are to be deleted. You can enter the word "all" to delete all matching entries. You can enter a single ID (the number in square brackets) to delete just that single entry. You can enter more than one ID, or an ID range separated by a space to delete multiple entries. Press [enter] to not delete anything. Note that the interactive delete behavior is a feature of the history function. The history builtin only supports ``--exact --case-sensitive`` deletion.
**merge**
Immediately incorporates history changes from other sessions. Ordinarily ``fish`` ignores history changes from sessions started after the current one. This command applies those changes immediately.
@@ -52,7 +52,7 @@ The following options are available:
These flags can appear before or immediately after one of the sub-commands listed above.
**-C** or **--case-sensitive**
Does a case-sensitive search. The default is case-insensitive. Note that prior to fish 2.4.0 the default was case-sensitive.
Does a case-sensitive search. The default is case-insensitive.
**-c** or **--contains**
Searches items in the history that contain the specified text string. This is the default for the **--search** flag. This is not currently supported by the **delete** subcommand.
``path change-extension`` returns the given paths, with their extension changed to the given new extension. The extension is the part after (and including) the last ".", unless that "." followed a "/" or the basename is "." or "..", in which case there is no previous extension and the new one is simply added.
``path change-extension`` returns the given paths, with their extension changed to the given new extension. The extension is the part after (and including) the last ".", unless that "." followed a "/" or the basename is "." or "..", in which case there is no previous extension and the new one is added.
If the extension is empty, any previous extension is stripped, along with the ".". This is, of course, the inverse of ``path extension``.
@@ -101,7 +101,7 @@ If no option to determine how to split like ``--delimiter``, ``--line`` or ``--t
With the ``--line`` option, ``read`` reads a line of input from standard input into each provided variable, stopping when each variable has been filled. The line is not tokenized.
If no variable names are provided, ``read`` enters a special case that simply provides redirection from standard input to standard output, useful for command substitution. For instance, the fish shell command below can be used to read a password from the console instead of hardcoding it in the command itself, which prevents it from showing up in fish's history::
If no variable names are provided, ``read`` enters a special case that provides redirection from standard input to standard output, useful for command substitution. For instance, the fish shell command below can be used to read a password from the console instead of hardcoding it in the command itself, which prevents it from showing up in fish's history::
The *br*- (as in 'bright') forms are full-brightness variants of the 8 standard-brightness colors on many terminals. **brblack** has higher brightness than **black** - towards gray.
An RGB value with three or six hex digits, such as A0FF33 or f2f can be used. Fish will choose the closest supported color. A three digit value is equivalent to specifying each digit twice; e.g., ``set_color 2BC`` is the same as ``set_color 22BBCC``. Hexadecimal RGB values can be in lower or uppercase. Depending on the capabilities of your terminal (and the level of support ``set_color`` has for it) the actual color may be approximated by a nearby matching reserved color name or ``set_color`` may not have an effect on color.
An RGB value with three or six hex digits, such as A0FF33 or f2f can be used.
A three digit value is equivalent to specifying each digit twice; e.g., ``set_color 2BC`` is the same as ``set_color 22BBCC``.
Hexadecimal RGB values can be in lower or uppercase.
A second color may be given as a desired fallback color. e.g. ``set_color 124212 brblue`` will instruct set_color to use *brblue* if a terminal is not capable of the exact shade of grey desired. This is very useful when an 8 or 16 color terminal might otherwise not use a color.
If :envvar:`fish_term24bit` is set to 0, fish will translate RGB values to the nearest color on the 256-color palette.
If :envvar:`fish_term256` is also set to 0, fish will translate them to the 16-color palette instead.
Fish launched as ``fish -d term_support`` will include diagnostic messages that indicate the color support mode in use.
If multiple colors are specified, fish prefers the first RGB one.
However if :envvar:`fish_term256` is set to 0, fish prefers the first named color specified.
The following options are available:
**-b** or **--background***COLOR*
Sets the background color.
**--underline-color***COLOR*
Set the underline color.
**-c** or **--print-colors**
Prints the given colors or a colored list of the 16 named colors.
@@ -46,18 +56,22 @@ The following options are available:
**-r** or **--reverse**
Sets reverse mode.
**-u** or **--underline**
Sets underlined mode.
**-u** or **--underline**, or **-uSTYLE** or **--underline=STYLE**
Set the underline mode; supported styles are **single** (default) and **curly**.
**--track=THEME**
Ignored. Included by default in universally-scoped color variables to tell fish to update
them as the associated theme changes.
This flag can be set for all variables when loading a theme with the `--track`` option, that is
:doc:`fish_config theme save THEME --track <fish_config>`.
**-h** or **--help**
Displays help about using this command.
Using the **normal** keyword will reset foreground, background, and all formatting back to default.
Notes
-----
1. Using the **normal** keyword will reset both background and foreground colors to whatever is the default for the terminal.
1. Using **set_color normal** will reset all colors and modes to the terminal's default.
2. Setting the background color only affects subsequently written characters. Fish provides no way to set the background color for the entire terminal window. Configuring the window background color (and other attributes such as its opacity) has to be done using whatever mechanisms the terminal provides. Look for a config option.
3. Some terminals use the ``--bold`` escape sequence to switch to a brighter color set rather than increasing the weight of text.
4.``set_color`` works by printing sequences of characters to standard output. If used in command substitution or a pipe, these characters will also be captured. This may or may not be desirable. Checking the exit status of ``isatty stdout`` before using ``set_color`` can be useful to decide not to colorize output in a script.
@@ -72,24 +86,3 @@ Examples
set_color blue; echo "Violets are blue"
set_color 62A; echo "Eggplants are dark purple"
set_color normal; echo "Normal is nice" # Resets the background too
Terminal Capability Detection
-----------------------------
Fish uses some heuristics to determine what colors a terminal supports to avoid sending sequences that it won't understand.
In particular it will:
- Enable 256 colors if :envvar:`TERM` contains "xterm", except for known exceptions (like MacOS 10.6 Terminal.app)
- Enable 24-bit ("true-color") even if the $TERM entry only reports 256 colors. This includes modern xterm, VTE-based terminals like Gnome Terminal, Konsole and iTerm2.
- Detect support for italics, dim, reverse and other modes.
If terminfo reports 256 color support for a terminal, 256 color support will always be enabled.
To force true-color support on or off, set :envvar:`fish_term24bit` to "1" for on and 0 for off - ``set -g fish_term24bit 1``.
To debug color palette problems, ``tput colors`` may be useful to see the number of colors in terminfo for a terminal. Fish launched as ``fish -d term_support`` will include diagnostic messages that indicate the color support mode in use.
The ``set_color`` command uses the terminfo database to look up how to change terminal colors on whatever terminal is in use. Some systems have old and incomplete terminfo databases, and lack color information for terminals that support it. Fish assumes that all terminals can use the `ANSI X3.64 <https://en.wikipedia.org/wiki/ANSI_escape_code>`_ escape sequences if the terminfo definition indicates a color below 16 is not supported.
fish will search the working directory to resolve relative paths but will not search :envvar:`PATH` .
If no file is specified and stdin is not the terminal, or if the file name ``-`` is used, stdin will be read.
If no file is specified and a file or pipeline is connected to standard input, or if the file name ``-`` is used, ``source`` will read from standard input. If no file is specified and there is no redirected file or pipeline on standard input, an error will be printed.
The exit status of ``source`` is the exit status of the last job to execute. If something goes wrong while opening or reading the file, ``source`` exits with a non-zero status.
@@ -41,8 +41,3 @@ Example
source ~/.config/fish/config.fish
# Causes fish to re-read its initialization file.
Caveats
-------
In fish versions prior to 2.3.0, the :envvar:`argv` variable would have a single element (the name of the sourced file) if no arguments are present. Otherwise, it would contain arguments without the name of the sourced file. That behavior was very confusing and unlike other shells such as bash and zsh.
``string escape`` escapes each *STRING* in one of three ways. The first is **--style=script**. This is the default. It alters the string such that it can be passed back to ``eval`` to produce the original argument again. By default, all special characters are escaped, and quotes are used to simplify the output when possible. If **-n** or **--no-quoted** is given, the simplifying quoted format is not used. Exit status: 0 if at least one string was escaped, or 1 otherwise.
``string escape`` escapes each *STRING* in one of several ways.
**--style=script** (default) alters the string such that it can be passed back to ``eval`` to produce the original argument again. By default, all special characters are escaped, and quotes are used to simplify the output when possible. If **-n** or **--no-quoted** is given, the simplifying quoted format is not used. Exit status: 0 if at least one string was escaped, or 1 otherwise.
**--style=var** ensures the string can be used as a variable name by hex encoding any non-alphanumeric characters. The string is first converted to UTF-8 before being encoded.
``string match`` tests each *STRING* against *PATTERN* and prints matching substrings. Only the first match for each *STRING* is reported unless **-a** or **--all** is given, in which case all matches are reported.
If you specify the **-e** or **--entire** then each matching string is printed including any prefix or suffix not matched by the pattern (equivalent to ``grep`` without the **-o** flag). You can, obviously, achieve the same result by prepending and appending **\*** or **.*** depending on whether or not you have specified the **--regex** flag. The **--entire** flag is simply a way to avoid having to complicate the pattern in that fashion and make the intent of the ``string match`` clearer. Without **--entire** and **--regex**, a *PATTERN* will need to match the entire *STRING* before it will be reported.
If you specify the **-e** or **--entire** then each matching string is printed including any prefix or suffix not matched by the pattern (equivalent to ``grep`` without the **-o** flag). You can, obviously, achieve the same result by prepending and appending **\*** or **.*** depending on whether or not you have specified the **--regex** flag. The **--entire** flag is a way to avoid having to complicate the pattern in that fashion and make the intent of the ``string match`` clearer. Without **--entire** and **--regex**, a *PATTERN* will need to match the entire *STRING* before it will be reported.
Matching can be made case-insensitive with **--ignore-case** or **-i**.
If **--groups-only** or **-g** is given, only the capturing groups will be reported - meaning the full match will be skipped. This is incompatible with **--entire** and **--invert**, and requires **--regex**. It is useful as a simple cutting tool instead of ``string replace``, so you can simply choose "this part" of a string.
If **--groups-only** or **-g** is given, only the capturing groups will be reported - meaning the full match will be skipped. This is incompatible with **--entire** and **--invert**, and requires **--regex**. It is useful as a simple cutting tool instead of ``string replace``, so you can choose "this part" of a string.
If **--index** or **-n** is given, each match is reported as a 1-based start position and a length. By default, PATTERN is interpreted as a glob pattern matched against each entire *STRING* argument. A glob pattern is only considered a valid match if it matches the entire *STRING*.
@@ -52,13 +52,13 @@ Match Glob Examples
::
>_ string match '?' a
>_ string match 'a' a
a
>_ string match 'a*b' axxb
axxb
>_ string match -i 'a??B' Axxb
>_ string match -i 'a*B' Axxb
Axxb
>_ string match -- '-*' -h foo --version bar
@@ -67,7 +67,7 @@ Match Glob Examples
-h
--version
>_ echo 'ok?' | string match '*\?'
>_ echo 'ok?' | string match '*?'
ok?
# Note that only the second STRING will match here.
``string repeat`` repeats the *STRING***-n** or **--count** times. The **-m** or **--max** option will limit the number of outputted characters (excluding the newline). This option can be used by itself or in conjunction with **--count**. If both **--count** and **--max** are present, max char will be outputed unless the final repeated string size is less than max, in that case, the string will repeat until count has been reached. Both **--count** and **--max** will accept a number greater than or equal to zero, in the case of zero, nothing will be outputed. The first argument is interpreted as *COUNT* if **--count** or **--max** are not explicilty specified. If **-N** or **--no-newline** is given, the output won't contain a newline character at the end. Exit status: 0 if yielded string is not empty, 1 otherwise.
``string repeat`` repeats the *STRING***-n** or **--count** times. The **-m** or **--max** option will limit the number of outputted characters (excluding the newline). This option can be used by itself or in conjunction with **--count**. If both **--count** and **--max** are present, max char will be outputted unless the final repeated string size is less than max, in that case, the string will repeat until count has been reached. Both **--count** and **--max** will accept a number greater than or equal to zero, in the case of zero, nothing will be outputted. The first argument is interpreted as *COUNT* if **--count** or **--max** are not explicitly specified. If **-N** or **--no-newline** is given, the output won't contain a newline character at the end. Exit status: 0 if yielded string is not empty, 1 otherwise.
@@ -30,6 +30,7 @@ See also the **--delimiter** option of the :doc:`read <read>` command.
``split0`` has the important property that its output is not further split when used in a command substitution, allowing for the command substitution to produce elements containing newlines. This is most useful when used with Unix tools that produce zero bytes, such as ``find -print0`` or ``sort -z``. See split0 examples below.
Be aware that commandline arguments cannot include NULs, so you likely want to pass to ``string split0`` via a pipe, not a command substitution.
.. END DESCRIPTION
@@ -65,6 +66,7 @@ NUL Delimited Examples
::
>_ # Count files in a directory, without being confused by newlines.
>_ # Note: Don't use `string split0 (find . -print0)`, because arguments cannot include NUL.
@@ -13,7 +13,7 @@ Use the :doc:`set <cmds/set>` command::
set -x key value # typically set -gx key value
set -e key
Since fish 3.1 you can set an environment variable for just one command using the ``key=value some command`` syntax, like in other shells. The two lines below behave identically - unlike other shells, fish will output ``value`` both times::
Since fish 3.1 you can set an environment variable for one command using the ``key=value some command`` syntax, like in other shells. The two lines below behave identically - unlike other shells, fish will output ``value`` both times::
Because history substitution is an awkward interface that was invented before interactive line editing was even possible. Instead of adding this pseudo-syntax, fish opts for nice history searching and recall features. Switching requires a small change of habits: if you want to modify an old line/word, first recall it, then edit.
As a special case, most of the time history substitution is used as ``sudo !!``. In that case just press :kbd:`alt-s`, and it will recall your last commandline with ``sudo`` prefixed (or toggle a ``sudo`` prefix on the current commandline if there is anything).
As a special case, most of the time history substitution is used as ``sudo !!``. In that case press :kbd:`alt-s`, and it will recall your last commandline with ``sudo`` prefixed (or toggle a ``sudo`` prefix on the current commandline if there is anything).
In general, fish's history recall works like this:
- Like other shells, the Up arrow, ``up`` recalls whole lines, starting from the last executed line. So instead of typing ``!!``, you would just hit the up-arrow.
- Like other shells, the Up arrow, ``up`` recalls whole lines, starting from the last executed line. So instead of typing ``!!``, you would hit the up-arrow.
- If the line you want is far back in the history, type any part of the line and then press Up one or more times. This will filter the recalled lines to ones that include this text, and you will get to the line you want much faster. This replaces "!vi", "!?bar.c" and the like. If you want to see more context, you can press ``ctrl-r`` to open the history in the pager.
@@ -174,7 +174,7 @@ In general, fish's history recall works like this:
See :ref:`documentation <editor>` for more details about line editing in fish.
That being said, you can use :ref:`abbreviations` to implement history substitution. Here's just ``!!``::
That being said, you can use :ref:`abbreviations` to implement history substitution. Here's ``!!`` only::
function last_history_item; echo $history[1]; end
abbr -a !! --position anywhere --function last_history_item
@@ -232,7 +232,7 @@ Use the ``$status`` variable. This replaces the ``$?`` variable used in other sh
end
If you are just interested in success or failure, you can run the command directly as the if-condition::
If you are only interested in success or failure, you can run the command directly as the if-condition::
if somecommand
echo "Command succeeded"
@@ -330,7 +330,7 @@ This is more important to fish than other shells because features like syntax hi
Sometimes, there is disagreement on the width. There are numerous causes and fixes for this:
- It is possible the character is simply too new for your system to know - in this case you need to refrain from using it.
- It is possible the character is too new for your system to know - in this case you need to refrain from using it.
- Fish or your terminal might not know about the character or handle it wrong - in this case fish or your terminal needs to be fixed, or you need to update to a fixed version.
- The character has an "ambiguous" width and fish thinks that means a width of X while your terminal thinks it's Y. In this case you either need to change your terminal's configuration or set $fish_ambiguous_width to the correct value.
- The character is an emoji and the host system only supports Unicode 8, while you are running the terminal on a system that uses Unicode >= 9. In this case set $fish_emoji_width to 2.
@@ -340,13 +340,21 @@ This also means that a few things are unsupportable:
- Non-monospace fonts - there is *no way* for fish to figure out what width a specific character has as it has no influence on the terminal's font rendering.
- Different widths for multiple ambiguous width characters - there is no way for fish to know which width you assign to each character.
.._faq-terminal-compatibility:
fish does not work in a specific terminal
-----------------------------------------
The terminal might not meet all of :doc:`fish's requirements <terminal-compatibility>`.
Please report this to your terminal's and to fish's issue tracker.
.._faq-uninstalling:
Uninstalling fish
-----------------
If you want to uninstall fish, first make sure fish is not set as your shell. Run ``chsh -s /bin/bash`` if you are not sure.
If you installed it with a package manager, just use that package manager's uninstall function. If you built fish yourself, assuming you installed it to /usr/local, do this::
If you installed it with a package manager, use that package manager's uninstall function. If you built fish yourself, assuming you installed it to /usr/local, do this::
@@ -192,7 +192,7 @@ Note that both of these are bashisms, and most things can easily be expressed wi
source (command | psub)
just use::
Use::
command | source
@@ -246,7 +246,7 @@ is mostly the same as
foo
EOF
Just like with heredocs, the command has to be prepared to read from stdin. Sometimes this requires special options to be used, often giving a filename of ``-`` turns it on.
Like with heredocs, the command has to be prepared to read from stdin. Sometimes this requires special options to be used, often giving a filename of ``-`` turns it on.
For example::
@@ -266,7 +266,7 @@ and could be written in other shells as
rxvt-unicode
EOF
So heredocs really are just minor syntactical sugar that introduces a lot of special rules, which is why fish doesn't have them. Pipes are a core concept, and are simpler and compose nicer.
So heredocs really are minor syntactical sugar that introduces a lot of special rules, which is why fish doesn't have them. Pipes are a core concept, and are simpler and compose nicer.
..[#] For example, the "EOF" is just a convention, the terminator can be an arbitrary string, something like "THISISTHEEND" also works. And using ``<<-`` trims leading *tab* characters (but not other whitespace), so you can indent the lines, but only with tabs. Substitutions (variables, commands) are done on the heredoc by default, but not if the terminator is quoted: ``cat << "EOF"``.
@@ -326,7 +326,7 @@ and a rough fish equivalent::
This shows a few differences:
- Fish provides :doc:`set_color <cmds/set_color>` to color text. It can use the 16 named colors and also RGB sequences (so you could also use ``set_color 5555FF``)
- Instead of introducing specific escapes like ``\h`` for the hostname, the prompt is simply a function. To achieve the effect of ``\h``, fish provides helper functions like :doc:`prompt_hostname <cmds/prompt_hostname>`, which prints a shortened version of the hostname.
- Instead of introducing specific escapes like ``\h`` for the hostname, the prompt is a function. To achieve the effect of ``\h``, fish provides helper functions like :doc:`prompt_hostname <cmds/prompt_hostname>`, which prints a shortened version of the hostname.
- Fish offers other helper functions for adding things to the prompt, like :doc:`fish_vcs_prompt <cmds/fish_vcs_prompt>` for adding a display for common version control systems (git, mercurial, svn), and :doc:`prompt_pwd <cmds/prompt_pwd>` for showing a shortened ``$PWD`` (the user's home directory becomes ``~`` and any path component is shortened).
The default prompt is reasonably full-featured and its code can be read via ``type fish_prompt``.
@@ -417,7 +417,7 @@ This includes things like:
baz &
done
Fish does not currently have subshells. You will have to find a different solution. The isolation can usually be achieved by just scoping variables (with ``set -l``), but if you really do need to run your code in a new shell environment you can use ``fish -c 'your code here'`` to do so explicitly.
Fish does not currently have subshells. You will have to find a different solution. The isolation can usually be achieved by scoping variables (with ``set -l``), but if you really do need to run your code in a new shell environment you can use ``fish -c 'your code here'`` to do so explicitly.
``()`` subshells are often confused with ``{}`` grouping, which does *not* use a subshell. When you just need to group, you can use ``begin; end`` in fish::
@@ -427,7 +427,7 @@ Fish does not currently have subshells. You will have to find a different soluti
# becomes
begin; foo; bar; end | baz
The pipe will simply be run in the same process, so ``while read`` loops can set variables outside::
The pipe will be run in the same process, so ``while read`` loops can set variables outside::
fish suggests commands as you type, based on :ref:`command history <history-search>`, completions, and valid file paths. As you type commands, you will see a suggestion offered after the cursor, in a muted gray color (which can be changed with the ``fish_color_autosuggestion`` variable).
To accept the autosuggestion (replacing the command line contents), press :kbd:`right` (``→``) or :kbd:`ctrl-f`. To accept the first suggested word, press :kbd:`alt-right` (``→``) or :kbd:`alt-f`. If the autosuggestion is not what you want, just ignore it: it won't execute unless you accept it.
To accept the autosuggestion (replacing the command line contents), press :kbd:`right` (``→``) or :kbd:`ctrl-f`. To accept the first suggested word, press :kbd:`alt-right` (``→``) or :kbd:`alt-f`. If the autosuggestion is not what you want, ignore it: it won't execute unless you accept it.
Autosuggestions are a powerful way to quickly summon frequently entered commands, by typing the first few characters. They are also an efficient technique for navigating through directory hierarchies.
@@ -38,7 +38,7 @@ If you don't like autosuggestions, you can disable them by setting ``$fish_autos
Tab Completion
--------------
Tab completion is a time saving feature of any modern shell. When you type :kbd:`tab`, fish tries to guess the rest of the word under the cursor. If it finds just one possibility, it inserts it. If it finds more, it inserts the longest unambiguous part and then opens a menu (the "pager") that you can navigate to find what you're looking for.
Tab completion is a time saving feature of any modern shell. When you type :kbd:`tab`, fish tries to guess the rest of the word under the cursor. If it finds exactly one possibility, it inserts it. If it finds more, it inserts the longest unambiguous part and then opens a menu (the "pager") that you can navigate to find what you're looking for.
The pager can be navigated with the arrow keys, :kbd:`pageup` / :kbd:`pagedown`, :kbd:`tab` or :kbd:`shift-tab`. Pressing :kbd:`ctrl-s` (the ``pager-toggle-search`` binding - :kbd:`/` in vi mode) opens up a search menu that you can use to filter the list.
@@ -56,7 +56,7 @@ It also provides a large number of program specific scripted completions. Most o
You can also write your own completions or install some you got from someone else. For that, see :ref:`Writing your own completions <completion-own>`.
Completion scripts are loaded on demand, just like :ref:`functions are <syntax-function-autoloading>`. The difference is the ``$fish_complete_path``:ref:`list <variables-lists>` is used instead of ``$fish_function_path``. Typically you can drop new completions in ~/.config/fish/completions/name-of-command.fish and fish will find them automatically.
Completion scripts are loaded on demand, like :ref:`functions are <syntax-function-autoloading>`. The difference is the ``$fish_complete_path``:ref:`list <variables-lists>` is used instead of ``$fish_function_path``. Typically you can drop new completions in ~/.config/fish/completions/name-of-command.fish and fish will find them automatically.
.._color:
@@ -89,7 +89,16 @@ Or, to see all themes, right in your terminal::
Syntax highlighting variables
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The colors used by fish for syntax highlighting can be configured by changing the values of various variables. The value of these variables can be one of the colors accepted by the :doc:`set_color <cmds/set_color>` command. The modifier switches accepted by ``set_color`` like ``--bold``, ``--dim``, ``--italics``, ``--reverse`` and ``--underline`` are also accepted.
The colors used by fish for syntax highlighting can be configured by changing the values of various variables. The value of these variables can be one of the colors accepted by the :doc:`set_color <cmds/set_color>` command.
Options accepted by ``set_color`` like
``--background=``,
``--bold``,
``--dim``,
``--italics``,
``--reverse``,
``--underline`` and
``--underline-color=``
are also accepted.
Example: to make errors highlighted and red, use::
@@ -217,6 +226,8 @@ This prompt is determined by running the :doc:`fish_prompt <cmds/fish_prompt>` a
The output of the former is displayed on the left and the latter's output on the right side of the terminal.
For :ref:`vi mode <vi-mode>`, the output of :doc:`fish_mode_prompt <cmds/fish_mode_prompt>` will be prepended on the left.
If :envvar:`fish_transient_prompt` is set to 1, fish will redraw the prompt with a ``--final-rendering`` argument before running a commandline, allowing you to change it before pushing it to the scrollback.
Fish ships with a few prompts which you can see with :doc:`fish_config <cmds/fish_config>`. If you run just ``fish_config`` it will open a web interface [#]_ where you'll be shown the prompts and can pick which one you want. ``fish_config prompt show`` will show you the prompts right in your terminal.
For example ``fish_config prompt choose disco`` will temporarily select the "disco" prompt. If you like it and decide to keep it, run ``fish_config prompt save``.
@@ -303,9 +314,11 @@ Some bindings are common across Emacs and vi mode, because they aren't text edit
-:kbd:`alt-enter` inserts a newline at the cursor position. This is useful to add a line to a commandline that's already complete.
-:kbd:`alt-left` (``←``) and :kbd:`alt-right` (``→``) move the cursor one argument left or right, or moves forward/backward in the directory history if the command line is empty. If the cursor is already at the end of the line, and an autosuggestion is available, :kbd:`alt-right` (``→``) (or :kbd:`alt-f`) accepts the first argument in the suggestion.
-:kbd:`alt-left` (``←``) and :kbd:`alt-right` (``→``) move the cursor left or right by one argument (or one word on macOS).
If the command line is empty, they move forward/backward in the directory history.
If the cursor is already at the end of the line, and an autosuggestion is available, :kbd:`alt-right` (``→``) (or :kbd:`alt-f`) accepts the first argument (or word on macOS) in the suggestion.
-:kbd:`ctrl-left` (``←``) and :kbd:`ctrl-right` (``→``) move the cursor one word left or right. These accept one word of the autosuggestion - the part they'd move over.
-:kbd:`ctrl-left` (``←``) and :kbd:`ctrl-right` (``→``) move the cursor left or right by one word. These accept one word of the autosuggestion - the part they'd move over.
-:kbd:`shift-left` (``←``) and :kbd:`shift-right` (``→``) move the cursor one word left or right, without stopping on punctuation. These accept one big word of the autosuggestion.
@@ -325,9 +338,15 @@ Some bindings are common across Emacs and vi mode, because they aren't text edit
-:kbd:`ctrl-x` copies the current buffer to the system's clipboard, :kbd:`ctrl-v` inserts the clipboard contents. (see :doc:`fish_clipboard_copy <cmds/fish_clipboard_copy>` and :doc:`fish_clipboard_paste <cmds/fish_clipboard_paste>`)
-:kbd:`alt-d` or :kbd:`ctrl-delete` moves the next word to the :ref:`killring`.
-:kbd:`alt-d` moves the next word to the :ref:`killring`.
-:kbd:`alt-delete` moves the next argument to the :ref:`killring`.
-:kbd:`ctrl-delete` moves the next word (or next argument on macOS) to the :ref:`killring`.
-:kbd:`alt-d` lists the directory history if the command line is empty.
-:kbd:`alt-delete` moves the next argument (or word on macOS) to the :ref:`killring`.
-:kbd:`shift-delete` removes the current history item or autosuggestion from the command history.
-:kbd:`alt-h` (or :kbd:`f1`) shows the manual page for the current command, if one exists.
@@ -360,11 +379,14 @@ To enable emacs mode, use :doc:`fish_default_key_bindings <cmds/fish_default_key
-:kbd:`ctrl-b`, :kbd:`ctrl-f` move the cursor one character left or right or accept the autosuggestion just like the :kbd:`left` (``←``) and :kbd:`right` (``→``) shared bindings (which are available as well).
-:kbd:`alt-b`, :kbd:`alt-f` move the cursor one word left or right, or accept one word of the autosuggestion. If the command line is empty, moves forward/backward in the directory history instead.
-:kbd:`ctrl-n`, :kbd:`ctrl-p` move the cursor up/down or through history, like the up and down arrow shared bindings.
-:kbd:`delete` or :kbd:`backspace` or :kbd:`ctrl-h` removes one character forwards or backwards respectively.
-:kbd:`ctrl-backspace` removes one word backwards and :kbd:`alt-backspace` removes one argument backwards.
On macOS, it's the other way round.
-:kbd:`alt-<` moves to the beginning of the commandline, :kbd:`alt->` moves to the end.
@@ -382,7 +404,7 @@ To enable emacs mode, use :doc:`fish_default_key_bindings <cmds/fish_default_key
-:kbd:`ctrl-z`, :kbd:`ctrl-_` (:kbd:`ctrl-/` on some terminals) undo the most recent edit of the line.
-:kbd:`alt-/` reverts the most recent undo.
-:kbd:`alt-/` or :kbd:`ctrl-shift-z` reverts the most recent undo.
-:kbd:`ctrl-r` opens the history in a pager. This will show history entries matching the search, a few at a time. Pressing :kbd:`ctrl-r` again will search older entries, pressing :kbd:`ctrl-s` (that otherwise toggles pager search) will go to newer entries. The search bar will always be selected.
@@ -476,6 +498,7 @@ Command mode is also known as normal mode.
-:kbd:`p` pastes text from the :ref:`killring`.
-:kbd:`u` undoes the most recent edit of the command line.
-:kbd:`ctrl-r` redoes the most recent edit.
-:kbd:`[` and :kbd:`]` search the command history for the previous/next token containing the token under the cursor before the search was started. See the :ref:`history <history-search>` section for more information on history searching.
@@ -497,6 +520,8 @@ Insert mode
-:kbd:`backspace` removes one character to the left.
-:kbd:`ctrl-n` accepts the autosuggestion.
.._vi-mode-visual:
Visual mode
@@ -535,12 +560,12 @@ Custom bindings
In addition to the standard bindings listed here, you can also define your own with :doc:`bind <cmds/bind>`::
# Just clear the commandline on control-c
bind ctrl-c 'commandline -r ""'
# Prints ``^C`` and a new prompt
bind ctrl-c cancel-commandline
Put ``bind`` statements into :ref:`config.fish <configuration>` or a function called ``fish_user_key_bindings``.
If you change your mind on a binding and want to go back to fish's default, you can simply erase it again::
If you change your mind on a binding and want to go back to fish's default, you can erase it again::
bind --erase ctrl-c
@@ -592,7 +617,7 @@ Copy and paste (Kill Ring)
Fish uses an Emacs-style kill ring for copy and paste functionality. For example, use :kbd:`ctrl-k` (`kill-line`) to cut from the current cursor position to the end of the line. The string that is cut (a.k.a. killed in emacs-ese) is inserted into a list of kills, called the kill ring. To paste the latest value from the kill ring (emacs calls this "yanking") use :kbd:`ctrl-y` (the ``yank`` input function). After pasting, use :kbd:`alt-y` (``yank-pop``) to rotate to the previous kill.
Copy and paste from outside are also supported, both via the :kbd:`ctrl-x` / :kbd:`ctrl-v` bindings (the ``fish_clipboard_copy`` and ``fish_clipboard_paste`` functions [#]_) and via the terminal's paste function, for which fish enables "Bracketed Paste Mode", so it can tell a paste from manually entered text.
In addition, when pasting inside single quotes, pasted single quotes and backslashes are automatically escaped so that the result can be used as a single token simply by closing the quote after.
In addition, when pasting inside single quotes, pasted single quotes and backslashes are automatically escaped so that the result can be used as a single token by closing the quote after.
Kill ring entries are stored in ``fish_killring`` variable.
The commands ``begin-selection`` and ``end-selection`` (unbound by default; used for selection in vi visual mode) control text selection together with cursor movement commands that extend the current selection.
@@ -622,7 +647,7 @@ Searchable command history
After a command has been executed, it is remembered in the history list. Any duplicate history items are automatically removed. By pressing the up and down keys, you can search forwards and backwards in the history. If the current command line is not empty when starting a history search, only the commands containing the string entered into the command line are shown.
By pressing :kbd:`alt-up` (``↑``) and :kbd:`alt-down` (``↓``), a history search is also performed, but instead of searching for a complete commandline, each commandline is broken into separate elements just like it would be before execution, and the history is searched for an element matching that under the cursor.
By pressing :kbd:`alt-up` (``↑``) and :kbd:`alt-down` (``↓``), a history search is also performed, but instead of searching for a complete commandline, each commandline is broken into separate elements like it would be before execution, and the history is searched for an element matching that under the cursor.
For more complicated searches, you can press :kbd:`ctrl-r` to open a pager that allows you to search the history. It shows a limited number of entries in one page, press :kbd:`ctrl-r`[#]_ again to move to the next page and :kbd:`ctrl-s`[#]_ to move to the previous page. You can change the text to refine your search.
@@ -257,7 +257,7 @@ This is important when any redirections reference other file descriptors with th
Consider this helper function::
# Just make a function that prints something to stdout and stderr
# Make a function that prints something to stdout and stderr
function print
echo out
echo err >&2
@@ -281,7 +281,7 @@ Now let's see a few cases::
Job control
-----------
When you start a job in fish, fish itself will pause, and give control of the terminal to the program just started. Sometimes, you want to continue using the commandline, and have the job run in the background. To create a background job, append an ``&`` (ampersand) to your command. This will tell fish to run the job in the background. Background jobs are very useful when running programs that have a graphical user interface.
When you start a job in fish, fish itself will pause, and give control of the terminal to the program it just started. Sometimes, you want to continue using the commandline, and have the job run in the background. To create a background job, append an ``&`` (ampersand) to your command. This will tell fish to run the job in the background. Background jobs are very useful when running programs that have a graphical user interface.
Example::
@@ -314,7 +314,7 @@ For example, here's a simple function to list directories::
ls -l $argv
end
The first line tells fish to define a function by the name of ``ll``, so it can be used by simply writing ``ll`` on the commandline. The second line tells fish that the command ``ls -l $argv`` should be called when ``ll`` is invoked. :ref:`$argv <variables-argv>` is a :ref:`list variable <variables-lists>`, which always contains all arguments sent to the function. In the example above, these are simply passed on to the ``ls`` command. The ``end`` on the third line ends the definition.
The first line tells fish to define a function by the name of ``ll``, so it can be used by writing ``ll`` on the commandline. The second line tells fish that the command ``ls -l $argv`` should be called when ``ll`` is invoked. :ref:`$argv <variables-argv>` is a :ref:`list variable <variables-lists>`, which always contains all arguments sent to the function. In the example above, these are passed on to the ``ls`` command. The ``end`` on the third line ends the definition.
Calling this as ``ll /tmp/`` will end up running ``ls -l /tmp/``, which will list the contents of /tmp.
@@ -408,7 +408,7 @@ This is useful to explain what and why you are doing something::
command ls --color=auto $argv
end
There are no multiline comments. If you want to make a comment span multiple lines, simply start each line with a ``#``.
There are no multiline comments. If you want to make a comment span multiple lines, start each line with a ``#``.
Comments can also appear after a line like so::
@@ -436,7 +436,7 @@ Like other shells, but unlike typical programming languages you might know, the
This uses the :doc:`test <cmds/test>` command to see if the file /etc/os-release exists. If it does, it runs ``cat``, which prints it on the screen.
Unlike other shells, the condition command just ends after the first job, there is no ``then`` here. Combiners like ``and`` and ``or`` extend the condition.
Unlike other shells, the condition command ends after the first job, there is no ``then`` here. Combiners like ``and`` and ``or`` extend the condition.
A more complicated example with a :ref:`command substitution <expand-command-substitution>`::
@@ -460,7 +460,7 @@ Because ``test`` can be used for many different tests, it is important to quote
The :doc:`not <cmds/not>` keyword can be used to invert the status::
# Just see if the file contains the string "fish" anywhere.
# Check if the file contains the string "fish" anywhere.
# This executes the `grep` command, which searches for a string,
# and if it finds it returns a status of 0.
# The `not` then turns 0 into 1 or anything else into 0.
@@ -530,7 +530,7 @@ Or you can have a case where it is necessary to stop early::
If this went on after seeing that the command "foo" doesn't exist, it would try to run ``foo`` and error because it wasn't found!
Combiners really just execute step-by-step, so it isn't recommended to build longer chains of them because they might do something you don't want. Consider::
Combiners execute step-by-step, so it isn't recommended to build longer chains of them because they might do something you don't want. Consider::
test -e /etc/my.config
or echo "OH NO WE NEED A CONFIG FILE"
@@ -567,7 +567,7 @@ will print "Still running" once a second. You can abort it with ctrl-c.
echo file: $file
end
will print each file in the current directory. The part after the ``in`` is just a list of arguments, so you can use any :ref:`expansions <expand>` there::
will print each file in the current directory. The part after the ``in`` is a list of arguments, so you can use any :ref:`expansions <expand>` there::
set moreanimals bird fox
for animal in {cat,}fish dog $moreanimals
@@ -620,7 +620,7 @@ When a parameter includes an :ref:`unquoted <quotes>` ``*`` star (or "asterisk")
-``**`` matches any number of characters (including zero), and also descends into subdirectories. If ``**`` is a segment by itself, that segment may match zero times, for compatibility with other shells.
-``?`` can match any single character except ``/``. This is deprecated and can be disabled via the ``qmark-noglob``:ref:`feature flag<featureflags>`, so ``?`` will just be an ordinary character.
-``?`` can match any single character except ``/``. This is deprecated and can be disabled via the ``qmark-noglob``:ref:`feature flag<featureflags>`, so ``?`` will be an ordinary character.
Wildcard matches are sorted case insensitively. When sorting matches containing numbers, they are naturally sorted, so that the strings '1' '5' and '12' would be sorted like 1, 5, 12.
@@ -658,7 +658,7 @@ Variable expansion
One of the most important expansions in fish is the "variable expansion". This is the replacing of a dollar sign (``$``) followed by a variable name with the _value_ of that variable.
In the simplest case, this is just something like::
A simple example::
echo $HOME
@@ -788,11 +788,10 @@ Some more examples::
# Output is 1 2 3
echo $$var[2][3]
# $var[1] is listtwo, third element of that is 6, output is 6
# $var[2] is listtwo, third element of that is 6, output is 6
echo $$var[..][2]
# The second element of every variable, so output is
# 2 5
# The second element of every variable, so output is 2 5
Variables as command
''''''''''''''''''''
@@ -859,18 +858,18 @@ Examples::
# Set ``$data`` to the contents of data, splitting on NUL-bytes.
set data (cat data | string split0)
Sometimes you want to pass the output of a command to another command that only accepts files. If it's just one file, you can usually just pass it via a pipe, like::
Sometimes you want to pass the output of a command to another command that only accepts files. If it's just one file, you can usually pass it via a pipe, like::
grep fish myanimallist1 | wc -l
but if you need multiple or the command doesn't read from standard input, "process substitution" is useful. Other shells allow this via ``foo <(bar) <(baz)``, and fish uses the :doc:`psub <cmds/psub>` command::
# Compare just the lines containing "fish" in two files:
# Compare only the lines containing "fish" in two files:
diff -u (grep fish myanimallist1 | psub) (grep fish myanimallist2 | psub)
This creates a temporary file, stores the output of the command in that file and prints the filename, so it is given to the outer command.
Fish has a default limit of 100 MiB on the data it will read in a command sustitution. If that limit is reached the command (all of it, not just the command substitution - the outer command won't be executed at all) fails and ``$status`` is set to 122. This is so command substitutions can't cause the system to go out of memory, because typically your operating system has a much lower limit, so reading more than that would be useless and harmful. This limit can be adjusted with the ``fish_read_limit`` variable (`0` meaning no limit). This limit also affects the :doc:`read <cmds/read>` command.
Fish has a default limit of 1 GiB on the data it will read in a command substitution. If that limit is reached the command (all of it, not just the command substitution - the outer command won't be executed at all) fails and ``$status`` is set to 122. This is so command substitutions can't cause the system to go out of memory, because typically your operating system has a much lower limit, so reading more than that would be useless and harmful. This limit can be adjusted with the ``fish_read_limit`` variable (`0` meaning no limit). This limit also affects the :doc:`read <cmds/read>` command.
..[#] One exception: Setting ``$IFS`` to empty will disable line splitting. This is deprecated, use :doc:`string split <cmds/string-split>` instead.
@@ -909,7 +908,7 @@ If there is no "," or variable expansion between the curly braces, they will not
If after expansion there is nothing between the braces, the argument will be removed (see :ref:`the Combining Lists <cartesian-product>` section)::
> echo foo-{$undefinedvar}
# Output is an empty line, just like a bare `echo`.
# Output is an empty line, like a bare `echo`.
If there is nothing between a brace and a comma or two commas, it's interpreted as an empty element::
@@ -1326,7 +1325,7 @@ To see universal variables in action, start two fish sessions side by side, and
:ref:`Universal variables <variables-universal>` are stored in the file ``.config/fish/fish_variables``. Do not edit this file directly, as your edits may be overwritten. Edit the variables through fish scripts or by using fish interactively instead.
Do not append to universal variables in :ref:`config.fish <configuration>`, because these variables will then get longer with each new shell instance. Instead, simply set them once at the command line.
Do not append to universal variables in :ref:`config.fish <configuration>`, because these variables will then get longer with each new shell instance. Instead, set them once at the command line.
.._variables-export:
@@ -1369,7 +1368,7 @@ To access one element of a list, use the index of the element inside of square b
echo $PATH[3]
List indices start at 1 in fish, not 0 like in other languages. This is because it requires less subtracting of 1 and many common Unix tools like ``seq`` work better with it (``seq 5`` prints 1 to 5, not 0 to 5). An invalid index is silently ignored resulting in no value (not even an empty string, just no argument at all).
List indices start at 1 in fish, not 0 like in other languages. This is because it requires less subtracting of 1 and many common Unix tools like ``seq`` work better with it (``seq 5`` prints 1 to 5, not 0 to 5). An invalid index is silently ignored resulting in no value (not even an empty string, no argument at all).
If you don't use any brackets, all the elements of the list will be passed to the command as separate items. This means you can iterate over a list with ``for``::
@@ -1379,7 +1378,7 @@ If you don't use any brackets, all the elements of the list will be passed to th
This goes over every directory in :envvar:`PATH` separately and prints a line saying it is in the path.
To create a variable ``smurf``, containing the items ``blue`` and ``small``, simply write::
To create a variable ``smurf``, containing the items ``blue`` and ``small``, write::
set smurf blue small
@@ -1441,7 +1440,7 @@ Lists can be inspected with the :doc:`count <cmds/count>` or the :doc:`contains
> contains -i blue $smurf
1
A nice thing about lists is that they are passed to commands one element as one argument, so once you've set your list, you can just pass it::
A nice thing about lists is that they are passed to commands one element as one argument, so once you've set your list, you can pass it::
set -l grep_args -r "my string"
grep $grep_args . # will run the same as `grep -r "my string"` .
@@ -1566,13 +1565,12 @@ You can change the settings of fish by changing the values of certain variables.
..envvar:: fish_term24bit
If this is set to 1, fish will assume the terminal understands 24-bit RGB color sequences, and won't translate them to the 256 or 16 color palette.
This is often detected automatically.
If this is set to 0, fish will not output 24-bit RGB true-color sequences but the nearest color on the 256 color palette (or the 16 color palette, if :envvar:`fish_term256` is 0).
..envvar:: fish_term256
If this is set to 1, fish will assume the terminal understands 256 colors, and won't translate matching colors down to the 16 color palette.
This is usually autodetected.
If this is set to 0 and :envvar:`fish_term24bit` is 0, translate RGB colors down to the 16 color palette.
Also, if this is set to 0, :doc:`set_color <cmds/set_color>`/` commands such as ``set_color ff0000 red`` will prefer the named color.
..envvar:: fish_ambiguous_width
@@ -1586,6 +1584,10 @@ You can change the settings of fish by changing the values of certain variables.
controls if :ref:`autosuggestions` are enabled. Set it to 0 to disable, anything else to enable. By default they are on.
..envvar:: fish_transient_prompt
If this is set to 1, fish will redraw prompts with a ``--final-rendering`` argument before running a commandline, allowing you to change it before pushing it to the scrollback. This enables :ref:`transient prompts <transient-prompt>`.
..envvar:: fish_handle_reflow
determines whether fish should try to repaint the commandline when the terminal resizes. In terminals that reflow text this should be disabled. Set it to 1 to enable, anything else to disable.
@@ -1715,7 +1717,7 @@ Fish also provides additional information through the values of certain environm
..ENVVAR:: SHLVL
the level of nesting of shells. Fish increments this in interactive shells, otherwise it simply passes it along.
the level of nesting of shells. Fish increments this in interactive shells, otherwise it only passes it along.
..envvar:: status
@@ -1725,12 +1727,6 @@ Fish also provides additional information through the values of certain environm
the "generation" count of ``$status``. This will be incremented only when the previous command produced an explicit status. (For example, background jobs will not increment this).
..ENVVAR:: TERM
the type of the current terminal. When fish tries to determine how the terminal works - how many colors it supports, what sequences it sends for keys and other things - it looks at this variable and the corresponding information in the terminfo database (see ``man terminfo``).
Note: Typically this should not be changed as the terminal sets it to the correct value.
..ENVVAR:: USER
the current username. This variable can be changed.
@@ -1845,7 +1841,7 @@ The "locale" of a program is its set of language and regional settings that depe
..envvar:: LC_MONETARY
Determines currency, how it is formated, and the symbols used.
Determines currency, how it is formatted, and the symbols used.
..envvar:: LC_NUMERIC
@@ -1954,7 +1950,7 @@ Let's make up an example. This function will :ref:`glob <expand-wildcard>` the f
printf '%s\n' $files
end
If you run this as ``show_files /``, it will most likely ask you until you press Y/y or N/n. If you run this as ``show_files / | cat``, it will print the files without asking. If you run this as ``show_files .``, it might just print something without asking because there are fewer than five files.
If you run this as ``show_files /``, it will most likely ask you until you press Y/y or N/n. If you run this as ``show_files / | cat``, it will print the files without asking. If you run this as ``show_files .``, it might print something without asking because there are fewer than five files.
.._identifiers:
@@ -2022,17 +2018,19 @@ You can see the current list of features via ``status features``::
qmark-noglob on 3.0 ? no longer globs
regex-easyesc on 3.1 string replace -r needs fewer \\'s
ampersand-nobg-in-token on 3.4 & only backgrounds if followed by a separating character
remove-percent-self off 3.8 %self is no longer expanded (use $fish_pid)
test-require-arg off 3.8 builtin test requires an argument
remove-percent-self off 4.0 %self is no longer expanded (use $fish_pid)
test-require-arg off 4.0 builtin test requires an argument
ignore-terminfo on 4.1 do not look up $TERM in terminfo database
Here is what they mean:
-``stderr-nocaret`` was introduced in fish 3.0 (and made the default in 3.3). It makes ``^`` an ordinary character instead of denoting an stderr redirection, to make dealing with quoting and such easier. Use ``2>`` instead. This can no longer be turned off since fish 3.5. The flag can still be tested for compatibility, but a ``no-stderr-nocaret`` value will simply be ignored.
-``qmark-noglob`` was also introduced in fish 3.0 (and made the default in 3.8). It makes ``?`` an ordinary character instead of a single-character glob. Use a ``*`` instead (which will match multiple characters) or find other ways to match files like ``find``.
-``regex-easyesc`` was introduced in 3.1. It makes it so the replacement expression in ``string replace -r`` does one fewer round of escaping. Before, to escape a backslash you would have to use ``string replace -ra '([ab])' '\\\\\\\\$1'``. After, just ``'\\\\$1'`` is enough. Check your ``string replace`` calls if you use this anywhere.
-``ampersand-nobg-in-token`` was introduced in fish 3.4. It makes it so a ``&`` i no longer interpreted as the backgrounding operator in the middle of a token, so dealing with URLs becomes easier. Either put spaces or a semicolon after the ``&``. This is recommended formatting anyway, and ``fish_indent`` will have done it for you already.
-``remove-percent-self`` turns off the special ``%self`` expansion. It was introduced in 3.8. To get fish's pid, you can use the :envvar:`fish_pid` variable.
-``test-require-arg`` removes :doc:`builtin test <cmds/test>`'s one-argument form (``test "string"``. It was introduced in 3.8. To test if a string is non-empty, use ``test -n "string"``. If disabled, any call to ``test`` that would change sends a :ref:`debug message <debugging-fish>` of category "deprecated-test", so starting fish with ``fish --debug=deprecated-test`` can be used to find offending calls.
-``stderr-nocaret`` was introduced in fish 3.0 and cannot be turned off since fish 3.5. It can still be tested for compatibility, but a ``no-stderr-nocaret`` value will be ignored. The flag made ``^`` an ordinary character instead of denoting an stderr redirection. Use ``2>`` instead.
-``qmark-noglob`` was also introduced in fish 3.0 (and made the default in 4.0). It makes ``?`` an ordinary character instead of a single-character glob. Use a ``*`` instead (which will match multiple characters) or find other ways to match files like ``find``.
-``regex-easyesc`` was introduced in 3.1 (and made the default in 3.5). It makes it so the replacement expression in ``string replace -r`` does one fewer round of escaping. Before, to escape a backslash you would have to use ``string replace -ra '([ab])' '\\\\\\\\$1'``. After, just ``'\\\\$1'`` is enough. Check your ``string replace`` calls if you use this anywhere.
-``ampersand-nobg-in-token`` was introduced in fish 3.4 (and made the default in 3.5). It makes it so a ``&`` i no longer interpreted as the backgrounding operator in the middle of a token, so dealing with URLs becomes easier. Either put spaces or a semicolon after the ``&``. This is recommended formatting anyway, and ``fish_indent`` will have done it for you already.
-``remove-percent-self`` turns off the special ``%self`` expansion. It was introduced in 4.0. To get fish's pid, you can use the :envvar:`fish_pid` variable.
-``test-require-arg`` removes :doc:`builtin test <cmds/test>`'s one-argument form (``test "string"``. It was introduced in 4.0. To test if a string is non-empty, use ``test -n "string"``. If disabled, any call to ``test`` that would change sends a :ref:`debug message <debugging-fish>` of category "deprecated-test", so starting fish with ``fish --debug=deprecated-test`` can be used to find offending calls.
-``ignore-terminfo`` disables lookup of $TERM in the terminfo database. Use ``no-ignore-terminfo`` to turn it back on.
These changes are introduced off by default. They can be enabled on a per session basis::
@@ -2053,12 +2051,6 @@ Prefixing a feature with ``no-`` turns it off instead. E.g. to reenable the ``?`
set -Ua fish_features no-qmark-noglob
Currently, the following features are enabled by default:
- stderr-nocaret - ``^`` no longer redirects stderr, use ``2>``. Enabled by default in fish 3.3.0. No longer changeable since fish 3.5.0.
- regex-easyesc - ``string replace -r`` requires fewer backslashes in the replacement part. Enabled by default in fish 3.5.0.
- ampersand-nobg-in-token - ``&`` in the middle of a word is a normal character instead of backgrounding. Enabled by default in fish 3.5.0.
.._event:
Event handlers
@@ -2122,12 +2114,14 @@ For more information on how to define new event handlers, see the documentation
Debugging fish scripts
----------------------
Fish includes basic built-in debugging facilities that allow you to stop execution of a script at an arbitrary point. When this happens you are presented with an interactive prompt where you can execute any fish command to inspect or change state (there are no debug commands as such). For example, you can check or change the value of any variables using :doc:`printf <cmds/printf>` and :doc:`set <cmds/set>`. As another example, you can run :doc:`status print-stack-trace <cmds/status>` to see how the current breakpoint was reached. To resume normal execution of the script, simply type :doc:`exit <cmds/exit>` or :kbd:`ctrl-d`.
Fish includes basic built-in debugging facilities that allow you to stop execution of a script at an arbitrary point. When this happens you are presented with an interactive prompt where you can execute any fish command to inspect or change state (there are no debug commands as such). For example, you can check or change the value of any variables using :doc:`printf <cmds/printf>` and :doc:`set <cmds/set>`. As another example, you can run :doc:`status print-stack-trace <cmds/status>` to see how the current breakpoint was reached. To resume normal execution of the script, type :doc:`exit <cmds/exit>` or :kbd:`ctrl-d`.
To start a debug session simply insert the :doc:`builtin command <cmds/breakpoint>```breakpoint`` at the point in a function or script where you wish to gain control, then run the function or script. Also, the default action of the ``TRAP`` signal is to call this builtin, meaning a running script can be actively debugged by sending it the ``TRAP`` signal (``kill -s TRAP <PID>``). There is limited support for interactively setting or modifying breakpoints from this debug prompt: it is possible to insert new breakpoints in (or remove old ones from) other functions by using the ``funced`` function to edit the definition of a function, but it is not possible to add or remove a breakpoint from the function/script currently loaded and being executed.
To start a debug session insert the :doc:`builtin command <cmds/breakpoint>```breakpoint`` at the point in a function or script where you wish to gain control, then run the function or script. Also, the default action of the ``TRAP`` signal is to call this builtin, meaning a running script can be actively debugged by sending it the ``TRAP`` signal (``kill -s TRAP <PID>``). There is limited support for interactively setting or modifying breakpoints from this debug prompt: it is possible to insert new breakpoints in (or remove old ones from) other functions by using the ``funced`` function to edit the definition of a function, but it is not possible to add or remove a breakpoint from the function/script currently loaded and being executed.
Another way to debug script issues is to set the :envvar:`fish_trace` variable, e.g. ``fish_trace=1 fish_prompt`` to see which commands fish executes when running the :doc:`fish_prompt <cmds/fish_prompt>` function.
fish writes various control sequences to the terminal.
Some must be implemented to enable basic functionality,
while others enable optional features and may be ignored by the terminal.
The terminal must be able to parse Control Sequence Introducer (CSI) commands, Operating System Commands (OSC) and optionally Device Control Strings (DCS).
These are defined by ECMA-48.
If a valid CSI, OSC or DCS sequence does not represent a command implemented by the terminal, the terminal must ignore it.
Control sequences are denoted in a fish-like syntax.
Special characters other than ``\`` are not escaped.
Spaces are only added for readability and are not part of the sequence.
Placeholders are written as ``<Ps>`` for a number or ``<Pt>`` for an arbitrary printable string.
**NOTE:** fish does not rely on your system's terminfo database.
In this document, terminfo (TI) codes are included for reference only.
Required Commands
-----------------
..list-table::
:widths:auto
:header-rows:1
* - Sequence
- TI
- Description
- Origin
* - ``\r``
- n/a
- Move cursor to the beginning of the line
-
* - ``\n``
- cud1
- Move cursor down one line.
-
* - ``\e[PsA``
- cuu
- Move cursor up Ps columns, or one column if no parameter.
- VT100
* - ``\e[PsC``
- cuf
- Move cursor to the right Ps columns, or one column if no parameter.
- VT100
* - ``\x08``
- cub1
- Move cursor one column to the left.
- VT100
* - ``\e[PsD``
- cub
- Move cursor to the left Ps times.
- VT100
* - ``\e[H``
- cup
- Set cursor position (no parameters means: move to row 1, column 1).
- VT100
* - ``\e[K``
- el
- Clear to end of line.
- VT100
* - ``\e[J``
- ed
- Clear to the end of screen.
- VT100
* - ``\e[2J``
- clear
- Clear the screen.
- VT100
* - ``\e[0c``
-
- Request primary device attribute.
The terminal must respond with a CSI command that starts with the ``?`` parameter byte (so a sequence starting with ``\e[?``) and has ``c`` as final byte.
- VT100
* - n/a
- am
- Soft wrap text at screen width.
-
* - n/a
- xenl
- Printing to the last column does not move the cursor to the next line.
Verify this by running ``printf %0"$COLUMNS"d 0; sleep 3``
-
Optional Commands
-----------------
..list-table::
:widths:auto
:header-rows:1
* - Sequence
- TI
- Description
- Origin
* - ``\t``
- it
- Move the cursor to the next tab stop (à 8 columns).
This is mainly relevant if your prompt includes tabs.
-
* - ``\e[m``
- sgr0
- Turn off bold/dim/italic/underline/reverse attribute modes and select default colors.
-
* - ``\e[1m``
- bold
- Enter bold mode.
-
* - ``\e[2m``
- dim
- Enter dim mode.
-
* - ``\e[3m``
- sitm
- Enter italic mode.
-
* - ``\e[4m``
- smul
- Enter underline mode.
-
* - ``\e[4:3m``
- Su
- Enter curly underline mode.
- kitty
* - ``\e[7m``
- rev
- Enter reverse video mode (swap foreground and background colors).
-
* - ``\e[23m``
- ritm
- Exit italic mode.
-
* - ``\e[24m``
- rmul
- Exit underline mode.
-
* - ``\e[38;5; Ps m``
- setaf
- Select foreground color Ps from the 256-color-palette.
-
* - ``\e[48;5; Ps m``
- setab
- Select background color Ps from the 256-color-palette.
-
* - ``\e[58:5: Ps m`` (note: colons not semicolons)
- Su
- Select underline color Ps from the 256-color-palette.
- kitty
* - ``\e[ Ps m``
- setaf
setab
- Select foreground/background color. This uses a color in the aforementioned 256-color-palette, based on the range that contains the parameter:
30-37 maps to foreground 0-7,
40-47 maps to background 0-7,
90-97 maps to foreground 8-15 and
100-107 maps to background 8-15.
-
* - ``\e[38;2; Ps ; Ps ; Ps m``
-
- Select foreground color from 24-bit RGB colors.
-
* - ``\e[48;2; Ps ; Ps ; Ps m``
-
- Select background color from 24-bit RGB colors.
-
* - ``\e[49m``
-
- Reset background color to the terminal's default.
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.