Release notes

fish 4.9.3 (released September 08, 2026)

This release fixes another macOS issue where dead keys, for example the two-key sequence ",space on the US International keyboard layout would incorrectly insert space (#12979).

fish 4.9.2 (released September 05, 2026)

This release corrects the fix for macOS terminals from 4.9.1 (#12973)

fish 4.9.1 (released September 04, 2026)

This release fixes the following problems identified in fish 4.9.0:

  • On non-default keyboard layouts, fish executed bindings for physical keys instead of only bindings for the layout’s key. For example, on the Dvorak layout, typing s would insert ; because there is a default binding for ; (#12968).

  • When typing space to accept a character entered via certain IMEs, fish would insert a space instead of the desired character, which has been fixed (#12974).

  • On macOS terminals, keys like option-l would execute bindings for alt-l instead of the historical behavior of inserting a character (like @ on a German layout) (#12973).

fish 4.9.0 (released September 03, 2026)

Interactive improvements

  • To mitigate issues in Konsole version v26.07.80’s implementation of the kitty keyboard protocol, fish no longer requests that protocol on Konsole. The omit-term-workarounds feature flag can be turned on to enable the kitty keyboard protocol on Konsole again (#12948).

  • On some terminals like kitty, keys like shift-space and space can now be mapped independently (#12898).

  • Fixed slow tab completion in directories that contain slow-to-resolve symlinks (e.g. links to network-mounted files) (#12905).

  • Abbreviations can now be given a description, which will be displayed in the completion pager (#11291).

  • Vi mode commands like cF and cT now work correctly (#12947).

Scripting improvements

  • List indexing can now be nested in more cases; for example $foo[$bar[1] 2] is now allowed (#12903).

  • Escaped square brackets (e.g. \133 for [) are no longer considered a slicing operator (#7969).

  • Variables containing a closing square brackets and used to index into another variable will no longer close the slice early (#12819).

  • Builtin help pages now respect an override of the man function (#12886).

  • Commands like status=123 echo $status now throw an error instead of silently ignore the variable override (#7790).

Regression fixes:

  • (From 4.6.0) Chinese and Japanese translation of error messages owned by the C library were broken (#12895).

  • (From 4.3.2) Erasing read-only variables with set --erase was accidentally allowed.

  • (From 4.0.0) Builtin fg was not working on NetBSD (#12929).

fish 4.8.1 (released July 14, 2026)

Interactive improvements

  • On non-macOS platforms, alt-backspace, alt-delete, alt-left and alt-right operate on words again instead of tokens (#12122) eliminating cross-platform differences in input handling.

  • Builtin and function commands can now be colored separately via new variables fish_color_builtin and fish_color_function (#12837).

  • Add fish_darcs_prompt for Darcs repository status.

  • Fixed a crash in commandline --current-process when the cursor is inside a &| pipe (#12868).

  • Since prompt marking (via OSC 133) causes an issue in Konsole’s default configuration, prompt marking had been disabled for Konsole in 4.8.0. Now the omit-term-workarounds feature flag can be enabled to enable prompt marking on Konsole again (#12859).

Regression fixes:

  • (From 4.8.0) abbr --position=anywhere completions are no longer offered in argument position, to avoid cluttering the completion pager (#12838).

  • (From 4.8.0) pacman -Q short option completions (#12857).

fish 4.8.0 (released June 24, 2026)

Notable improvements and fixes

  • Translatable messages defined in Rust source code can and should now be translated using Fluent instead of GNU gettext. For now, GNU gettext continues to be used for translating messages defined in fish scripts. To make Fluent easy to work with, we have added tooling based on the new fluent-ftl-tools library. See Contributing Translations (#11928).

Deprecations and removed features

  • Builtin complete’s --command and --path options no longer unescape their argument.

Interactive improvements

  • History search would sometimes forget about commands after those were re-run in concurrent sessions. This has been fixed (#10300).

  • fish_hg_prompt, fish_git_prompt and fish_fossil_prompt now strip control characters from VCS state read off disk, matching prompt_pwd.

  • Abbreviations with --position=anywhere can now be completed in argument position, not just in command position (#12630).

  • Path component movement (ctrl-w) skips escaped characters.

  • Completion of short option groups will now handle --condition correctly (#12821).

  • Fixed an issue where ctrl-c might fail to cancel certain functions (#12802).

  • On the first run after upgrading from an older version, fish will try harder to check if the current theme matches a historical default. If it does match, fish won’t create ~/.config/fish/conf.d/fish_frozen_theme.fish when upgrading from fish < 4.3. In particular, on systems where fish version 3.x was installed originally, fish will now avoid creating that file on upgrade (#12725).

Scripting improvements

  • cd supports the -L and -P options, like other shells, to allow specifying whether symbolic links (symlinks) are resolved when changing directories (#7206).

  • cd with a relative path will now retry using the real current directory, if $PWD has been moved (#12700).

  • Nested brace expansions now strip unquoted leading and trailing spaces from entries consistently (#12794).

  • bind shows the files where bindings were defined (#12504).

Other improvements

  • fish no longer creates the __fish_initialized universal variable on startup. If you don’t expect to need to downgrade to earlier versions, you can remove it with set --erase __fish_initialized. This means that fish now only creates universal variables if instructed by the user.

For distributors and developers

  • With the exception of the $CMAKE_INSTALL_PREFIX/share/fish/man directory, fish no longer installs files to $CMAKE_INSTALL_PREFIX/share/fish. In particular, this means that both $CMAKE_INSTALL_PREFIX/share/fish/completions and $CMAKE_INSTALL_PREFIX/share/fish/functions should no longer exist. These directories have been ignored since fish 4.2. If another package installs fish scripts there, they should be corrected to install to extra_completionsdir (typically $CMAKE_INSTALL_PREFIX/share/fish/vendor_completions.d), extra_functionsdir (typically $CMAKE_INSTALL_PREFIX/share/fish/vendor_functions.d) or extra_confdir (typically $CMAKE_INSTALL_PREFIX/share/fish/vendor_functions.d) instead. See also the output of for var in completions functions conf; pkgconf fish --variable="$var"dir; end.

Regression fixes:

  • (from 4.4.0) Vi mode c,W key binding wrongly deleted trailing spaces (#12790).

  • (from 4.4.0) Vi mode x in builtin read (#12724).

  • (from 4.3.3) Repeated tab would sometimes insert smartcase completions redundantly.

  • (from 4.3.0) Pressing escape during command execution could insert garbage text into the command line (#12379).

fish 4.7.1 (released May 08, 2026)

This release fixes a regression in 4.7.0 that caused the web config (fish_config) to fail to start (#12717).

fish 4.7.0 (released May 05, 2026)

Deprecations and removed features

  • The default theme (i.e. the fish_color_* variables) is no longer set in non-interactive shells.

Interactive improvements

  • prompt_pwd now strips control characters.

  • Repaint events (as triggered by changes to color variables or by event handlers running commandline -f repaint) no longer reset the completion pager and other transient UI states (#12683).

  • fish_color_valid_path now respects background and underline colors (#12622).

  • funced will no longer lose work if there are parse errors multiple times without new changes to the file.

  • Fixed a case where directory completions were sorted in a surprising order (#12695).

  • When at the command token, the alt-o binding will now open read-only files too (#12671).

  • Private mode in-memory history (set fish_history) is no longer shared with builtin read (#12662).

Other improvements

  • History is no longer corrupted with NUL bytes when fish receives SIGTERM or SIGHUP (#10300).

  • fish_update_completions now handles groff \X'...' device control escapes, fixing completion generation for man pages produced by help2man 1.50 and later (such as coreutils 9.10).

  • Removing history entries via the web-based config is more intuitive.

  • If XDG_DATA_DIRS is empty, the default value is assumed, which means that fish will now also use configuration from paths like $PREFIX/share/fish/vendor_completions.d (#11349).

  • Some internal file descriptors were moved to number 10 or higher, to reduce risk of clashes with those used by the user in scripts.

  • The wording of error messages has been made consistent, especially for builtin subcommands (#12556).

For distributors and developers

  • When the default global config directory ($PREFIX/etc/fish) exists but has been overridden via -DCMAKE_INSTALL_SYSCONFDIR, fish will now respect that override (#10748).

  • build_tools/update_translations.fish has been replaced by cargo xtask gettext {check,new,update} (#12676).

  • cargo xtask shellcheck to lint shell-scripts.

Regression fixes:

  • (from 4.6) Vi mode dl (#12461).

  • (from 4.6) Backspace after newline (#12583).

  • (from 4.3.3) Long options were spuriously completed after typing short options (85e76ba3561).

  • (from 3.2) nosuchcommand || echo hello executes the right hand side again (#12654).

fish 4.6.0 (released March 28, 2026)

Notable improvements and fixes

  • New Spanish translations (#12489).

  • New Japanese translations (#12499).

Deprecations and removed features

  • The default width for emoji is switched from 1 to 2, improving the experience for users connecting to old systems from modern desktops. Users of old desktops who notice that lines containing emoji are misaligned can set $fish_emoji_width back to 1 (#12562).

Interactive improvements

  • The tab completion pager now left-justifies the description of each column (#12546).

  • fish now supports the SHELL_PROMPT_PREFIX, SHELL_PROMPT_SUFFIX, and SHELL_WELCOME environment variables. The prefix and suffix are automatically prepended and appended to the left prompt, and the welcome message is displayed on startup after the greeting. These variables are set by systemd’s run0 for example (#10924).

Improved terminal support

  • set_color is able to turn off italics, reverse mode, strikethrough and underline individually (e.g. --italics=off).

  • set_color learned the foreground (--foreground or -f) and reset (--reset) options.

  • An error caused by slow terminal responses at macOS startup has been addressed (#12571).

Other improvements

  • Signals like SIGWINCH (as sent on terminal resize) no longer interrupt builtin output (#12496).

  • For compatibility with Bash, fish now accepts |& as alternate spelling of &|, for piping both standard output and standard error (#11516).

  • fish_indent now preserves comments and newlines immediately preceding a brace block ({ }) (#12505).

  • A crash when suspending certain pipelines with ctrl-z has been fixed (#12301).

For distributors and developers

  • cargo xtask subcommands no longer panic on test failures.

Regression fixes:

  • (from 4.5.0) Intermediate ⏎ artifact when redrawing prompt (#12476).

  • (from 4.4.0) history honors explicitly specified --color= again (#12512).

  • (from 4.4.0) Vi mode dl and dh (#12461).

  • (from 4.3.0) Error completing of commands starting with - (#12522).

fish 4.5.0 (released February 17, 2026)

This is mostly a patch release for Vi mode regressions in 4.4.0 but other minor behavior changes are included as well.

Interactive improvements

  • ctrl-l no longer cancels history search (#12436).

  • History search cursor positioning now works correctly with characters of arbitrary width.

Deprecations and removed features

  • fish no longer reads the terminfo database to alter behaviour based on the TERM environment variable, and does not depend on ncurses or terminfo. The ignore-terminfo feature flag, introduced and enabled by default in fish 4.1, is now permanently enabled. fish may no longer work correctly on Data General Dasher D220 and Wyse WY-350 terminals, but should continue to work on all known terminal emulators released in the 21st century.

Regression fixes:

  • (from 4.4.0) Vi mode d,f key binding did not work (#12417).

  • (from 4.4.0) Vi mode c,w key binding wrongly deleted trailing spaces (#12443).

  • (from 4.4.0) Vi mode crash on c,i,w after accepting autosuggestion (#12430).

  • (from 4.4.0) fish_vi_key_bindings called with a mode argument produced an error (#12413).

  • (from 4.0.0) Build on Illumos (#12410).

fish 4.4.0 (released February 03, 2026)

Deprecations and removed features

  • The default fossil prompt has been disabled (#12342).

Interactive improvements

  • The bind builtin lists mappings from all modes if --mode is not provided (#12214).

  • Line-wise autosuggestions that don’t start a command are no longer shown (739b82c34db, 58e7a50de8a).

  • Builtin history now assumes that PAGER supports ANSI color sequences.

  • fish now clears the terminal’s FLUSHO flag when acquiring control of the terminal, to fix an issue caused by pressing ctrl-o on macOS (#12304).

New or improved bindings

  • Vi mode word movements (w, W, e, and E) are now largely in line with Vim. The only exception is that underscores are treated as word separators (#12269).

  • New special input functions to support these movements: forward-word-vi, kill-word-vi, forward-bigword-vi, kill-bigword-vi, forward-word-end, backward-word-end, forward-bigword-end, backward-bigword-end, kill-a-word, kill-inner-word, kill-a-bigword, and kill-inner-bigword.

  • Vi mode key bindings now support counts for movement and deletion commands (e.g. d3w or 3l), via a new operator mode (#2192).

  • New catppuccin-* color themes.

Improved terminal support

  • set_color learned the strikethrough (--strikethrough or -s) modifier.

For distributors and developers

  • The CMake option WITH_GETTEXT has been renamed to WITH_MESSAGE_LOCALIZATION, to reflect that it toggles localization independently of the backend used in the implementation.

  • New cargo xtask commands can replace some CMake workflows.

Regression fixes:

  • (from 4.1.0) Crash when autosuggesting Unicode characters with nontrivial lowercase mapping (#12326, 78f4541116e).

  • (from 4.3.0) Glitch on read --prompt-str "" (#12296).

fish 4.3.3 (released January 07, 2026)

This release fixes the following problems identified in fish 4.3.0:

  • Selecting a completion could insert only part of the token (#12249).

  • Glitch with soft-wrapped autosuggestions and fish_right_prompt (#12255).

  • Spurious echo in tmux when typing a command really fast (#12261).

  • tomorrow theme always using the light variant (#12266).

  • fish_config theme choose sometimes not shadowing themes set by e.g. webconfig (#12278).

  • The sample prompts and themes are correctly installed (#12241).

  • Last line of command output could be hidden when missing newline (#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 fish_color_valid_path, indicating that file.txt will be clobbered (#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 (#12224).

  • extra_functionsdir (usually vendor_functions.d) and friends were not used (#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 (#12230).

  • Spurious echo of ^[[I in some scenarios (#12232).

  • Infinite prompt redraw loop on some prompts (#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 (#12223).

fish 4.3.0 (released December 28, 2025)

Deprecations and removed features

  • fish no longer sets user-facing universal variables 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 ~/.config/fish/conf.d/fish_frozen_key_bindings.fish files. We suggest that you delete those files and set your theme in ~/.config/fish/config.fish.

    • You can still configure fish to propagate theme changes instantly; see here 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 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 (#11993).

  • 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 : (#5363).

  • Prefix-matching completions are now shown even if they don’t match the case typed by the user (#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 (#12045).

New or improved bindings

  • ctrl-w (backward-kill-path-component) also deletes escaped spaces (#2016).

  • New special input functions backward-path-component, forward-path-component and kill-path-component (#12127).

Improved terminal support

  • Themes can now be made color-theme-aware by including both [light] and [dark] sections in the theme file. 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 (#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 (#12191).

  • OSC 133 prompt markers now also mark the prompt end, which improves shell integration with terminals like iTerm2 (#11837).

  • Operating-system-specific key bindings are now decided based on the terminal’s host OS.

  • New feature flag 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 (#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 ctrl-l edge cases in multiline command lines (#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 (#12052).

  • fish_config’s theme selector (the “colors” tab) was broken, which has been fixed (#12053).

fish 4.2.0 (released November 10, 2025)

Notable improvements and fixes

  • History-based autosuggestions now include multi-line commands.

  • A transient prompt containing more lines than the final prompt will now be cleared properly (#11875).

  • Taiwanese Chinese translations have been added.

  • French translations have been supplemented (#11842).

Deprecations and removed features

  • fish now assumes UTF-8 for character encoding even if the system does not have a UTF-8 locale. Input bytes which are not valid UTF-8 are still round-tripped correctly. For example, file paths using legacy encodings can still be used, but may be rendered differently on the command line.

  • On systems where no multi-byte locale is available, fish will no longer fall back to using ASCII replacements for Unicode characters such as “…”.

Interactive improvements

  • The title of the terminal tab can now be set separately from the window title by defining the fish_tab_title function (#2692).

  • fish now hides the portion of a multiline prompt that is scrolled out of view due to a huge command line. This prevents duplicate lines after repainting with partially visible prompt (#11911).

  • fish_config prompt’s choose and save subcommands have been taught to reset fish_mode_prompt in addition to the other prompt functions (#11937).

  • fish no longer force-disables mouse capture (DECSET/DECRST 1000), so you can use those commands to let mouse clicks move the cursor or select completions items (#4918).

  • The alt-p binding no longer adds a redundant space to the command line.

  • When run as a login shell on macOS, fish now sets MANPATH correctly when that variable was already present in the environment (#10684).

  • A Windows-specific case of the web-based config failing to launch has been fixed (#11805).

  • A MSYS2-specific workaround for Konsole and WezTerm has been added, to prevent them from using the wrong working directory when opening new tabs (#11981).

For distributors and developers

  • Release tags and source code tarballs are GPG-signed again (#11996).

  • Documentation in release tarballs is now built with the latest version of Sphinx, which means that pre-built man pages include OSC 8 hyperlinks.

  • The Sphinx dependency is now specified in pyproject.toml, which allows you to use uv to provide Sphinx for building documentation (e.g. uv run cargo install --path .).

  • The minimum supported Rust version (MSRV) has been updated to 1.85.

  • The standalone build mode has been made the default. This means that the files in $CMAKE_INSTALL_PREFIX/share/fish will not be used anymore, except for HTML docs. As a result, future upgrades will no longer break running shells if one of fish’s internal helper functions has been changed in the updated version. For now, the data files are still installed redundantly, to prevent upgrades from breaking already-running shells (#11921). To reverse this change (which should not be necessary), patch out the embed-data feature from cmake/Rust.cmake. This option will be removed in future.

  • OpenBSD 7.8 revealed an issue with fish’s approach for displaying builtin man pages, which has been fixed.

Regression fixes:

  • (from 4.1.0) Fix the web-based config for Python 3.9 and older (#12039).

  • (from 4.1.0) Correct wrong terminal modes set by fish -c 'read; cat (#12024).

  • (from 4.1.0) On VTE-based terminals, stop redrawing the prompt on resize again, to avoid glitches.

  • (from 4.1.0) On MSYS2, fix saving/loading of universal variables (#11948).

  • (from 4.1.0) Fix error using man for the commands ! . : [ { (#11955).

  • (from 4.1.0) Fix build issues on illumos systems (#11982).

  • (from 4.1.0) Fix crash on invalid function command (#11912).

  • (from 4.0.0) Fix build on SPARC and MIPS Linux by disabling SIGSTKFLT.

  • (from 4.0.0) Fix crash when passing negative PIDs to builtin wait (#11929).

  • (from 4.0.0) On Linux, fix status fish-path output when fish has been reinstalled since it was started.

fish 4.1.2 (released October 7, 2025)

This release fixes the following regressions identified in 4.1.0:

  • Fixed spurious error output when completing remote file paths for scp (#11860).

  • Fixed the alt-l binding not formatting ls output correctly (one entry per line, no colors) (#11888).

  • Fixed an issue where focus events (currently only enabled in tmux) would cause multiline prompts to be redrawn in the wrong line (#11870).

  • Stopped printing output that would cause a glitch on old versions of Midnight Commander (#11869).

  • Added a fix for some configurations of Zellij where escape key processing was delayed (#11868).

  • Fixed a case where the web-based configuration tool would generate invalid configuration (#11861).

  • Fixed a case where pasting into fish -c read would fail with a noisy error (#11836).

  • Fixed a case where upgrading fish would break old versions of fish that were still running.

    In general, fish still needs to be restarted after it is upgraded, except for standalone builds.

fish 4.1.1 (released September 30, 2025)

This release fixes the following regressions identified in 4.1.0:

  • Many of our new Chinese translations were more confusing than helpful; they have been fixed or removed (#11833).

    Note that you can work around this type of issue by configuring fish’s message localization: if your environment contains something like LANG=zh_CN.UTF-8, you can use set -g LC_MESSAGES en to use English messages inside fish. This will not affect fish’s child processes unless LC_MESSAGES was already exported.

  • Some 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 (#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 (#11841).

  • A WezTerm issue breaking shifted key input has resurfaced on some versions of WezTerm; our workaround has been extended to cover all versions for now (#11204).

  • Fixed a crash in the web-based configuration tool when using the new underline styles (#11840).

fish 4.1.0 (released September 27, 2025)

Notable improvements and fixes

  • Compound commands (begin; echo 1; echo 2; end) can now be written using braces ({ echo1; echo 2 }), like in other shells.

  • fish now supports transient prompts: if fish_transient_prompt is set to 1, fish will reexecute prompt functions with the --final-rendering argument before running a commandline (#11153).

  • Tab completion results are truncated up to the common directory path, instead of somewhere inside that path. E.g. if you complete “share/functions”, and it includes the files “foo.fish” and “bar.fish”, the completion pager will now show “…/foo.fish” and “…/bar.fish” (#11250).

  • Self-installing builds as created by e.g. cargo install no longer install other files, see below.

  • Our gettext-based message-localization has been reworked, adding translations to self-installing builds; see below.

Deprecations and removed features

  • set_color --background=COLOR no longer implicitly activates bold mode. If your theme is stored in universal variables (the historical default), some bold formatting might be lost. To fix this, we suggest updating to the latest version of our theme, to explicitly activate bold mode, for example use fish_config theme save "fish default".

  • {echo,echo} or { echo, echo } are no longer interpreted as brace expansion tokens but as compound commands.

  • Terminfo-style key names (bind -k nul) are no longer supported. They had been superseded by fish’s own key names since 4.0 (#11342).

  • fish no longer reads the terminfo database, so its behavior is generally no longer affected by the TERM environment variable (#11344). For the time being, this change can be reversed via the ignore-terminfo feature flag. To do so, run the following once and restart fish:

    set -Ua fish_features no-ignore-terminfo
    
  • The --install option when fish is built as self-installing is removed, see below.

  • set_color ff0000 now outputs 24-bit RGB true-color even if COLORTERM is unset. One can override this by setting fish_term24bit to 0 (#11372).

  • fish now requires the terminal to respond to queries for the Primary Device Attribute. For now, this can be reversed via a feature flag, by running (once) set -Ua fish_features no-query-term and restarting fish.

  • Users of GNU screen may experience minor glitches when starting fish.

Scripting improvements

  • The argparse builtin has seen many improvements, see below.

  • The string pad command now has a -C/--center option.

  • The psub command now allows combining --suffix with --fifo (#11729).

  • The read builtin has learned the --tokenize-raw option to tokenize without quote removal (#11084).

Interactive improvements

  • Autosuggestions are now also provided in multi-line command lines. Like ctrl-r, these operate only on the current line.

  • Autosuggestions used to not suggest multi-line command-lines from history; now autosuggestions include individual lines from multi-line command-lines.

  • The history pager search now preserves ordering between ctrl-s forward and ctrl-r backward searches.

  • Instead of highlighting events by flashing all text to the left of the cursor, failing history token search (alt-.) flashes the associated token, failing tab-completion flashes the to-be-completed token (#11050), deleting an autosuggestion (shift-delete) flashes the suggestion, and all other scenarios flash the full command line.

  • Pasted commands are now stripped of any $  command prefixes, to help pasting code snippets.

  • Builtin help options (e.g. abbr --help) now use man directly, meaning that variables like MANWIDTH are respected (#11786).

  • funced will now edit copied functions directly, instead of the file where function --copy was invoked. (#11614)

  • Added a simple fish_jj_prompt which reduces visual noise in the prompt inside Jujutsu repositories that are colocated with Git.

New or improved bindings

  • On non-macOS systems, alt-left, alt-right, alt-backspace and alt-delete no longer operate on punctuation-delimited words but on whole arguments, possibly including special characters like / and quoted spaces. On macOS, the corresponding ctrl- prefixed keys operate on whole arguments. Word operations are still available via the other respective modifier, just like in most web browsers.

  • ctrl-z (undo) after executing a command will restore the previous cursor position instead of placing the cursor at the end of the command line.

  • The alt-s binding will now also use run0 if available.

  • Some mouse support has been added: the OSC 133 prompt marking feature has learned about kitty’s click_events=1 flag, which allows moving fish’s cursor by clicking in the command line, and selecting pager items (#10932).

  • Before clearing the screen and redrawing, ctrl-l now pushes all text located above the prompt to the terminal’s scrollback, via a new special input function scrollback-push. For compatibility with terminals that do not implement ECMA-48’s SCROLL UP command, this function is only used if the terminal advertises support for that via XTGETTCAP.

  • Vi mode has learned ctrl-a (increment) and ctrl-x (decrement) (#11570).

Completions

  • git completions now show the remote URL as description when completing remotes.

  • systemctl completions no longer print escape codes if SYSTEMD_COLORS happens to be set (#11465).

  • Added and improved many completion scripts, notably tmux.

Improved terminal support

  • Support for double, curly, dotted and dashed underlines, for use in fish_color_* variables and the set_color builtin (#10957).

  • Underlines can now be colored independent of text (#7619).

  • New documentation page Terminal Compatibility (also accessible via man fish-terminal-compatibility) lists the terminal control sequences used by fish.

Other improvements

  • Updated Chinese and German translations.

  • fish_indent --dump-parse-tree now emits simple metrics about the tree including its memory consumption.

  • We added some tools to improve development workflows, for example build_tools/{check,update_translations,release}.sh and tests/test_driver.py. In conjunction with cargo, these enable almost all day-to-day development tasks without using CMake.

For distributors

  • Builtin commands that support the --help option now require the man program. The direct dependency on mandoc and nroff has been removed.

  • fish no longer uses gettext MO files, see below. If you have use cases which are incompatible with our new approach, please let us know.

  • The fish_indent and fish_key_reader programs are now also available as builtins. If fish is invoked via e.g. a symlink with one of these names, it will act like the given tool (i.e. it’s a multi-call binary). This allows truly distributing fish as a single file (#10876).

  • The CMake build configuration has been simplified and no longer second-guesses rustup. It will run rustc and cargo via PATH or in ~/.cargo/bin/. If that doesn’t match your setup, set the Rust_COMPILER and Rust_CARGO CMake variables (#11328).

  • Cygwin support has been reintroduced, since Rust gained a Cygwin target (#11238).

  • CMake 3.15 is now required.

Changes to self-installing builds

The self-installing build type introduced in fish 4.0 has been changed (#11143). Now fish built with embedded data will just read the data straight from its own binary or write it out to temporary files when necessary, instead of requiring an installation step on start. That means it is now possible to build fish as a single file and copy it to any system with a compatible CPU architecture, including as a different user, without extracting any files. As before, this is the default when building via cargo, and disabled when building via CMake. For packagers we continue to recommend CMake.

Note: When fish is built like this, the __fish_data_dir variable will be empty because that directory no longer has meaning. You should generally not need these files. For example, if you want to make sure that completions for “foo” are loaded, use complete -C"foo " >/dev/null instead). The raw files are still exposed via status subcommands, mainly for fish’s internal use, but you can also use them as a last resort.

Remaining benefits of a full installation (as currently done by CMake) are:

  • man pages like fish(1) in standard locations, easily accessible from outside fish.

  • a local copy of the HTML documentation, typically accessed via the help function. In builds with embedded data, help will redirect to e.g. https://fishshell.com/docs/current/

  • fish_indent and fish_key_reader as separate files, making them easily accessible outside fish

  • an (empty) /etc/fish/config.fish as well as empty directories /etc/fish/{functions,completions,conf.d}

  • $PREFIX/share/pkgconfig/fish.pc, which defines directories for configuration-snippets, like vendor_completions.d

Changes to gettext localization

We replaced several parts of the gettext functionality with custom implementations (#11726). Most notably, message extraction, which should now work reliably, and the runtime implementation, where we no longer dynamically link to gettext, but instead use our own implementation, whose behavior is similar to GNU gettext, with some minor deviations. Our implementation now fully respects fish variables, so locale variables do not have to be exported for fish localizations to work. They still have to be exported to inform other programs about language preferences. The LANGUAGE environment variable is now treated as a path variable, meaning it is an implicitly colon-separated list. While we no longer have any runtime dependency on gettext, we still need gettext tools for building, most notably msgfmt. When building without msgfmt available, localization will not work with the resulting executable. Localization data is no longer sourced at runtime from MO files on the file system, but instead built into the executable. This is always done, independently of the other data embedding, so all fish executables will have access to all message catalogs, regardless of the state of the file system. Disabling our new localize-messages cargo feature will cause fish to be built without localization support. CMake builds can continue to use the WITH_GETTEXT option, with the same semantics as the localize-messages feature. The current implementation does not provide any configuration options for controlling which language catalogs are built into the executable (other than disabling them all). As a workaround, you can delete files in the po directory before building to exclude unwanted languages.

Changes to the argparse builtin

  • argparse now saves recognised options, including option-arguments in argv_opts, allowing them to be forwarded to other commands (#6466).

  • argparse options can now be marked to be deleted from argv_opts (by adding a & at the end of the option spec, before a ! if present). There is now also a corresponding -d / --delete option to fish_opt.

  • argparse --ignore-unknown now removes preceding known short options from groups containing unknown options (e.g. when parsing -abc, if a is known but b is not, then argv will contain -bc).

  • argparse now has an -u / --move-unknown option that works like --ignore-unknown but preserves unknown options in argv.

  • argparse now has an -S / --strict-longopts option that forbids abbreviating long options or passing them with a single dash (e.g. if there is a long option called foo, --fo and --foo won’t match it).

  • argparse now has a -U / --unknown-arguments option to specify how to parse unknown option’s arguments.

  • argparse now allows specifying options that take multiple optional values by using =* in the option spec (#8432). In addition, fish_opt has been modified to support such options by using the --multiple-vals together with -o / --optional-val; -m is also now acceptable as an abbreviation for --multiple-vals.

  • fish_opt no longer requires you give a short flag name when defining options, provided you give it a long flag name with more than one character.

  • argparse option specifiers for long-only options can now start with /, allowing the definition of long options with a single letter. Due to this change, the --long-only option to fish_opt is now no longer necessary and is deprecated.

  • fish_opt now has a -v / --validate option you can use to give a fish script to validate values of the option.


fish 4.0.9 (released September 27, 2025)

This release fixes:

  • a regression in 4.0.6 causing shifted keys to not be inserted on some terminals (#11813).

  • a regression in 4.0.6 causing the build to fail on systems where char is unsigned (#11804).

  • a regression in 4.0.0 causing a crash on an invalid bg invocation.


fish 4.0.8 (released September 18, 2025)

This release fixes a regression in 4.0.6 that caused user bindings to be shadowed by either fish’s or a plugin’s bindings (#11803).


fish 4.0.6 (released September 12, 2025)

This release of fish fixes a number of issues identified in fish 4.0.2:

  • fish now properly inherits $PATH under Windows WSL2 (#11354).

  • Remote filesystems are detected properly again on non-Linux systems.

  • the printf builtin no longer miscalculates width of multi-byte characters (#11412).

  • For many years, fish has been “relocatable” -- it was possible to move the entire CMAKE_INSTALL_PREFIX and fish would use paths relative to its binary. Only gettext locale paths were still determined purely at compile time, which has been fixed.

  • the commandline builtin failed to print the commandline set by a commandline -C invocation, which broke some completion scripts. This has been corrected (#11423).

  • To work around terminals that fail to parse Operating System Command (OSC) sequences, a temporary feature flag has been added. It allows you to disable prompt marking (OSC 133) by running (once) set -Ua fish_features no-mark-prompt and restarting fish (#11749).

  • The routines to save history and universal variables have seen some robustness improvements.

  • builtin status current-command no longer prints a trailing blank line.

  • A crash displaying multi-line quoted command substitutions has been fixed (#11444).

  • Commands like set fish_complete_path ... accidentally disabled completion autoloading, which has been corrected.

  • nmcli completions have been fixed to query network information dynamically instead of only when completing the first time.

  • Git completions no longer print an error when no git-foo executable is in PATH.

  • Custom completions like complete foo -l long -xa ... that use the output of commandline -t. on a command-line like foo --long= have been invalidated by a change in 4.0; the completion scripts have been adjusted accordingly (#11508).

  • Some completions were misinterpreted, which caused garbage to be displayed in the completion list. This has been fixed.

  • fish no longer interprets invalid control sequences from the terminal as if they were alt-[ or alt-o key strokes.

  • bind has been taught about the printscreen and menu keys.

  • alt-delete now deletes the word right of the cursor.

  • ctrl-alt-h erases the last word again (#11548).

  • alt-left alt-right were misinterpreted because they send unexpected sequences on some terminals; a workaround has been added. (#11479).

  • Key bindings like bind shift-A are no longer accepted; use bind shift-a or bind A.

  • Key bindings like bind shift-a take precedence over bind A when the key event included the shift modifier.

  • Bindings using shift with non-ASCII letters (such as ctrl-shift-ä) are now supported.

  • Bindings with modifiers such as bind ctrl-w work again on non-Latin keyboard layouts such as a Russian one. This is implemented by allowing key events such as ctrl-ц to match bindings of the corresponding Latin key, using the kitty keyboard protocol’s base layout key (#11520).

  • Vi mode: The cursor position after pasting via p has been corrected.

  • Vi mode: Trying to replace the last character via r no longer replaces the last-but-one character (#11484).


fish 4.0.2 (released April 20, 2025)

This release of fish fixes a number of issues identified in fish 4.0.1:

  • Completions are quoted, rather than backslash-escaped, only if the completion is unambiguous. Continuing to edit the token is therefore easier (#11271). This changes the behavior introduced in 4.0.0 where all completions were quoted.

  • The warning when the terminfo database can’t be found has been downgraded to a log message. fish will act as if the terminal behaves like xterm-256color, which is correct for the vast majority of cases (#11277, #11290).

  • Key combinations using the super (Windows/command) key can now (actually) be bound using the super- prefix (#11217). This was listed in the release notes for 4.0.1 but did not work correctly.

  • function is stricter about argument parsing, rather than allowing additional parameters to be silently ignored (#11295).

  • Using parentheses in the test builtin works correctly, following a regression in 4.0.0 where they were not recognized (#11387).

  • delete in Vi mode when Num Lock is active will work correctly (#11303).

  • Abbreviations cannot alter the command-line contents, preventing a crash (#11324).

  • Improvements to various completions, including new completions for wl-randr (#11301), performance improvements for cargo completions by avoiding network requests (#11347), and other improvements for btrfs (#11320), cryptsetup (#11315), git (#11319, #11322, #11323), jj (#11046), and systemd-analyze (#11314).

  • The Mercurial (hg) prompt can handle working directories that contain an embedded newline, rather than producing errors (#11348).

  • A number of crashes have been fixed. Triggers include prompts containing backspace characters (#11280), history pager search (#11355), invalid UTF-8 in read (#11383), and the kill-selection binding (#11367).

  • A race condition in the test suite has been fixed (#11254), and a test for fish versioning relaxed to support downstream distributors’ modifications (#11173).

  • Small improvements to the documentation (#11264, #11329, #11361).


fish 4.0.1 (released March 12, 2025)

This release of fish includes the following improvements compared to fish 4.0.0:

  • Key combinations using the super (Windows/command) key can be bound using the super- prefix (#11217).

  • Konsole’s menu shows the “Open folder with” option again (#11198).

  • $fish_color_search_match will now only be applied to the foreground color if it has an explicit foreground. For example, this allows setting::

    set -g fish_color_search_match --reverse

  • Cursor shape commands (\e[2 q) are no longer sent in non-interactive shells or in redirections (#11255).

  • status gained a is-interactive-read subcommand, to check whether the script is being called from an interactive read invocation.

  • fish’s background tasks are now started in a way that avoids an error on macOS Terminal.app (#11181).

  • Using key combinations within qemu should work correctly.

  • Prompts containing control characters no longer cause incorrect display of command lines (#11252).

  • Cancelling the command-line in Vi mode displays correctly again (#11261).

  • The acidhub prompt properly displays the git branch again (#11179).

  • Completions for wine correctly include files again (#11202).

  • On macOS, paths from /etc/paths and /etc/manpaths containing colons are handled correctly (#10684). This functionality was included in the 4.0.0 release notes but was missing from the source code.

  • The XTerm modifyOtherKeys keyboard encoding is no longer used under WezTerm, as it does not work correctly in all layouts (#11204).

  • option-left and other similar keys should now work in iTerm versions before 3.5.12; the kitty keyboard protocol is now disabled on these versions (#11192).

  • The kitty keyboard protocol is no longer used under Midnight Commander, as it does not work correctly (#10640).

  • fish now sends the commandline along with the OSC 133 semantic prompt command start sequence. This fixes a test in the kitty terminal (#11203).

  • Git completions for third-party commands like “git-absorb” are completed correctly again (#11205).

  • Completions for diskutil no longer produce an error (#11201).

  • The output of certain error messages no longer prints newlines to standard output (#11248).

  • A number of crashes have been fixed, including file names longer than 255 bytes (#11221), using fish on a btrfs filesystem (#11219), history files that do not have the expected format (#11236), and pasting into an empty command line (#11256).


fish 4.0.0 (released February 27, 2025)

fish’s core code has been ported from C++ to Rust (#9512). This means a large change in dependencies and how to build fish. However, there should be no direct impact on users. Packagers should see the For Distributors section at the end.

Notable backwards-incompatible changes

  • As part of a larger binding rework, bind gained a new key notation. In most cases the old notation should keep working, but in rare cases you may have to change a bind invocation to use the new notation. See below for details.

  • ctrl-c now calls a new bind function called clear-commandline. The old behavior, which leaves a “^C” marker, is available as cancel-commandline (#10935)

  • random will produce different values from previous versions of fish when used with the same seed, and will work more sensibly with small seed numbers. The seed was never guaranteed to give the same result across systems, so we do not expect this to have a large impact (#9593).

  • Variables in command position that expand to a subcommand keyword are now forbidden to fix a likely user error. For example, set editor command emacs; $editor is no longer allowed (#10249).

  • functions --handlers will now list handlers in a different order. Now it is definition order, first to last, where before it was last to first. This was never specifically defined, and we recommend not relying on a specific order (#9944).

  • The qmark-noglob feature, introduced in fish 3.0, is enabled by default. That means ? will no longer act as a single-character glob. You can, for the time being, turn it back on by adding no-qmark-noglob to fish_features and restarting fish:

    set -Ua fish_features no-qmark-noglob
    

    The flag will eventually be made read-only, making it impossible to turn off.

  • Terminals that fail to ignore unrecognized OSC or CSI sequences may display garbage. We know cool-retro-term and emacs’ ansi-term are affected, but most mainstream terminals are not.

  • fish no longer searches directories from the Windows system/user $PATH environment variable for Linux executables. To execute Linux binaries by name (i.e. not with a relative or absolute path) from a Windows folder, make sure the /mnt/c/... path is explicitly added to $fish_user_paths and not just automatically appended to $PATH by wsl.exe (#10506).

  • Under Microsoft Windows Subsystem for Linux 1 (not WSL 2), backgrounded jobs that have not been disowned and do not terminate on their own after a SIGHUP + SIGCONT sequence will be explicitly killed by fish on exit (after the usual prompt to close or disown them) to work around a WSL 1 deficiency that sees backgrounded processes that run into SIGTTOU remain in a suspended state indefinitely (#5263). The workaround is to explicitly disown processes you wish to outlive the shell session.

Notable improvements and fixes

  • fish now requests XTerm’s modifyOtherKeys keyboard encoding and kitty keyboard protocol’s progressive enhancements (#10359). Depending on terminal support, this allows to binding more key combinations, including arbitrary combinations of modifiers ctrl, alt and shift, and distinguishing (for example) ctrl-i from tab.

    Additionally, bind now supports a human-readable syntax in addition to byte sequences. This includes modifier names, and names for keys like enter and backspace. For example

    • bind up 'do something' binds the up-arrow key instead of a two-key sequence (“u” and then “p”)

    • bind ctrl-x,alt-c 'do something' binds a sequence of two keys.

    Any key argument that starts with an ASCII control character (like \e or \cX) or is up to 3 characters long, not a named key, and does not contain , or - will be interpreted in the old syntax to keep compatibility for the majority of bindings.

    Keyboard protocols can be turned off by disabling the “keyboard-protocols” feature flag:

    set -Ua fish_features no-keyboard-protocols
    

    This is a temporary measure to work around buggy terminals (#11056), which appear to be relatively rare. Use this if something like “=0” or “=5u” appears in your commandline mysteriously.

  • fish can now be built as a self-installing binary (#10367). That means it can be easily built on one system and copied to another, where it can extract supporting files. To do this, run:

    cargo install --path . # in a clone of the fish repository
    # or `cargo build --release` and copy target/release/fish{,_indent,_key_reader} wherever you want
    

    The first time it runs interactively, it will extract all the data files to ~/.local/share/fish/install/. A specific path can be used for the data files with fish --install=PATH To uninstall, remove the fish binaries and that directory.

    This build system is experimental; the main build system, using cmake, remains the recommended approach for packaging and installation to a prefix.

  • A new function fish_should_add_to_history can be overridden to decide whether a command should be added to the history (#10302).

  • Bindings can now mix special input functions and shell commands, so bind ctrl-g expand-abbr "commandline -i \n" works as expected (#8186).

  • Special input functions run from bindings via commandline -f are now applied immediately, instead of after the currently executing binding (#3031, #10126). For example, commandline -i foo; commandline | grep foo succeeds now.

  • Undo history is no longer truncated after every command, but kept for the lifetime of the shell process.

  • The ctrl-r history search now uses glob syntax (#10131).

  • The ctrl-r history search now operates only on the line or command substitution at cursor, making it easier to combine commands from history (#9751).

  • Abbreviations can now be restricted to specific commands. For instance:

    abbr --add --command git back 'reset --hard HEAD^'
    

    will expand “back” to reset --hard HEAD^, but only when the command is git (#9411).

Deprecations and removed features

  • commandline --tokenize (short option -o) has been deprecated in favor of commandline --tokens-expanded (short option -x) which expands variables and other shell syntax, removing the need to use eval in completion scripts (#10212).

  • Two new feature flags:

    • remove-percent-self (see status features) disables PID expansion of %self, which has been supplanted by $fish_pid (#10262).

    • test-require-arg disables test’s one-argument mode. That means test -n without an additional argument will return false, test -z will keep returning true. Any other option without an argument, anything that is not an option and no argument will be an error. This also goes for [, test’s alternate name. This is a frequent source of confusion and so we are breaking with POSIX explicitly in this regard. In addition to the feature flag, there is a debug category “deprecated-test”. Running fish with fish -d deprecated-test will show warnings whenever a test invocation that would change is used. (#10365).

    These can be enabled with:

    set -Ua fish_features remove-percent-self test-require-arg
    

    We intend to enable them by default in future, and after that eventually make them read-only.

  • Specifying key names as terminfo names (using the bind -k syntax) is deprecated and may be removed in a future version.

  • When a terminal pastes text into fish using bracketed paste, fish used to switch to a special paste bind mode. This bind mode has been removed. The behavior on paste is no longer configurable.

  • When an interactive fish is stopped or terminated by a signal that cannot be caught (SIGSTOP or SIGKILL), it may leave the terminal in a state where keypresses with modifiers are sent as CSI u sequences, instead of traditional control characters or escape sequences that are recognized by Readline and compatible programs, such as bash and python. If this happens, you can use the reset command from ncurses to restore the terminal state.

  • fish_key_reader --verbose no longer shows timing information.

  • Terminal information is no longer read from hashed terminfo databases, or termcap databases (#10269). The vast majority of systems use a non-hashed terminfo database, which is still supported.

  • source returns an error if used without a filename or pipe/redirection (#10774).

Scripting improvements

  • for loops will no longer remember local variables from the previous iteration (#10525).

  • A new history append subcommand appends a command to the history, without executing it (#4506).

  • A new redirection: <? /path/to/file will try opening the file as input, and if it doesn’t succeed silently uses /dev/null instead. This can help with checks like test -f /path/to/file; and string replace foo bar < /path/to/file. (#10387)

  • A new option commandline --tokens-raw prints a list of tokens without any unescaping (#10212).

  • A new option commandline --showing-suggestion tests whether an autosuggestion is currently displayed (#10586).

  • functions and type now show that a function was copied and its source, rather than solely Defined interactively (#6575).

  • Stack trace now shows line numbers for copied functions (#6575).

  • foo & && bar is now a syntax error, like in other shells (#9911).

  • if -e foo; end now prints a more accurate error (#10000).

  • cd into a directory that is not readable but accessible (permissions --x) is now possible (#10432).

  • An integer overflow in string repeat leading to a near-infinite loop has been fixed (#9899).

  • string shorten behaves better in the presence of non-printable characters, including fixing an integer overflow that shortened strings more than intended (#9854).

  • string pad no longer allows non-printable characters as padding (#9854).

  • string repeat now allows omission of -n when the first argument is an integer (#10282).

  • string match and replace have a new --max-matches option to return as soon as the specified number of matches have been identified, which can improve performance in scripts (#10587).

  • functions --handlers-type caller-exit once again lists functions defined as function --on-job-exit caller, rather than them being listed by functions --handlers-type process-exit.

  • A new set --no-event option sets or erases variables without triggering a variable event. This can be useful to change a variable in an event handler (#10480).

  • Commas in command substitution output are no longer used as separators in brace expansion, preventing a surprising expansion in some cases (#5048).

  • Universal variables can now store strings containing invalid UTF-8 (#10313).

  • A new path basename -E option that causes it to return the basename (“filename” with the directory prefix removed) with the final extension (if any) also removed. This is a shorter version of path change-extension "" (path basename $foo) (#10521).

  • A new math --scale-mode option to select truncate, round, floor, ceiling as you wish; the default value is truncate. (#9117).

  • random is now less strict about its arguments, allowing a start larger or equal to the end. (#10879)

  • function --argument-names now produces an error if a read-only variable name is used, rather than simply ignoring it (#10842).

  • Tilde expansion in braces (that is, {~,}) works correctly (#10610).

Interactive improvements

  • Autosuggestions were sometimes not shown after recalling a line from history, which has been fixed (#10287).

  • Up-arrow search matches -- which are highlighted in reverse colors -- are no longer syntax-highlighted, to fix bad contrast with the search match highlighting.

  • Command abbreviations (those with --position command or without a --position) now also expand after decorators like command (#10396).

  • Abbreviations now expand after process separators like ; and |. This fixes a regression in version 3.6 (#9730).

  • When exporting interactively defined functions (using type, functions or funcsave) the function body is now indented, to match the interactive command line editor (#8603).

  • ctrl-x (fish_clipboard_copy) on multiline commands now includes indentation (#10437).

  • ctrl-v (fish_clipboard_paste) now strips ASCII control characters from the pasted text. This is consistent with normal keyboard input (#5274).

  • When a command like fg %2 fails to find the given job, it no longer behaves as if no job spec was given (#9835).

  • Redirection in command position like >echo is now highlighted as error (#8877).

  • fish_vi_cursor now works properly inside the prompt created by builtin read (#10088).

  • fish no longer fails to open a FIFO if interrupted by a terminal resize signal (#10250).

  • read --help and friends no longer ignore redirections. This fixes a regression in version 3.1 (#10274).

  • Measuring a command with time now considers the time taken for command substitution (#9100).

  • fish_add_path now automatically enables verbose mode when used interactively (in the command line), in an effort to be clearer about what it does (#10532).

  • fish no longer adopts TTY modes of failed commands (#10603).

  • complete -e cmd now prevents autoloading completions for cmd (#6716).

  • fish’s default color scheme no longer uses the color “blue”, as it has bad contrast against the background in a few terminal’s default palettes (#10758, #10786) The color scheme will not be upgraded for existing installs. If you want, you should select it again via fish_config.

  • Command lines which are larger than the terminal are now displayed correctly, instead of multiple blank lines being displayed (#7296).

  • Prompts that use external commands will no longer produce an infinite loop if the command crashes (#9796).

  • The output of jobs shows “-” for jobs that have the same process group ID as the fish process, rather than “-2” (#10833).

  • Job expansion (%1 syntax) works properly for jobs that are a mixture of external commands and functions (#10832).

  • Command lines which have more lines than the terminal can be displayed and edited correctly (#10827).

  • Functions that have been erased are no longer highlighted as valid commands (#10866).

  • not, time, and variable assignments (that is not time a=b env) is correctly recognized as valid syntax (#10890).

  • The Web-based configuration removes old right-hand-side prompts again, fixing a regression in fish 3.4.0 (#10675).

  • Further protection against programs which crash and leave the terminal in an inconsistent state (#10834, #11038).

  • A workaround for git being very slow on macOS has been applied, improving performance after a fresh boot (#10535).

New or improved bindings

  • When the cursor is on a command that resolves to an executable script, alt-o will now open that script in your editor (#10266).

  • During up-arrow history search, shift-delete will delete the current search item and move to the next older item. Previously this was only supported in the history pager.

  • shift-delete will also remove the currently-displayed autosuggestion from history, and remove it as a suggestion.

  • ctrl-Z (also known as ctrl-shift-z) is now bound to redo.

  • Some improvements to the alt-e binding which edits the command line in an external editor:

    • The editor’s cursor position is copied back to fish. This is currently supported for Vim and Kakoune.

    • Cursor position synchronization is only supported for a set of known editors, which are now also detected in aliases which use complete --wraps. For example, use complete --wraps my-vim vim to synchronize cursors when EDITOR=my-vim.

    • Multiline commands are indented before being sent to the editor, which matches how they are displayed in fish.

  • The ...-path-component bindings, like backward-kill-path-component, now treat # as part of a path component (#10271).

  • Bindings like alt-l that print output in between prompts now work correctly with multiline commandlines.

  • alt-d on an empty command line lists the directory history again. This restores the behavior of version 2.1.

  • history-prefix-search-backward and -forward now maintain the cursor position, instead of moving the cursor to the end of the command line (#10430).

  • The following keys have refined behavior if the terminal supports the new keyboard encodings:

    • shift-enter now inserts a newline instead of executing the command line.

    • ctrl-backspace now deletes the last word instead of only one character (#10741).

    • ctrl-delete deletes the next word (same as alt-d).

  • New special input functions:

    • forward-char-passive and backward-char-passive are like their non-passive variants but do not accept autosuggestions or move focus in the completion pager (#10398).

    • forward-token, backward-token, kill-token, and backward-kill-token are similar to the *-bigword variants but for the whole argument token (which includes escaped spaces) (#2014).

    • clear-commandline, which merely clears the command line, as an alternative to cancel-commandline which prints ^C and a new prompt (#10213).

  • The accept-autosuggestion special input function now returns false when there was nothing to accept (#10608).

  • Vi mode has seen some improvements but continues to suffer from the lack of people working on it.

    • New default cursor shapes for insert and replace mode.

    • ctrl-n in insert mode accepts autosuggestions (#10339).

    • Outside insert mode, the cursor will no longer be placed beyond the last character on the commandline.

    • When the cursor is at the end of the commandline, a single l will accept an autosuggestion (#10286).

    • The cursor position after pasting (p) has been corrected.

    • Added an additional binding, _, for moving to the beginning of the line (#10720).

    • When the cursor is at the start of a line, escaping from insert mode no longer moves the cursor to the previous line.

    • Added bindings for clipboard interaction, like ",+,p and ",+,y,y.

    • Deleting in visual mode now moves the cursor back, matching vi (#10394).

    • The ;, ,, v, V, I, and gU bindings work in visual mode (#10601, #10648).

    • Support % motion (#10593).

    • ctrl-k to remove the contents of the line beyond the cursor in all modes (#10648).

    • Support ab and ib vi text objects. New input functions are introduced jump-{to,till}-matching-bracket (#1842).

    • The E binding now correctly handles the last character of the word, by jumping to the next word (#9700).

Completions

  • Command-specific tab completions may now offer results whose first character is a period. For example, it is now possible to tab-complete git add for files with leading periods. The default file completions hide these files, unless the token itself has a leading period (#3707).

  • Option completion now uses fuzzy subsequence filtering, just like non-option completion (#830). This means that --fb may be completed to --foobar if there is no better match.

  • Completions that insert an entire token now use quotes instead of backslashes to escape special characters (#5433).

  • Normally, file name completions start after the last : or = in a token. This helps commands like rsync --files-from=. This special meaning can now disabled by escaping these separators as \: and \=. This matches Bash’s behavior. Note that this escaping is usually not necessary since the completion engine already tries to guess whether the separator is actually part of a file name.

  • Various new completion scripts and numerous updates to existing ones.

  • Completions could hang if the PAGER environment variable was sent to certain editors on macOS, FreeBSD and some other platforms. This has been fixed (#10820).

  • Generated completions are now stored in $XDG_CACHE_HOME/fish or ~/.cache/fish by default (#10369)

  • A regression in fish 3.1, where completing a command line could change it completely, has been fixed (#10904).

Improved terminal support

  • fish now marks the prompt and command-output regions (via OSC 133) to enable terminal shell integration (#10352). Shell integration shortcuts can scroll to the next/previous prompt or show the last command output in a pager.

  • fish now reports the working directory (via OSC 7) unconditionally instead of only for some terminals (#9955).

  • fish now sets the terminal window title (via OSC 0) unconditionally instead of only for some terminals (#10037).

  • Focus reporting in tmux is no longer disabled on the first prompt.

  • Focus reporting is now disabled during commands run inside key bindings (#6942).

  • Cursor changes are applied to all terminals that support them, and the list of specifically-supported terminals has been removed (#10693).

  • If it cannot find the terminfo entry given by TERM environment variable, fish will now use an included xterm-256color definition to match the vast majority of current terminal emulators (#10905). If you need to have a specific terminfo profile for your terminal’s TERM variable, install it into the terminfo database.

  • Further improvements to the correct display of prompts which fill the width of the terminal (#8164).

Other improvements

  • status gained a build-info subcommand, to print information on how fish was built, to help with debugging (#10896).

  • fish_indent will now collapse multiple empty lines into one (#10325).

  • fish_indent now preserves the modification time of files if there were no changes (#10624).

  • Performance in launching external processes has been improved for many cases (#10869).

  • Performance and interactivity under Windows Subsystem for Linux has been improved, with a workaround for Windows-specific locations being appended to $PATH by default (#10506).

  • On macOS, paths from /etc/paths and /etc/manpaths containing colons are handled correctly (#10684).

  • Additional filesystems such as AFS are properly detected as remote, which avoids certain hangs due to expensive filesystem locks (#10818).

  • A spurious error when launching multiple instances of fish for the first time has been removed (#10813).

For distributors

fish has been ported to Rust. This means a significant change in dependencies, which are listed in the README. In short, Rust 1.70 or greater is required, and a C++ compiler is no longer needed (although a C compiler is still required, for some C glue code and the tests).

CMake remains the recommended build system, because of cargo’s limited support for installing support files. Version 3.5 remains the minimum supported version. The Xcode generator for CMake is not supported any longer (#9924). CMake builds default to optimized release builds (#10799).

fish no longer depends on the ncurses library, but still uses a terminfo database. When packaging fish, please add a dependency on the package containing your terminfo database instead of curses.

The test target was removed as it can no longer be defined in new CMake versions. Use make fish_run_tests. Any existing test target will not print output if it fails (#11116).

The Web-based configuration has been rewritten to use Alpine.js (#9554).


fish 4.0b1 (released December 17, 2024)

A number of improvements were included in fish 4.0.0 following the beta release of 4.0b1. These include fixes for regressions, improvements to completions and documentation, and the removal of a small number of problematic changes.

The full list of fixed issues can be found on the GitHub milestone page for 4.0-final.


fish 3.7.1 (released March 19, 2024)

This release of fish fixes the following problems identified in fish 3.7.0:

  • Deleting the last history entry via history delete works again (#10190).

  • Wildcards (*) will no longer sometimes generate paths that did not exist (#10205).

This release also contains some improvements:

  • A crash when trying to run an ELF program with a missing interpreter has been fixed. This crashed in the process after fork, so did not affect the fish process that tried to start the program (#10199).

  • funced will now always source the file after it has written it, even if the contents did not change. This prevents issues if the file was otherwise modified (#10318).

  • The warning for when a builtin returns a negative exit code was improved, now mentioning the original status (#10187).

  • Added completions for

  • Some improvements to documentation and completions.


fish 3.7.0 (released January 1, 2024)

This release of fish includes a number of improvements over fish 3.6.4, detailed below. Although work continues on the porting of fish internals to the Rust programming language, that work is not included in this release. fish 3.7.0 and any future releases in the 3.7 series remain C++ programs.

Notable improvements and fixes

  • Improvements to the history pager, including:

    • The history pager will now also attempt subsequence matches (#9476), so you can find a command line like git log 3.6.1..Integration_3.7.0 by searching for gitInt.

    • Opening the history pager will now fill the search field with a search string if you’re already in a search (#10005). This makes it nicer to search something with up and then later decide to switch to the full pager.

    • Closing the history pager with enter will now copy the search text to the commandline if there was no match, so you can continue editing the command you tried to find right away (#9934).

  • Performance improvements for command completions and globbing, where supported by the operating system, especially on slow filesystems such as NFS (#9891, #9931, #10032, #10052).

  • fish can now be configured to wait a specified amount of time for a multi-key sequence to be completed, instead of waiting indefinitely. For example, this makes binding kj to switching modes in vi mode possible. The timeout can be set via the new fish_sequence_key_delay_ms variable (#7401), and may be set by default in future versions.

Deprecations and removed features

  • LS_COLORS is no longer set automatically by the ls function (#10080). Users that set .dircolors should manually import it using other means. Typically this would be set -gx LS_COLORS (dircolors -c .dircolors | string split ' ')[3]

Scripting improvements

  • Running exit with a negative number no longer crashes fish (#9659).

  • fish --command will now return a non-zero status if parsing failed (#9888).

  • The jobs builtin will now escape the commands it prints (#9808).

  • string repeat no longer overflows if the count is a multiple of the chunk size (#9900).

  • The builtin builtin will now properly error out with invalid arguments instead of doing nothing and returning true (#9942).

  • command time in a pipeline is allowed again, as is command and and command or (#9985).

  • exec will now also apply variable overrides, so FOO=bar exec will now set $FOO correctly (#9995).

  • umask will now handle empty symbolic modes correctly, like umask u=,g=rwx,o= (#10177).

  • Improved error messages for errors occurring in command substitutions (#10054).

Interactive improvements

  • read no longer enables bracketed paste so it doesn’t stay enabled in combined commandlines like mysql -p(read --silent) (#8285).

  • Vi mode now uses fish_cursor_external to set the cursor shape for external commands (#4656).

  • Opening the history search in vi mode switches to insert mode correctly (#10141).

  • Vi mode cursor shaping is now enabled in iTerm2 (#9698).

  • Completing commands as root includes commands not owned by root, fixing a regression introduced in fish 3.2.0 (#9699).

  • Selection uses fish_color_selection for the foreground and background colors, as intended, rather than just the background (#9717).

  • The completion pager will no longer sometimes skip the last entry when moving through a long list (#9833).

  • The interactive history delete interface now allows specifying index ranges like “1..5” (#9736), and history delete --exact now properly saves the history (#10066).

  • Command completion will now call the stock manpath on macOS, instead of a potential Homebrew version. This prevents awkward error messages (#9817).

  • the redo special input function restores the pre-undo cursor position.

  • A new bind function history-pager-delete, bound to shift-delete by default, will delete the currently-selected history pager item from history (#9454).

  • fish_key_reader will now use printable characters as-is, so pressing “ö” no longer leads to it telling you to bind \u00F6 (#9986).

  • open can be used to launch terminal programs again, as an xdg-open bug has been fixed and a workaround has been removed (#10045).

  • The repaint-mode binding will now only move the cursor if there is repainting to be done. This fixes alt combination bindings in vi mode (#7910).

  • A new clear-screen bind function is used for ctrl-l by default. This clears the screen and repaints the existing prompt at first, so it eliminates visible flicker unless the terminal is very slow (#10044).

  • The alias convenience function has better support for commands with unusual characters, like + (#8720).

  • A longstanding issue where items in the pager would sometimes display without proper formatting has been fixed (#9617).

  • The alt-l binding, which lists the directory of the token under the cursor, correctly expands tilde (~) to the home directory (#9954).

  • Various fish utilities that use an external pager will now try a selection of common pagers if the PAGER environment variable is not set, or write the output to the screen without a pager if there is not one available (#10074).

  • Command-specific tab completions may now offer results whose first character is a period. For example, it is now possible to tab-complete git add for files with leading periods. The default file completions hide these files, unless the token itself has a leading period (#3707).

Improved prompts

  • The default theme now only uses named colors, so it will track the terminal’s palette (#9913).

  • The Dracula theme has now been synced with upstream (#9807); use fish_config to re-apply it to pick up the changes.

  • fish_vcs_prompt now also supports fossil (#9497).

  • Prompts which display the working directory using the prompt_pwd function correctly display directories beginning with dashes (#10169).

Completions

Other improvements

  • Improvements and corrections to the documentation.

  • The Web-based configuration now uses a more readable style when printed, such as for a keybinding reference (#9828).

  • Updates to the German translations (#9824).

  • The colors of the Nord theme better match their official style (#10168).

For distributors

  • The licensing information for some of the derived code distributed with fish was incomplete. Though the license information was present in the source distribution, it was not present in the documentation. This has been corrected (#10162).

  • The CMake configure step will now also look for libterminfo as an alternative name for libtinfo, as used in NetBSD curses (#9794).


fish 3.6.4 (released December 5, 2023)

This release contains a complete fix for the test suite failure in fish 3.6.2 and 3.6.3.


fish 3.6.3 (released December 4, 2023)

This release contains a fix for a test suite failure in fish 3.6.2.


fish 3.6.2 (released December 4, 2023)

This release of fish contains a security fix for CVE-2023-49284, a minor security problem identified in fish 3.6.1 and previous versions (thought to affect all released versions of fish).

fish uses certain Unicode non-characters internally for marking wildcards and expansions. It incorrectly allowed these markers to be read on command substitution output, rather than transforming them into a safe internal representation.

For example, echo \UFDD2HOME has the same output as echo $HOME.

While this may cause unexpected behavior with direct input, this may become a minor security problem if the output is being fed from an external program into a command substitution where this output may not be expected.


fish 3.6.1 (released March 25, 2023)

This release of fish contains a number of fixes for problems identified in fish 3.6.1, as well as some enhancements.

Notable improvements and fixes

  • abbr --erase now also erases the universal variables used by the old abbr function. That means:

    abbr --erase (abbr --list)
    

    can now be used to clean out all old abbreviations (#9468).

  • abbr --add --universal now warns about --universal being non-functional, to make it easier to detect old-style abbr calls (#9475).

Deprecations and removed features

  • The Web-based configuration for abbreviations has been removed, as it was not functional with the changes abbreviations introduced in 3.6.0 (#9460).

Scripting improvements

  • abbr --list no longer escapes the abbr name, which is necessary to be able to pass it to abbr --erase (#9470).

  • read will now print an error if told to set a read-only variable, instead of silently doing nothing (#9346).

  • set_color -v no longer crashes fish (#9640).

Interactive improvements

  • Using fish_vi_key_bindings in combination with fish’s --no-config mode works without locking up the shell (#9443).

  • The history pager now uses more screen space, usually half the screen (#9458)

  • Variables that were set while the locale was C (the default ASCII-only locale) will now properly be encoded if the locale is switched (#2613, #9473).

  • Escape during history search restores the original command line again (fixing a regression in 3.6.0).

  • Using --help on builtins now respects the $MANPAGER variable, in preference to $PAGER (#9488).

  • ctrl-g closes the history pager, like other shells (#9484).

  • The documentation for the :, [ and . builtin commands can now be looked up with man (#9552).

  • fish no longer crashes when searching history for non-ASCII codepoints case-insensitively (#9628).

  • The alt-s binding will now also use please if available (#9635).

  • Themes that don’t specify every color option can be installed correctly in the Web-based configuration (#9590).

  • Compatibility with Midnight Commander’s prompt integration has been improved (#9540).

  • A spurious error, noted when using fish in Google Drive directories under WSL 2, has been silenced (#9550).

  • Using read in fish_greeting or similar functions will not trigger an infinite loop (#9564).

  • Compatibility when upgrading from old versions of fish (before 3.4.0) has been improved (#9569).

Improved prompts

  • The git prompt will compute the stash count to be used independently of the informative status (#9572).

Completions

  • Added completions for:

    • apkanalyzer (#9558)

    • neovim (#9543)

    • otool

    • pre-commit (#9521)

    • proxychains (#9486)

    • scrypt (#9583)

    • stow (#9571)

    • trash and helper utilities trash-empty, trash-list, trash-put, trash-restore (#9560)

    • ssh-copy-id (#9675)

  • Improvements to many completions, including the speed of completing directories in WSL 2 (#9574).

  • Completions using __fish_complete_suffix are now offered in the correct order, fixing a regression in 3.6.0 (#8924).

  • git completions for git-foo-style commands was restored, fixing a regression in 3.6.0 (#9457).

  • File completion now offers ../ and ./ again, fixing a regression in 3.6.0 (#9477).

  • The behaviour of completions using __fish_complete_path matches standard path completions (#9285).

Other improvements

  • Improvements and corrections to the documentation.

For distributors

  • fish 3.6.1 builds correctly on Cygwin (#9502).


fish 3.6.0 (released January 7, 2023)

Notable improvements and fixes

  • By default, ctrl-r now opens the command history in the pager (#602). This is fully searchable and syntax-highlighted, as an alternative to the incremental search seen in other shells. The new special input function history-pager has been added for custom bindings.

  • Abbreviations are more flexible (#9313, #5003, #2287):

    • They may optionally replace tokens anywhere on the command line, instead of only commands

    • Matching tokens may be described using a regular expression instead of a literal word

    • The replacement text may be produced by a fish function, instead of a literal word

    • They may position the cursor anywhere in the expansion, instead of at the end

    For example:

    function multicd
        echo cd (string repeat -n (math (string length -- $argv[1]) - 1) ../)
    end
    
    abbr --add dotdot --regex '^\.\.+$' --function multicd
    

    This expands .. to cd ../, ... to cd ../../ and .... to cd ../../../ and so on.

    Or:

    function last_history_item; echo $history[1]; end
    abbr -a !! --position anywhere --function last_history_item
    

    which expands !! to the last history item, anywhere on the command line, mimicking other shells’ history expansion.

    See the documentation for more.

  • path gained a new mtime subcommand to print the modification time stamp for files. For example, this can be used to handle cache file ages (#9057):

    > touch foo
    > sleep 10
    > path mtime --relative foo
    10
    
  • string gained a new shorten subcommand to shorten strings to a given visible width (#9156):

    > string shorten --max 10 "Hello this is a long string"
    Hello thi…
    
  • test (aka [) gained -ot (older than) and -nt (newer than) operators to compare file modification times, and -ef to compare whether the arguments are the same file (#3589).

  • fish will now mark the extent of many errors with a squiggly line, instead of just a caret (^) at the beginning (#9130). For example:

    checks/set.fish (line 471): for: a,b: invalid variable name. See `help identifiers`
    for a,b in y 1 z 3
        ^~^
    
  • A new function, fish_delta, shows changes that have been made in fish’s configuration from the defaults (#9255).

  • set --erase can now be used with multiple scopes at once, like set -efglU foo (#7711, #9280).

  • status gained a new subcommand, current-commandline, which retrieves the entirety of the currently-executing command line when called from a function during execution. This allows easier job introspection (#8905, #9296).

Deprecations and removed features

  • The \x and \X escape syntax is now equivalent. \xAB previously behaved the same as \XAB, except that it would error if the value “AB” was larger than “7f” (127 in decimal, the highest ASCII value) (#9247, #9245, #1352).

  • The fish_git_prompt will now only turn on features if the appropriate variable has been set to a true value (of “1”, “yes” or “true”) instead of just checking if it is defined. This allows specifically turning features off without having to erase variables, such as via universal variables. If you have defined a variable to a different value and expect it to count as true, you need to change it (#9274). For example, set -g __fish_git_prompt_show_informative_status 0 previously would have enabled informative status (because any value would have done so), but now it turns it off.

  • Abbreviations are no longer stored in universal variables. Existing universal abbreviations are still imported, but new abbreviations should be added to config.fish.

  • The short option -r for abbreviations has changed from rename to regex, for consistency with string.

Scripting improvements

  • argparse can now be used without option specifications, to allow using --min-args, --max-args or for commands that take no options (but might in future) (#9006):

    function my_copy
        argparse --min-args 2 -- $argv
        or return
    
        cp $argv
    end
    
  • set --show now shows when a variable was inherited from fish’s parent process, which should help with debugging (#9029):

    > set --show XDG_DATA_DIRS
    $XDG_DATA_DIRS: set in global scope, exported, a path variable with 4 elements
    $XDG_DATA_DIRS[1]: |/home/alfa/.local/share/flatpak/exports/share|
    $XDG_DATA_DIRS[2]: |/var/lib/flatpak/exports/share|
    $XDG_DATA_DIRS[3]: |/usr/local/share|
    $XDG_DATA_DIRS[4]: |/usr/share|
    $XDG_DATA_DIRS: originally inherited as |/home/alfa/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share/:/usr/share/|
    
  • The read limit is now restored to the default when fish_read_limit is unset (#9129).

  • math produces an error for division-by-zero, as well as augmenting some errors with their extent (#9190). This changes behavior in some limited cases, such as:

    math min 1 / 0, 5
    

    which would previously print “5” (because in floating point division “1 / 0” yields infinite, and 5 is smaller than infinite) but will now return an error.

  • fish_clipboard_copy and fish_clipboard_paste can now be used in pipes (#9271):

    git rev-list 3.5.1 | fish_clipboard_copy
    
    fish_clipboard_paste | string join + | math
    
  • status fish-path returns a fully-normalised path, particularly noticeable on NetBSD (#9085).

Interactive improvements

  • If the terminal definition for TERM can’t be found, fish now tries using the “xterm-256color” and “xterm” definitions before “ansi” and “dumb”. As the majority of terminal emulators in common use are now more or less xterm-compatible (often even explicitly claiming the xterm-256color entry), this should often result in a fully or almost fully usable terminal (#9026).

  • A new variable, fish_cursor_selection_mode, can be used to configure whether the command line selection includes the character under the cursor (inclusive) or not (exclusive). The new default is exclusive; use set fish_cursor_selection_mode inclusive to get the previous behavior back (#7762).

  • fish’s completion pager now fills half the terminal on first tab press instead of only 4 rows, which should make results visible more often and save key presses, without constantly snapping fish to the top of the terminal (#9105, #2698).

  • The complete-and-search binding, used with shift-tab by default, selects the first item in the results immediately (#9080).

  • bind output is now syntax-highlighted when used interactively.

  • alt-h (the default __fish_man_page binding) does a better job of showing the manual page of the command under cursor (#9020).

  • If fish_color_valid_path contains an actual color instead of just modifiers, those will be used for valid paths even if the underlying color isn’t “normal” (#9159).

  • The key combination for the QUIT terminal sequence, often ctrl-\ (\x1c), can now be used as a binding (#9234).

  • fish’s vi mode uses normal xterm-style sequences to signal cursor change, instead of using the iTerm’s proprietary escape sequences. This allows for a blinking cursor and makes it work in complicated scenarios with nested terminals. (#3741, #9172)

  • When running fish on a remote system (such as inside SSH or a container), ctrl-x now copies to the local client system’s clipboard if the terminal supports OSC 52.

  • commandline gained two new options, --selection-start and --selection-end, to set the start/end of the current selection (#9197, #9215).

  • fish’s builtins now handle keyboard interrupts (ctrl-c) correctly (#9266).

Completions

  • Added completions for:

  • Improvements to many completions, including making cd completion much faster (#9220).

  • Completion of tilde (~) works properly even when the file name contains an escaped character (#9073).

  • fish no longer loads completions if the command is used via a relative path and is not in PATH (#9133).

  • fish no longer completes inside of comments (#9320).

Improved terminal support

  • Opening help on WSL now uses PowerShell to open the browser if available, removing some awkward UNC path errors (#9119).

Other improvements

  • The Web-based configuration tool now works on systems with IPv6 disabled (#3857).

  • Aliases can ignore arguments by ending them with # (#9199).

  • string is now faster when reading large strings from stdin (#9139).

  • string repeat uses less memory and is faster. (#9124)

  • Builtins are much faster when writing to a pipe or file. (#9229).

  • Performance improvements to highlighting (#9180) should make using fish more pleasant on slow systems.

  • On 32-bit systems, globs like * will no longer fail to return some files, as large file support has been enabled.

Fixed bugs

  • The history search text for a token search is now highlighted correctly if the line contains multiple instances of that text (#9066).

  • process-exit and job-exit events are now generated for all background jobs, including those launched from event handlers (#9096).

  • A crash when completing a token that contained both a potential glob and a quoted variable expansion was fixed (#9137).

  • prompt_pwd no longer accidentally overwrites a global or universal $fish_prompt_pwd_full_dirs when called with the -d or --full-length-dirs option (#9123).

  • A bug which caused fish to freeze or exit after running a command which does not preserve the foreground process group was fixed (#9181).

  • The “Disco” sample prompt no longer prints an error in some working directories (#9164). If you saved this prompt, you should run fish_config prompt save disco again.

  • fish launches external commands via the given path again, rather than always using an absolute path. This behaviour was inadvertently changed in 3.5.0 and is visible, for example, when launching a bash script which checks $0 (#9143).

  • printf no longer tries to interpret the first argument as an option (#9132).

  • Interactive read in scripts will now have the correct keybindings again (#9227).

  • A possible stack overflow when recursively evaluating substitutions has been fixed (#9302).

  • A crash with relative $CDPATH has been fixed (#9407).

  • printf now properly fills extra %d specifiers with 0 even on macOS and BSD (#9321).

  • fish_key_reader now correctly exits when receiving a SIGHUP (like after closing the terminal) (#9309).

  • fish_config theme save now works as documented instead of erroring out (#9088, #9273).

  • fish no longer triggers prompts to install command line tools when first run on macOS (#9343).

  • fish_git_prompt now quietly fails on macOS if the xcrun cache is not yet populated (#6625), working around a potential hang.

For distributors

  • The vendored PCRE2 sources have been removed. It is recommended to declare PCRE2 as a dependency when packaging fish. If the CMake variable FISH_USE_SYSTEM_PCRE2 is false, fish will now download and build PCRE2 from the official repo (#8355, #8363). Note this variable defaults to true if PCRE2 is found installed on the system.


fish 3.5.1 (released July 20, 2022)

This release of fish introduces the following small enhancements:

  • Cursor shaping for Vi mode is enabled by default in tmux, and will be used if the outer terminal is capable (#8981).

  • printf returns a better error when used with arguments interpreted as octal numbers (#9035).

  • history merge when in private mode is now an error, rather than wiping out other sessions’ history (#9050).

  • The error message when launching a command that is built for the wrong architecture on macOS is more helpful (#9052).

  • Added completions for:

  • Improvements to some completions.

This release also fixes a number of problems identified in fish 3.5.0.

  • Completing git blame or git -C works correctly (#9053).

  • On terminals that emit a CSI u sequence for shift-space, fish inserts a space instead of printing an error. (#9054).

  • status fish-path on Linux-based platforms could print the path with a “ (deleted)” suffix (such as /usr/bin/fish (deleted)), which is now removed (#9019).

  • Cancelling an initial command (from fish’s --init-command option) with ctrl-c no longer prevents configuration scripts from running (#9024).

  • The job summary contained extra blank lines if the prompt used multiple lines, which is now fixed (#9044).

  • Using special input functions in bindings, in combination with and/or conditionals, no longer crashes (#9051).


fish 3.5.0 (released June 16, 2022)

Notable improvements and fixes

  • A new path builtin command to filter and transform paths (#7659, #8958). For example, to list all the separate extensions used on files in /usr/share/man (after removing one extension, commonly a “.gz”):

    path filter -f /usr/share/man/** | path change-extension '' | path extension | path sort -u
    
  • Tab (or any key bound to complete) now expands wildcards instead of invoking completions, if there is a wildcard in the path component under the cursor (#954, #8593).

  • Scripts can now catch and handle the SIGINT and SIGTERM signals, either via function --on-signal or with trap (#6649).

Deprecations and removed features

  • The stderr-nocaret feature flag, introduced in fish 3.0 and enabled by default in fish 3.1, has been made read-only. That means it is no longer possible to disable it, and code supporting the ^ redirection has been removed (#8857, #8865).

    To recap: fish used to support ^ to redirect stderr, so you could use commands like:

    test "$foo" -gt 8 ^/dev/null
    

    to ignore error messages. This made the ^ symbol require escaping and quoting, and was a bit of a weird shortcut considering 2> already worked, which is only one character longer.

    So the above can simply become:

    test "$foo" -gt 8 2>/dev/null
    
  • The following feature flags have been enabled by default:

    • regex-easyesc, which makes string replace -r not do a superfluous round of unescaping in the replacement expression. That means e.g. to escape any “a” or “b” in an argument you can use string replace -ra '([ab])' '\\\\$1' foobar instead of needing 8 backslashes.

      This only affects the replacement expression, not the match expression (the '([ab])' part in the example). A survey of plugins on GitHub did not turn up any affected code, so we do not expect this to affect many users.

      This flag was introduced in fish 3.1.

    • ampersand-nobg-in-token, which means that & will not create a background job if it occurs in the middle of a word. For example, echo foo&bar will print “foo&bar” instead of running echo foo in the background and then starting bar as a second job.

      Reformatting with fish_indent would already introduce spaces, turning echo foo&bar into echo foo & bar.

      This flag was introduced in fish 3.4.

    To turn off these flags, add no-regex-easyesc or no-ampersand-nobg-in-token to fish_features and restart fish:

    set -Ua fish_features no-regex-easyesc
    

    Like stderr-nocaret, they will eventually be made read-only.

  • Most string subcommands no longer append a newline to their input if the input didn’t have one (#8473, #3847)

  • fish’s escape sequence removal (like for string length --visible or to figure out how wide the prompt is) no longer has special support for non-standard color sequences like from Data General terminals, e.g. the Data General Dasher D220 from 1984. This removes a bunch of work in the common case, allowing string length --visible to be much faster with unknown escape sequences. We don’t expect anyone to have ever used fish with such a terminal (#8769).

  • Code to upgrade universal variables from fish before 3.0 has been removed. Users who upgrade directly from fish versions 2.7.1 or before will have to set their universal variables & abbreviations again. (#8781)

  • The meaning of an empty color variable has changed (#8793). Previously, when a variable was set but empty, it would be interpreted as the “normal” color. Now, empty color variables cause the same effect as unset variables - the general highlighting variable for that type is used instead. For example:

    set -g fish_color_command blue
    set -g fish_color_keyword
    

    would previously make keywords “normal” (usually white in a dark terminal). Now it’ll make them blue. To achieve the previous behavior, use the normal color explicitly: set -g fish_color_keyword normal.

    This makes it easier to make self-contained color schemes that don’t accidentally use color that was set before. fish_config has been adjusted to set known color variables that a theme doesn’t explicitly set to empty.

  • eval is now a reserved keyword, so it can’t be used as a function name. This follows set and read, and is necessary because it can’t be cleanly shadowed by a function - at the very least eval set -l argv foo breaks. fish will ignore autoload files for it, so left over eval.fish from previous fish versions won’t be loaded.

  • The git prompt in informative mode now defaults to skipping counting untracked files, as this was extremely slow. To turn it on, set __fish_git_prompt_showuntrackedfiles or set the git config value “bash.showuntrackedfiles” to true explicitly (which can be done for individual repositories). The “informative+vcs” sample prompt already skipped display of untracked files, but didn’t do so in a way that skipped the computation, so it should be quite a bit faster in many cases (#8980).

  • The __terlar_git_prompt function, used by the “Terlar” sample prompt, has been rebuilt as a configuration of the normal fish_git_prompt to ease maintenance, improve performance and add features (like reading per-repo git configuration). Some slight changes remain; users who absolutely must have the same behavior are encouraged to copy the old function (#9011, #7918, #8979).

Scripting improvements

  • Quoted command substitution that directly follow a variable expansion (like echo "$var$(echo x)") no longer affect the variable expansion (#8849).

  • fish now correctly expands command substitutions that are preceded by an escaped dollar (like echo \$(echo)). This regressed in version 3.4.0.

  • math can now handle underscores (_) as visual separators in numbers (#8611, #8496):

    math 5 + 2_123_252
    
  • math’s min and max functions now take a variable number of arguments instead of always requiring 2 (#8644, #8646):

    > math min 8,2,4
    2
    
  • read is now faster as the last process in a pipeline (#8552).

  • string join gained a new --no-empty flag to skip empty arguments (#8774, #8351).

  • read now only triggers the fish_read event, not the fish_prompt event (#8797). It was supposed to work this way in fish 3.2.0 and later, but both events were emitted.

  • The TTY modes are no longer restored when non-interactive shells exit. This fixes wrong tty modes in pipelines with interactive commands. (#8705).

  • Some functions shipped with fish printed error messages to standard output, but they now they rightly go to standard error (#8855).

  • jobs now correctly reports CPU usage as a percentage, instead of as a number of clock ticks (#8919).

  • process-exit events now fire when the process exits even if the job has not yet exited, fixing a regression in 3.4.1 (#8914).

Interactive improvements

  • fish now reports a special error if a command wasn’t found and there is a non-executable file by that name in PATH (#8804).

  • less and other interactive commands would occasionally be stopped when run in a pipeline with fish functions; this has been fixed (#8699).

  • Case-changing autosuggestions generated mid-token now correctly append only the suffix, instead of duplicating the token (#8820).

  • ulimit learned a number of new options for the resource limits available on Linux, FreeBSD ande NetBSD, and returns a specific warning if the limit specified is not available on the active operating system (#8823, #8786).

  • The vared command can now successfully edit variables named “tmp” or “prompt” (#8836, #8837).

  • time now emits an error if used after the first command in a pipeline (#8841).

  • fish_add_path now prints a message for skipped non-existent paths when using the -v flag (#8884).

  • Since fish 3.2.0, pressing ctrl-d while a command is running would end up inserting a space into the next commandline, which has been fixed (#8871).

  • A bug that caused multi-line prompts to be moved down a line when pasting or switching modes has been fixed (#3481).

  • The Web-based configuration system no longer strips too many quotes in the abbreviation display (#8917, #8918).

  • fish started with --no-config will now use the default keybindings (#8493)

  • When fish inherits a USER environment variable value that doesn’t correspond to the current effective user ID, it will now correct it in all cases (#8879, #8583).

  • fish sets a new EUID variable containing the current effective user id (#8866).

  • history search no longer interprets the search term as an option (#8853)

  • The status message when a job terminates should no longer be erased by a multiline prompt (#8817)

New or improved bindings

  • The alt-s binding will now insert doas instead of sudo if necessary (#8942).

  • The kill-whole-line special input function now kills the newline preceding the last line. This makes dd in vi-mode clear the last line properly.

  • The new kill-inner-line special input function kills the line without any newlines, allowing cc in vi-mode to clear the line while preserving newlines (#8983).

  • On terminals that emit special sequences for these combinations, shift-space is bound like space, and ctrl-enter is bound like return (#8874).

Improved prompts

  • A new Astronaut prompt (#8775), a multi-line prompt using plain text reminiscent of the Starship.rs prompt.

Completions

  • Added completions for:

  • complete can now be given multiple --condition options. They will be attempted in the order they were given, and only if all succeed will the completion be made available (as if they were connected with &&). This helps with caching - fish’s complete system stores the return value of each condition as long as the commandline doesn’t change, so this can reduce the number of conditions that need to be evaluated (#8536, #8967).

Improved terminal support

  • Working directory reporting is enabled for kitty (#8806).

  • Changing the cursor shape is now enabled by default in iTerm2 (#3696).

For distributors

  • libatomic is now correctly detected as necessary when building on RISC-V (#8850, #8851).

  • In some cases, the build process found the wrong libintl on macOS. This has been corrected (#5244).

  • The paths for completions, functions, and configuration snippets now include subdirectories fish/vendor_completions.d, fish/vendor_functions.d, and fish/vendor_conf.d (respectively) within XDG_DATA_HOME (or ~/.local/share if not defined) (#8887, #7816).


fish 3.4.1 (released March 25, 2022)

This release of fish fixes the following problems identified in fish 3.4.0:

  • An error printed after upgrading, where old instances could pick up a newer version of the fish_title function, has been fixed (#8778)

  • fish builds correctly on NetBSD (#8788) and OpenIndiana (#8780).

  • nextd-or-forward-word, bound to alt-right by default, was inadvertently changed to move like forward-bigword. This has been corrected (#8790).

  • funcsave -q and funcsave --quiet now work correctly (#8830).

  • Issues with the csharp and nmcli completions were corrected.

If you are upgrading from version 3.3.1 or before, please also review the release notes for 3.4.0 (included below).


fish 3.4.0 (released March 12, 2022)

Notable improvements and fixes

  • fish’s command substitution syntax has been extended: $(cmd) now has the same meaning as (cmd) but it can be used inside double quotes, to prevent line splitting of the results (#159):

    foo (bar | string collect)
    # can now be written as
    foo "$(bar)"
    
    # and
    
    foo (bar)
    # can now be written as
    foo $(bar)
    # this will still split on newlines only.
    
  • Complementing the prompt command in 3.3.0, fish_config gained a theme subcommand to show and pick from the sample themes (meaning color schemes) directly in the terminal, instead of having to open a Web browser. For example fish_config theme choose Nord loads the Nord theme in the current session (#8132). The current theme can be saved with fish_config theme dump, and custom themes can be added by saving them in ~/.config/fish/themes/.

  • set and read learned a new option, --function, to set a variable in the function’s top scope. This should be a more familiar way of scoping variables and avoids issues with --local, which is actually block-scoped (#565, #8145):

    function demonstration
        if true
            set --function foo bar
            set --local baz banana
        end
        echo $foo # prints "bar" because $foo is still valid
        echo $baz # prints nothing because $baz went out of scope
    end
    
  • string pad now excludes escape sequences like colors that fish knows about, and a new --visible flag to string length makes it use that kind of visible width. This is useful to get the number of terminal cells an already colored string would occupy, like in a prompt. (#8182, #7784, #4012):

    > string length --visible (set_color red)foo
    3
    
  • Performance improvements to globbing, especially on systems using glibc. In some cases (large directories with files with many numbers in the names) this almost halves the time taken to expand the glob.

  • Autosuggestions can now be turned off by setting $fish_autosuggestion_enabled to 0, and (almost) all highlighting can be turned off by choosing the new “None” theme. The exception is necessary colors, like those which distinguish autosuggestions from the actual command line. (#8376)

  • The fish_git_prompt function, which is included in the default prompts, now overrides git to avoid running commands set by per-repository configuration. This avoids a potential security issue in some circumstances, and has been assigned CVE-2022-20001 (#8589).

Deprecations and removed features

  • A new feature flag, ampersand-nobg-in-token makes & only act as background operator if followed by a separator. In combination with qmark-noglob, this allows entering most URLs at the command line without quoting or escaping (#7991). For example:

    > echo foo&bar # will print "foo&bar", instead of running "echo foo" in the background and executing "bar"
    > echo foo & bar # will still run "echo foo" in the background and then run "bar"
    # with both ampersand-nobg-in-token and qmark-noglob, this argument has no special characters anymore
    > open https://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=youtu.be
    

    As a reminder, feature flags can be set on startup with fish --features ampersand-nobg-in-token,qmark-noglob or with a universal variable called fish_features:

    > set -Ua fish_features ampersand-nobg-in-token
    
  • $status is now forbidden as a command, to prevent a surprisingly common error among new users: Running if $status (#8171). This applies only to $status, other variables are still allowed.

  • set --query now returns an exit status of 255 if given no variable names. This means if set -q $foo will not enter the if-block if $foo is empty or unset. To restore the previous behavior, use if not set -q foo; or set -q $foo - but this is unlikely to be desirable (#8214).

  • _ is now a reserved keyword (#8342).

  • The special input functions delete-or-exit, nextd-or-forward-word and prevd-or-backward-word replace fish functions of the same names (#8538).

  • Mac OS X 10.9 is no longer supported. The minimum Mac version is now 10.10 “Yosemite.”

Scripting improvements

  • string collect supports a new --allow-empty option, which will output one empty argument in a command substitution that has no output (#8054). This allows commands like test -n (echo -n | string collect --allow-empty) to work more reliably. Note this can also be written as test -n "$(echo -n)" (see above).

  • string match gained a --groups-only option, which makes it only output capturing groups, excluding the full match. This allows string match to do simple transformations (#6056):

    > string match -r --groups-only '(.*)fish' 'catfish' 'twofish' 'blue fish' | string escape
    cat
    two
    'blue '
    
  • $fish_user_paths is now automatically deduplicated to fix a common user error of appending to it in config.fish when it is universal (#8117). fish_add_path remains the recommended way to add to $PATH.

  • return can now be used outside functions. In scripts, it does the same thing as exit. In interactive mode,it sets $status without exiting (#8148).

  • An oversight prevented all syntax checks from running on commands given to fish -c (#8171). This includes checks such as exec not being allowed in a pipeline, and $$ not being a valid variable. Generally, another error was generated anyway.

  • fish_indent now correctly reformats tokens that end with a backslash followed by a newline (#8197).

  • commandline gained an --is-valid option to check if the command line is syntactically valid and complete. This allows basic implementation of transient prompts (#8142).

  • commandline gained a --paging-full-mode option to check if the pager is showing all the possible lines (no “7 more rows” message) (#8485).

  • List expansion correctly reports an error when used with all zero indexes (#8213).

  • Running fish with a directory instead of a script as argument (eg fish .) no longer leads to an infinite loop. Instead it errors out immediately (#8258)

  • Some error messages occurring after fork, like “text file busy” have been replaced by bespoke error messages for fish (like “File is currently open for writing”). This also restores error messages with current glibc versions that removed sys_errlist (#8234, #4183).

  • The realpath builtin now also squashes leading slashes with the --no-symlinks option (#8281).

  • When trying to cd to a dangling (broken) symbolic link, fish will print an error noting that the target is a broken link (#8264).

  • On MacOS terminals that are not granted permissions to access a folder, cd would print a spurious “rotten symlink” error, which has been corrected to “permission denied” (#8264).

  • Since fish 3.0, for loops would trigger a variable handler function before the loop was entered. As the variable had not actually changed or been set, this was a spurious event and has been removed (#8384).

  • math now correctly prints negative values and values larger than 2**31 when in hex or octal bases (#8417).

  • dirs always produces an exit status of 0, instead of sometimes returning 1 (#8211).

  • cd "" no longer crashes fish (#8147).

  • set --query can now query whether a variable is a path variable via --path or --unpath (#8494).

  • Tilde characters (~) produced by custom completions are no longer escaped when applied to the command line, making it easier to use the output of a recursive complete -C in completion scripts (#4570).

  • set --show reports when a variable is read-only (#8179).

  • Erasing $fish_emoji_width will reset fish to the default guessed emoji width (#8274).

  • The la function no longer lists entries for “.” and “..”, matching other systems defaults (#8519).

  • abbr -q returns the correct exit status when given multiple abbreviation names as arguments (#8431).

  • command -v returns an exit status of 127 instead of 1 if no command was found (#8547).

  • argparse with --ignore-unknown no longer breaks with multiple unknown options in a short option group (#8637).

  • Comments inside command substitutions or brackets now correctly ignore parentheses, quotes, and brackets (#7866, #8022, #8695).

  • complete -C supports a new --escape option, which turns on escaping in returned completion strings (#3469).

  • Invalid byte or unicode escapes like \Utest or \xNotHex are now a tokenizer error instead of causing the token to be truncated (#8545).

Interactive improvements

  • Vi mode cursors are now set properly after ctrl-c (#8125).

  • funced will try to edit the whole file containing a function definition, if there is one (#391).

  • Running a command line consisting of just spaces now deletes an ephemeral (starting with space) history item again (#8232).

  • Command substitutions no longer respect job control, instead running inside fish’s own process group (#8172). This more closely matches other shells, and improves ctrl-c reliability inside a command substitution.

  • history and __fish_print_help now properly support less before version 530, including the version that ships with macOS. (#8157).

  • help now knows which section is in which document again (#8245).

  • fish’s highlighter will now color options (starting with - or --) with the color given in the new $fish_color_option, up to the first --. It falls back on $fish_color_param, so nothing changes for existing setups (#8292).

  • When executing a command, abbreviations are no longer expanded when the cursor is separated from the command by spaces, making it easier to suppress abbreviation expansion of commands without arguments. (#8423).

  • fish_key_reader’s output was simplified. By default, it now only prints a bind statement. The previous per-character timing information can be seen with a new --verbose switch (#8467).

  • Custom completions are now also loaded for commands that contain tildes or variables like ~/bin/fish or $PWD/fish (#8442).

  • Command lines spanning multiple lines will not be overwritten by the completion pager when it fills the entire terminal (#8509, #8405).

  • When redrawing a multiline prompt, the old prompt is now properly cleared (#8163).

  • Interactive completion would occasionally ignore the last word on the command line due to a race condition. This has been fixed (#8175).

  • Propagation of universal variables from a fish process that is closing is faster (#8209).

  • The command line is drawn in the correct place if the prompt ends with a newline (#8298).

  • history learned a new subcommand clear-session to erase all history from the current session (#5791).

  • Pressing ctrl-c in fish_key_reader will no longer print the incorrect “Press [ctrl-C] again to exit” message (#8510).

  • The default command-not-found handler for Fedora/PackageKit now passes the whole command line, allowing for functionality such as running the suggested command directly (#8579).

  • When looking for locale information, the Debian configuration is now used when available (#8557).

  • Pasting text containing quotes from the clipboard trims spaces more appropriately (#8550).

  • The clipboard bindings ignore X-based clipboard programs if the DISPLAY environment variable is not set, which helps prefer the Windows clipboard when it is available (such as on WSL).

  • funcsave will remove a saved copy of a function that has been erased with functions --erase.

  • The Web-based configuration tool gained a number of improvements, including the ability to set pager colors.

  • The default fish_title prints a shorter title with shortened $PWD and no more redundant “fish” (#8641).

  • Holding down an arrow key won’t freeze the terminal with long periods of flashing (#8610).

  • Multi-char bindings are no longer interrupted if a signal handler enqueues an event. (#8628).

New or improved bindings

  • escape can now bound without breaking arrow key bindings (#8428).

  • The alt-h binding (to open a command’s manual page) now also ignores command (#8447).

Improved prompts

  • The fish_status_to_signal helper function returns the correct signal names for the current platform, rather than Linux (#8530).

  • The prompt_pwd helper function learned a --full-length-dirs N option to keep the last N directory components unshortened. In addition the number of characters to shorten each component should be shortened to can now be given as -d N or --dir-length N. (#8208):

    > prompt_pwd --full-length-dirs 2 -d 1 ~/dev/fish-shell/share/tools/web_config
    ~/d/f/s/tools/web_config
    

Completions

  • Added completions for:

  • Improvements to many completions, especially for git aliases (#8129), subcommands (#8134) and submodules (#8716).

  • Many adjustments to complete correct options for system utilities on BSD and macOS.

  • When evaluating custom completions, the command line state no longer includes variable overrides (var=val). This unbreaks completions that read commandline -op.

Improved terminal support

  • Dynamic terminal titles are enabled on WezTerm (#8121).

  • Directory history navigation works out of the box with Apple Terminal’s default key settings (#2330).

  • fish now assumes Unicode 9+ widths for emoji under iTerm 2 (#8200).

  • Skin-tone emoji modifiers (U+1F3FB through U+1F3FF) are now measured as width 0 (#8275).

  • fish’s escape sequence removal now also knows Tmux’s wrapped escapes.

  • Vi mode cursors are enabled in Apple Terminal.app (#8167).

  • Vi cursor shaping and $PWD reporting is now also enabled on foot (#8422).

  • ls will use colors also on newer versions of Apple Terminal.app (#8309).

  • The delete and shift-tab keys work more reliably under st (#8352, #8354).

Other improvements

  • fish’s test suite now uses ctest, and has become much faster to run. It is now also possible to run only specific tests with targets named test_$filename - make test_set.fish only runs the set.fish test. (#7851)

  • The HTML version of the documentation now includes copy buttons for code examples (#8218).

  • The HTML version of the documentation and the web-based configuration tool now pick more modern system fonts instead of falling back to Arial and something like Courier New most of the time (#8632).

  • The Debian & Ubuntu package linked from fishshell.com is now a single package, rather than split into fish and fish-common (#7845).

  • The macOS installer does not assert that Rosetta is required to install fish on machines with Apple Silicon (#8566).

  • The macOS installer now cleans up previous .pkg installations when upgrading. (#2963).

For distributors

  • The minimum version of CMake required to build fish is now 3.5.0.

  • The CMake installation supports absolute paths for CMAKE_INSTALL_DATADIR (#8150).

  • Building using NetBSD curses works on any platform (#8087).

  • The build system now uses the default linker instead of forcing use of the gold or lld linker (#8152).


fish 3.3.1 (released July 6, 2021)

This release of fish fixes the following problems identified in fish 3.3.0:

  • The prompt and command line are redrawn correctly in response to universal variable changes (#8088).

  • A superfluous error that was produced when setting the PATH or CDPATH environment variables to include colon-delimited components that do not exist was removed (#8095).

  • The Vi mode indicator in the prompt is repainted correctly after ctrl-c cancels the current command (#8103).

  • fish builds correctly on platforms that do not have a spawn.h header, such as old versions of OS X (#8097).

A number of improvements to the documentation, and fixes for completions, are included as well.

If you are upgrading from version 3.2.2 or before, please also review the release notes for 3.3.0 (included below).


fish 3.3.0 (released June 28, 2021)

Notable improvements and fixes

  • fish_config gained a prompt subcommand to show and pick from the sample prompts directly in the terminal, instead of having to open a webbrowser. For example fish_config prompt choose default loads the default prompt in the current session (#7958).

  • The documentation has been reorganized to be easier to understand (#7773).

Deprecations and removed features

  • The $fish_history value “default” is no longer special. It used to be treated the same as “fish” (#7650).

  • Redirection to standard error with the ^ character has been disabled by default. It can be turned back on using the stderr-nocaret feature flag, but will eventually be disabled completely (#7105).

  • Specifying an initial tab to fish_config now only works with fish_config browse (eg fish_config browse variables), otherwise it would interfere with the new prompt subcommand (see below) (#7958).

Scripting improvements

  • math gained new functions log2 (like the documentation claimed), max and min (#7856). math functions can be used without the parentheses (eg math sin 2 + 6), and functions have the lowest precedence in the order of operations (#7877).

  • Shebang (#!) lines are no longer required within shell scripts, improving support for scripts with concatenated binary contents. If a file fails to execute and passes a (rudimentary) binary safety check, fish will re-invoke it using /bin/sh (#7802).

  • Exit codes are better aligned with bash. A failed execution now reports $status of 127 if the file is not found, and 126 if it is not executable.

  • echo no longer writes its output one byte at a time, improving performance and allowing use with Linux’s special API files (/proc, /sys and such) (#7836).

  • fish should now better handle cd on filesystems with broken stat(3) responses (#7577).

  • Builtins now properly report a $status of 1 upon unsuccessful writes (#7857).

  • string match with unmatched capture groups and without the --all flag now sets an empty variable instead of a variable containing the empty string. It also correctly imports the first match if multiple arguments are provided, matching the documentation. (#7938).

  • fish produces more specific errors when a command in a command substitution wasn’t found or is not allowed. This now prints something like “Unknown command” instead of “Unknown error while evaluating command substitution”.

  • fish_indent allows inline variable assignments (FOO=BAR command) to use line continuation, instead of joining them into one line (#7955).

  • fish gained a --no-config option to disable configuration files. This applies to user-specific and the systemwide config.fish (typically in /etc/fish/config.fish), and configuration snippets (typically in conf.d directories). It also disables universal variables, history, and loading of functions from system or user configuration directories (#7921, #1256).

  • When universal variables are unavailable for some reason, setting a universal variable now sets a global variable instead (#7921).

  • $last_pid now contains the process ID of the last process in the pipeline, allowing it to be used in scripts (#5036, #5832, #7721). Previously, this value contained the process group ID, but in scripts this was the same as the running fish’s process ID.

  • process-exit event handlers now receive the same value as $status in all cases, instead of receiving -1 when the exit was due to a signal.

  • process-exit event handlers for PID 0 also received JOB_EXIT events; this has been fixed.

  • job-exit event handlers may now be created with any of the PIDs from the job. The handler is passed the last PID in the job as its second argument, instead of the process group.

  • Trying to set an empty variable name with set no longer works (these variables could not be used in expansions anyway).

  • fish_add_path handles an undefined PATH environment variable correctly (#8082).

Interactive improvements

  • Commands entered before the previous command finishes will now be properly syntax highlighted.

  • fish now automatically creates config.fish and the configuration directories in $XDG_CONFIG_HOME/fish (by default ~/.config/fish) if they do not already exist (#7402).

  • $SHLVL is no longer incremented in non-interactive shells. This means it won’t be set to values larger than 1 just because your environment happens to run some scripts in $SHELL in its startup path (#7864).

  • fish no longer rings the bell when flashing the command line. The flashing should already be enough notification and the bell can be annoying (#7875).

  • fish --help is more helpful if the documentation isn’t installed (#7824).

  • funced won’t include an entry on where a function is defined, thanks to the new functions --no-details option (#7879).

  • A new variable, fish_killring, containing entries from the killring, is now available (#7445).

  • fish --private prints a note on private mode on startup even if $fish_greeting is an empty list (#7974).

  • fish no longer attempts to lock history or universal variable files on remote filesystems, including NFS and Samba mounts. In rare cases, updates to these files may be dropped if separate fish instances modify them simultaneously. (#7968).

  • wait and on-process-exit work correctly with jobs that have already exited (#7210).

  • __fish_print_help (used for --help output for fish’s builtins) now respects the LESS environment variable, and if not set, uses better default pager settings (#7997).

  • Errors from alias are now printed to standard error, matching other builtins and functions (#7925).

  • ls output is colorized on OpenBSD if colorls utility is installed (#8035)

  • The default pager color looks better in terminals with light backgrounds (#3412).

  • Further robustness improvements to the bash history import (#7874).

  • fish now tries to find a Unicode-aware locale for encoding (LC_CTYPE) if started without any locale information, improving the display of emoji and other non-ASCII text on misconfigured systems (#8031). To allow a C locale, set the variable fish_allow_singlebyte_locale to 1.

  • The Web-based configuration and documentation now feature a dark mode if the browser requests it (#8043).

  • Color variables can now also be given like --background red and -b red, not just --background=red (#8053).

  • exit run within fish_prompt now exits properly (#8033).

  • When attempting to execute the unsupported POSIX-style brace command group ({ ... }) fish will suggest its equivalent begin; ...; end commands (#6415).

New or improved bindings

  • Pasting in Vi mode puts text in the right place in normal mode (#7847).

  • Vi mode’s u is bound to undo instead of history-search-backward, following GNU readline’s behavior. Similarly, ctrl-r is bound to redo instead of history-search-backward, following Vim (#7908).

  • s in Vi visual mode now does the same thing as c (#8039).

  • The binding for ",*,y now uses fish_clipboard_copy, allowing it to support more than just xsel.

  • The ctrl-space binding can be correctly customised (#7922).

  • exit works correctly in bindings (#7967).

  • The f1 binding, which opens the manual page for the current command, now works around a bug in certain less versions that fail to clear the screen (#7863).

  • The binding for alt-s now toggles whether sudo is prepended, even when it took the commandline from history instead of only adding it.

  • The new functions fish_commandline_prepend and fish_commandline_append allow toggling the presence of a prefix/suffix on the current commandline. (#7905).

  • backward-kill-path-component ctrl-w) no longer erases parts of two tokens when the cursor is positioned immediately after /. (#6258).

Improved prompts

  • The default Vi mode prompt now uses foreground instead of background colors, making it less obtrusive (#7880).

  • Performance of the “informative” git prompt is improved somewhat (#7871). This is still slower than the non-informative version by its very nature. In particular it is IO-bound, so it will be very slow on slow disks or network mounts.

  • The sample prompts were updated. Some duplicated prompts, like the various classic variants, or less useful ones, like the “justadollar” prompt were removed, some prompts were cleaned up, and in some cases renamed. A new “simple” and “disco” prompt were added (#7884, #7897, #7930). The new prompts will only take effect when selected and existing installed prompts will remain unchanged.

  • A new prompt_login helper function to describe the kind of “login” (user, host and chroot status) for use in prompts. This replaces the old “debian chroot” prompt and has been added to the default and terlar prompts (#7932).

  • The Web-based configuration’s prompt picker now shows and installs right prompts (#7930).

  • The git prompt now has the same symbol order in normal and “informative” mode, and it’s customizable via $__fish_git_prompt_status_order (#7926).

Completions

  • Added completions for:

  • Improvements to plenty of completions!

  • Commands that wrap cd (using complete --wraps cd) get the same completions as cd (#4693).

  • The --force-files option to complete works for bare arguments, not just options (#7920).

  • Completion descriptions for functions don’t include the function definition, making them more concise (#7911).

  • The kill completions no longer error on MSYS2 (#8046).

  • Completion scripts are now loaded when calling a command via a relative path (like ./git) (#6001, #7992).

  • When there are multiple completion candidates, fish inserts their shared prefix. This prefix was computed in a case-insensitive way, resulting in wrong case in the completion pager. This was fixed by only inserting prefixes with matching case (#7744).

Improved terminal support

  • fish no longer tries to detect a missing new line during startup, preventing an erroneous ⏎ from appearing if the terminal is resized at the wrong time, which can happen in tiling window managers (#7893).

  • fish behaves better when it disagrees with the terminal on the width of characters. In particular, staircase effects with right prompts should be gone in most cases (#8011).

  • If the prompt takes up the entire line, the last character should no longer be chopped off in certain terminals (#8002).

  • fish’s reflow handling has been disabled by default for kitty (#7961).

  • The default prompt no longer produces errors when used with a dumb terminal (#7904).

  • Terminal size variables are updated for window size change signal handlers (SIGWINCH).

  • Pasting within a multi-line command using a terminal that supports bracketed paste works correctly, instead of producing an error (#7782).

  • set_color produces an error when used with invalid arguments, rather than empty output which interacts badly with Cartesian product expansion.

For distributors

  • fish runs correctly on platforms without the O_CLOEXEC flag for open(2) (#8023).


fish 3.2.2 (released April 7, 2021)

This release of fish fixes a number of additional issues identified in the fish 3.2 series:

  • The command-not-found handler used suggestions from pacman on Arch Linux, but this caused major slowdowns on some systems and has been disabled (#7841).

  • fish will no longer hang on exit if another process is in the foreground on macOS (#7901).

  • Certain programs (such as lazygit) could create situations where fish would not receive keystrokes correctly, but it is now more robust in these situations (#7853).

  • Arguments longer than 1024 characters no longer trigger excessive CPU usage on macOS (#7837).

  • fish builds correctly on macOS when using new versions of Xcode (#7838).

  • Completions for aura (#7865) and tshark (#7858) should no longer produce errors.

  • Background jobs no longer interfere with syntax highlighting (a regression introduced in fish 3.2.1, #7842).

If you are upgrading from version 3.1.2 or before, please also review the release notes for 3.2.1 and 3.2.0 (included below).


fish 3.2.1 (released March 18, 2021)

This release of fish fixes the following problems identified in fish 3.2.0:

  • Commands in key bindings are run with fish’s internal terminal modes, instead of the terminal modes typically used for commands. This fixes a bug introduced in 3.2.0, where text would unexpectedly appear on the terminal, especially when pasting (#7770).

  • Prompts which use the internal __fish_print_pipestatus function will display correctly rather than carrying certain modifiers (such as bold) further than intended (#7771).

  • Redirections to internal file descriptors is allowed again, reversing the changes in 3.2.0. This fixes a problem with Midnight Commander (#7769).

  • Universal variables should be fully reliable regardless of operating system again (#7774).

  • fish_git_prompt no longer causes screen flickering in certain terminals (#7775).

  • fish_add_path manipulates the fish_user_paths variable correctly when moving multiple paths (#7776).

  • Pasting with a multi-line command no longer causes a __fish_tokenizer_state error (#7782).

  • psub inside event handlers cleans up temporary files properly (#7792).

  • Event handlers declared with --on-job-exit $fish_pid no longer run constantly (#7721), although these functions should use --on-event fish_exit instead.

  • Changing terminal modes inside config.fish works (#7783).

  • set_color --print-colors no longer prints all colors in bold (#7805)

  • Completing commands starting with a - no longer prints an error (#7809).

  • Running fish_command_not_found directly no longer produces an error on macOS or other OSes which do not have a handler available (#7777).

  • The new type builtin now has the (deprecated) --quiet long form of -q (#7766).

It also includes some small enhancements:

  • help and fish_config work correctly when fish is running in a Chrome OS Crostini Linux VM (#7789).

  • The history file can be made a symbolic link without it being overwritten (#7754), matching a similar improvement for the universal variable file in 3.2.0.

  • An unhelpful error (“access: No error”), seen on Cygwin, is no longer produced (#7785).

  • Improvements to the rsync completions (#7763), some completion descriptions (#7788), and completions that use IP address (#7787).

  • Improvements to the appearance of fish_config (#7811).

If you are upgrading from version 3.1.2 or before, please also review the release notes for 3.2.0 (included below).


fish 3.2.0 (released March 1, 2021)

Notable improvements and fixes

  • Undo and redo support for the command-line editor and pager search (#1367). By default, undo is bound to Control+Z, and redo to Alt+/.

  • Builtins can now output before all data is read. For example, string replace no longer has to read all of stdin before it can begin to output. This makes it usable also for pipes where the previous command hasn’t finished yet, like:

    # Show all dmesg lines related to "usb"
    dmesg -w | string match '*usb*'
    
  • Prompts will now be truncated instead of replaced with "> " if they are wider than the terminal (#904). For example:

    ~/dev/build/fish-shell-git/src/fish-shell/build (makepkg)>
    

    will turn into:

    …h-shell/build (makepkg)>
    

    It is still possible to react to the COLUMNS variable inside the prompt to implement smarter behavior.

  • fish completes ambiguous completions after pressing tab even when they have a common prefix, without the user having to press tab again (#6924).

  • fish is less aggressive about resetting terminal modes, such as flow control, after every command. Although flow control remains off by default, enterprising users can now enable it with stty (#2315, #7704).

  • A new “fish_add_path” helper function to add paths to $PATH without producing duplicates, to be used interactively or in config.fish (#6960, #7028). For example:

    fish_add_path /opt/mycoolthing/bin
    

    will add /opt/mycoolthing/bin to the beginning of $fish_user_path without creating duplicates, so it can be called safely from config.fish or interactively, and the path will just be there, once.

  • Better errors with “test” (#6030):

    > test 1 = 2 and echo true or false
    test: Expected a combining operator like '-a' at index 4
    1 = 2 and echo true or echo false
          ^
    

    This includes numbering the index from 1 instead of 0, like fish lists.

  • A new theme for the documentation and Web-based configuration (#6500, #7371, #7523), matching the design on fishshell.com.

  • fish --no-execute will no longer complain about unknown commands or non-matching wildcards, as these could be defined differently at runtime (especially for functions). This makes it usable as a static syntax checker (#977).

  • string match --regex now integrates named PCRE2 capture groups as fish variables, allowing variables to be set directly from string match (#7459). To support this functionality, string is now a reserved word and can no longer be wrapped in a function.

  • Globs and other expansions are limited to 512,288 results (#7226). Because operating systems limit the number of arguments to commands, larger values are unlikely to work anyway, and this helps to avoid hangs.

  • A new “fish for bash users” documentation page gives a quick overview of the scripting differences between bash and fish (#2382), and the completion tutorial has also been moved out into its own document (#6709).

Syntax changes and new commands

  • Range limits in index range expansions like $x[$start..$end] may be omitted: $start and $end default to 1 and -1 (the last item) respectively (#6574):

    echo $var[1..]
    echo $var[..-1]
    echo $var[..]
    

    All print the full list $var.

  • When globbing, a segment which is exactly ** may now match zero directories. For example **/foo may match foo in the current directory (#7222).

Scripting improvements

  • The type, _ (gettext), . (source) and : (no-op) functions are now implemented builtins for performance purposes (#7342, #7036, #6854).

  • set and backgrounded jobs no longer overwrite $pipestatus (#6820), improving its use in command substitutions (#6998).

  • Computed (“electric”) variables such as status are now only global in scope, so set -Uq status returns false (#7032).

  • The output for set --show has been shortened, only mentioning the scopes in which a variable exists (#6944). In addition, it now shows if a variable is a path variable.

  • A new variable, fish_kill_signal, is set to the signal that terminated the last foreground job, or 0 if the job exited normally (#6824, #6822).

  • A new subcommand, string pad, allows extending strings to a given width (#7340, #7102).

  • string sub has a new --end option to specify the end index of a substring (#6765, #5974).

  • string split has a new --fields option to specify fields to output, similar to cut -f (#6770).

  • string trim now also trims vertical tabs by default (#6795).

  • string replace no longer prints an error if a capturing group wasn’t matched, instead treating it as empty (#7343).

  • string subcommands now quit early when used with --quiet (#7495).

  • string repeat now handles multiple arguments, repeating each one (#5988).

  • printf no longer prints an error if not given an argument (not even a format string).

  • The true and false builtins ignore any arguments, like other shells (#7030).

  • fish_indent now removes unnecessary quotes in simple cases (#6722) and gained a --check option to just check if a file is indented correctly (#7251).

  • fish_indent indents continuation lines that follow a line ending in a backslash, |, && or ||.

  • pushd only adds a directory to the stack if changing to it was successful (#6947).

  • A new fish_job_summary function is called whenever a background job stops or ends, or any job terminates from a signal (#6959, #2727, #4319). The default behaviour can now be customized by redefining it.

  • status gained new dirname and basename convenience subcommands to get just the directory to the running script or the name of it, to simplify common tasks such as running (dirname (status filename)) (#7076, #1818).

  • Broken pipelines are now handled more smoothly; in particular, bad redirection mid-pipeline results in the job continuing to run but with the broken file descriptor replaced with a closed file descriptor. This allows better error recovery and is more in line with other shells’ behaviour (#7038).

  • jobs --quiet PID no longer prints “no suitable job” if the job for PID does not exist (eg because it has finished) (#6809, #6812).

  • jobs now shows continued child processes correctly (#6818)

  • disown should no longer create zombie processes when job control is off, such as in config.fish (#7183).

  • command, jobs and type builtins support --query as the long form of -q, matching other builtins. The long form --quiet is deprecated (#7276).

  • argparse no longer requires a short flag letter for long-only options (#7585) and only prints a backtrace with invalid options to argparse itself (#6703).

  • argparse now passes the validation variables (e.g. $_flag_value) as local-exported variables, avoiding the need for --no-scope-shadowing in validation functions.

  • complete takes the first argument as the name of the command if the --command/-c option is not used, so complete git is treated like complete --command git, and it can show the loaded completions for specific commands with complete COMMANDNAME (#7321).

  • set_color -b (without an argument) no longer prints an error message, matching other invalid invocations of this command (#7154).

  • exec no longer produces a syntax error when the command cannot be found (#6098).

  • set --erase and abbr --erase can now erase multiple things in one go, matching functions --erase (#7377).

  • abbr --erase no longer prints errors when used with no arguments or on an unset abbreviation (#7376, #7732).

  • test -t, for testing whether file descriptors are connected to a terminal, works for file descriptors 0, 1, and 2 (#4766). It can still return incorrect results in other cases (#1228).

  • Trying to execute scripts with Windows line endings (CRLF) produces a sensible error (#2783).

  • Trying to execute commands with arguments that exceed the operating system limit now produces a specific error (#6800).

  • An alias that delegates to a command with the same name no longer triggers an error about recursive completion (#7389).

  • math now has a --base option to output the result in hexadecimal or octal (#7496) and produces more specific error messages (#7508).

  • math learned bitwise functions bitand, bitor and bitxor, used like math "bitand(0xFE, 5)" (#7281).

  • math learned tau for those who don’t like typing “2 * pi”.

  • Failed redirections will now set $status (#7540).

  • fish sets exit status in a more consistent manner after errors, including invalid expansions like $foo[.

  • Using read --silent while fish is in private mode was adding these potentially-sensitive entries to the history; this has been fixed (#7230).

  • read can now read interactively from other files, and can be used to read from the terminal via read </dev/tty (if the operating system provides /dev/tty) (#7358).

  • A new fish_status_to_signal function for transforming exit statuses to signal names has been added (#7597, #7595).

  • The fallback realpath builtin supports the -s/--no-symlinks option, like GNU realpath (#7574).

  • functions and type now explain when a function was defined via source instead of just saying Defined in -.

  • Significant performance improvements when globbing, appending to variables or in math.

  • echo no longer interprets options at the beginning of an argument (eg echo "-n foo") (#7614).

  • fish now finds user configuration even if the HOME environment variable is not set (#7620).

  • fish no longer crashes when started from a Windows-style working directory (eg F:\path) (#7636).

  • fish -c now reads the remaining arguments into $argv (#2314).

  • The pwd command supports the long options --logical and --physical, matching other implementations (#6787).

  • fish --profile now only starts profiling after fish is ready to execute commands (all configuration is completed). There is a new --profile-startup option that only profiles the startup and configuration process (#7648).

  • Builtins return a maximum exit status of 255, rather than potentially overflowing. In particular, this affects exit, return, functions --query, and set --query (#7698, #7702).

  • It is no longer an error to run builtin with closed stdin. For example count <&- now prints 0, instead of failing.

  • Blocks, functions, and builtins no longer permit redirecting to file descriptors other than 0 (standard input), 1 (standard output) and 2 (standard error). For example, echo hello >&5 is now an error. This prevents corruption of internal state (#3303).

Interactive improvements

  • fish will now always attempt to become process group leader in interactive mode (#7060). This helps avoid hangs in certain circumstances, and allows tmux’s current directory introspection to work (#5699).

  • The interactive reader now allows ending a line in a logical operators (&& and ||) instead of complaining about a missing command. (This was already syntactically valid, but interactive sessions didn’t know about it yet).

  • The prompt is reprinted after a background job exits (#1018).

  • fish no longer inserts a space after a completion ending in ., , or - is accepted, improving completions for tools that provide dynamic completions (#6928).

  • If a filename is invalid when first pressing tab, but becomes valid, it will be completed properly on the next attempt (#6863).

  • help string match/replace/<subcommand> will show the help for string subcommands (#6786).

  • fish_key_reader sets the exit status to 0 when used with --help or --version (#6964).

  • fish_key_reader and fish_indent send output from --version to standard output, matching other fish binaries (#6964).

  • A new variable $status_generation is incremented only when the previous command produces an exit status (#6815). This can be used, for example, to check whether a failure status is a holdover due to a background job, or actually produced by the last run command.

  • fish_greeting is now a function that reads a variable of the same name, and defaults to setting it globally. This removes a universal variable by default and helps with updating the greeting. However, to disable the greeting it is now necessary to explicitly specify universal scope (set -U fish_greeting) or to disable it in config.fish (#7265).

  • Events are properly emitted after a job is cancelled (#2356).

  • fish_preexec and fish_postexec events are no longer triggered for empty commands (#4829, #7085).

  • Functions triggered by the fish_exit event are correctly run when the terminal is closed or the shell receives SIGHUP (#7014).

  • The fish_prompt event no longer fires when read is used. If you need a function to run any time read is invoked by a script, use the new fish_read event instead (#7039).

  • A new fish_posterror event is emitted when attempting to execute a command with syntax errors (#6880, #6816).

  • The debugging system has now fully switched from the old numbered level to the new named category system introduced in 3.1. A number of new debugging categories have been added, including config, path, reader and screen (#6511). See the output of fish --print-debug-categories for the full list.

  • The warning about read-only filesystems has been moved to a new “warning-path” debug category and can be disabled by setting a debug category of -warning-path (#6630):

    fish --debug=-warning-path
    
  • The enabled debug categories are now printed on shell startup (#7007).

  • The -o short option to fish, for --debug-output, works correctly instead of producing an invalid option error (#7254).

  • fish’s debugging can now also be enabled via FISH_DEBUG and FISH_DEBUG_OUTPUT environment variables. This helps with debugging when no commandline options can be passed, like when fish is called in a shebang (#7359).

  • Abbreviations are now expanded after all command terminators (eg ; or |), not just space, as in fish 2.7.1 and before (#6970), and after closing a command substitution (#6658).

  • The history file is now created with user-private permissions, matching other shells (#6926). The directory containing the history file was already private, so there should not have been any private data revealed.

  • The output of time is now properly aligned in all cases (#6726, #6714) and no longer depends on locale (#6757).

  • The command-not-found handling has been simplified. When it can’t find a command, fish now just executes a function called fish_command_not_found instead of firing an event, making it easier to replace and reason about. Previously-defined __fish_command_not_found_handler functions with an appropriate event listener will still work (#7293).

  • ctrl-c handling has been reimplemented in C++ and is therefore quicker (#5259), no longer occasionally prints an “unknown command” error (#7145) or overwrites multiline prompts (#3537).

  • ctrl-c no longer kills background jobs for which job control is disabled, matching POSIX semantics (#6828, #6861).

  • Autosuggestions work properly after ctrl-c cancels the current command line (#6937).

  • History search is now case-insensitive unless the search string contains an uppercase character (#7273).

  • fish_update_completions gained a new --keep option, which improves speed by skipping completions that already exist (#6775, #6796).

  • Aliases containing an embedded backslash appear properly in the output of alias (#6910).

  • open no longer hangs indefinitely on certain systems, as a bug in xdg-open has been worked around (#7215).

  • Long command lines no longer add a blank line after execution (#6826) and behave better with backspace (#6951).

  • functions -t works like the long option --handlers-type, as documented, instead of producing an error (#6985).

  • History search now flashes when it found no more results (#7362)

  • fish now creates the path in the environment variable XDG_RUNTIME_DIR if it does not exist, before using it for runtime data storage (#7335).

  • set_color --print-colors now also respects the bold, dim, underline, reverse, italic and background modifiers, to better show their effect (#7314).

  • The fish Web configuration tool (fish_config) shows prompts correctly on Termux for Android (#7298) and detects Windows Services for Linux 2 properly (#7027). It no longer shows the history variable as it may be too large (one can use the History tab instead). It also starts the browser in another thread, avoiding hangs in some circumstances, especially with Firefox’s Developer Edition (#7158). Finally, a bug in the Source Code Pro font may cause browsers to hang, so this font is no longer chosen by default (#7714).

  • funcsave gained a new --directory option to specify the location of the saved function (#7041).

  • help works properly on MSYS2 (#7113) and only uses cmd.exe if running on WSL (#6797).

  • Resuming a piped job by its number, like fg %1, works correctly (#7406). Resumed jobs show the correct title in the terminal emulator (#7444).

  • Commands run from key bindings now use the same TTY modes as normal commands (#7483).

  • Autosuggestions from history are now case-sensitive (#3978).

  • $status from completion scripts is no longer passed outside the completion, which keeps the status display in the prompt as the last command’s status (#7555).

  • Updated localisations for pt_BR (#7480).

  • fish_trace output now starts with -> (like fish --profile), making the depth more visible (#7538).

  • Resizing the terminal window no longer produces a corrupted prompt (#6532, #7404).

  • functions produces an error rather than crashing on certain invalid arguments (#7515).

  • A crash in completions with inline variable assignment (eg A= b) has been fixed (#7344).

  • fish_private_mode may now be changed dynamically using set (#7589), and history is kept in memory in private mode (but not stored permanently) (#7590).

  • Commands with leading spaces may be retrieved from history with up-arrow until a new command is run, matching zsh’s HIST_IGNORE_SPACE (#1383).

  • Importing bash history or reporting errors with recursive globs (**) no longer hangs (#7407, #7497).

  • bind now shows \x7f for the del key instead of a literal DEL character (#7631)

  • Paths containing variables or tilde expansion are only suggested when they are still valid (#7582).

  • Syntax highlighting can now color a command as invalid even if executed quickly (#5912).

  • Redirection targets are no longer highlighted as error if they contain variables which will likely be defined by the current commandline (#6654).

  • fish is now more resilient against broken terminal modes (#7133, #4873).

  • fish handles being in control of the TTY without owning its own process group better, avoiding some hangs in special configurations (#7388).

  • Keywords can now be colored differently by setting the fish_color_keyword variable (fish_color_command is used as a fallback) (#7678).

  • Just like fish_indent, the interactive reader will indent continuation lines that follow a line ending in a backslash, |, && or || (#7694).

  • Commands with a trailing escaped space are saved in history correctly (#7661).

  • fish_prompt no longer mangles Unicode characters in the private-use range U+F600-U+F700. (#7723).

  • The universal variable file, fish_variables, can be made a symbolic link without it being overwritten (#7466).

  • fish is now more resilient against mktemp failing (#7482).

New or improved bindings

  • As mentioned above, new special input functions undo (ctrl-_ or ctrl-z) and redo (alt-/) can be used to revert changes to the command line or the pager search field (#6570).

  • ctrl-z is now available for binding (#7152).

  • Additionally, using the cancel special input function (bound to escape by default) right after fish picked an unambiguous completion will undo that (#7433).

  • fish_clipboard_paste (ctrl-v) trims indentation from multiline commands, because fish already indents (#7662).

  • Vi mode bindings now support dh, dl, c0, cf, ct, cF, cT, ch, cl, y0, ci, ca, yi, ya, di, da, d;, d,, o, O and Control+left/right keys to navigate by word (#6648, #6755, #6769, #7442, #7516).

  • Vi mode bindings support ~ (tilde) to toggle the case of the selected character (#6908).

  • Functions up-or-search and down-or-search (up and down) can cross empty lines, and don’t activate search mode if the search fails, which makes them easier to use to move between lines in some situations.

  • If history search fails to find a match, the cursor is no longer moved. This is useful when accidentally starting a history search on a multi-line commandline.

  • The special input function beginning-of-history (pageup) now moves to the oldest search instead of the youngest - that’s end-of-history (pagedown).

  • A new special input function forward-single-char moves one character to the right, and if an autosuggestion is available, only take a single character from it (#7217, #4984).

  • Special input functions can now be joined with or as a modifier (adding to and), though only some commands set an exit status (#7217). This includes suppress-autosuggestion to reflect whether an autosuggestion was suppressed (#1419)

  • A new function __fish_preview_current_file, bound to alt-o, opens the current file at the cursor in a pager (#6838, #6855).

  • edit_command_buffer (alt-e and alt-v) passes the cursor position to the external editor if the editor is recognized (#6138, #6954).

  • __fish_prepend_sudo (alt-s) now toggles a sudo prefix (#7012) and avoids shifting the cursor (#6542).

  • __fish_prepend_sudo (alt-s) now uses the previous commandline if the current one is empty, to simplify rerunning the previous command with sudo (#7079).

  • __fish_toggle_comment_commandline (alt-#) now uncomments and presents the last comment from history if the commandline is empty (#7137).

  • __fish_whatis_current_token (alt-w) prints descriptions for functions and builtins (#7191, #2083).

  • The definition of “word” and “bigword” for movements was refined, fixing (eg) vi mode’s behavior with e on the second-to-last char, and bigword’s behavior with single-character words and non-blank non-graphical characters (#7353, #7354, #4025, #7328, #7325)

  • fish’s clipboard bindings now also support Windows Subsystem for Linux via PowerShell and clip.exe (#7455, #7458) and will properly copy newlines in multi-line commands.

  • Using the *-jump special input functions before typing anything else no longer crashes fish.

  • Completing variable overrides (foo=bar) could replace the entire thing with just the completion in some circumstances. This has been fixed (#7398).

Improved prompts

  • The default and example prompts print the correct exit status for commands prefixed with not (#6566).

  • git prompts include all untracked files in the repository, not just those in the current directory (#6086).

  • The git prompts correctly show stash states (#6876, #7136) and clean states (#7471).

  • The Mercurial prompt correctly shows untracked status (#6906), and by default only shows the branch for performance reasons. A new variable $fish_prompt_hg_show_informative_status can be set to enable more information.

  • The fish_vcs_prompt passes its arguments to the various VCS prompts that it calls (#7033).

  • The Subversion prompt was broken in a number of ways in 3.1.0 and has been restored (#6715, #7278).

  • A new helper function fish_is_root_user simplifies checking for superuser privilege (#7031, #7123).

  • New colorschemes - ayu Light, ayu Dark and ayu Mirage (#7596).

  • Bugs related to multiline prompts, including repainting (#5860) or navigating directory history (#3550) leading to graphical glitches have been fixed.

  • The nim prompt now handles vi mode better (#6802)

Improved terminal support

  • A new variable, fish_vi_force_cursor, can be set to force fish_vi_cursor to attempt changing the cursor shape in vi mode, regardless of terminal (#6968). The fish_vi_cursor option --force-iterm has been deprecated.

  • diff will now colourize output, if supported (#7308).

  • Autosuggestions appear when the cursor passes the right prompt (#6948) or wraps to the next line (#7213).

  • The cursor shape in Vi mode changes properly in Windows Terminal (#6999, #6478).

  • The spurious warning about terminal size in small terminals has been removed (#6980).

  • Dynamic titles are now enabled in Alacritty (#7073) and emacs’ vterm (#7122).

  • Current working directory updates are enabled in foot (#7099) and WezTerm (#7649).

  • The width computation for certain emoji agrees better with terminals (especially flags). (#7237).

  • Long command lines are wrapped in all cases, instead of sometimes being put on a new line (#5118).

  • The pager is properly rendered with long command lines selected (#2557).

  • Sessions with right prompts can be resized correctly in terminals that handle reflow, like GNOME Terminal (and other VTE-based terminals), upcoming Konsole releases and Alacritty. This detection can be overridden with the new fish_handle_reflow variable (#7491).

  • fish now sets terminal modes sooner, which stops output from appearing before the greeting and prompt are ready (#7489).

  • Better detection of new Konsole versions for true color support and cursor shape changing.

  • fish no longer attempts to modify the terminal size via TIOCSWINSZ, improving compatibility with Kitty (#6994).

Completions

  • Added completions for

    • 7z, 7za and 7zr (#7220)

    • alias (#7035)

    • alternatives (#7616)

    • apk (#7108)

    • asciidoctor (#7000)

    • avifdec and avifenc (#7674)

    • bluetoothctl (#7438)

    • cjxl and djxl (#7673)

    • cmark (#7000)

    • create_ap (#7096)

    • deno (#7138)

    • dhclient (#6684)

    • Postgres-related commands dropdb, createdb, pg_restore, pg_dump and pg_dumpall (#6620)

    • dotnet (#7558)

    • downgrade (#6751)

    • gapplication, gdbus, gio and gresource (#7300)

    • gh (#7112)

    • gitk

    • groups (#6889)

    • hashcat (#7746)

    • hikari (#7083)

    • icdiff (#7503)

    • imv (#6675)

    • john (#7746)

    • julia (#7468)

    • k3d (#7202)

    • ldapsearch (#7578)

    • lightdm and dm-tool (#7624)

    • losetup (#7621)

    • micro (#7339)

    • mpc (#7169)

    • Metasploit’s msfconsole, msfdb and msfvenom (#6930)

    • mtr (#7638)

    • mysql (#6819)

    • ncat, nc.openbsd, nc.traditional and nmap (#6873)

    • openssl (#6845)

    • prime-run (#7241)

    • ps2pdf{12,13,14,wr} (#6673)

    • pyenv (#6551)

    • rst2html, rst2html4, rst2html5, rst2latex, rst2man, rst2odt, rst2pseudoxml, rst2s5, rst2xetex, rst2xml and rstpep2html (#7019)

    • spago (#7381)

    • sphinx-apidoc, sphinx-autogen, sphinx-build and sphinx-quickstart (#7000)

    • strace (#6656)

    • systemd’s bootctl, coredumpctl, hostnamectl (#7428), homectl (#7435), networkctl (#7668) and userdbctl (#7667)

    • tcpdump (#6690)

    • tig

    • traceroute and tracepath (#6803)

    • windscribe (#6788)

    • wireshark, tshark, and dumpcap

    • xbps-* (#7239)

    • xxhsum, xxh32sum, xxh64sum and xxh128sum (#7103)

    • yadm (#7100)

    • zopfli and zopflipng (#6872)

  • Lots of improvements to completions, including:

    • git completions can complete the right and left parts of a commit range like from..to or left...right.

    • Completion scripts for custom Git subcommands like git-xyz are now loaded with Git completions. The completions can now be defined directly on the subcommand (using complete git-xyz), and completion for git xyz will work. (#7075, #7652, #4358)

    • make completions no longer second-guess make’s file detection, fixing target completion in some cases (#7535).

    • Command completions now correctly print the description even if the command was fully matched (like in ls<TAB>).

    • set completions no longer hide variables starting with __, they are sorted last instead.

  • Improvements to the manual page completion generator (#7086, #6879, #7187).

  • Significant performance improvements to completion of the available commands (#7153), especially on macOS Big Sur where there was a significant regression (#7365, #7511).

  • Suffix completion using __fish_complete_suffix uses the same fuzzy matching logic as normal file completion, and completes any file but sorts files with matching suffix first (#7040, #7547). Previously, it only completed files with matching suffix.

For distributors

  • fish has a new interactive test driver based on pexpect, removing the optional dependency on expect (and adding an optional dependency on pexpect) (#5451, #6825).

  • The CHANGELOG was moved to restructured text, allowing it to be included in the documentation (#7057).

  • fish handles ncurses installed in a non-standard prefix better (#6600, #7219), and uses variadic tparm on NetBSD curses (#6626).

  • The Web-based configuration tool no longer uses an obsolete Angular version (#7147).

  • The fish project has adopted the Contributor Covenant code of conduct (#7151).

Deprecations and removed features

  • The fish_color_match variable is no longer used. (Previously this controlled the color of matching quotes and parens when using read).

  • fish 3.2.0 will be the last release in which the redirection to standard error with the ^ character is enabled. The stderr-nocaret feature flag will be changed to “on” in future releases.

  • string is now a reserved word and cannot be used for function names (see above).

  • fish_vi_cursor’s option --force-iterm has been deprecated (see above).

  • command, jobs and type long-form option --quiet is deprecated in favor of --query (see above).

  • The fish_command_not_found event is no longer emitted, instead there is a function of that name. By default it will call a previously-defined __fish_command_not_found_handler. To emit the event manually use emit fish_command_not_found.

  • The fish_prompt event no longer fires when read is used. If you need a function to run any time read is invoked by a script, use the new fish_read event instead (#7039).

  • To disable the greeting message permanently it is no longer enough to just run set fish_greeting interactively as it is no longer implicitly a universal variable. Use set -U fish_greeting or disable it in config.fish with set -g fish_greeting.

  • The long-deprecated and non-functional -m/--read-mode options to read were removed in 3.1b1. Using the short form, or a never-implemented -B option, no longer crashes fish (#7659).

  • With the addition of new categories for debug options, the old numbered debugging levels have been removed.

For distributors and developers

  • fish source tarballs are now distributed using the XZ compression method (#5460).

  • The fish source tarball contains an example FreeDesktop entry and icon.

  • The CMake variable MAC_CODESIGN_ID can now be set to “off” to disable code-signing (#6952, #6792).

  • Building on on macOS earlier than 10.13.6 succeeds, instead of failing on code-signing (#6791).

  • The pkg-config file now uses variables to ensure paths used are portable across prefixes.

  • The default values for the extra_completionsdir, extra_functionsdir and extra_confdir options now use the installation prefix rather than /usr/local (#6778).

  • A new CMake variable FISH_USE_SYSTEM_PCRE2 controls whether fish builds with the system-installed PCRE2, or the version it bundles. By default it prefers the system library if available, unless Mac codesigning is enabled (#6952).