Commit Graph

32 Commits

Author SHA1 Message Date
Johannes Altmanninger
1fe5497b5d Remove redundant saving of TTY flags
The logic added by 2dbaf10c36 (Also refresh TTY timestamps
after external commands from bindings, 2024-10-21) is obsoleted
by TtyHandoff.  That module is also responsible for calling
reader_save_screen_state after it writes to the TTY, so we don't
actually need to check if it wrote anything.
2025-12-14 15:37:46 +01:00
Johannes Altmanninger
2309c27a2d Replace ifdef with cfg! 2025-12-14 10:24:49 +01:00
xtqqczze
27852a6734 fix: clippy::ptr_as_ptr
https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr

Closes #12136
2025-12-11 17:46:58 +01:00
xtqqczze
831411ddd5 fix: clippy::ref_as_ptr
https://rust-lang.github.io/rust-clippy/master/index.html#ref_as_ptr

Part of #12136
2025-12-11 17:46:58 +01:00
xtqqczze
ec77c34ebe fix: clippy::borrow_as_ptr
https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr

Part of #12136
2025-12-11 17:46:58 +01:00
Daniel Rainer
75c005a4d4 lint: convert is_some+unwrap into if let
This fixes an `unnecessary_unwrap` lint shown by nightly Clippy.

Closes #12130
2025-12-10 16:15:41 +01:00
Asuka Minato
656b39a0b3 Also show case-insensitive prefix matches in completion pager
[ja: made some changes and added commit message]

Fixes #7944
Closes #11910
2025-12-05 16:12:34 +01:00
Johannes Altmanninger
4ffa06fb7e Fix section names in suggested "help" commands
Fixes 2cd60077e6 (help: get section titles from Sphinx, 2025-11-05)
Fixes #12082
2025-11-23 12:30:22 +01:00
Johannes Altmanninger
790beedbb0 Prefer terminal (client) OS for selecting native key bindings
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
2025-11-19 17:13:58 +01:00
Johannes Altmanninger
64cb4398c6 Longer timeout on invalid escape sequences
For historical reasons, fish does not implement the VT state
machine but uses a relatively low timeout when reading
escape sequences.  This might be causing issues like
https://github.com/fish-shell/fish-shell/issues/11841#issuecomment-3544505235
so let's cautiously increase the timeout.

Make it opt-in and print a noisy error when we time out, so we can
find affected terminals.
2025-11-19 17:13:58 +01:00
Johannes Altmanninger
9165251a0b Feature flag for eventually disabling terminal workarounds
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
2025-11-19 17:06:25 +01:00
Johannes Altmanninger
02a6afd2b0 Link terminal workarounds with comments
It's hard to get rid of these workarounds. Let's at least brand them.

Ref: #11819
2025-11-19 16:42:45 +01:00
Johannes Altmanninger
289057f981 reset_abandoning_line: actually clear line on first prompt
Frequently when I launch a new shell and type away, my input is
echoed in the terminal before fish gets a chance to set shell modes
(turn off ECHO and put the terminal into non-canonical mode).

This means that fish assumption about the cursor x=0 is wrong, which
causes the prompt (here '$ ') to be draw at the wrong place, making
it look like this:

	ececho hello

This seems to have been introduced in 4.1.0 in a0e687965e (Fix
unsaved screen modification, 2025-01-14). Not sure how it wasn't a
problem before.

Fix this by clearing to the beginning of the line after turning off
ECHO but before we draw anything to the screen.

This turns this comment in the patch context into a true statement:

> This means that `printf %s foo; fish` will overwrite the `foo`

Note that this currently applies per-reader, so builtin "read" will
also clear the line before doing anything.
We could potentially change this in future, if we both
1. query the cursor x before we output anything
2. refactor the screen module to properly deal with x>0 states.

But even if we did that, it wouldn't change the fact that we want
to force x=0 if the cursor has only been moved due to ECHO, so I'm
not sure.
2025-11-16 11:47:47 +01:00
Johannes Altmanninger
33bf808084 fish_tab_title: fix tab title accidentally including window title
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.
2025-11-09 13:08:47 +01:00
Johannes Altmanninger
a772470b76 Multi-line autosuggestions
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.
2025-11-08 21:18:25 +01:00
Johannes Altmanninger
77bdd4fbde reader: use unqualified enum variants in match statement
This reduces noise although the indentation is not great.
2025-11-08 21:18:25 +01:00
Johannes Altmanninger
3fdaa543ed reader: remove unused parameter 2025-11-08 21:18:25 +01:00
Johannes Altmanninger
336be1e36d termsize: better types
The u16 is implied by libc::winsize.
2025-11-08 21:18:25 +01:00
Johannes Altmanninger
382027663f termsize: try to simplify a little bit
Also add "safe_" prefix to functions we require to be
async-signal-safe.
2025-11-08 21:18:25 +01:00
Johannes Altmanninger
1d58b84637 mouse handling: fish's screen always starts at x=0
We already assume elsewhere that e.g. \r will return us to x=0
(fish coordinates).
2025-11-08 21:18:25 +01:00
Johannes Altmanninger
88ead18709 Move query-interrupt event-variant into query-result enum
I think the interruption event is grouped next to the check-exit one
because it used to be implemented as check exit but with a global flag
(I didn't check whether that applied to master).

Move it to the logical place.
2025-11-08 21:18:25 +01:00
Johannes Altmanninger
70058bdee2 reader: remove unused check
The readline state is never finished before the very first loop
iteration.  Move the check for rls.finished next to the one that
implements "read -n1" -- in future we might use the return value
for both.
2025-11-08 21:18:25 +01:00
Johannes Altmanninger
d6ed5f843e fish_tab_title to set terminal tab title independent of window title
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
2025-11-06 13:02:23 +01:00
ken
199475b6ca Stop disabling mouse tracking
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]
2025-11-06 13:02:23 +01:00
Johannes Altmanninger
60b50afefd Fix missing ICANON regression after read in noninteractive shell
Since commit 7e3fac561d (Query terminal only just before reading
from it, 2025-09-25),

	fish -c 'read; cat'

fails to turn ICANON back on for cat.

Even before that commit, I don't know how this ever worked.  Before or
after, we'd call tcsetattr() only to set our shell modes, not the
ones for external commands (term_donate)

I also don't think there's a good reason why we set modes twice
(between term_donate () and old_modes), but I'll make a minimal (=
safer) change for now until I understand this.

The only change from 7e3fac561d was that instead of doing things in
this order:

	terminal_init()
		set_shell_modes
	read
		reader_push()
		reader_readline()
			save & restore old_modes
	cat

we now do

	read
		reader_push()
			terminal_init()
				set_shell_modes()
		reader_readline()
			save & restore old_modes
	cat

So we call set_shell_modes() just before saving modes,
which obviously makes us save the wrong thing.
Again, not sure how that wasn't a problem before.

Fix it by saving modes before calling terminal_init().

Fixes #12024
2025-11-06 13:02:23 +01:00
Johannes Altmanninger
0b6afbd17b Prefer commandline case over same-length autosuggestion
If I run

	history append 'echo -X'

and type "echo -x", it renders as "echo -X".

This is not wrong but can be pretty confusing, (since the
autosuggestion is the same length as the command line).

Let's favor the case typed by the user in this specific case I guess.
Should add a full solution later.

Part of #11452
2025-11-04 14:13:22 +01:00
Peter Ammon
1846d7fd7e Merge branch 'cleanup-thread-pool'
This merges changes that make thread pools instanced. We no longer have
a single global thread pool. This results in significant simplifications
especially in the reader (no more "canary").
2025-11-01 11:46:25 -07:00
Peter Ammon
1a1da0649a Clean up Debounces and remove the global thread pool
Prior to this commit, there was a singleton set of "debouncers" used to run
code in the background because it might perform blocking I/O - for example,
for syntax highlighting or computing autosuggestions. The complexity arose
because we might push or pop a reader. For example, a long-blocking, stale
autosuggestion thread might suddenly complete, but the reader it was for
(e.g. for `builtin_read`) is now popped. This was the basis for complex
logic like the "canary" to detect a dead Reader.

Fix this by making the Debouncers per-reader. This removes some globals and
complicated logic; it also makes this case trivial: a long-running thread
that finishes after the Reader is popped, will just produce a Result and
then go away, with nothing reading out that Result.

This also simplifies tests because there's no longer a global thread pool
to worry about. Furthermore we can remove other gross hacks like ForceSend.
2025-10-31 19:40:13 -07:00
Peter Ammon
69ccc9be18 Factor Debounce out of threads.rs
Preparation to clean this up.
2025-10-31 19:40:12 -07:00
Peter Ammon
2f5260aabd Make a reader-specific thread pool
This concerns threads spawned by the reader for tasks like syntax
highlighting that may need to perform I/O.

These are different from other threads typically because they need to
"report back" and have their results handled.

Create a dedicated module where this logic can live.
This also eliminates the "global" thread pool.
2025-10-31 19:40:10 -07:00
Peter Ammon
a868be6ba4 Factor fill_history_pager_complete into its own function 2025-10-31 19:40:06 -07:00
Peter Ammon
8822ba3035 Migrate reader into a submodule.
Support future breaking up of this big module. No functional change.
2025-10-31 19:40:05 -07:00