FISH-TERMINAL-COMPATIBILITY(1)

πŸšπŸ’– FISH-TERMINAL-COMPATIBILITY(1) πŸ’–πŸš

okay so bestie, this is FISH-TERMINAL-COMPATIBILITY(1) from fish-shell, and it’s literally the vibe check for your terminal. fish writes various control sequences to the terminal. Some must be implemented to enable basic functionality, while others enable optional features and may be ignored by the terminal. no cap.

Your terminal must be able to parse Control Sequence Introducer (CSI) commands, Operating System Commands (OSC) and optionally Device Control Strings (DCS). These are defined by ECMA-48. If a valid CSI, OSC or DCS sequence does not represent a command implemented by the terminal, the terminal must ignore it. periodt.

Control sequences are denoted in a fish-like syntax. Special characters other than \ are not escaped. Spaces are only added for readability and are not part of the sequence. Placeholders are written as Ps for a number or Pt for an arbitrary printable string.

πŸ“ NOTE: fish does not rely on your system's terminfo database. In this document, terminfo (TI) codes are included for reference only. iykyk.

✨ REQUIRED COMMANDS ✨

these are the non-negotiables, bestie β€” basic functionality is giving main character energy only if your terminal has these. πŸ’…

  • \r β€” TI: n/a β€” move cursor to the beginning of the line.
  • \n β€” TI: cud1 β€” move cursor down one line.
  • \e[ Ps A β€” TI: cuu β€” move cursor up Ps columns, or one column if no parameter.
  • \e[ Ps C β€” TI: cuf β€” move cursor to the right Ps columns, or one column if no parameter.
  • \x08 β€” TI: cub1 β€” move cursor one column to the left.
  • \e[ Ps D β€” TI: cub β€” move cursor to the left Ps times.
  • \e[H β€” TI: cup β€” set cursor position (no parameters means: move to row 1, column 1).
  • \e[K β€” TI: el β€” clear to end of line.
  • \e[J β€” TI: ed β€” clear to the end of screen.
  • \e[2J β€” TI: clear β€” clear the screen.
  • \e[0c β€” TI: (blank) β€” request Primary Device Attribute. The terminal must respond with a CSI command that starts with the ? parameter byte (so a sequence starting with \e[?) and has c as final byte. Failure to implement this will cause a brief pause at startup followed by a warning. For the time being, both can be turned off by turning off the query-terminal feature flag <#featureflags>. 😭
  • n/a β€” TI: am β€” soft wrap text at screen width.
  • n/a β€” TI: xenl β€” printing to the last column does not move the cursor to the next line. Verify this by running printf %0"$COLUMNS"d 0; sleep 3.

πŸŽ€ OPTIONAL COMMANDS πŸŽ€

these are the optional feature flexes, bestie β€” your terminal may ignore them, but when it ate, it ate. πŸ“

  • \t β€” TI: it β€” move the cursor to the next tab stop (every 8 columns). This is mainly relevant if your prompt includes tabs.
  • \e[m β€” TI: sgr0 β€” turn off bold/dim/italic/underline/strikethrough/reverse attribute modes and select default colors.
  • \e[1m β€” TI: bold β€” enter bold mode.
  • \e[2m β€” TI: dim β€” enter dim mode.
  • \e[3m β€” TI: sitm β€” enter italic mode.
  • \e[4m β€” TI: smul β€” enter underline mode.
  • \e[4:2m β€” TI: Su β€” enter double underline mode.
  • \e[4:3m β€” TI: Su β€” enter curly underline mode.
  • \e[4:4m β€” Su β€” enter dotted underline mode ✨
  • \e[4:5m β€” Su β€” enter dashed underline mode, because apparently one kind of underline was never gonna be enough πŸ’…
  • \e[7m β€” rev β€” enter reverse video mode (it literally swaps your foreground and background colors, the icon of a glow-up) πŸ”„
  • \e[9m β€” smxx β€” enter strikethrough mode
  • \e[23m β€” ritm β€” exit italic mode
  • \e[24m β€” rmul β€” exit underline mode
  • \e[29m β€” rmxx β€” exit strikethrough mode
  • \e[38;5; Ps m β€” setaf β€” select foreground color Ps from the 256-color-palette 🎨
  • \e[48;5; Ps m β€” setab β€” select background color Ps from the 256-color-palette
  • \e[58:5: Ps m (note: colons not semicolons 🫠) β€” Su β€” select underline color Ps from the 256-color-palette. yes bestie, the underline gets its own color now, we're so back
  • \e[ Ps m β€” setaf setab β€” select foreground/background color. This one uses a color in the aforementioned 256-color-palette, based on the range that contains the parameter: 30-37 maps to foreground 0-7, 40-47 maps to background 0-7, 90-97 maps to foreground 8-15 and 100-107 maps to background 8-15. retro-coded but it slays
  • \e[38;2; Ps ; Ps ; Ps m β€” no terminfo cap listed β€” select foreground color from 24-bit RGB colors 🌈
  • \e[48;2; Ps ; Ps ; Ps m β€” no terminfo cap listed β€” select background color from 24-bit RGB colors
  • \e[39m β€” no terminfo cap listed β€” reset the foreground color back to whatever the terminal's default is, we're going home 🏠
  • \e[49m β€” no terminfo cap listed β€” reset the background color back to the terminal's default
  • \e[58:2:: Ps : Ps : Ps m (note: colons not semicolons, again, iykyk) β€” Su β€” select underline color from 24-bit RGB colors
  • \e[59m β€” Su β€” reset the underline color to the default (which means it follows the foreground color) 🫢
  • \e[ Ps S β€” indn β€” scroll up the content (not the viewport!) Ps lines. this one is called SCROLL UP / SU by ECMA-48 and "scroll forward" by terminfo, she's got range πŸ‘‘. When fish detects support for this feature, status test-terminal-features scroll-content-up will return 0, which enables the ctrl+l binding to use the scrollback-push special input function. lowkey the fanciest thing on this whole page
  • \e[= Ps u, \e[? Ps u β€” n/a β€” enable the kitty keyboard protocol βŒ¨οΈπŸ’–
  • \e[6n β€” n/a β€” request a cursor position report. the response must be of the form \e[ Ps ; Ps R where the first parameter is the row number and the second parameter is the column number. both start at 1 (not zero, we're not animals). This is used for truncating multiline autosuggestions at the screen's bottom edge, by the scrollback-push special input function, and inside terminals that implement the OSC 133 click_events feature πŸ“
  • \e[ \x20 q β€” Se β€” reset the cursor style to the terminal's default. This is not used as of today but may be in future, so consider it a coming-soon teaser ⭐
  • \e[ Ps \x20 q β€” Ss β€” set cursor style (DECSCUSR); Ps is 2, 4 or 6 for block, underscore or line shape. pick your fighter πŸ’…
  • \e[ Ps q β€” terminfo: n/a β€” asking the terminal for its name and version (XTVERSION ✨). Fr fr this one is only for temporary workarounds when a terminal is being incompatible, okay? iykyk.
  • \e[?25h β€” terminfo: cvvis β€” cursor visibility: on DECTCEM. your girl is back πŸ’…
  • \e[?1004h β€” terminfo: n/a β€” enable focus reporting. πŸ‘€
  • \e[?1004l β€” terminfo: n/a β€” disable focus reporting. no more watching me πŸ™ˆ
  • \e[?1049h β€” terminfo: n/a β€” enable the alternate screen buffer. main character energy β€” whole new screen, who dis.
  • \e[?1049l β€” terminfo: n/a β€” disable the alternate screen buffer. back to reality 😭
  • \e[?2004h β€” terminfo: (blank) β€” enable bracketed paste. πŸŽ€
  • \e[?2004l β€” terminfo: (blank) β€” disable bracketed paste.
  • \e[?2031h β€” terminfo: (blank) β€” enable unsolicited color theme reporting (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/). the way this works is: once it's on, the terminal should send \e[?997;1n or \e[?997;2n whenever its color theme changes. and that? that's what prompts fish to go query for the background color. lowkey genius πŸ¦‹
  • \e[?2031l β€” terminfo: (blank) β€” disable unsolicited color theme reporting. ok bestie we get it, no more theme updates πŸ’€
  • \e]0; Pt \e\\ β€” terminfo: ts β€” set the terminal window title (OSC 0). this is the one used in fish_title 🫢
  • \e]1; Pt \e\\ β€” terminfo: ts β€” set the terminal tab title (OSC 1). yep, tabs get their own. used in fish_tab_title ✨
  • \e]7;file:// Pt / Pt \e\\ β€” terminfo: (blank) β€” report the working directory (OSC 7). important detail: since the terminal might be running on a different system than a (remote) shell, that hostname (the first parameter) will not be localhost. no cap, don't assume 🧚
  • \e]8;; Pt \e\\ β€” terminfo: (blank) β€” create a hyperlink (OSC 8) β€” https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda. this is literally what fish's man pages use for links πŸ‘‘
  • \e]11;?\e\\ β€” terminfo: n/a β€” query the background color. 🌈

a valid response would be of the form \e]11;rgb: Pt / Pt / Pt \e\\ or \e]11;rgba: Pt / Pt / Pt / Pt\e\\, where the first three parameters each consist of one to four hex digits, representing red, blue and green components. (yes that's the order the page says β€” red, blue and green. not me questioning it, just reporting it πŸ™ˆ)

this is used to populate the fish_terminal_color_theme environment variable (fish_terminal_color_theme), which in turn is used to select a theme variant (fish-config-theme-files) optimized for the terminal's color theme. so the whole vibe matches, periodt πŸ’–

  • \e]52;c; Pt \e\\ β€” terminfo: (blank) β€” copy to clipboard (OSC 52). used by fish_clipboard_copy πŸ“
  • \e]133;A;click_events=1\e\\ β€” terminfo: (blank) β€” mark the prompt start (OSC 133), with kitty's click_events extension. what does the click_events extension even do? it enables mouse clicks to move the cursor or select pager items β€” assuming cursor position reporting is available. key caveat bestie, don't forget the assumption ⭐
  • \e]133;B\e\\ β€” terminfo: (blank) β€” mark the prompt end (OSC 133). that's a wrap on the prompt πŸ’…
  • \e]133;C;cmdline_url= Pt \e\\ β€” terminfo: (blank) β€” mark the command start (OSC 133), with kitty's cmdline_url extension, whose parameter is the URL-encoded command line. yes, URL-encoded. encode it πŸ”₯
  • \e]133;D; Ps \e\\ β€” terminfo: (blank) β€” mark the command end (OSC 133). Ps here is the exit status β€” so that's how the terminal knows if your command ate or flopped πŸ’€
  • \eP+q Pt \e\\ β€” this is the "hey bestie, what's your terminfo say?" request (XTGETTCAP). The parameter you send is the capability's hex-encoded terminfo code. πŸ’…

The terminal has to clap back in one of two shapes: \eP1+q Pt \e\\ (that's the "boolean" form) or \eP1+q Pt = Pt \e\\ (that's the "string" form). Either way, the first parameter in the reply must match the parameter you sent. No substitutions, no cap. 🫢

fish goes shopping for these string capabilities:

  • indn
    • the response's second parameter is ignored. literally just vibes, we don't read it. πŸ™ˆ
  • query-os-name (for status terminal-os <#status-terminal-os>)
    • terminals running on Unix should respond with the hex encoding of $(uname -s) as the second parameter. that's the whole assignment, bestie. ✨

πŸ–₯️ DCS COMMANDS AND GNU SCREEN

okay so this is the part where things get a lil spicy. 🌢️

DCS parsing is optional β€” why? because fish temporarily switches to the alternate screen before printing any DCS commands. cute, right? except. πŸ’€

GNU screen doesn't allow turning on the alternate screen buffer by default, and it doesn't treat DCS commands in a compatible way either. so fish's initial prompt may get straight-up garbled by a DCS payload like +q696e646e. not the aesthetic we were going for. 😭

For the time being, fish works around this by checking for the presence of the STY environment variable. If that doesn't work for some reason, you can add this to your ~/.screenrc:

altscreen on

Or add this to your config.fish:

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

either one, pick your fighter. πŸ₯Š


πŸ”€ UNICODE CODEPOINTS

By default, fish outputs the following non-ASCII characters:

Γ— β–Ί ΒΆ ⏎ β€’ ● … ΞΌ ’ β€˜ β€œ ”

as well as control pictures (U+2400 through U+241F), and locale-specific ones in translated messages <#variables-locale>. 🌈

so yeah, if you ever wondered why your terminal is serving looks β€” that's the character set doing it. πŸ‘‘


πŸ‘‘ Author

fish-shell developers

(icons. legends. the main characters.)


fish-shell developers


and that's a wrap on the whole page, bestie!! πŸŽ€ that was FISH-TERMINAL-COMPATIBILITY(1) from fish 4.9, dated Sep 08, 2026 β€” go forth and have a terminal that actually behaves, ily, bye πŸ’–βœ¨πŸ¦‹

πŸ“¦ where this page comes from
  • arch rolling: fish 4.9.3-1 Β· GPL-2.0-only AND BSD-3-Clause AND ISC AND MIT AND PSF-2.0
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms