Commit Graph

30 Commits

Author SHA1 Message Date
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
b1e681030b Add OSC 133 prompt end marker
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
2025-11-19 17:13:58 +01:00
Johannes Altmanninger
012007ce7b Test balloon for ST OSC terminator
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
2025-11-19 16:40:57 +01:00
Johannes Altmanninger
ac94bc774b Update changelog 2025-11-10 07:28:35 +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
a8b7d89ba5 doc terminal-compatibility: document Unicode characters used in output
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.
2025-11-08 21:18:25 +01:00
Fabian Boehm
8c69e62a78 terminal-compatibility: Remove "Origin" column
This isn't very useful, makes the table very wide and invites discussion on who exactly invented
what.

Let's leave that to the historians.

Fixes #12031
2025-11-08 14:54:57 +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
a767739c06 doc terminal-compatibility: fix inconsistent parameter wildcard notation 2025-11-03 09:17:00 +01:00
Johannes Altmanninger
aec459c795 Upgrade and pin Sphinx version
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
2025-11-01 12:58:13 +01:00
Johannes Altmanninger
0da12a6b55 Primary Device Attribute is a proper noun
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
2025-09-30 12:06:08 +02:00
Johannes Altmanninger
b964072c11 Move scrollback-push feature detection to fish script
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.
2025-09-27 14:22:18 +02:00
Johannes Altmanninger
abae6157d9 Changelog: reduce verbosity a bit, add some more 2025-09-27 14:22:18 +02:00
Johannes Altmanninger
08ad5c26ea Give scroll-forward a less confusing name
ECMA-48 calls CSI S "scroll up", so use something like that but try
to avoid ambiguity.
2025-09-26 12:52:28 +02:00
Johannes Altmanninger
f821d6dd7f Feature flag for turning off TTY querying
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.
2025-09-24 15:51:32 +02:00
Johannes Altmanninger
bbd7205de1 Document GNU screen incompatibily & workarounds
The problem described in 829709c9c4 (Replace synchronized update
workaround, 2025-04-25) doesn't seem too bad; let's document the
workaround.

We could probably also remove our $STY-based workaround.  I'm not
yet sure how many problems that one will cause.

Closes #11437
2025-09-24 15:51:32 +02:00
Johannes Altmanninger
c31e769f7d Use XTVERSION for terminal-specific workarounds
As mentioned in earlier commit
("Query terminal before reading config").

Closes #11812
2025-09-24 15:51:32 +02:00
Johannes Altmanninger
06ede39ec9 Degrade gracefully when failing to receive cursor position report
Follow up the cursor position report query with a primary device
attribute one.  When that one arrives, any cursor position response
must have arrived too. This allows us to prevent a hang on terminals
that only support primary device attribute.
2025-09-24 15:51:32 +02:00
Johannes Altmanninger
064a45635c Document inter-dependencies between optional terminal features
- document that we currently require "cursor position report" if
  either of both click_events or XTGETTCAP+indn is implemented.
  One of the following patches will remove this requirement.
- document properly that scrollback-push currently only works
  when XTGETTCAP+indn is implemented. There are still a few terminals
  that don't support SCROLL UP, for example the Linux Console,
  and there is no better way to find out if it's supported.
2025-09-24 15:51:32 +02:00
Johannes Altmanninger
156fa8081c Underline styles for double/dotted/dashed
My phone uses dotted underline to indicate errors; that seems nice, a bit
less aggressive than curly.  Unfortunately dotted underlines are not as well
supported in terminal emulators; sometimes they are barely visible.  So it's
unlikely that we want to use --underline=dotted for an important theme.
Add double and dashed too I guess, even though I don't have a concrete
use case..
2025-05-11 22:18:06 +02:00
Johannes Altmanninger
1122bba3c1 Fix typo in docs 2025-04-29 13:51:18 +02:00
Johannes Altmanninger
829709c9c4 Replace synchronized update workaround
Old versions of ConHost and Putty can't parse DCS sequences.
For this reason, we briefly switch to the alternate screen buffer while sending
DCS-format (e.g. XTGETTCAP) queries. For extra paranoia, we wrapped this
procedure in a synchronized update. This doesn't seem to be needed; neither
ConHost nor Putty show glitches when the synchronized update is omitted.

As of today, every terminal that implements XTGETTCAP also implements
synchronized updates but that might change.

Let's remove it, to reduce surprise for users and terminal developers.

As a bonus, this also fixes a glitch on Terminal.app which fails to parse
the synchronized-update query (`printf '\x1b[?2026$p'`) and echoes the "p"
(bug report ID FB17141059). Else we could work around this with another
alternate screen buffer.

Unfortunately, this change surfaces two issues with GNU screen.  For one,
they don't allow apps to use the alternate screen features (the user may
allow it with "altscreen on"). Second, screen unconditionally echoes
the payload of DCS commands.  A possible fix has been suggested at
https://lists.gnu.org/archive/html/screen-devel/2025-04/msg00010.html

I think this combination of behaviors is unique among terminals.  I'm sure
there are more terminals that don't parse DCS commands yet, but I think almost
all terminals implement alternate screen buffer. Probably only terminal
multiplexers are prone to this issue. AFAICT very few multiplexers exists,
so we can work around those until they are fixed.

Disable XTGETTCAP queries for GNU screen specifically.  Unfortunately screen
does not implement XTVERSION, so I don't know how to reliably identify
it. Instead, check STY and some commonly-used values TERM values.
This has false negatives in some edge cases.
But the worst thing that happens is that "+q696e646e" will be echoed once
at startup, which is easy to ignore, or work around with something like

	function workaround --on-event fish_prompt
		commandline -f repaint
		functions --erase workaround
	end

which I don't think we should apply by default, because it can mask other
issues.

We should give screen more time to respond. I guess I'll open an issue so
we don't forget. In doubt, we can always go back to the previous approach
(but implement it in fish script).

Alternative workaround: instead of the alternative screen buffer, we could
try something like clr_eol/clr_bol to erase the spuriously echoed text. I
tried to do this in various ways but (surprisingly) failed.
2025-04-29 13:31:13 +02:00
Johannes Altmanninger
7bdb561d24 builtin set_color: stop resetting unrelated attributes on --background=normal
"set_color --background=normal" resets all attributes.  I don't expect anyone
relied on this behavior. Let's remove it, to reduce surprise.  This also
improves consistency with "set_color --underline-color=normal".

As suggested in
https://github.com/fish-shell/fish-shell/issues/11417#issuecomment-2825023522

For backwards compatibility reasons, "set_color normal" still resets
everything though.  In future we could make "set_color --foreground=normal"
reset only foreground.

Closes #11418
2025-04-29 10:14:32 +02:00
Johannes Altmanninger
ce631fd2fb Colored underlines in set_color and fish_color_*
Add a new underline-color option to set_color (instead of adding an optional
color argument to --underline); this allows to set the underline color
independently of underline style (line, curly, etc.). I don't think this
flexibility is very important but this approach is probably the least hacky.

Note that there are two variants:
1. \e[58:5:1m
2. \e[58;5;1m

Variant 1 breaks:
breakage from colon-variant for colored underlines
- cool-retro-term makes text blink
- GNU screen (goes into bold mode)
- terminology (goes into bold mode)

Variant 2 would break:
- mintty (Cygwin terminal) -- it enables bold font instead.
- Windows Terminal (where it paints the foreground yellow)
- JetBrains terminals echo the colons instead of consuming them
- putty
- GNU screen (goes into bold mode)
- st
- urxvt
- xterm
- etc.

So choose variant 1.

Closes #11388
Closes #7619
2025-04-21 18:38:11 +02:00
Johannes Altmanninger
cc9849c279 Curly underlines in set_color and fish_color_*
set_color --underline=curly outputs \e[4:3m which breaks the following
terminals:
- Terminal.app interprets it as yellow background
- abduco and dvtm interpret it as green foreground
- JetBrains terminals interprets it as yellow background
- urxvt interprets it as yellow background

terminals that interpret curly as single underline:
- tmux [1]
- emacs ansi-term [2]
- emacs vterm
- GNU screen (also wrongly turns on italic mode)
- terminology (also wrongly turns on italic mode)
- Vim's :terminal

[1]: https://github.com/orgs/tmux/discussions/4477
[2]: https://lists.gnu.org/archive/html/bug-gnu-emacs/2025-04/msg01093.html

Closes #10957
2025-04-21 18:12:42 +02:00
Johannes Altmanninger
6cf96c5950 sgr0 *does* reset both foreground and background color
We have a a workaround with a comment saying

> We don't know if exit_attribute_mode resets colors, so we set it to
> something known.

I'm pretty sure fish (and other software) makes this assumption.
I'd be very surprised if a relevant terminal behaves differently.
Let's remove our attempt to work around around this.

While at it, extract a function to be used in two other places
(but don't change their behavior yet).
2025-04-21 17:37:36 +02:00
Johannes Altmanninger
afa517d907 doc/terminal-compatibility: document cursor shaping sequence
While at it, also document the command to reset the shape to the default,
which we should probably use.  See foot commit 49034bb7 (csi: let CSI 0 q mean
"switch to user configured cursor style", 2019-07-22).

As of today, the XTerm documentation is a not clear on this; in
XTerm itself, CSI 0 q may actually change the cursor because they have an
additional default cursor is configured differently..
2025-04-16 11:24:33 +02:00
Johannes Altmanninger
17b4b39c8b Stop reading terminfo database
Our use of the terminfo database in /usr/share/terminfo/$TERM is both
1. a way for users to configure app behavior in their terminal (by
   setting TERM, copying around and modifying terminfo files)
2. a way for terminal emulator developers to advertise support for
   backwards-incompatible features that are not otherwise easily observable.

To 1: this is not ideal (it's very easy to break things). There's not many
things that realistically need configuration; let's use shell variables
instead.

To 2: in practice, feature-probing via terminfo is often wrong.  There's not
many backwards-incompatible features that need this; for the ones that do
we can still use terminfo capabilities but query the terminal via XTGETTCAP
directly, skipping the file (which may not exist on the same system as
the terminal).

---

Get rid of terminfo. If anyone finds a $TERM where we need different behavior,
we can hardcode that into fish.

* Allow to override this with `fish_features=no-ignore-terminfo fish`
  Not sure if we should document this, since it's supposed to be removed soon,
  and if someone needs this (which we don't expect), we'd like to know.
  * This is supported on a best-effort basis; it doesn't match the previous
    behavior exactly.  For simplicity of implementation, it will not change
    the fact that we now:
    * use parm_left_cursor (CSI Ps D) instead of  cursor_left (CSI D) if
      terminfo claims the former is supported
    * no longer support eat_newline_glitch, which seems no longer present
      on today's ConEmu and ConHost
* Tested as described in https://github.com/fish-shell/fish-shell/pull/11345#discussion_r2030121580
* add `man fish-terminal-compatibility` to state our assumptions.
  This could help terminal emulator developers.
* assume `parm_up_cursor` is supported if the terminal supports XTGETTCAP
* Extract all control sequences to src/terminal_command.rs.
* Remove the "\x1b(B" prefix from EXIT_ATTRIBUTE_MODE. I doubt it's really
  needed.
* assume it's generally okay to output 256 colors
  Things have improved since commit 3669805627 (Improve compatibility with
  0-16 color terminals., 2016-07-21).
  Apparently almost every actively developed terminal supports it, including
  Terminal.app and GNU screen.
  * That is, we default `fish_term256` to true and keep it only as a way to
    opt out of the the full 256 palette (e.g. switching to the 16-color
    palette).
    * `TERM=xterm-16color` has the same opt-out effect.
* `TERM` is generally ignored but add back basic compatiblity by turning
  off color for "ansi-m", "linux-m" and "xterm-mono"; these are probably
  not set accidentally.
* Since `TERM` is (mostly) ignored, we don't need the magic "xterm" in
  tests. Unset it instead.
* Note that our pexpect tests used a dumb terminal because:
  1. it makes fish do a full redraw of the commandline everytime, making it
     easier to write assertions.
  2. it disables all control sequences for colors, etc, which we usually
     don't want to test explicitly.
  I don't think TERM=dumb has any other use, so it would be better
  to print escape sequences unconditionally, and strip them in
  the test driver (leaving this for later, since it's a bit more involved).

Closes #11344
Closes #11345
2025-04-11 15:11:22 +02:00