The help_sections.rs file was added to the tarball only as a quick hack.
There is a cyclic dependency between docs and fish:
"fish_indent" via "crates/build-man-pages" depends on "doc_src/".
So every "touch doc_src/foo.rst && ninja -Cbuild sphinx-docs"
re-builds fish.
In future "fish_indent" should not depend on "crates/build-man-pages".
Until then, a following commit wants to break this cyclic dependency
in a different way: we won't embed man pages (matching historical
behavior), which means that CMake builds won't need to run
sphinx-build.
But sphinx-build is also used for extracting help sections.
Also, the fix for #12082 will use help sections elsewhere in the code.
Prepare to remove the dependency on doc_src by committing the help
sections (we already do elsewhere).
When running fish inside SSH and local and remote OS differ, fish
uses key bindings for the remote OS, which is weird. Fix that by
asking the terminal for the OS name.
This should be available on foot and kitty soon, see
https://codeberg.org/dnkl/foot/pulls/2217#issuecomment-8249741
Ref: #11107
iTerm2 displays commands in other UI widgets such as in Command History
(View → Toolbelt → Command History). This needs prompt end marker
so the terminal can distinguish prompt from the command line.
Closes#11837
We've removed several terminal-specific workarounds but also added
some recently. Most of the non-Apple issues have been reported
upstream. Many of our workarounds were only meant to be temporary.
Some workarounds are unreliable and some can cause introduce other
problems.
Add a feature flag we can use later to let users turn off workarounds.
This doesn't disable anything yet, mostly because because despite being
off-by-default, this might surprise people who use "fish_features=all".
The fix would be "fish_features=all,no-omit-term-workarounds".
So we'd want a high degree of confidence.
For now we'll use this only with the next commit.
Closes#11819
Use \e\\ as sequence terminator for the first OSC 133 prompt start
marker. The intention is to find out if a terminal fails to parse
this. If needed, the user can turn it off by adding "no-mark-prompt"
to their feature flags; but the shell is still usable without this.
Part of #12032
Historically, Sphinx was required when building "standalone" builds,
else they would have no man pages.
This means that commit 0709e4be8b (Use standalone code paths by
default, 2025-10-26) broke man pages for users who build from a
tarball where non-standalone builds would use prebuilt docs.
Add a hack to use prebuilt docs again.
In future, we'll remove prebuilt docs, see #12052.
Also use the correct OSC number.
Note that this only works on few terminals (such as iTerm2). Not sure
if it's worth for us to have this feature but I guess multiple users
have requested it.
Unlike other shells, fish tries to make it easy to work with multiline
commands. Arguably, it's often better to use a full text editor but
the shell can feel more convenient.
Spreading long commands into multiple lines can improve readability,
especially when there is some semantic grouping (loops, pipelines,
command substitutions, quoted parts). Note that in Unix shell, every
quoted string can span multiple lines, like Python's triple quotes,
so the barrier to writing a multiline command is quite low.
However these commands are not autosuggested. From
1c4e5cadf2 (commitcomment-150853293)
> the reason we don't offer multi-line autosuggestion is that they
> can cause the command line to "jump" to make room for the second
> and third lines, if you're at the bottom of your terminal.
This jumping (as done by nushell for example) might be surprising,
especially since there is no limit on the height of a command.
Let's maybe avoid this jumping by rendering only however many lines
from the autosuggestion can fit on the screen without scrolling.
The truncation is hinted at by a single ellipsis ("…") after the
last suggested character, just like when a single-line autosuggestion
is truncated. (We might want to use something else in future.)
To implement this, query for the cursor position after every command,
so we know the y-position of the shell prompt within the terminal
window (whose height we already know).
Also, after we register a terminal window resize, query for the cursor
position before doing anything else (until we od #12004, only height
changes are relevant), to prevent this scenario:
1. move prompt to bottom of terminal
2. reduce terminal height
3. increase terminal height
4. type a command that triggers a multi-line autosuggestion
5. observe that it would fail to truncate properly
As a refresher: when we fail to receive a query response, we always
wait for 2 seconds, except if the initial query had also failed,
see b907bc775a (Use a low TTY query timeout only if first query
failed, 2025-09-25).
If the terminal does not support cursor position report (which is
unlikely), show at most 1 line worth of autosuggestion. Note that
either way, we don't skip multiline commands anymore. This might make
the behavior worse on such terminals, which are probably not important
enough. Alternatively, we could use no limit for such terminals,
that's probably the better fallback behavior. The only reason I didn't
do that yet is to stay a little bit closer to historical behavior.
Storing the prompt's position simplifies scrollback-push and the mouse
click handler, which no longer need to query. Move some associated
code to the screen module.
Technically we don't need to query for cursor position if the previous
command was empty. But for now we do, trading a potential optimization
for andother simplification.
Disable this feature in pexpect tests for now, since those are still
missing some terminal emulation features.
Not sure if this will be useful but the fact that we use very
few Unicode characters, suggests that we are insecure about
this. Having some kind of central and explicit listing might help
future decision-making. Obviously, completions and translations use
more characters, but those are not as central.
Some modern terminals allow creating tabs in a single window;
this functionality has a lot of overlap with what a window manager
already provides, so I'm not sure if it's a good idea. Regardless,
a lot of people still use terminal tabs (or even multiple levels of
tabs via tmux!), so let's add a fish-native way to set the tab title
independent of the window title.
Closes#2692
Commit eecc223 (Recognize and disable mouse-tracking CSI events,
2021-02-06) made fish disable mouse reporting whenever we receive a
mouse event. This was because at the time we didn't have a parser
for mouse inputs. We do now, so let's allow users to toggle mouse
support with
printf '\e[?1000h'
printf '\e[?1000l'
Currently the only mouse even we support is left click (to move cursor
in commandline, select pager items).
Part of #4918
See #12026
[ja: tweak patch and commit message]
No need to define "cmd-foo" anchors; use :doc:`foo <cmds/foo>`
instead. If we want "cmd-foo" but it should be tested.
See also 38b24c2325 (docs: Use :doc: role when linking to commands,
2022-09-23).
functions/help and completions/help duplicate a lot of information
from doc_src. Get this information from Sphinx.
Drop short section titles such as "help globbing" in favor of the
full HTML anchor:
help language#wildcards-globbing
I think the verbosity is no big deal because we have tab completion,
we're trading in conciseness for consistency and better searchability.
In future, we can add back shorter invocations like "help globbing"
(especially given that completion descriptions often already repeated
the anchor path), but it should be checked by CI.
Also
- Remove some unused Sphinx anchors
- Remove an obsoleted script.
- Test that completions are in sync with Sphinx sources.
(note that an alternative would be to check
in the generated help_sections.rs file, see
https://internals.rust-lang.org/t/how-fail-on-cargo-warning-warnings-from-build-rs/23590/5)
Here's a list of deleted msgids. Some of them were unused, for others
there was a better message (+ translation).
$variable $variable 变量
(command) command substitution (命令) 命令替换
< and > redirections < 和 > 重定向
Autoloading functions 自动加载函数
Background jobs 后台作业
Builtin commands 内建命令
Combining different expansions 合并不同的展开
Command substitution (SUBCOMMAND) 命令替换 (子命令)
Defining aliases 定义别名
Escaping characters 转义字符
Help on how to reuse previously entered commands 关于如何重复使用先前输入的命令的帮助
How lists combine 列表如何组合
Job control 作业控制
Local, global and universal scope 局域、全局和通用作用域
Other features 其他功能
Programmable prompt 可编程提示符
Shell variable and function names Shell 变量和函数名
Some common words 一些常用词
The status variable 状况变量
Variable scope for functions 函数的变量作用域
Vi mode commands Vi 模式命令
What set -x does `set -x` 做什么
Writing your own completions 自己写补全
ifs and elses if 和 else
var[x..y] slices var[x..y] 切片
{a,b} brace expansion {a,b} 大括号展开
~ expansion ~ 展开
Closes#11796
If a language is specified using only the language code, without a
region identifier, assume that the user prefers translations from any
variant of the language over the next fallback option. For example, when
a user sets `LANGUAGE=zh:pt`, assume that the user prefers both `zh_CN` and
`zh_TW` over the next fallback option. The precedence of the different
variants of a language will be arbitrary. In this example, with the
current set of relevant available catalogs (`pt_BR`, `zh_CN`, `zh_TW`),
the effective precedence will be either `zh_CN:zh_TW:pt_BR` or
`zh_TW:zh_CN:pt_BR`.
Users who want more control over the order can
specify variants to get the results they want.
For example:
- `LANGUAGE=zh_TW:zh:pt` will result in `zh_TW:zh_CN:pt_BR`.
- `LANGUAGE=zh_CN:pt:zh` will result in `zh_CN:pt_BR:zh_TW`.
- `LANGUAGE=zh_CN:pt` will result in `zh_CN:pt_BR`.
English is always used as the last fallback.
This approach (like the previous approach) differs from GNU gettext
semantics, which map region-less language codes to on specific "default"
variant of the language, without specifying how this default is chosen.
We want to avoid making such choices and believe it is better to utilize
translations from all language variants we have available when users do
not explicitly specify their preferred variant. This way, users have an
easier time discovering localization availability, and can be more
explicit in their preferences if they don't like the defaults.
If there are conflicts with gettext semantics, users can also set locale
variables without exporting them, so fish uses different values than its
child processes.
Closes#12011
When users update fish by replacing files, existing shells might
throw weird errors because internal functions in share/functions/
might have changed.
This is easy to remedy by restarting the shell,
but I guess it would be nice if old shells kept using old data.
This is somewhat at odds with lazy-loading.
But we can use the standalone mode. Turn that on by default.
Additionally, this could simplify packaging. Some packages incorrectly
put third party files into /usr/share/fish/completion/ when they ought
to use /usr/share/fish/vendor_completions.d/ for that. That packaging
mistake can make file conflicts randomly appearing when either fish
or foo ships a completion for foo. Once we actually stop installing
/usr/share/fish/completions, there will no longer be a conflict (for
better or worse, things will silently not work, unless packagers
notice that the directory doesn't actually exist anymore).
The only advantage of having /usr/share/fish/ on the file system is
discoverability. But getting the full source code is better anyway.
Note that we still install (redundant) $__fish_data_dir when using
CMake. This is to not unnecessarily break both
1. already running (old) shells as users upgrade to 4.2
2. plugins (as mentioned in an earlier commit),
We can stop installing $__fish_data_dir once we expect 99% of users
to upgrade from at least 4.2.
If we end up reverting this, we should try to get rid of the embed-data
knob in another way, but I'm not sure how.
Closes#11921
To-do:
- maybe make it a feature flag so users can turn it off without
recompiling with "set -Ua no-embed-data".
When building from a clean tag, set the date at the bottom of the
manpages to the tag creation date. This allows to "diff -r" the
extracted tarball to check that CI produces the same as any other
system.
Part of #11996
In future, we should ask "renovatebot" to update these version. I
don't have an opinion on whether to use "uv" or something else, but
I think we do want lockfiles, and I don't know of a natural way to
install Sphinx via Cargo.
No particular reason for this Python version.
Part of #11996
* since c8001b5023 (encoding: use UTF-8 everywhere, 2025-10-18)
we always use UTF-8, which simplifies docs.
* emphasize that we (as of an earlier commit) document only the locale
variables actually used by fish. We could change this in future,
as long as the docs make it obvious whether it's about fish or
external programs.
* make things a bit more concise
* delete a stale comment - missing encoding support is no longer a problem
We may have used LC_COLLATE in the past via libc functions but I
don't think we do today. In future, we could document the variables
not used by fish, but we should make it obvious what we're documenting.
Link to history, printf and "builtin _" which are the only(?) users
of LC_TIME, LC_NUMERIC and LC_MESSAGES respectively (besides the core
equivalent of "builtin _").
These are obsolete as of c8001b5023 (encoding: use UTF-8 everywhere,
2025-10-18). The only place where we still read the user's LC_CTYPE
is in libc::wcwidth(), but that's kind of a regression -- we should
always be using a UTF-8 LC_CTYPE if possible -- which will be fixed
by a following commit.
Now that the « chsh -s $(command -v) » approach should work both
in and outside fish, it seems like we should use that.
Non-macOS users probably shouldn't do this, but there's already a
big warning above this section.
Fixes#11931
Previously, if you called a function parameter 'argv', within the body
of the function, argv would be set to *all* the arguments to the
function, and not the one indicated by the parameter name.
The same behaviour happened if you inherited a variable named 'argv'.
Both behaviours were quite surprising, so this commit makes things more
obvious, although they could alternatively simply be made errors.
Part of #11780
This makes it so that printing a function definition will only use one
--argument-names group, instead of one for argument name.
For example, "function foo -a x y; ..." will print with "function foo
--argument-names x y" instead of "function foo --argument-names x
--argument-names y", which is very bizarre.
Moreover, the documentation no longer says that argument-names "Has to
be the last option.". This sentence appears to have been introduced in
error by pull #10524, since the ability to have options afterwards was
deliberately added by pull #6188.
Part of #11780
We don't care about any specific attributes but we do very much care
about the specific query and response format associated with VT100's
primary device attribute query. Use a proper noun to emphasize that
we want that one and no other.
Ref: https://github.com/fish-shell/fish-shell/pull/11833#discussion_r2385659040
I'm not aware of a lot of sensible use cases where users need to access
our files directly. The one example we know about is zoxide overriding
exactly our version of "function cd", ignoring any user-provided cd.
I think this is already hacky. But I guess it's here to stay.
I think we should not recommend this for external use, or at least
ask users to tell us what they are using this for.
Given that we expect these to be used mainly/only internally,
get-file/list-files are fine as names.
The other issue is that one has to be careful to always do
status list-files 2>/dev/null
to support non-embedded builds.
Closes#11555
A lot of terminals support CSI Ps S. Currently we only allow them
to use scrollback-up if they advertise it via XTGETTCAP. This seems
surprising; it's better to make visible in fish script whether this
is supposed to be working. The canonical place is in "bind ctrl-l"
output.
The downside here is that we need to expose something that's rarely
useful. But the namespace pollution is not so bad, and this gives
users a nice paper trail instead of having to look in the source code.
sphinx-build fails with
sphinx.errors.SphinxError: Builder name markdown not registered or available through entry point
Apparently this issue was hidden locally by caching, and not checked
in CI because of this error causing
tests/checks/sphinx-markdown-changelog.fish to be skipped.
sphinx-build 7.2.6
runner@runnervm3ublj:~/work/fish-shell/fish-shell$ python -c 'import sphinx_markdown_builder'
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/runner/.local/lib/python3.12/site-packages/sphinx_markdown_builder/__init__.py", line 6, in <module>
from sphinx.util.typing import ExtensionMetadata
ImportError: cannot import name 'ExtensionMetadata' from 'sphinx.util.typing' (/usr/lib/python3/dist-packages/sphinx/util/typing.py)
This reverts commit 7b495497d7.
While at it, fail the test earlier if something went wrong, because the
remaining check will likely also fail and confuse.
Commit 5e317497ef (Query terminal before reading config, 2025-05-17)
disabled the kitty keyboard protocol in "fish -c read". This seems
surprising, and it's not actually necessary that we query before
reading config; we only need query results before we read from
the TTY for the first time (which is about the time we call
__fish_config_interactive). Let's do that, reverting parts of
5e317497ef.
As is, building man pages or HTML docs while sphinx_markdown_builder
is installed, will result in unrelated warnings. Remove those by
removing it from the extensions config. Markdown building (only used
for changelog) seems to work without this just fine.
Currently, `__fish_git_prompt_char_upstream_diverged` can only be set to
a combination of `__fish_git_prompt_char_upstream_behind` and
`__fish_git_prompt_char_upstream_ahead`s plain-text options. Adding a
combination of the less-plain character options gives users more choice.
Closes#11817
Experience with OSC 133 and kitty keyboard protocol enabling sequences
has shown that a lot of users are still on incompatible terminals.
It's not always easy to fix those terminals straight away. There
are probably some more environments where primary device attribute
queries are not answered.
Add a feature flag (similar to keyboard-protocols and mark-prompt)
to allow users to turn this off.
When the terminal fails to respond to primary device attribute, we
already print an error pointing to "help terminal-compatibility".
Inside that document, inside the "primary device attribute" section,
point out this new feature flag.
(not sure if we should also include this in 4.1 but I guess better
safe than sorry)
So far, terminals that fail to parse OSC sequences are the only reason
for wanting to turn off OSC 133. Let's allow to work around it by
adding a feature flag (which is implied to be temporary).
To use it, run this once, and restart fish:
set -Ua fish_features no-mark-prompt
Tested with
fish -i | string escape | grep 133 &&
! fish_features=no-mark-prompt fish -i | string escape | grep 133
Closes#11749
Also #11609
(cherry picked from commit 6900b89c82)