Multiple PRs fail with
pkg: Repository FreeBSD-ports cannot be opened. 'pkg update' required
Updating database digests format: . done
pkg: No packages available to install matching 'cmake-core' have been found in the repositories
Rust 1.70 stabilized `std::sync::OnceLock`, which replaces
`once_cell::sync::OnceCell`.
With this, we only have a single remaining direct dependency on
`once_cell`: `VAR_DISPATCH_TABLE` in `src/env_dispatch.rs`, where we use
`Lazy::get`. This can be replaced with `LazyLock::get` once our MSRV
reaches 1.94, where the function is stabilized.
At the moment, `serial_test` depends on `once_cell`, so even if we
eliminate it as a direct dependency, it will remain a transitive
dependency.
Closes#12289
Rust 1.80 stabilized `std::sync::LazyLock`, which replaces
`once_cell::sync::Lazy`. There is one exception in
`src/env_dispatch.rs`, which still uses the `once_cell` variant, since
the code there relies on `Lazy::get`, which also exists for `LazyLock`,
but will only be stabilized in Rust 1.94, so we can't use it yet.
Part of #12289
This is useful for running the checks with a toolchain which is
different from the default toolchain, for example to check if everything
works with our MSRV, or on beta/nightly toolchains. Additionally,
providing a way to run using the nightly toolchain allows writing
wrappers around `check.sh` which make use of nightly-only features.
The toolchain could be changed using `rustup toolchain default`, but if
the toolchain should only be used for a specific run, this is
inconvenient, and it does not allow for concurrent builds using
different toolchains.
Closes#12281
Webconfig persists themes to ~/.config/fish/conf.d/fish_frozen_theme.fish
(the name is due to historical reasons).
That file's color variables have no "--theme=foo" annotations, which
means that fish_config can't distinguish them from other "user-set"
values. We can change this in future, but that doesn't affect the
following fix.
A "fish_config theme choose foo" command is supposed to
overwrite all variables that are defined in "foo.theme".
If the theme is color-theme-aware *and* this command runs before
$fish_terminal_color_theme is initialized, we delay loading of the
theme until that initialization happens. But the --on-variable
invocation won't have the override bit set, thus it will not touch
variables that don't have "--theme=*" value. Fix this by clearing
immediately the variables mentioned in the theme.
Fixes#12278
While at it, tweak the error message for this command because it's
not an internal error:
fish -c 'echo yes | fish_config theme save tomorrow'
This replaces `initialize_gettext`. It is only defined when the
`localize-messages` feature is enabled, to avoid giving the impression
that it does anything useful when the feature is disabled.
With this change, Fluent will be initialized as well once it is added,
without requiring any additional code for initialization.
Closes#12190
Extract the language selection code from the gettext crate, and to a
lesser extent from `src/localization/mod.rs` and put it into
`src/localization/settings.rs`. No functional changes are intended.
Aside from better separation of concerns, this refactoring makes it
feasible to reuse the language selection logic for Fluent later on.
Part of #12190
The __fish_migrate.fish function spawns a "sh -c 'sleep 7' &" child
process that inherits stdin/stdout/stderr file descriptors fish.
This means that if the app running "fish
tests/checks/__fish_migrate.fish" actually waits for fish to close its
standard file descriptors, it will appear to hang for 7 seconds. Fix
that by closing the file descriptors in the background job when
creating it.
Closes#12271
The backward compat hack canonicalization caused us to always treat
"tomorrow" light theme.
Restrict this hack to the legacy name (Tomorrow); don't do it when
the new canonical name (tomorrow) is used. The same issue does not
affect other themes because their legacy names always have a "light"
or 'dark' suffix, which means that the canonical name is different,
so the legacy hacks don't affect the canonical name.
Fixes#12266
This logic exists to not break user configurations as we renamed
themes. But user-sourced themes haven't been renamed.
(It's also questionable whether we should really have these compat
hacks; they might cause confusion in the long run).
- Add missing options and completions for fetch, show-branch, am,
checkout, archive, grep, pull, push, revert, rm, config, clean, and
other commands
- Replace TODO comments with actual option completions for improved
usability
- Ensure all new options have appropriate descriptions and argument
handling for fish shell completion
Closes#12263
Due to the way tmux implements it, color theme reporting
causes issues when typing commands really quickly (such as
when synthesizing keys). We're working on fixing this, see
https://github.com/tmux/tmux/issues/4787#issuecomment-3707866550
Disable it for now. AFAIK other terminals are not affected.
Closes#12261
- Fix the background color of .function-body in dark mode to improve readability.
- Switch to Tomorrow Night Bright color theme for better contrast and readability in dark mode.
- Format all stylesheets of fish_config.
Closes#12257
Something like
PATH=mypath builtin fish_indent --help
runs "fish -c '__fish_print_help fish_indent'" internally. Since we
don't call setenv(), the PATH update doesn't reach the child shell.
Fix this by using what other builtins use if we are one (i.e. if we
have a Parser in context).
Fixes#12229
Maybe also #12085
We sometimes use explicit reclaim() and sometimes rely on the drop
implementation. This adds an unnecesary step to reading all uses of
this code. Make this consistent. Use drop everywhere though we could
use explicit reclaim too.
Prior to f417cbc981 (Show soft-wrapped portions in autosuggestions,
2025-12-11), we'd truncate autosuggestions before the right prompt.
We no longer do that for autosuggestions that soft-wrap, which means
we try to draw both right prompt and suggestion in the same space.
Make suggestion paint over right prompt for now, since this seems to
be a simple and robust solution. We can revisit this later.
Fixes#12255
If "will_replace_token" is set, we generally only consider
appending completions. This changed in commit 656b39a0b3 (Also show
case-insensitive prefix matches in completion pager, 2025-11-23) which
also allowed icase completions as long as they are also prefix matches.
Such replacing completions might cause the common prefix to be empty,
which breaks the appending completions.
Fix this by not considering these replacing completions for the
common-prefix computation. The pager already doesn't show the prefix
for these completions specifically.
Fixes#12249
We skip completions where "will_replace_token != c.replaces_token()".
This means that
- if will_replace_token, we filter out non-replacing completions.
But those do not exist because, by definition, will_replace_token
is true iff there are no non-replacing completions.
- if !will_replace_token, we filter out replacing completions.
From the definition of will_replace_token follows that there is
some non-replacing completion, which must be a prefix or exact match.
Since we've filtered by rank, any replacing ones must have the same rank.
So the replacement bit must be due to smartcase. Smartcase
completions are already passed through explicitly here since
656b39a0b3 (Also show case-insensitive prefix matches in completion
pager, 2025-11-23).
So the cases where we 'continue' here can never happen.
Remove this redundant check.
The tuple (will_replace_token, all_matches_exact_or_prefix) can never
be (false, false).
Proof by contraction:
1. Goal: show unsatisfiability of: !will_replace_token && !all_matches_exact_or_prefix
2. Substitute defintions: !all(replaces) && !all(is_exact_or_prefix)
3. wlog, !replaces(c1) && !is_exact_or_prefix(c2)
4. since c1 and c2 have same rank we know that !is_exact_or_prefix(c1)
5. !is_exact_or_prefix() implies requires_full_replacement()
6. all callers that create a Completion from StringFuzzyMatch::try_create(),
set CompleteFlags::REPLACE_TOKEN if requires_full_replacement(),
so requires_full_replacement() implies replaces()
7. From 4-6 follows: !is_exact_or_prefix(c1) implies replaces(c1), which is a contradiction
A recent change attempted this:
let result: std::io::Result<()> = { code()? }
However this doesn't initialize the Result on error - instead it
returns from the function, meaning that the error would be silently
dropped.
Fix that by reporting the error at the call site instead.
Commit fbad0ab50a (reset_abandoning_line: remove redundant
allocations, 2025-11-13) uses byte count of ⏎ (3) instead of char
count (1), thus overestimating the number of spaces this symbol takes.
Fixes#12246
Rust has this annoying design where all of the syscall conveniences on
File assume that it owns its fd; in particular this means that we can't
easily construct File from stdin, a raw file descriptor, etc.
The usual workarounds are to construct a File and then mem::forget it
(this is apparently idiomatic Rust!). But this has problems of its own:
for example it can't easily be used in Drop.
Introduce BorrowedFdFile which wraps File with ManuallyDrop and then
never drops the file (i.e. it's always forgotten). Replace some raw FDs
with BorrowedFdFile.
Prior to this commit, this code:
fish_indent <&-
would panic as we would construct a File with a negative fd.
Check for a closed fd as other builtins do.
Since fish_indent became a builtin, it cannot be canceled with control-C,
because Rust's `read_to_end` retries on EINTR. Add our own function which
propagates EINTR and use it.
Fixes#12238
Commit 7996637db5 (Make fish immediately show color changes again,
2025-12-01) repaints unnecessarily when a local unexported color
variable changes. Also, it repaints when the change comes from
fish_prompt, causing an easy infinite loop. Same when changing TERM,
COLORTERM and others.
This feature is relevant when using a color-theme aware theme, so
try to keep it. Repaint only on global/universal changes.
Also ignore changes if already repainting fish prompt.
This change may be at odds with concurrent execution (parser should
not care about whether we are repainting) but that's intentional
because of 1. time constraints and 2. I'm not sure what the solution
will look like; we could use the event infrastructure. But a lot of
existing variable listeners don't use that.
Extract a context object we pass whenever we mutate the environment; While
at it, use it to pass EnvMode::USER, to reduce EnvMode responsibilities.
Fixes#12233
We set "global_modified" to true if the global exist, or if the
default scope is global but not if EnvMode::GLOBAL.
This is an accident from 77aeb6a2a8 (Port execution, 2023-10-08).
Restore it. Tested in a following commit.
We have pretty weird behavior:
$ set --path somepath 1 2 3
set --erase --unpath somepath[2]
[1]$ set --path somepath 1 2 3
set --erase --unpath somepath
$
The first command fails to erase from the variable, because the
--path/--unpath mismatch prevents us from accessing the variable.
The second succeeds at erasing because we ignore --path/--unpath.
We should probably fix this; for now only simplify the unrelated
change added by fed64999bc (Allow erasing in multiple scopes in one
go, 2022-10-15):
we implement "set --erase --global --path" as
try_erase(scope="--global")
try_erase(scope="--path")
Do this instead, which is closer to historical behavior.
try_erase(scope="--global --path")
This also allows us to express more obviously the behavior if no scope
(out of -lfgU) was specified.
Just following basic shellscript optimization:
- Remove a useless use of cat (`status get-file` takes microseconds,
`status get-file | cat` is on the order of a millisecond - slower with
bigger $PATH)
- Pipe, don't run in a loop
- Filter early
This reduces the time taken from 12ms to 6ms on one of my systems, and
6.5ms to 4.5ms on another.
This is paid on every single shell startup, including
non-interactively, so it's worth it.
There's more to investigate, but this is a good first pass.
Commit 7b4802091a installs fish_indent and fish_key_reader as
hardlinks to fish. When we create our fat binary for macOS, we add
3 of these X86 binaries to the fattened one,
resulting in a corrupted Mach-O binary. Fix that.
Fixes#12224
Commit 135fc73191 (Remove man/HTML docs from tarball, require Sphinx
instead, 2025-11-20) broke cross compilation of tarballs.
Add an option to allow users to pick any fish_indent (such as
"target/debug/fish_indent" as created by "cargo build"), to allow
cross compilation.
In future, we should remove this option in favor of doing all of this
transparently at build type (in build.rs).
Ref: https://matrix.to/#/!YLTeaulxSDauOOxBoR:matrix.org/$psPcu-ogWK5q9IkgvfdvBGTdJ2XGhNq5z_Ug0iTCx2Q
When I ssh to a macOS system, typing ctrl-p ctrl-j in quick succession
sometimes causes ^[[I (focus in) to be echoed. Looks like we fail to
disable terminal-echo in time. Possible race condition? Revert until
we find out more.
This reverts commit 7dd2004da7.
Closes#12232
The __fish_data_with_file wrapper was born out of a desire to simplify
handling of file paths that may or may not be embedded into the
fish binary.
Since 95aeb16ca2 (Remove embed-data feature flag, 2025-11-20) this is
no longer needed since almost everything is embedded unconditionally.
The exception is man pages (see a1baf97f54 (Do not embed man pages
in CMake builds, 2025-11-20)), but they use __fish_data_with_directory.
Man pages used to be built by "build.rs" but now are built by a
dependent "crates/build-man-pages/build.rs". This means that changing
the environment of build.rs is ineffective.
In future, "fn get_version" should probably be a part of
"crates/build-helper/", so Cargo builds only need to compute the
version once.
Lack of this dependency means that "build-man-pages" does not
pass FISH_BUILD_VERSION, which means that Sphinx will fall back to
build_tools/git_version_gen.sh. This acceptable for now given that
"build-man-pages" is not used in CMake builds.
Commit 2343a6b1f1 passed the FISH_BUILD_VERSION_FILE to
sphinx-manpages to remove the fish_indent dependency.
For sphinx-docs this has been solved in another way in e895f96f8a
(Do not rely on `fish_indent` for version in Sphinx, 2025-08-19).
This is a needless inconsistency.
Remove it. Use FISH_BUILD_VERSION_FILE whenever possible, since that
means that a full build process only needs to call git_version_gen.sh
once.
Keep the fallback to git_version_gen.sh, in case someone calls
sphinx-build directly.
Prior to commit 135fc73191 (Remove man/HTML docs from tarball, require
Sphinx instead, 2025-11-20), HTML docs were built from a Git worktree.
Now they are built in the tarball. We call
build_tools/git_version_gen.sh from doc_src so it fails to find the
version file. Fix that.
Fixes#12228
Not being able to delete these for good (if unused) seems to be
a nuisance. Let's go back to storing universal __fish_initialized
also on fresh installations, which I guess is a small price to to
avoid recreating these files.
Closes#12230
Commit 30942e16dc (Fix prefix/suffix icase comparisons, 2025-12-27)
incorrectly treated "gs " as prefix of "gs" which causes a crash
immediately after expanding that abbreviation iff "gs" is our
autosuggestion (i.e. there's no history autosuggestion taking
precedence).
Fixes#12223
Now that the default theme no longer contains light/dark sections,
we don't need to wait for $fish_terminal_color_theme to be initialized
before setting it.
Let's set it before loading user config to allow users to do things
like "set -e fish_color_command" in their config.
Fixes#12209
If we're overriding the theme with --color-theme=, we don't need to
register the hook because $fish_terminal_color_theme will be ignored.
Also if the theme is not color-theme aware, there is no need to
register the hook.
The readability concern in ed881bcdd8 (Make default theme use named
colors only, 2023-07-25) was no longer relevant, but people might
prefer we use terminal colors by default, because other apps do too,
and because it's a well-known way to make colors look good across
both dark and light mode.
If we revert this, we should make sure fish_default_mode_prompt.fish
and prompt_login.fish also use RGB colors
As reported on Gitter, running "echo İ" makes history autosuggestion
for "echo i" crash. This is because history search correctly
returns the former, but string_prefixes_string_case_insensitive("i",
"İ") incorrectly returns false. This is because the prefix check
is implemented by trimming the rhs to the length of the prefix and
checking if the result is equal to the prefix. This is wrong because
the prefix computation should operate on the canonical lowercase
version, because that's what history search uses.
The theme marker is set by "fish_config theme choose" to allow
us to react to terminal color theme changes, and to tell future
"fish_config theme choose" invocations which variables it should erase
-- it should not erase color variables not set in the theme file,
like Git prompt colors.
I'm not sure if either really makes sense for "fish_config theme save".
Reacting to terminal color theme changes is weird for universals.
I'm not sure if "fish_config theme save" should erase universal
variables that are not defined in the theme. Historically, it did
so for a hardcoded list of colors, which is hacky. For now let's
err on the side of leaving around color variables.
The "save" subcommand is deprecated; it's possible that this changes
in future (and we add support for "--theme" to it) but I'm not sure
if we have enough need for that.
Users who run the default theme are silently migrated to global
variables. Universal color variables are deleted, leaving existing
sessions uncolored. Tell the user to restart them, and make some
other improvements; now it looks like:
fish: upgraded to version 4.3:
* Color variables are no longer set in universal scope.
To restore syntax highlighting in other fish sessions, please restart them.
* The fish_key_bindings variable is no longer set in universal scope by default.
Migrated it to a global variable set in ~/.config/fish/conf.d/fish_frozen_key_bindings.fish
Same for users who do not use the default theme (who already got a
message before this change). For them, the first bullet point looks
like this:
[...]
* Color variables are no longer set in universal scope by default.
Migrated them to global variables set in ~/.config/fish/conf.d/fish_frozen_theme.fish
To restore syntax highlighting in other fish sessions, please restart them.
[...]
Closes#12161
These fall back to param/command roles, so there's no need to
duplicate the value.
Make sure the "set fish_color_o<TAB>" still works if they're not
defined.
Leave it as a comment in theme files I guess, since users copy-pasting
a theme might reasonably want to set it.
Closes#12209
Change the input of some functions to take `impl IntoCharIter`, allowing
them to accept more input. Implementing this efficiently means that no
owned types should be passed into these functions, because their
`IntoCharIter` implementation would require unnecessary allocations.
Instead, convert the uses which previously passed `WString` by prefixing
an `&`, so the borrowed `&WString` is passed instead.
To allow for wider use of the modified functions, `IntoCharIter`
implementations are added for `&String`, `&Cow<str>`, and `&Cow<wstr>`.
Closes#12207
Removed in 9edd0cf8ee (Remove some now unused CMake bits, 2024-07-07).
The replacements are not documented in prose but in the GitHub
release workflow.
This command
echo $(/bin/echo -n 1; echo -n 2)
sometimes outputs "21" because we implement this as
let bufferfill = IoBufferfill::create_opts(...);
...
let eval_res = parser.eval_with(...);
let buffer = IoBufferfill::finish(bufferfill);
i.e. /bin/echo and builtin echo both output to the same buffer; the
builtin does inside parser.eval_with(), and the external process may
or may not output before that, depending on when the FD monitor thread
gets scheduled (to run item_callback).
(Unrelated to that we make sure to consume all available input in
"IoBufferfill::finish(bufferfill)" but that doesn't help with
ordering.)
Fix this by reading all available data from stdout after the child
process has exited.
This means we need to pass the BufferFill down to
process_mark_finished_children().
We don't need to do this for builtins like "fg" or "wait",
because commands that buffer output do not get job control, see
2ca66cff53 (Disable job control inside command substitutions,
2021-07-26).
We also don't need to do it when reaping from reader because there
should be no buffering(?).
fish still deviates from other shells in that it doesn't wait for
it's child's stdout to be closed, meaning that this will behave
non-deterministically.
fish -c '
echo -n $(
sh -c " ( for i in \$(seq 10000); do printf .; done ) & "
)
' | wc -c
We should fix that later.
Closes#12018
The existing functionality of converting a `&wstr` to bytes (unescaping
PUA codepoints) and writing these to a file descriptor can be reused for
Rust's built-in strings by making the input type generic. This is
simple, because the only functionality we need is converting the input
into a `char` iterator, which is available for both types.
While at it, rename the functions to have more accurate and informative
names.
Closes#12206
When the output is redirected, Python buffer its whole output, unlike
a TTY output where only lines are buffered.
In GitHub actions in particular, it means that we can't see any progress
after each test. And if a test blocks forever, there is no output at all.
So flush the output after printing each result to see the progress
being made
Run fish_indent on test scripts that will be modified in a later
commit
Not running it on all the files because a quarter of them need fixing,
some of which are badly formatted on purpose
This is done in preparation for Fluent's FTL files, which will be placed
in `localization/fluent/`. Having a shared parent reduces top-level
clutter in the repo and makes it easier to find the localization files
for translators, including realizing that both PO and FTL files exist.
We keep PO and FTL files in separate directories because we need to
rebuild on any changes in the PO directory (technically only when there
are changes to `*.po` files, but due to technical limitations we can't
reliably trigger rebuilds only if those changes but not other files in
the same directory.) Changes to FTL files do not require rebuilds for
dev builds, since for these `rust-embed` does not actually embed them
into the binary but rather loads them from the file system at runtime.
Closes#12193
The upstream completions have not been updated for some time, but the
docker binary can generate completions. These include dynamic
completions for image names and so on.
Closes#12197.
Localization deserves its own module. As a first step, this module is
created here. This will be followed up by significant refactoring in
preparation for supporting Fluent alongside gettext.
`localization/mod.rs` is used instead of `localization.rs` because it is
planned to split this module into submodules.
Part of #12190
The needless_return lint was disabled almost two years ago, alongside
several other lints. It might have been helpful for porting from C++.
Now, I think we can enable that lint again, since omitting the returns
results in equivalent, more concise code, which should not be harder to
read.
The only manual changes in this commit are removing the lint exception
from `Cargo.toml` and removing the unnecessary returns inside `cfg_if!`
macro invocations (in `src/fd_monitor.rs` and `src/proc.rs`).
All other changes were generated by
`cargo clippy --workspace --all-targets --fix && cargo fmt`
Closes#12189
Having the prelude in wchar is not great. The wchar module was empty
except for the prelude, and its prelude included things from wutil.
Having a top-level prelude module in the main crate resolves this. It
allows us to completely remove the wchar module, and a top-level prelude
module makes more sense conceptually. Putting non-wchar things into the
prelude also becomes more sensible, if we ever want to do that.
Closes#12182
After I run a child process like "fish -C 'cd /tmp'", the terminal
will have a stale working directory.
Let's send the OSC 7 notification also once for every fresh prompt
(which is less frequent than the calls to fish_prompt).
This is not fully correct, since it will not work for cases like bind
ctrl-g 'fish -C "cd /tmp"' which allow running external commands
without creating a fresh prompt. We can fix those later, using the
code paths for bracketed paste and friends.
A minor argument for not fixing this just yet is that some people
override "__fish_update_cwd_osc" to work around bugs in their terminal.
Closes#12191Closes#11778Closes#11777
When I run "read" and press enter on the foot terminal, I see a "^[[I"
echoed in the TTY. This is because
1. builtin read creates a TtyHandoff and runs enable_tty_protocols()
2. it runs Reader::readline(), which creates another TtyHandoff.
3. before Reader::readline() returns, it unsets shell modes
(turning ECHO back on). It also drops its TtyHandoff,
which enables TTY protocols again.
4. Enabling focus reporting causes this terminal to send
focus-in event immediately.
This is our fault; we should not have TTY protocols enabled while
ECHO is on.
Fix this by removing the first TtyHandoff (which seems redundant),
meaning that the second one will not try to re-enable protocols.
Breaks the build on OpenBSD.
This is another case of a nix feature being unavailable on some platforms,
so start documenting them.
This reverts commit d6108e5bc0.
Fixes#12192
Our error marking code:
```
function foobar
^~~~~~~^
```
runs fish_wcswidth to figure out how wide the squiggly line should be.
That function returns -1 when it runs into a codepoint that wcwidth
returns -1 for, so the marking would stop at a single `^`.
In some cases, this happens because the error range includes a
newline.
Since we already find the end of the line, and can only mark one line,
we clamp the squiggles at the end of that line.
This improves some markings.
See discussion in #12171
A subsequent commit will need to test for cygwin in a new crate. On
current stable Rust (1.92) this works via `#[cfg(target_os = "cygwin)]`,
but our MSRV (1.85) does not support this. To avoid code duplication,
the OS detection logic is extracted into the build helper crate. For
now, only `detect_cygwin` is needed, but it would be inconsistent to
extract that but not the same functions for other operating systems.
Part of #12183
Another reduction in size of the main crate. Also allows other crates to
depend on the new wchar crate.
The original `src/wchar.rs` file is kept around for now to keep the
prelude imports working.
Part of #12182
Dependencies between crates must form a DAG. This means that breaking up
the large library crate requires breaking dependency cycles. The goal of
this commit is creating a crate which contains some of the main crate's
functionality, without depending on the main crate.
To start off, we only move things required for extracting `src/wchar.rs`
and `src/wchar_ext.rs`, which will happen in a subsequent commit.
Part of #12182
This should help with improving incremental build speed. Extracting this
code is easy, since it does not have dependencies. It also unblocks
further extraction of code which depends on widecharwidth.
Closes#12181
We have logic to prevent "commandline --cursor 123" inside "complete
-C" from setting the transient commandline's cursor.
But reading this cursor ("commandline --cursor")
is fine and expected to work by completion scripts.
I don't expect there is a use case for setting the cursor while
computing completions, so let's make that an error for now.
Could revisit that.
Closes#11993
This test removes $PWD which would cause an error if it were to start
a new process. Normaly we would "cd -" before the removal but later
assertions expect an empty $PWD, so stay there, but don't remove it
to prevent possible surprise.
stage_wildcards has no need for INTERNAL_SEPARATOR. Remove it already
at this stage, to avoid the need to have the workaround in the generic
decoding routine.
Unfortunately we still can't add assert!(!fish_reserved_codepoint(c));
to wcs2bytes_callback, since builtin printf still passes arbitrary
characters. We should fix that later.
Test that printf now behaves correctly for INTERNAL_SEPARATOR.
Also add a regression test for 0c9b73e317.
For some reason r-a shows this diagnostic even though we suppress it
in Cargo.toml (I still need to create a bug report).
Making these upper case would be noisy at the call sites, and it
probably doesn't help since we don't think of these identifiers
as global variables (we never access their fields directly).
Silence the r-a warning for now.
See #12156
This is part of the larger effort of splitting up fish's huge main crate
to improve incremental build speed.
We could extract more logic from `src/wutil/gettext.rs` into the new
crate, but this would require putting wide-string handling into that
crate, which I'm not sure we want. Doing so would have the advantage
that crates which don't depend on fish's main crate (i.e. all crates
other than fish's main crate itself and the binary crates built on top
of it) could then localize messages as well. This will be less relevant
if we replace gettext with Fluent for messages originating from the Rust
sources.
Closes#12108
Based on the discussion in
https://github.com/fish-shell/fish-shell/pull/11967
Introduce a `status language` builtin, which has subcommands for
controlling and inspecting fish's message localization status.
The motivation for this is that using only the established environment
variables `LANGUAGE`, `LC_ALL`, `LC_MESSAGES`, and `LANG` can cause
problems when fish interprets them differently from GNU gettext.
In addition, these are not well-suited for users who want to override
their normal localization settings only for fish, since fish would
propagate the values of these variables to its child processes.
Configuration via these variables still works as before, but now there
is the `status language set` command, which allows overriding the
localization configuration.
If `status language set` is used, the language precedence list will be
taken from its remaining arguments.
Warnings will be shown for invalid arguments.
Once this command was used, the localization related environment
variables are ignored.
To go back to taking the configuration from the environment variables
after `status language set` was executed, users can run `status language
unset`.
Running `status language` without arguments shows information about the
current message localization status, allowing users to better understand
how their settings are interpreted by fish.
The `status language list-available` command shows which languages are
available to choose from, which is used for completions.
This commit eliminates dependencies from the `gettext_impl` module to
code in fish's main crate, allowing for extraction of this module into
its own crate in a future commit.
Closes#12106
We delete the tmpdir unconditionally once all tests are completed, so
there is no point in printing a path which will no longer exist when
analyzing test failures. The paths don't contain any useful information,
so let's delete them to avoid confusion and useless output.
Before this, our test driver printed littlecheck's output before the
test result (test name, duration, PASSED/FAILED/SKIPPED).
This makes it harder to read the output and is inconsistent with the way
pexpect test failures are shown.
Starting with this commit, the result is printed first for both test
types, followed by details about failures, if any.
This reverts commit 52ea511768 ("cleanup: remove useless `INTERNAL_SEPARATOR` handling").
I don't know how to test this given that we don't know what users exist (maybe "root"?).
Fixes#12175
`alias` is terrible, but the main downside of this is that it shows up
in the output of `alias`, which it shouldn't because the user didn't
define these.
This appends "-g" to RUSTFLAGS if the cmake build type is debug or
RelWithDebInfo.
However, these are already mapped to cargo profiles that enable these
things, see https://doc.rust-lang.org/cargo/reference/profiles.html:
> The debug setting controls the -C debuginfo flag which controls the
amount of debug information included in the compiled binary.
(`rustc -g` is equivalent to `debuginfo=2`)
By setting $RUSTFLAGS in cmake, we bake it into the generated
makefile (/ninja thing), which is surprising.
See #12165
Path component movement is not aware of fish syntax -- and we should
be careful as we teach it some fish syntax, because it is expected
to be used on command lines that have unclosed quotes etc.
Tab completion typically uses backslashes to escape paths with spaces.
Using ctrl-w on such path components doesn't work well because it
stops at the escaped space.
Add a quick hack to change it to skip over backslashed spaces. Note that
this isn't fully correct because it will treat backslashes inside
quotes the same way. Not sure what we should do here. We could have
ctrl-w erase all of this
"this is"'only\ one 'path component
But that might be surprising.
Regardless of what we end up with, skipping over backslashed whitespace
seems totally fine, so add that now
Closes#2016
From each logical line in the autosuggestion, we show all or nothing.
This means that we may truncate too early -- specifically 1 + the
number of soft-wrappings in this line. Fix that.
See also #12153
Implicitly-universal variables have some downsides:
- It's surprising that "set fish_color_normal ..."
and "set fish_key_bindings fish_vi_key_bindings" propagate to other
shells and persist, especially since all other variables (and other
shells) would use the global scope.
- they don't play well with tracking configuration in Git.
- we don't know how to roll out updates to the default theme (which is
problematic since can look bad depending on terminal background
color scheme).
It's sort of possible to use only globals and unset universal variables
(because fish only sets them at first startup), but that requires
knowledge of fish internals; I don't think many people do that.
So:
- Set all color variables that are not already set as globals.
- To enable this do the following, once, after upgrading:
copy any existing universal color variables to globals, and:
- if existing universal color variables exactly match
the previous default theme, and pretend they didn't exist.
- else migrate the universals to ~/.config/fish/conf.d/fish_frozen_theme.fish,
which is a less surprising way of persisting this.
- either way, delete all universals to do the right thing for most users.
- Make sure that webconfig's "Set Theme" continues to:
- instantly update all running shells
- This is achieved by a new universal variable (but only for
notifying shells, so this doesn't actually need to be persisted).
In future, we could use any other IPC mechanism such as "kill -SIGUSR1"
or if we go for a new feature, "varsave" or "set --broadcast", see
https://github.com/fish-shell/fish-shell/issues/7317#issuecomment-701165897https://github.com/fish-shell/fish-shell/pull/8455#discussion_r757837137.
- persist the theme updates, completely overriding any previous theme.
Use the same "fish_frozen_theme.fish" snippet as for migration (see above).
It's not meant to be edited directly. If people want flexibility
the should delete it.
It could be a universal variable instead of a conf snippet file;
but I figured that the separate file looks nicer
(we can have better comments etc.)
- Ask the terminal whether it's using dark or light mode, and use an
optimized default. Add dark/light variants to themes,
and the "unknown" variant for the default theme.
Other themes don't need the "unknown" variant;
webconfig already has a background color in context,
and CLI can require the user to specify variant explicitly if
terminal doesn't advertise colors.
- Every variable that is set as part of fish's default behavior
gets a "--label=default" tacked onto it.
This is to allow our fish_terminal_color_theme event handler to
know which variables it is allowed to update. It's also necessary
until we revert 7e3fac561d (Query terminal only just before reading
from it, 2025-09-25) because since commit, we need to wait until
the first reader_push() to get query results. By this time, the
user's config.fish may already have set variables.
If the user sets variables via either webconfig, "fish_config theme
{choose,save}", or directly via "set fish_color_...", they'd almost
always remove this label.
- For consistency, make default fish_key_bindings global
(note that, for better or worse, fish_add_path still remains as
one place that implicitly sets universal variables, but it's not
something we inject by default)
- Have "fish_config theme choose" and webconfig equivalents reset
all color variables. This makes much more sense than keeping a
hardcoded subset of "known colors"; and now that we don't really
expect to be deleting universals this way, it's actually possible
to make this change without much fear.
Should have split this into two commits (the changelog entries are
intertwined though).
Closes#11580Closes#11435Closes#7317
Ref: https://github.com/fish-shell/fish-shell/issues/12096#issuecomment-3632065704
This is incomplete, and we'll solve the problem differently. For now,
leave colors that are not mentioned in the theme. This causes problems
for sparse themes, but a following commit will fix that by making
"fish_config theme choose" erase all variables set by a previous
invocation (but not erase variables set by the user). Only webconfig
won't do that since it (historically) uses copy semantics, but we
could change that too if needed.
This also breaks the guarantee mentioned by this comment in webconfig:
> Ensure that we have all the color names we know about, so that if the
> user deletes one he can still set it again via the web interface
which should be fine because:
1. a following commit will always set all globals at interactive init,
so colors should only be missing in edge cases ("fish -c fish_config").
2. it's easy to recover from by setting a default theme.
For better or worse, "set -L" prints all of $history, which makes
"fish_config theme show" very slow. Fix this by only printing the
relevant variables. While at, make the escaping function use the
shared subset of fish and POSIX shell quoting syntax, to allow a
following commit to use shlex.split().
A following commit wants to add some more logic and call some of
fish_config's private APIs from webconfig. We could keep it all in
one file but I'm not sure we should so try the splitting we usually do.
Historically, fish tried to re-exec the prompt and repaint immediately
when a color variable changed.
Commit f5c6306bde (Do not repaint prompt on universal variable events,
but add event handler for fish_color_cwd, 2006-05-11) restricted this
to only variables used in the prompt like "fish_color_cwd".
Commit 0c9a1a56c2 (Lots of work on web config Change to make fish
immediately show color changes, 2012-03-25) added repainting back
for all colors (except for pager colors).
Commit ff62d172e5 (Stop repainting in C++, 2020-12-11) undid that.
Finally, 69c71052ef (Remove __fish_repaint, 2021-03-04) removed the
--on-variable repaint handlers added by the first commit.
So if color changes via either
1. webconfig
2. an event handler reacting to the terminal switching between light/dark mode
3. a binding etc.
then we fail to redraw. Affects both colors used in prompts and those
not used in prompts.
Fix that by adding back the hack from the second commit. This is
particularly important for case 2, to be added by a following commit.
In future we can remove this hack by making "--on-variable" take
a wildcard.
I can no longer reproduce the issue described in bdd478bbd0 (Disable
focus reporting on non-tmux again for now, 2024-04-18). Maybe the
TTY handoff changes fixed this. Let's remove this workaround and
enable focus reporting everywhere.
Start by converting the "default" theme's colors to RGB, using
XTerm colors since they are simple, see
https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit.
Then make the following changes:
for both default-light and default-dark:
- Reinstate fish_color_command/fish_color_keyword as blue since one
of the reasons in 81ff6db62d (default color scheme: Make commands
"normal" color, 2024-10-02) doesn't hold anymore.
- bravely replace "fish_pager_color_selected_background -r" with
something that hopefully matches better.
Note we can't trivially use the fallback to
"fish_color_search_match", since for unknown reasons,
"fish_pager_color_selected_background" is only for background and
the others are for foreground.
for default-light:
- brgreen (00ff00) looks bad on light background, so replace it with green (00cd00).
This means that we no longer use two different shades of green in the default theme
(which helps address the "fruit salad" mentioned 81ff6db62d).
- yellow (cdcd00) looks bad on light background, make it darker (a0a000)
- fish_pager_color_progress's --background=cyan (00cdcd) seems a bit too bright, make it darker
- same for other uses of cyan (also for consistency)
- this means fish_color_operator / fish_color_escape can use 00cdcd I guess.
for default-dark:
- use bright green (00ff00) for all greens
- use bright blue (5c5cff) instead of regular blue for command/keyword
- make autosuggestions a bit lighter (9f9f9f instead of 7f7f7f)
- etc.. I think I made the two themes mostly symmetrical.
Part of #11580
The "fish-" prefix is not needed here and it would add more noise to
a following commit which adds default-{dark,light} variants that use
24 bit RGB colors.
Don't set fish_pager_color_completion,
it already falls back to fish_color_normal.
Also remove a comment, it's obvious and maybe no longer
true, since 8 bit colors are widely available now, see
https://github.com/fish-shell/fish-shell/issues/11344#issuecomment-3568265178
Though we prefer 24 bit colors wherever we can.
For historical reasons (namely the webconfig origin), our theme
names contain spaces and uppercase letters which can be inconvenient
when using the "fish_config theme choose" shell command. Use more
conventional file names.
Web config still uses the pretty names, using the ubiquitous "# name:"
property.
This function returns a heterogeneous list (containing dicts/lists)
by accident. Fix that and reduce code duplication. Fixes c018bfdb4d
(Initial work to add support for angularjs, 2013-08-17).
Note that we don't need to set the mtime anymore -- it was added in
5b5b53872c (tarball generation: include config.h.in, set mode and
ownership, 2013-09-09) for autotools' multi-stage builds.
Advantages of prebuilt docs:
- convenient for users who compile the tarball
- convenient for packagers who don't have sphinx-build packaged
(but packaging/installing that should be easy nowadays?
see https://github.com/fish-shell/fish-shell/issues/12052#issuecomment-3520336984)
Disadvantages:
- Extra build stage / code path
- Users who switch from building from tarball to building from source
might be surprised to lose docs.
- People put the [tarballs into Git repositories](https://salsa.debian.org/debian/fish), which seems weird.
Remove the tarball.
Let's hope this is not too annoying to users who build on outdated
distros that don't have sphinx -- but those users can probably use
our static builds, skipping all compilation.
To avoid breaking packagers who use `-DBUILD_DOCS=OFF` (which still
installs prebuilt docs), rename the option.
Closes#12088
The logic added by 2dbaf10c36 (Also refresh TTY timestamps
after external commands from bindings, 2024-10-21) is obsoleted
by TtyHandoff. That module is also responsible for calling
reader_save_screen_state after it writes to the TTY, so we don't
actually need to check if it wrote anything.
We silence erros from the key binding function since 2c5151bb78 (Fix
bug in key binding code causing unneeded error messages, 2007-10-31).
Reasons are
1. fish_key_bindings is not a valid function
2. fish_key_bindings runs "bind -k" for things that are not supported (#1155)
Both reasons are obsolete:
1. we already check that earlier
2. "-k" is gone. (Also, we could have silenced "bind -k" invocations instead).
- Prefer the command name without `.exe` since the extension is optional
when launching application on Windows...
- ... but if the user started to type the extension, then use it.
- If there is no description and/or completion for `foo.exe` then
use those for `foo`
Closes#12100
Discussion with terminal authors indicates a slight preference for
removing the prefix. We don't need it at this point, since we only
use it to detect macOS clients.
Two issues:
1. "complete -e foo" doesn't erase wrap definitions
2. "complete -e foo --wraps" erases things other than the wrap definitions
Fix them.
There's another issue, the second erase command leaves around an
extra complete entry. Let's leave that for later.
Fixes#12150
These tests are unreliable in CI when running with address sanitiation
enabled, resulting in intermittent CI failures.
Disable them to get rid of the many false positives to reduce annoyance
and to avoid desensitization regarding failures of the asan CI job.
Suggested in
https://github.com/fish-shell/fish-shell/pull/12132#issuecomment-3605639954Closes#12142Closes#12132Closes#12126
This lint is intended to make it harder to unintentionally cast a
function to an int. We do want to store function pointers in a usize
here, so add the intermediate cast suggested by the lint.
Closes#12131
Buggy programs parsing "fish_indent --ansi" output break because
we wemit SGR0 after the final newline. I suppose this is weird,
and there's no need to wait until after the \n to emit SGR0 so let's
move it before that.
Closes#12096
We should isolate conditionally-compiled code as much as possible,
to allow the compiler to do more work, and to simplify code.
Do that for the embedding definition for __fish_build_paths, like we
already do for "Docs". Duplicate the workaround we use to set the
embedded struct to a "virtually empty" directory. Don't set it to
"$FISH_RESOLVED_BUILD_DIR", because that directory can contain >50k
files, and in debug mode listing files (even if all are excluded)
would take a second.
Ref: https://github.com/fish-shell/fish-shell/pull/12103#issuecomment-3592280477
This should also fix#12120.
Multiple gettext-extraction proc macro instances can run at the same
time due to Rust's compilation model. In the previous implementation,
where every instance appended to the same file, this has resulted in
corruption of the file. This was reported and discussed in
https://github.com/fish-shell/fish-shell/pull/11928#discussion_r2488047964
for the equivalent macro for Fluent message ID extraction. The
underlying problem is the same.
The best way we have found to avoid such race condition is to write each
entry to a new file, and concatenate them together before using them.
It's not a beautiful approach, but it should be fairly robust and
portable.
Closes#12125
This eliminates the proc-macro panic occasionally observed in CI,
instead ignoring paths which cannot be canonicalized.
See #12120.
While this does not address the underlying issue of why the proc-macro
fail happens, it should result in builds no longer failing, and since
they failed in the case where no embedding is desired, there should be
no issue with ignoring failed path canonicalization, since we do not
want to embed anything in these cases.
The old approach does not properly protect from concurrent tests
accessing the same tempdir. Fix this by moving to the new tempfile
functionality. This also eliminates the need to explicitly create and
delete the directory. There is also no longer a reason to specify names
for the temporary directories, since name collisions are avoided using
more robust means, and there is little benefit to having the names in
the directory name.
Closes#12030
The `mkstemp` function opens files without setting `O_CLOEXEC`. We could
manually set this using `fnctl` once the file is opened, but that has
the issue of introducing race conditions. If fish `exec`s in another
thread before the `fnctl` call completes, the file would be left open.
One way of mitigating this is `mkostemp`, but that function is not
available on all systems fish supports, so we can't rely on it.
Instead, build our own tempfile creation logic which uses the `rand`
crate for getting entropy and relies on Rust's stdlib for the rest.
The stdlib functions we use set `O_CLOEXEC` by default.
For directory creation we keep using `mkdtemp`, since there we don't
open anything. We could replace this by extending our custom logic a
bit, which would allow us to drop the `nix` dependency for our
`tempfile` crate, but since the code is simpler as it is now and we need
nix in fish's main crate, there is no need to modify the directory
creation code.
Part of #12030
`SmallRng` was chosen in part due to limitation of old macOS versions.
This is no longer relevant, since the affected versions are not
supported by Rust anymore.
Switch everything which does not need fixed sequences based on a seed to
`ThreadRng`, which has better cryptographic properties and is
occasionally reseeded. Performance differences should not matter much,
since initialization of `ThreadRng` is not that expensive and it's
generation speed is easily fast enough for our purposes.
In some cases, like tests and the `random` builtin, we want a PRNG which
consistently produces the same sequence of values for a given seed.
`ThreadRng` does not do this, since it is occasionally reseeded
automatically. In these cases, we keep using `SmallRng`.
Part of #12030
Function names containing `gen` have been deprecated to avoid conflicts
with the Rust 2024 keyword, so this commit also switches to the new
names.
Part of #12030
Since we changed our MSRV to 1.85, macOS < 10.12 is no longer supported,
so the comment removed here is no longer relevant.
The workaround for old macOS was introduced in
9337c20c2 (Stop using the getrandom feature of the rand crate, 2024-10-07)
We might want to reconsider which RNGs and other features of the `rand`
crate we use, but there is no immediate need to do so, since the current
approach seems to have worked well enough.
Part of #12030
As discussed in #12112, this is a false friend (the libc logb()
does something else), and without keyword arguments or at least
function overloading, this is hard to read.
Better use "/ log(base)" trick.
The old handling of Unicode escape sequences seems partially obsolete
and unnecessarily complicated. For our purposes, Rust's u32 to char
parsing should be exactly what we want.
Due to fish treating certain code points specially, we need to check
if the provided character is among the special chars, and if so we need
to encode it using our PUA scheme. This was not done in the old code,
but is now.
Add tests for this.
Fixes#12081
Rework the error message for invalid code points.
The old message about invalid code points not yet being supported seems
odd. I don't think we should support this, so stop implying that we
might do so in the future.
In the new code, indicating that a Unicode character is
out of range is also not ideal, since the range is not contiguous.
E.g. `\uD800` is invalid, but \U0010FFFF is valid.
Refrain from referring to a "range" and instead just state that the
character is invalid.
Move formatting of the escape sequence into Rust's `format!` to simplify
porting to Fluent.
Closes#12118
While it's not necessary to rebuild the proc macro for extraction when
the env var controlling the output location changes, this way everything
using the macro will automatically be rebuilt when this env var changes,
making it impossible to forget adding this to other `build.rs` files.
For now, keeping the rebuild instructions in fish's main crate's
`build.rs` would be fine as well, but if we start breaking this crate
into smaller parts, it would become annoying to add the rebuild command
in every crate depending on gettext extraction.
Closes#12107
There was a mismatch between the extraction done from
`build_tools/check.sh` and the one done in
`build_tools/fish_xgettext.fish`, resulting in messages guarded by
default features being extracted by the former but not the latter.
This brings them in sync.
Ideally, we would enable all features for extraction, but compiling with
`--all-features` is broken and manually keeping the features lists
updated is tedious and error prone, so we'll settle on only using
default features for now.
Closes#12103
Improve separation of concerns by handling catalog lookup in the
`gettext_impl` module, while taking care of string interning and string
type conversion in the outer `gettext` function as before.
This improves isolation, meaning we no longer have to expose the
catalogs from `gettext_impl` to its parent module.
It also helps with readability.
Part of #12102
Modify the `str_enum!` macro to be able to handle multiple strings per
enum variant. This means that no separate step is required for defining
the enum. Instead definition of the enum and implementation of the
string conversion functions is now combined into a single macro
invocation, eliminating code duplication, as well as making it easier to
add and identify aliases for an enum variant.
Closes#12101
This seems to be a left-over detail from the C++ version. Setting the
first element to 0 does not have any effect, since that's the default,
and setting it to 1 seems to serve no purpose in the current code.
Part of #12101
There is no difference in how these two variants are treated. Keeping
the old command name around for compatibility is nice, but it does not
need to have its own enum variant.
Part of #12101
The -n flag adds warnings about preexisting problems because we don't
check it in CI, so let's not recommend that.
Not everyone uses cmake but it's still the source of truth for docs,
so mention the cmake incantation. Though it seems like the direct
sphinx-build invocation works just fine, so keep it first.
Commit 0893134543 (Added .editorconfig file (#3332) (#3313),
2016-08-25) trimmed trailing whitespace for Markdown file (which do
have significant trailing whitespace) but ReStructuredText does not,
and none of our Markdown files cares about this, so let's clean up
whitespace always.
This message is no longer used since we unconditionally embed files now.
The `#[allow(dead_code)]` annotation was needed to avoid warnings while
ensuring that message extraction was not broken.
Closes#12099
Completions for "foo bar=baz" are sourced from
1. file paths (and custom completions) where "bar=baz" is a subsequence.
2. file paths where "baz" is a subsequence.
I'm not sure if there is ever a case where 1 is non-empty and we
still want to show 2.
Bravely include this property in our completion ranking, and only
show the best ones.
This enables us to get rid of the hack added by b6c249be0c (Back out
"Escape : and = in file completions", 2025-01-10).
Closes#5363
This is another case where we can don't need to use complicated
formatting specifiers. There is also no need to use `wgettext_fmt` for
messages which don't contain any localizable parts.
The instances using `sprintf` could be kept as is, but I think it's
better to keep the width computation at the place where it can sensibly
be done, even though it is not done correctly at the moment because it
does not use grapheme widths.
Removing complicated conversion specifiers from localized messages helps
with the transition to Fluent.
Closes#12119
We already compute the length of the substring we want to print in Rust.
Passing that length as the precision to let printf formatting limit the
length is brittle, as it requires that the same semantics for "length"
are used.
Simplifying conversion specifiers also makes the transition to Fluent
easier.
Part of #12119
The newly added `cargo deny check licenses` command complains about the
licenses added in this commit not being explicitly allowed, so add them
to the config here. There is no intended change in semantics.
Closes#12097
As mentioned in https://github.com/fish-shell/fish-shell/issues/12055#issuecomment-3554869126
> instances of `/bin/sh` as freestanding commands within `.fish`
> files are most likely not automatically handled by `termux-exec`
and
> This topic is complicated by the fact that some Android ROMs _do_
> contain real `/bin/sh` files
Core uses /system/bin/sh on Android. Let's do the same from script
(even if /bin/sh exists), for consistency.
For paths embedded via `rust-embed`, we only need to rebuild on path
changes if the files are actually embedded.
To avoid having to remember and duplicate this logic for all embedded
paths, extract it into the build helper.
Closes#12083
Commit 0709e4be8b (Use standalone code paths by default, 2025-10-26)
mainly wanted to embed internal functions to unbreak upgrade scenarios.
Embedding man pages in CMake has small-ish disadvantages:
1. extra space usage
2. less discoverability
3. a "cyclic" dependency:
1. "sphinx-docs" depends on "fish_indent"
2. "fish_indent" via "crates/build-man-pages" depends on "doc_src/".
So every "touch doc_src/foo.rst && ninja -Cbuild sphinx-docs"
re-builds fish, just to re-run sphinx-build.
The significant one is number 3. It can be worked around by running
sphinx-build with stale "fish_indent" but I don't think we want to
do that.
Let's backtrack a little by stopping embedding man pages in CMake
builds; use the on-disk man pages (which we still install).
The remaining "regression" from 0709e4be8b is that "ninja -Cbuild
fish" needs to rebuild whenever anything in "share/" changes. I don't
know if that's also annoying?
Since man pages for "build/fish" are not in share/, expose the exact
path as $__fish_man_dir.
When $RELOCATED_PREFIX/bin/fish detects that
$RELOCATED_PREFIX/share/fish and $RELOCATED_PREFIX/etc/fish exist,
it uses paths from $RELOCATED_PREFIX (which is determined at runtime,
based on $argv), and not the prefix determined at compile time.
Except we do use DOCDIR (= ${CMAKE_INSTALL_FULL_DOCDIR}). This
seems like a weird side effect of commit b758c0c335 (Relax the
requirement that we find a working 'doc' directory in order for fish
to be relocatable. 2014-01-17) which enabled relocatable logic in
scenarios where $PREFIX/share/doc/fish was not installed.
This is weird; fish's "help" command should not take docs from a
different prefix.
Always use the matching docdir. This shouldn't make any practical
difference because since commit b5aea3fd8b (Revert "[cmake] Fix
installing docs", 2018-03-13), $PREFIX/share/doc/fish/CHANGELOG.rst
is always installed.
The help_sections.rs file was added to the tarball only as a quick hack.
There is a cyclic dependency between docs and fish:
"fish_indent" via "crates/build-man-pages" depends on "doc_src/".
So every "touch doc_src/foo.rst && ninja -Cbuild sphinx-docs"
re-builds fish.
In future "fish_indent" should not depend on "crates/build-man-pages".
Until then, a following commit wants to break this cyclic dependency
in a different way: we won't embed man pages (matching historical
behavior), which means that CMake builds won't need to run
sphinx-build.
But sphinx-build is also used for extracting help sections.
Also, the fix for #12082 will use help sections elsewhere in the code.
Prepare to remove the dependency on doc_src by committing the help
sections (we already do elsewhere).
This mode still has some problems (see the next commit) but having
it behind a feature flag doesn't serve us. Let's commit to the parts
we want to keep and drop anything that we don't want.
To reduce diff noise, use "if false" in the code paths used by man
pages; a following commit will use them.
macOS has en_US.UTF-8 but not C.UTF-8, which leads to a glitch when
typing "🐟". Fix that by trying the user's locale first, restoring
historical behavior.
Fixes 71a962653d (Be explicit about setlocale() scope, 2025-10-24).
Reported-by: Ilya Grigoriev <ilyagr@users.noreply.github.com>
When running fish inside SSH and local and remote OS differ, fish
uses key bindings for the remote OS, which is weird. Fix that by
asking the terminal for the OS name.
This should be available on foot and kitty soon, see
https://codeberg.org/dnkl/foot/pulls/2217#issuecomment-8249741
Ref: #11107
iTerm2 displays commands in other UI widgets such as in Command History
(View → Toolbelt → Command History). This needs prompt end marker
so the terminal can distinguish prompt from the command line.
Closes#11837
Historically, "fish_color_*" variables used a hand-written option
parser that would try to recover from invalid options.
Commit 037c1896d4 (Reuse wgetopt parsing for set_color for internal
colors, 2025-04-13) tried to preserve this recovering, but that
breaks WGetopter invariants.
I don't think this type of fallback is important, because
there's no reason we can't parse color variables (except maybe
forward-compatibility in future). Let's turn errors into the default
style; this should tell the user that their color is unsupported.
Fixes#12078
For historical reasons, fish does not implement the VT state
machine but uses a relatively low timeout when reading
escape sequences. This might be causing issues like
https://github.com/fish-shell/fish-shell/issues/11841#issuecomment-3544505235
so let's cautiously increase the timeout.
Make it opt-in and print a noisy error when we time out, so we can
find affected terminals.
We've removed several terminal-specific workarounds but also added
some recently. Most of the non-Apple issues have been reported
upstream. Many of our workarounds were only meant to be temporary.
Some workarounds are unreliable and some can cause introduce other
problems.
Add a feature flag we can use later to let users turn off workarounds.
This doesn't disable anything yet, mostly because because despite being
off-by-default, this might surprise people who use "fish_features=all".
The fix would be "fish_features=all,no-omit-term-workarounds".
So we'd want a high degree of confidence.
For now we'll use this only with the next commit.
Closes#11819
Commit 3f2e4b71bc (functions/__fish_print_help: bravely remove
fallback to mandoc/groff, 2025-11-09) savagely made commands like
"abbr -h" require man, or else it prints a noisy stack trace.
Some packages have not yet replaced "nroff/mandoc" with "man"
as dependency, and, independent of that, man is still an optional
dependency.
Make missing "man" a proper error, which is easier to read tan the
stack trace.
Use \e\\ as sequence terminator for the first OSC 133 prompt start
marker. The intention is to find out if a terminal fails to parse
this. If needed, the user can turn it off by adding "no-mark-prompt"
to their feature flags; but the shell is still usable without this.
Part of #12032
For now, we mostly use "/bin/sh" for background tasks; but sometimes
we call it as "sh". The former does not work on android, but I'm not
yet sure how we should fix that.
Let's make things consistent first, so they are easier to change
(we might remove some background tasks, or reimplement them in fish
script).
We always use python3 but don't use, say python3.999 until we update
our hardcoded list. This is inconsistent (we're careful about the
latter but not the former). Fix this by always picking the highest
minor version (>= 3.5+) there is. This also reduces maintenance work.
Note that NetBSD is the only OS we know about that doesn't provide
the python3 symlink OOTB. In future, the NetBSD package should
add a patch to replace "python3" in __fish_anypython.fish
with the correct path. Downstream discussion is at
https://mail-index.netbsd.org/pkgsrc-users/2025/11/17/msg042205.html
As mentioned in
https://github.com/fish-shell/fish-shell/issues/11921#issuecomment-3540587001,
binaries duplicate a lot of information unnecessarily.
$ cargo b --release
$ du -h target/release/fish{,_indent,_key_reader}
15M target/release/fish
15M target/release/fish_indent
4.1M target/release/fish_key_reader
34M total
Remove the duplication in CMake-installed builds by creating hard
links. I'm not sure how to do that for Cargo binaries yet (can we
write a portable wrapper script)?
This is still a bit weird because hardlinks are rarely used like
this; but symlinks may cause issues on MSYS2. Maybe we should write
a /bin/sh wrapper script instead.
This might help cross-compilation; even if it doesn't matter in
practice, this is more correct. While at it, get rid of $TARGET in
favor of the more accurate $CARGO_CFG_TARGET_OS.
Not yet sure how to do it for "has_small_stack".
Frequently when I launch a new shell and type away, my input is
echoed in the terminal before fish gets a chance to set shell modes
(turn off ECHO and put the terminal into non-canonical mode).
This means that fish assumption about the cursor x=0 is wrong, which
causes the prompt (here '$ ') to be draw at the wrong place, making
it look like this:
ececho hello
This seems to have been introduced in 4.1.0 in a0e687965e (Fix
unsaved screen modification, 2025-01-14). Not sure how it wasn't a
problem before.
Fix this by clearing to the beginning of the line after turning off
ECHO but before we draw anything to the screen.
This turns this comment in the patch context into a true statement:
> This means that `printf %s foo; fish` will overwrite the `foo`
Note that this currently applies per-reader, so builtin "read" will
also clear the line before doing anything.
We could potentially change this in future, if we both
1. query the cursor x before we output anything
2. refactor the screen module to properly deal with x>0 states.
But even if we did that, it wouldn't change the fact that we want
to force x=0 if the cursor has only been moved due to ECHO, so I'm
not sure.
Adds [`Vermin`](https://github.com/netromdk/vermin) to make sure our
user facing Python scripts conform to the proper minimum Python version
requirements.
The tool parses Python code into an AST and checks it against a database
of rules covering Python 2.0-3.13.
Testing Python version compatibility is tricky because most issues only
show up at runtime. Type annotations like `str | None` (Python 3.10+)
compile just fine (under pyc) and they don't throw an exception until
you actually call the relevant function.
This makes it hard to catch compatibility bugs without running the code
(through all possible execution paths) on every Python version.
Signed-off-by: seg6 <hi@seg6.space>
Closes#12044
Issue #11933 stems from Cygwin's flock implementation not being thread
safe. Previous code fixed the worst behavior (deadlock), at least in
some circumstance but still failed the history tests.
This new workaround correctly make flock usage thread safe by surrounding
it with a mutex lock.
The failing test can now pass and is much faster (5s instead of 15 on
my machine)
Upstream bug report: https://cygwin.com/pipermail/cygwin/2025-November/258963.htmlCloses#12068Closes#11933
As discovered in #12062, man-db as installed from brew is not affected
by the "read-only-filesystem" problem what makewhatis suffers from
(though users do need to run "gmandb" once).
Restrict the workaround to the path to macOS's apropos; hopefully
that's stable.
This breaks people who define an alias for apropos; I guess for those
we could check "command -v" instead, but that's weird because the thing
found by type is the actual thing we're gonna execute. So I'd first
rather want to find out why anyone would override this obscure command.
In POSIX sh, ";" is not a valid statement, leading to errors when the
__fish_cached callback argument has a trailing newline (5c2073135e
(Fix syntax error in __fish_print_port_packages.fish, 2025-11-14)).
Use a newline instead of ";", to avoid this error.
While at it, replace rogue tab characters.
`grep -Fx` will match fixed strings over the entire line.
`status list-files foo` will match anything that starts with "foo".
Since we always pass a suffix here, that's the same thing.
If we really cared, we could do `string match "*.$suffix"` or similar.
Fixes#12060
Historically, Sphinx was required when building "standalone" builds,
else they would have no man pages.
This means that commit 0709e4be8b (Use standalone code paths by
default, 2025-10-26) broke man pages for users who build from a
tarball where non-standalone builds would use prebuilt docs.
Add a hack to use prebuilt docs again.
In future, we'll remove prebuilt docs, see #12052.
This release fixes the following problems identified in fish 4.3.0:
- Selecting a completion could insert only part of the token (:issue:`12249`).
- Glitch with soft-wrapped autosuggestions and :doc:`fish_right_prompt <cmds/fish_right_prompt>` (:issue:`12255`).
- Spurious echo in tmux when typing a command really fast (:issue:`12261`).
-``tomorrow`` theme always using the light variant (:issue:`12266`).
-``fish_config theme choose`` sometimes not shadowing themes set by e.g. webconfig (:issue:`12278`).
- The sample prompts and themes are correctly installed (:issue:`12241`).
- Last line of command output could be hidden when missing newline (:issue:`12246`).
Other improvements include:
- The ``abbr``, ``bind``, ``complete``, ``functions``, ``history`` and ``type`` commands now support a ``--color`` option to control syntax highlighting in their output. Valid values are ``auto`` (default), ``always``, or ``never``.
- Existing file paths in redirection targets such as ``> file.txt`` are now highlighted using :envvar:`fish_color_valid_path`, indicating that ``file.txt`` will be clobbered (:issue:`12260`).
fish 4.3.2 (released December 30, 2025)
=======================================
This release fixes the following problems identified in 4.3.0:
- Pre-built macOS packages failed to start due to a ``Malformed Mach-O file`` error (:issue:`12224`).
-``extra_functionsdir`` (usually ``vendor_functions.d``) and friends were not used (:issue:`12226`).
- Sample config file ``~/.config/fish/config.fish/`` and config directories ``~/.config/fish/conf.d/``, ``~/.config/fish/completions/`` and ``~/.config/fish/functions/`` were recreated on every startup instead of only the first time fish runs on a system (:issue:`12230`).
- Spurious echo of ``^[[I`` in some scenarios (:issue:`12232`).
- Infinite prompt redraw loop on some prompts (:issue:`12233`).
- The removal of pre-built HTML docs from tarballs revealed that cross compilation is broken because we use ``${CMAKE_BINARY_DIR}/fish_indent`` for building HTML docs.
As a workaround, the new CMake build option ``FISH_INDENT_FOR_BUILDING_DOCS`` can be set to the path of a runnable ``fish_indent`` binary.
fish 4.3.1 (released December 28, 2025)
=======================================
This release fixes the following problem identified in 4.3.0:
- Possible crash after expanding an abbreviation (:issue:`12223`).
fish 4.3.0 (released December 28, 2025)
=======================================
Deprecations and removed features
---------------------------------
- fish no longer sets user-facing :ref:`universal variables <variables-universal>` by default, making the configuration easier to understand.
Specifically, the ``fish_color_*``, ``fish_pager_color_*`` and ``fish_key_bindings`` variables are now set in the global scope by default.
After upgrading to 4.3.0, fish will (once and never again) migrate these universals to globals set at startup in the
``~/.config/fish/conf.d/fish_frozen_theme.fish`` and
We suggest that you delete those files and :ref:`set your theme <syntax-highlighting>` in ``~/.config/fish/config.fish``.
- You can still configure fish to propagate theme changes instantly; see :ref:`here <syntax-highlighting-instant-update>` for an example.
- You can still opt into storing color variables in the universal scope
via ``fish_config theme save`` though unlike ``fish_config theme choose``,
it does not support dynamic theme switching based on the terminal's color theme (see below).
- In addition to setting the variables which are explicitly defined in the given theme,
``fish_config theme choose`` now clears only color variables that were set by earlier invocations of a ``fish_config theme choose`` command
(which is how fish's default theme is set).
Scripting improvements
----------------------
- New :ref:`status language <status-language>` command allows showing and modifying language settings for fish messages without having to modify environment variables.
- When using a noninteractive fish instance to compute completions, ``commandline --cursor`` works as expected instead of throwing an error (:issue:`11993`).
-:envvar:`fish_trace` can now be set to ``all`` to also trace execution of key bindings, event handlers as well as prompt and title functions.
Interactive improvements
------------------------
- When typing immediately after starting fish, the first prompt is now rendered correctly.
- Completion accuracy was improved for file paths containing ``=`` or ``:`` (:issue:`5363`).
- Prefix-matching completions are now shown even if they don't match the case typed by the user (:issue:`7944`).
- On Cygwin/MSYS, command name completion will favor the non-exe name (``foo``) unless the user started typing the extension.
- When using the exe name (``foo.exe``), fish will use the description and completions for ``foo`` if there are none for ``foo.exe``.
- Autosuggestions now also show soft-wrapped portions (:issue:`12045`).
New or improved bindings
------------------------
-:kbd:`ctrl-w` (``backward-kill-path-component``) also deletes escaped spaces (:issue:`2016`).
- New special input functions ``backward-path-component``, ``forward-path-component`` and ``kill-path-component`` (:issue:`12127`).
Improved terminal support
-------------------------
- Themes can now be made color-theme-aware by including both ``[light]`` and ``[dark]`` sections in the :ref:`theme file <fish-config-theme-files>`.
Some default themes have been made color-theme-aware, meaning they dynamically adjust as your terminal's background color switches between light and dark colors (:issue:`11580`).
- The working directory is now reported on every fresh prompt (via OSC 7), fixing scenarios where a child process (like ``ssh``) left behind a stale working directory (:issue:`12191`).
- OSC 133 prompt markers now also mark the prompt end, which improves shell integration with terminals like iTerm2 (:issue:`11837`).
- Operating-system-specific key bindings are now decided based on the :ref:`terminal's host OS <status-terminal-os>`.
- New :ref:`feature flag <featureflags>```omit-term-workarounds`` can be turned on to prevent fish from trying to work around some incompatible terminals.
For distributors and developers
-------------------------------
- Tarballs no longer contain prebuilt documentation,
so building and installing documentation requires Sphinx.
To avoid users accidentally losing docs, the ``BUILD_DOCS`` and ``INSTALL_DOCS`` configuration options have been replaced with a new ``WITH_DOCS`` option.
-``fish_key_reader`` and ``fish_indent`` are now installed as hardlinks to ``fish``, to save some space.
Regression fixes:
-----------------
- (from 4.1.0) Crash on incorrectly-set color variables (:issue:`12078`).
- (from 4.1.0) Crash when autosuggesting Unicode characters with nontrivial lowercase mapping.
- (from 4.2.0) Incorrect emoji width computation on macOS.
- (from 4.2.0) Mouse clicks and :kbd:`ctrl-l` edge cases in multiline command lines (:issue:`12121`).
- (from 4.2.0) Completions for Git remote names on some non-glibc systems.
- (from 4.2.0) Expansion of ``~$USER``.
fish 4.2.1 (released November 13, 2025)
=======================================
This release fixes the following problems identified in 4.2.0:
- When building from a tarball without Sphinx (that is, with ``-DBUILD_DOCS=OFF`` or when ``sphinx-build`` is not found),
builtin man pages and help files were missing, which has been fixed (:issue:`12052`).
-``fish_config``'s theme selector (the "colors" tab) was broken, which has been fixed (:issue:`12053`).
fish 4.2.0 (released November 10, 2025)
=======================================
@@ -93,7 +205,7 @@ This release fixes the following regressions identified in 4.1.0:
This will not affect fish's child processes unless ``LC_MESSAGES`` was already exported.
- Some :doc:`fish_config <cmds/fish_config>` subcommands for showing prompts and themes had been broken in standalone Linux builds (those using the ``embed-data`` cargo feature), which has been fixed (:issue:`11832`).
- On Windows Terminal, we observed an issue where fish would fail to read the terminal's response to our new startup queries, causing noticeable lags and a misleading error message. A workaround has been added (:issue:`11841`).
- On Windows Terminal, we observed an issue where fish would fail to read the terminal's response to our new startup queries, causing noticeable lags and a misleading error message. A workaround has been added (:issue:`11841`).
- A WezTerm `issue breaking shifted key input <https://github.com/wezterm/wezterm/issues/6087>`__ has resurfaced on some versions of WezTerm; our workaround has been extended to cover all versions for now (:issue:`11204`).
- Fixed a crash in :doc:`the web-based configuration tool <cmds/fish_config>` when using the new underline styles (:issue:`11840`).
- using the `installer from fishshell.com <https://fishshell.com/>`__
- as a `standalone app from fishshell.com <https://fishshell.com/>`__
Note: The minimum supported macOS version is 10.10 "Yosemite".
Note: The minimum supported macOS version is 10.12.
Packages for Linux
~~~~~~~~~~~~~~~~~~
@@ -117,7 +117,7 @@ Dependencies
Compiling fish requires:
- Rust (version 1.85 or later)
- Rust (version 1.85 or later), including cargo
- CMake (version 3.15 or later)
- a C compiler (for system feature detection and the test helper binary)
- PCRE2 (headers and libraries) - optional, this will be downloaded if missing
@@ -157,10 +157,13 @@ In addition to the normal CMake build options (like ``CMAKE_INSTALL_PREFIX``), f
- 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).
-WITH_DOCS=ON|OFF - whether to build the documentation. By default, this is ON when Sphinx is installed.
-FISH_INDENT_FOR_BUILDING_DOCS - useful for cross-compilation.
Set this to the path to the ``fish_indent`` executable to use for building HTML docs.
By default, ``${CMAKE_BINARY_DIR}/fish_indent`` will be used.
If that's not runnable on the compile host,
you can build a native one with ``cargo build --bin fish_indent`` and set this to ``$PWD/target/debug/fish_indent``.
- FISH_USE_SYSTEM_PCRE2=ON|OFF - whether to use an installed pcre2. This is normally autodetected.
- MAC_CODESIGN_ID=String|OFF - the codesign ID to use on Mac, or "OFF" to disable codesigning.
- WITH_GETTEXT=ON|OFF - whether to include translations.
- extra_functionsdir, extra_completionsdir and extra_confdir - to compile in an additional directory to be searched for functions, completions and configuration snippets
@@ -185,13 +188,14 @@ You can also install Sphinx another way and drop the ``uv run --no-managed-pytho
This will place standalone binaries in ``~/.cargo/bin/``, but you can move them wherever you want.
To disable translations, disable the ``localize-messages`` feature by passing ``--no-default-features --features=embed-data`` to cargo.
To disable translations, disable the ``localize-messages`` feature by passing ``--no-default-features --features=embed-manpages`` to cargo.
You can also link this build statically (but not against glibc) and move it to other computers.
Here are the remaining advantages of a full installation, as currently done by CMake:
- Man pages like ``fish(1)`` installed in standard locations, easily accessible from outside fish.
- Separate files for builtins (e.g. ``$PREFIX/share/fish/man/man1/abbr.1``).
- A local copy of the HTML documentation, typically accessed via the ``help`` fish function.
In Cargo builds, ``help`` will redirect to `<https://fishshell.com/docs/current/>`__
- Ability to use our CMake options extra_functionsdir, extra_completionsdir and extra_confdir,
@@ -31,7 +31,7 @@ The work will **proceed on master**: no long-lived branches. Tests and CI contin
The Rust code will initially resemble the replaced C++. Fidelity to existing code is more important than Rust idiomaticity, to aid review and bisecting. But don't take this to extremes - use judgement.
The port will proceed "outside in." We'll start with leaf components (e.g. builtins) and proceed towards the core. Some components will have both a Rust and C++ implementation (e.g. FLOG), in other cases we'll change the existing C++ to invoke the new Rust implementations (builtins).
The port will proceed "outside in." We'll start with leaf components (e.g. builtins) and proceed towards the core. Some components will have both a Rust and C++ implementation (e.g. flog), in other cases we'll change the existing C++ to invoke the new Rust implementations (builtins).
@@ -58,7 +58,7 @@ The basic development loop for this port:
- Do this even if it results in less idiomatic Rust, but avoid being super-dogmatic either way.
- One technique is to paste the C++ into the Rust code, commented out, and go line by line.
4. Decide whether any existing C++ callers should invoke the Rust implementation, or whether we should keep the C++ one.
- Utility functions may have both a Rust and C++ implementation. An example is `FLOG` where interop is too hard.
- Utility functions may have both a Rust and C++ implementation. An example is `flog` where interop is too hard.
- Major components (e.g. builtin implementations) should _not_ be duplicated; instead the Rust should call C++ or vice-versa.
5. Remember to run `cargo fmt` and `cargo clippy` to keep the codebase somewhat clean (otherwise CI will fail). If you use rust-analyzer, you can run clippy automatically by setting `rust-analyzer.checkOnSave.command = "clippy"`.
@@ -93,7 +93,7 @@ None of the Rust string types are nul-terminated. We're taking this opportunity
One may create a `&wstr` from a string literal using the `wchar::L!` macro:
```rust
usecrate::wchar::prelude::*;
usecrate::prelude::*;
// This imports wstr, the L! macro, WString, a ToWString trait that supplies .to_wstring() along with other things
We have a prelude to make working with these string types a whole lot more ergonomic. In particular `WExt` supplies the null-terminated-compatible `.char_at(usize)`,
and a whole lot more methods that makes porting C++ code easier. It is also preferred to use char-based-methods like `.char_count()` and `.slice_{from,to}()`
and a whole lot more methods that makes porting C++ code easier. It is also preferred to use char-based-methods like `.char_count()` and `.slice_{from,to}()`
of the `WExt` trait over directly calling `.len()` and `[usize..]/[..usize]`, as that makes the code compatible with a potential future change to UTF8-strings.
```rust
@@ -144,7 +144,7 @@ These types should be confined to the FFI modules, in particular `wchar_ffi`. Th
### Format strings
Rust's builtin `std::fmt` modules do not accept runtime-provided format strings, so we mostly won't use them, except perhaps for FLOG / other non-translated text.
Rust's builtin `std::fmt` modules do not accept runtime-provided format strings, so we mostly won't use them, except perhaps for flog / other non-translated text.
Instead we'll continue to use printf-style strings, with a Rust printf implementation.
@@ -23,6 +23,8 @@ If other programs launched via fish should respect these locale variables they h
For :envvar:`LANGUAGE` you can use a list, or use colons to separate multiple languages.
If the :ref:`status language set <status-language>` command was used, its arguments specify the language precedence, and the environment variables are ignored.
@@ -46,7 +46,7 @@ Combining these features, it is possible to create custom syntaxes, where a regu
> abbr >> ~/.config/fish/config.fish
> abbr --erase (abbr --list)
Alternatively you can keep them in a separate :ref:`configuration file <configuration>` by doing something like the following::
> abbr > ~/.config/fish/conf.d/myabbrs.fish
@@ -75,7 +75,6 @@ With **--set-cursor=MARKER**, the cursor is moved to the first occurrence of **M
With **-f FUNCTION** or **--function FUNCTION**, **FUNCTION** is treated as the name of a fish function instead of a literal replacement. When the abbreviation matches, the function will be called with the matching token as an argument. If the function's exit status is 0 (success), the token will be replaced by the function's output; otherwise the token will be left unchanged. No **EXPANSION** may be given separately.
@@ -104,6 +104,10 @@ The following options are available:
**-s** or **--silent**
Silences some of the error messages, including for unknown key names and unbound sequences.
**--color***WHEN*
Controls when to use syntax highlighting colors when listing bindings.
*WHEN* can be ``auto`` (the default, colorize if the output :doc:`is a terminal <isatty>`), ``always``, or ``never``.
**-h** or **--help**
Displays help about using this command.
@@ -145,12 +149,17 @@ The following special input functions are available:
``backward-kill-line``
move everything from the beginning of the line to the cursor to the killring
.._cmd-bind-backward-kill-path-component:
``backward-kill-path-component``
move one path component to the left of the cursor to the killring. A path component is everything likely to belong to a path component, i.e. not any of the following: `/={,}'\":@ |;<>&`, plus newlines and tabs.
``backward-kill-word``
move the word to the left of the cursor to the killring. The "word" here is everything up to punctuation or whitespace.
``backward-path-component``
move one :ref:`path component <cmd-bind-backward-kill-path-component>` to the left.
``backward-word``
move one word to the left
@@ -241,6 +250,9 @@ The following special input functions are available:
commandline, does not accept the current autosuggestion (if any). Does not change the selected item in the completion pager,
if shown.
``forward-path-component``
move one :ref:`path component <cmd-bind-backward-kill-path-component>` to the right; or if at the end of the commandline, accept a path component from the current autosuggestion.
``forward-single-char``
move one character to the right; or if at the end of the commandline, accept a single char from the current autosuggestion.
@@ -308,6 +320,9 @@ The following special input functions are available:
``kill-line``
move everything from the cursor to the end of the line to the killring
``kill-path-component``
move one :ref:`path component <cmd-bind-backward-kill-path-component>` to the killring.
@@ -74,6 +74,10 @@ The following options are available:
**--escape**
When used with ``-C``, escape special characters in completions.
**--color***WHEN*
Controls when to use syntax highlighting colors when printing completions.
*WHEN* can be ``auto`` (the default, colorize if the output :doc:`is a terminal <isatty>`), ``always``, or ``never``.
**-h** or **--help**
Displays help about using this command.
@@ -103,6 +107,31 @@ When erasing completions, it is possible to either erase all completions for a s
When ``complete`` is called without anything that would define or erase completions (options, arguments, wrapping, ...), it shows matching completions instead. So ``complete`` without any arguments shows all loaded completions, ``complete -c foo`` shows all loaded completions for ``foo``. Since completions are :ref:`autoloaded <syntax-function-autoloading>`, you will have to trigger them first.
.._completions-cygwin:
Cygwin / MSYS2 / Windows
------------------------
On Windows, binary executables have a ``.exe`` extension, but this extension is not required when calling an application (and if the name is not ambiguous, i.e. there isn't also a script called ``myprog`` in the same directory as ``myprog.exe``).
To unify completions between Windows and other OSes, on Cygwin/MSYS2/Windows, *COMMAND* does not require the ``.exe`` extension.
Completions for ``myprog`` will also be used for ``myprog.exe`` if there are no ambiguities, i.e. if there are no completions for ``myprog.exe`` specifically.
However, completions for ``myprog.exe`` will only be used when also using the ``.exe`` extension on the command line.
In other words:
::
complete -c myprog.exe ... #1
will only work for ``myprog.exe``
::
complete -c myprog ... #2
can work for both ``myprog`` and ``myprog.exe``. But if both completions exist, #2 will only be used for ``myprog`` while ``myprog.exe`` will use #1.
@@ -32,15 +37,20 @@ With the ``theme`` command ``fish_config`` can be used to view and choose a them
Available subcommands for the ``theme`` command:
-``choose`` loads a sample theme in the current session.
-``choose`` loads a theme in the current session.
If the theme has light and dark variants (see below), the one matching :envvar:`fish_terminal_color_theme` will be applied (also whenever that variable changes).
To override :envvar:`fish_terminal_color_theme`, pass the ``--color-theme`` argument.
-``demo`` displays some sample text in the current theme.
-``dump`` prints the current theme in a loadable format.
-``list`` lists the names of the available sample themes.
-``save`` saves the given theme to :ref:`universal variables <variables-universal>`.
-``show`` shows what the given sample theme (or all) would look like.
-``list`` lists the names of the available themes.
-``show`` shows what the given themes (or all) would look like.
-*(not recommended)*``save`` saves the given theme to :ref:`universal variables <variables-universal>`.
A theme set this way will not update as :envvar:`fish_terminal_color_theme` changes.
The **-h** or **--help** option displays help about using this command.
.._fish-config-theme-files:
Theme Files
-----------
@@ -60,24 +70,38 @@ The format looks like this:
::
# name: 'Cool Beans'
# preferred_background: black
# name: 'My Theme'
fish_color_autosuggestion 666
fish_color_cancel -r
fish_color_command normal
fish_color_comment '888' '--italics'
fish_color_cwd 0A0
fish_color_cwd_root A00
fish_color_end 009900
[light]
# preferred_background: ffffff
fish_color_normal 000000
fish_color_autosuggestion 7f7f7f
fish_color_command 0000ee
The two comments at the beginning are the name and background that the web config tool shows.
[dark]
# preferred_background: 000000
fish_color_normal ffffff
fish_color_autosuggestion 7f7f7f
fish_color_command 5c5cff
[unknown]
fish_color_normal normal
fish_color_autosuggestion brblack
fish_color_cancel -r
fish_color_command normal
The comments provide name and background color to the web config tool.
Themes can have three variants,
one for light mode,
one for dark mode,
and one for terminals that don't :ref:`report colors <term-compat-query-background-color>` (where :envvar:`fish_terminal_color_theme` is set to ``unknown``).
The other lines are just like ``set variable value``, except that no expansions are allowed. Quotes are, but aren't necessary.
Any color variable fish knows about that the theme doesn't set will be set to empty when it is loaded, so the old theme is completely overwritten.
.._fish_config-color-variables:
Other than that, .theme files can contain any variable with a name that matches the regular expression ``'^fish_(?:pager_)?color.*$'`` - starts with ``fish_``, an optional ``pager_``, then ``color`` and then anything.
Other than that, .theme files can contain any variable with a name that matches the regular expression ``'^fish_(?:pager_)?color_.*$'`` - starts with ``fish_``, an optional ``pager_``, then ``color_`` and then anything.
@@ -23,7 +23,7 @@ The fish_hg_prompt function displays information about the current Mercurial rep
By default, only the current branch is shown because ``hg status`` can be slow on a large repository. You can enable a more informative prompt by setting the variable ``$fish_prompt_hg_show_informative_status``, for example::
set --universal fish_prompt_hg_show_informative_status
set fish_prompt_hg_show_informative_status
If you enabled the informative status, there are numerous customization options, which can be controlled with fish variables.
@@ -72,7 +72,7 @@ Same as above but the value of the second flag cannot be the empty string:
::
set -l options (fish_opt -s h -l help)
set options $options (fish_opt -s m -l max -rv test \$_flag_valu != "''")
set options $options (fish_opt -s m -l max -rv test \$_flag_value != "''")
argparse $options -- $argv
Same as above but with a third flag that can be given multiple times saving the value of each instance seen and only a long flag name (``--token``) is defined:
@@ -82,7 +82,7 @@ Same as above but with a third flag that can be given multiple times saving the
::
set -l options (fish_opt --short=h --long=help)
set options $options (fish_opt --short=m --long=max --required-val --validate test \$_flag_valu != "''")
set options $options (fish_opt --short=m --long=max --required-val --validate test \$_flag_value != "''")
set options $options (fish_opt --long=token --multiple-vals)
@@ -29,6 +29,11 @@ When in doubt, use parentheses.
``math`` ignores whitespace between arguments and takes its input as multiple arguments (internally joined with a space), so ``math 2 +2`` and ``math "2 + 2"`` work the same.
``math 2 2`` is an error.
..note::
math is a simple tool for simple uses, provided for convenience. It internally works with floats for simplicity of implementation and can't do a number of things real calculators can.
If you find yourself limited by that, use a more full-featured tool.
The following options are available:
**-s***N* or **--scale***N*
@@ -153,7 +158,7 @@ Functions
``ln``
the base-e logarithm
``log`` or ``log10``
the base-10 logarithm
the base-10 logarithm. To compute the logarithm for an arbitrary base ``b``, use ``log(x) / log(b)``.
status language [list-available|set [LANGUAGE ...]|unset]
Description
-----------
@@ -118,19 +118,12 @@ The following operations (subcommands) are available:
as well as the man pages and themes. Which files are included depends on build settings.
Returns 0 if the file was included, 1 otherwise.
**list-files***FILE*
**list-files***FILE...*
NOTE: this subcommand is mainly intended for fish's internal use; let us know if you want to use it elsewhere.
This lists the files embedded in the fish binary at compile time. Only files where the path starts with the optional *FILE* argument are shown.
Returns 0 if something was printed, 1 otherwise.
**help-sections**
NOTE: this subcommand is intended for fish's internal use.
List section arguments for the :doc:`help <help>` command.
If you have the latest version of fish, these URL fragments are valid on `<https://fishshell.com/docs/current/>`__.
Always returns 0.
.._status-terminal:
**terminal**
@@ -138,6 +131,13 @@ The following operations (subcommands) are available:
This is not available during early startup but only starting from when the first interactive prompt is shown, possibly via builtin :doc:`read <read>`,
so before the first ``fish_prompt`` or ``fish_read``:ref:`event <event>`.
.._status-terminal-os:
**terminal-os**
Prints the name of the operating system (OS) the terminal is running on, as reported via :ref:`XTGETTCAP query-os-name <term-compat-xtgettcap>`.
Like :ref:`status terminal <status-terminal>`, this only works once the first interactive prompt is shown.
Returns 1 if the OS name is not available.
.._status-test-terminal-features:
**test-terminal-feature***FEATURE*
@@ -147,6 +147,32 @@ The following operations (subcommands) are available:
Currently the only available *FEATURE* is :ref:`scroll-content-up <term-compat-indn>`.
An error will be printed when passed an unrecognized feature.
.._status-language:
**language**
Show or modify message localization settings.
When invoked without arguments, the current language settings are shown.
Available subcommands:
**list-available**
prints the language names for which fish has translations.
These names can be used with the **set** subcommand.
**set**
sets the language precedence for fish's messages.
Overrides language settings configured via :ref:`environment variables <variables-locale>`, but only applies to fish itself, not to any child processes.
Takes a list of language names from the set shown by the **list-available** subcommand.
For some languages, fish's translation catalogs are incomplete, meaning not all messages can be shown in these languages.
Therefore, we allow specifying a list here, with translations taken from the first specified language which has a translation available for a message.
For example, after running ``status language set pt_BR fr``, all messages which have a translation into Brazilian Portuguese will be shown in that language.
The remaining messages will be shown in French, if a French translation is available.
If none of the specified languages have a translation available for a message, the message will be shown in English.
**unset**
undoes the effects of the **set** subcommand.
Language settings will be taken from environment variables again.
Notes
-----
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.