Fish prides itself on being really nice to use interactively. That’s down to a few features we’ll explain in the next few sections.
Fish is used by giving commands in the fish language, see The Fish Language for information on that.
Fish also has man pages for its commands, and translates the help pages to man pages. For example,
man set will show the documentation for
set as a man page.
Help on a specific builtin can also be obtained with the
-h parameter. For instance, to obtain help on the fg builtin, either type
fg -h or
The main page can be viewed via
help index (or just
man fish-doc. The tutorial can be viewed with
help tutorial or
fish suggests commands as you type, based on command history, completions, and valid file paths. As you type commands, you will see a suggestion offered after the cursor, in a muted gray color (which can be changed with the
To accept the autosuggestion (replacing the command line contents), press → or Control+F. To accept the first suggested word, press Alt+→ or Alt+F. If the autosuggestion is not what you want, just ignore it: it won’t execute unless you accept it.
Autosuggestions are a powerful way to quickly summon frequently entered commands, by typing the first few characters. They are also an efficient technique for navigating through directory hierarchies.
If you don’t like autosuggestions, you can disable them by setting
$fish_autosuggestion_enabled to 0:
set -g fish_autosuggestion_enabled 0
Tab completion is a time saving feature of any modern shell. When you type Tab, fish tries to guess the rest of the word under the cursor. If it finds just one possibility, it inserts it. If it finds more, it inserts the longest unambiguous part and then opens a menu (the “pager”) that you can navigate to find what you’re looking for.
The pager can be navigated with the arrow keys, Page Up / Page Down, Tab or Shift+Tab. Pressing Control+S (the
pager-toggle-search binding - / in vi-mode) opens up a search menu that you can use to filter the list.
Fish provides some general purpose completions, like for commands, variable names, usernames or files.
It also provides a large number of program specific scripted completions. Most of these completions are simple options like the
-l option for
ls, but a lot are more advanced. For example:
whatisshow the installed manual pages as completions.
makeuses targets in the Makefile in the current directory as completions.
mountuses mount points specified in fstab as completions.
yumshow installed or installable packages
You can also write your own completions or install some you got from someone else. For that, see Writing your own completions.
Completion scripts are loaded on demand, just like functions are. The difference is the
$fish_complete_path list is used instead of
$fish_function_path. Typically you can drop new completions in ~/.config/fish/completions/name-of-command.fish and fish will find them automatically.
Fish interprets the command line as it is typed and uses syntax highlighting to provide feedback. The most important feedback is the detection of potential errors. By default, errors are marked red.
Detected errors include:
Reading from or appending to a non-existing file.
Incorrect use of output redirects
To customize the syntax highlighting, you can set the environment variables listed in the Variables for changing highlighting colors section.
Fish also provides pre-made color themes you can pick with fish_config. Running just
fish_config opens a browser interface, or you can use
fish_config theme in the terminal.
For example, to disable nearly all coloring:
fish_config theme choose none
Or, to see all themes, right in your terminal:
fish_config theme show
Syntax highlighting variables¶
The colors used by fish for syntax highlighting can be configured by changing the values of various variables. The value of these variables can be one of the colors accepted by the set_color command. The modifier switches accepted by
--underline are also accepted.
Example: to make errors highlighted and red, use:
set fish_color_error red --bold
The following variables are available to change the highlighting colors in fish:
commands like echo
keywords like if - this falls back on the command color if unset
quoted text like
IO redirections like >/dev/null
process separators like
ordinary command parameters
parameters that are filenames (if the file exists)
options starting with “-”, up to the first “--” parameter
comments like ‘# important’
selected text in vi visual mode
parameter expansion operators like
character escapes like
autosuggestions (the proposed rest of a command)
the current working directory in the default prompt
the current working directory in the default prompt for the root user
the username in the default prompt
the hostname in the default prompt
the hostname in the default prompt for remote sessions (like ssh)
the last command’s nonzero exit code in the default prompt
the ‘^C’ indicator on a canceled command
history search matches and selected pager items (background only)
If a variable isn’t set or is empty, fish usually tries
$fish_color_normal, except for:
$fish_color_keyword, where it tries
$fish_color_option, where it tries
$fish_color_valid_path, if that doesn’t have a color, but only modifiers, it adds those to the color that would otherwise be used, like
$fish_color_param. But if valid paths have a color, it uses that and adds in modifiers from the other color.
Pager color variables¶
fish will sometimes present a list of choices in a table, called the pager.
Example: to set the background of each pager row, use:
set fish_pager_color_background --background=white
To have black text on alternating white and gray backgrounds:
set fish_pager_color_prefix black set fish_pager_color_completion black set fish_pager_color_description black set fish_pager_color_background --background=white set fish_pager_color_secondary_background --background=brwhite
Variables affecting the pager colors:
the progress bar at the bottom left corner
the background color of a line
the prefix string, i.e. the string that is to be completed
the completion itself, i.e. the proposed rest of the string
the completion description
background of the selected completion
prefix of the selected completion
suffix of the selected completion
description of the selected completion
background of every second unselected completion
prefix of every second unselected completion
suffix of every second unselected completion
description of every second unselected completion
When the secondary or selected variables aren’t set or are empty, the normal variables are used, except for
$fish_pager_color_selected_background, where the background of
$fish_color_search_match is tried first.
To avoid needless typing, a frequently-run command like
git checkout can be abbreviated to
gco using the abbr command.
abbr -a gco git checkout
gco and pressing Space or Enter, a
gco in command position will turn into
git checkout in the command line. If you want to use a literal
gco sometimes, use Control+Space .
This is a lot more powerful, for example you can make going up a number of directories easier with this:
function multicd echo cd (string repeat -n (math (string length -- $argv) - 1) ../) end abbr --add dotdot --regex '^\.\.+$' --function multicd
.. transforms to
cd ../, while
... turns into
cd ../../ and
.... expands to
The advantage over aliases is that you can see the actual command before using it, add to it or change it, and the actual command will be stored in history.
When using most virtual terminals, it is possible to set the message displayed in the titlebar of the terminal window. This can be done automatically in fish by defining the fish_title function. The fish_title function is executed before and after a new command is executed or put into the foreground and the output is used as a titlebar message. The status current-command builtin will always return the name of the job to be put into the foreground (or
fish if control is returning to the shell) when the fish_prompt function is called. The first argument to fish_title will contain the most recently executed foreground command as a string.
The default fish title shows the hostname if connected via ssh, the currently running command (unless it is fish) and the current working directory. All of this is shortened to not make the tab too wide.
To show the last command and working directory in the title:
function fish_title # `prompt_pwd` shortens the title. This helps prevent tabs from becoming very wide. echo $argv (prompt_pwd) pwd end
The output of the former is displayed on the left and the latter’s output on the right side of the terminal. The output of fish_mode_prompt will be prepended on the left, though the default function only does this when in vi-mode.
When it is started interactively, fish tries to run the fish_greeting function. The default fish_greeting prints a simple greeting. You can change its text by changing the
$fish_greeting variable, for instance using a universal variable:
set -U fish_greeting
set -g fish_greeting 'Hey, stranger!'
or you can script it by changing the function:
function fish_greeting random choice "Hello!" "Hi" "G'day" "Howdy" end
$fish_private_mode is set to a non-empty value, commands will not be written to the history file on disk.
You can also launch with
fish --private (or
fish -P for short). This both hides old history and prevents writing history to disk. This is useful to avoid leaking personal information (e.g. for screencasts) or when dealing with sensitive information.
You can query the variable
if test -n "$fish_private_mode" ...) if you would like to respect the user’s wish for privacy and alter the behavior of your own fish scripts.
Command line editor¶
The fish editor features copy and paste, a searchable history and many editor functions that can be bound to special keyboard shortcuts.
Like bash and other shells, fish includes two sets of keyboard shortcuts (or key bindings): one inspired by the Emacs text editor, and one by the Vi text editor. The default editing mode is Emacs. You can switch to Vi mode by running
fish_vi_key_bindings and switch back with
fish_default_key_bindings. You can also make your own key bindings by creating a function and setting the
fish_key_bindings variable to its name. For example:
function fish_hybrid_key_bindings --description \ "Vi-style bindings that inherit emacs-style bindings in all modes" for mode in default insert visual fish_default_key_bindings -M $mode end fish_vi_key_bindings --no-erase end set -g fish_key_bindings fish_hybrid_key_bindings
While the key bindings included with fish include many of the shortcuts popular from the respective text editors, they are not a complete implementation. They include a shortcut to open the current command line in your preferred editor (Alt+E by default) if you need the full power of your editor.
Emacs mode commands¶
To enable emacs mode, use
fish_default_key_bindings. This is also the default.
Home or Control+A moves the cursor to the beginning of the line.
End or Control+E moves to the end of line. If the cursor is already at the end of the line, and an autosuggestion is available, End or Control+E accepts the autosuggestion.
Control+B, Control+F move the cursor one character left or right or accept the autosuggestion just like the ← (Left) and → (Right) shared bindings (which are available as well).
Control+N, Control+P move the cursor up/down or through history, like the up and down arrow shared bindings.
Delete or Backspace removes one character forwards or backwards respectively. This also goes for Control+H, which is indistinguishable from backspace.
Alt+Backspace removes one word backwards.
Alt+< moves to the beginning of the commandline, Alt+> moves to the end.
Control+K deletes from the cursor to the end of line (moving it to the Copy and paste (Kill Ring)).
Escape and Control+G cancel the current operation. Immediately after an unambiguous completion this undoes it.
Alt+C capitalizes the current word.
Alt+U makes the current word uppercase.
Control+T transposes the last two characters.
Alt+T transposes the last two words.
Control+Z, Control+_ (Control+/ on some terminals) undo the most recent edit of the line.
Alt+/ reverts the most recent undo.
Control+R opens the history in a pager. This will show history entries matching the search, a few at a time. Pressing Control+R again will search older entries, pressing Control+S (that otherwise toggles pager search) will go to newer entries. The search bar will always be selected.
You can change these key bindings using the bind builtin.
Vi mode commands¶
Vi mode allows for the use of Vi-like commands at the prompt. Initially, insert mode is active. Escape enters command mode. The commands available in command, insert and visual mode are described below. Vi mode shares some bindings with Emacs mode.
To enable vi mode, use
It is also possible to add all emacs-mode bindings to vi-mode by using something like:
function fish_user_key_bindings # Execute this once per mode that emacs bindings should be used in fish_default_key_bindings -M insert # Then execute the vi-bindings so they take precedence when there's a conflict. # Without --no-erase fish_vi_key_bindings will default to # resetting all bindings. # The argument specifies the initial mode (insert, "default" or visual). fish_vi_key_bindings --no-erase insert end
When in vi-mode, the fish_mode_prompt function will display a mode indicator to the left of the prompt. To disable this feature, override it with an empty function. To display the mode elsewhere (like in your right prompt), use the output of the
When a binding switches the mode, it will repaint the mode-prompt if it exists, and the rest of the prompt only if it doesn’t. So if you want a mode-indicator in your
fish_prompt, you need to erase
fish_mode_prompt e.g. by adding an empty file at
~/.config/fish/functions/fish_mode_prompt.fish. (Bindings that change the mode are supposed to call the repaint-mode bind function, see bind)
fish_vi_cursor function will be used to change the cursor’s shape depending on the mode in supported terminals. The following snippet can be used to manually configure cursors after enabling vi-mode:
# Emulates vim's cursor shape behavior # Set the normal and visual mode cursors to a block set fish_cursor_default block # Set the insert mode cursor to a line set fish_cursor_insert line # Set the replace mode cursor to an underscore set fish_cursor_replace_one underscore # The following variable can be used to configure cursor shape in # visual mode, but due to fish_cursor_default, is redundant here set fish_cursor_visual block
blink can be added after each of the cursor shape parameters to set a blinking cursor in the specified shape.
If the cursor shape does not appear to be changing after setting the above variables, it’s likely your terminal emulator does not support the capabilities necessary to do this. It may also be the case, however, that
fish_vi_cursor has not detected your terminal’s features correctly (for example, if you are using
tmux). If this is the case, you can force
fish_vi_cursor to set the cursor shape by setting
config.fish. You’ll have to restart fish for any changes to take effect. If cursor shape setting remains broken after this, it’s almost certainly an issue with your terminal emulator, and not fish.
Command mode is also known as normal mode.
h moves the cursor left.
l moves the cursor right.
k and j search the command history for the previous/next command containing the string that was specified on the commandline before the search was started. If the commandline was empty when the search started, all commands match. See the history section for more information on history searching. In multi-line commands, they move the cursor up and down respectively.
i enters insert mode at the current cursor position.
Shift+R enters insert mode at the beginning of the line.
v enters visual mode at the current cursor position.
a enters insert mode after the current cursor position.
Shift+A enters insert mode at the end of the line.
o inserts a new line under the current one and enters insert mode
O (capital-“o”) inserts a new line above the current one and enters insert mode
0 (zero) moves the cursor to beginning of line (remaining in command mode).
d+d deletes the current line and moves it to the Copy and paste (Kill Ring).
Shift+D deletes text after the current cursor position and moves it to the Copy and paste (Kill Ring).
p pastes text from the Copy and paste (Kill Ring).
u undoes the most recent edit of the command line.
Control+R redoes the most recent edit.
[ and ] search the command history for the previous/next token containing the token under the cursor before the search was started. See the history section for more information on history searching.
/ opens the history in a pager. This will show history entries matching the search, a few at a time. Pressing it again will search older entries, pressing Control+S (that otherwise toggles pager search) will go to newer entries. The search bar will always be selected.
Backspace moves the cursor left.
g / G moves the cursor to the beginning/end of the commandline, respectively.
:q exits fish.
Escape enters command mode.
Backspace removes one character to the left.
← (Left) and → (Right) extend the selection backward/forward by one character.
h moves the cursor left.
l moves the cursor right.
k moves the cursor up.
j moves the cursor down.
b and w extend the selection backward/forward by one word.
Escape and Control+C enter command mode.
c and s remove the selection and switch to insert mode.
~ toggles the case (upper/lower) on the selection, and enters command mode.
"*y copies the selection to the clipboard, and enters command mode.
In addition to the standard bindings listed here, you can also define your own with bind:
# Just clear the commandline on control-c bind \cc 'commandline -r ""'
bind statements into config.fish or a function called
If you change your mind on a binding and want to go back to fish’s default, you can simply erase it again:
bind --erase \cc
Fish remembers its preset bindings and so it will take effect again. This saves you from having to remember what it was before and add it again yourself.
The terminal tells fish which keys you pressed by sending some sequences of bytes to describe that key. For some keys, this is easy - pressing a simply means the terminal sends “a”. In others it’s more complicated and terminals disagree on which they send.
In these cases, fish_key_reader can tell you how to write the key sequence for your terminal. Just start it and press the keys you are interested in:
> fish_key_reader # pressing control-c Press a key: Press [ctrl-C] again to exit bind \cC 'do something' > fish_key_reader # pressing the right-arrow Press a key: bind \e\[C 'do something'
Note that some key combinations are indistinguishable or unbindable. For instance control-i is the same as the tab key. This is a terminal limitation that fish can’t do anything about.
Also, Escape is the same thing as Alt in a terminal. To distinguish between pressing Escape and then another key, and pressing Alt and that key (or an escape sequence the key sends), fish waits for a certain time after seeing an escape character. This is configurable via the
If you want to be able to press Escape and then a character and have it count as Alt+that character, set it to a higher value, e.g.:
set -g fish_escape_delay_ms 100
Copy and paste (Kill Ring)¶
Fish uses an Emacs-style kill ring for copy and paste functionality. For example, use Control+K (kill-line) to cut from the current cursor position to the end of the line. The string that is cut (a.k.a. killed in emacs-ese) is inserted into a list of kills, called the kill ring. To paste the latest value from the kill ring (emacs calls this “yanking”) use Control+Y (the
yank input function). After pasting, use Alt+Y (
yank-pop) to rotate to the previous kill.
Copy and paste from outside are also supported, both via the Control+X / Control+V bindings (the
fish_clipboard_paste functions ) and via the terminal’s paste function, for which fish enables “Bracketed Paste Mode”, so it can tell a paste from manually entered text.
In addition, when pasting inside single quotes, pasted single quotes and backslashes are automatically escaped so that the result can be used as a single token simply by closing the quote after.
Kill ring entries are stored in
end-selection (unbound by default; used for selection in vi visual mode) control text selection together with cursor movement commands that extend the current selection.
fish_cursor_selection_mode can be used to configure if that selection should include the character under the cursor (
inclusive) or not (
exclusive). The default is
exclusive, which works well with any cursor shape. For vi mode, and particularly for the
underscore cursor shapes you may prefer
The fish commandline editor can be used to work on commands that are several lines long. There are three ways to make a command span more than a single line:
Pressing the Enter key while a block of commands is unclosed, such as when one or more block commands such as
ifdo not have a corresponding end command.
Pressing Alt+Enter instead of pressing the Enter key.
By inserting a backslash (
\) character before pressing the Enter key, escaping the newline.
The fish commandline editor works exactly the same in single line mode and in multiline mode. To move between lines use the left and right arrow keys and other such keyboard shortcuts.
Searchable command history¶
After a command has been executed, it is remembered in the history list. Any duplicate history items are automatically removed. By pressing the up and down keys, you can search forwards and backwards in the history. If the current command line is not empty when starting a history search, only the commands containing the string entered into the command line are shown.
By pressing Alt+↑ and Alt+↓, a history search is also performed, but instead of searching for a complete commandline, each commandline is broken into separate elements just like it would be before execution, and the history is searched for an element matching that under the cursor.
For more complicated searches, you can press Ctrl+R to open a pager that allows you to search the history. It shows a limited number of entries in one page, press Ctrl+R  again to move to the next page and Ctrl+S  to move to the previous page. You can change the text to refine your search.
History searches are case-insensitive unless the search string contains an uppercase character. You can stop a search to edit your search string by pressing Esc or Page Down.
Prefixing the commandline with a space will prevent the entire line from being stored in the history. It will still be available for recall until the next command is executed, but will not be stored on disk. This is to allow you to fix misspellings and such.
The command history is stored in the file
$XDG_DATA_HOME/fish/fish_history if that variable is set) by default. However, you can set the
fish_history environment variable to change the name of the history session (resulting in a
<session>_history file); both before starting the shell and while the shell is running.
See the history command for other manipulations.
To search for previous entries containing the word ‘make’, type
make in the console and press the up key.
If the commandline reads
cd m, place the cursor over the
m character and press Alt+↑ to search for previously typed words containing ‘m’.