OFFSET偏移
← All articlesOFFSET / FIELD NOTESNO. 048

Fish: from key bindings to an editable command line

Cover Emacs and Vi bindings, completion, abbreviations, PATH, events, and prompt configuration.

English translation · Code and commands follow the Chinese original.

IN THESE READING PATHSShells, terminals, and sessions ↗
About 7 min readStart reading

Fish 4.x: an intelligent shell with syntax highlighting, completion, and history suggestions out of the box. It uses Emacs key bindings by default, with an optional vi mode. These shortcuts are compiled from Fish 4.x notes; terminals and custom bindings may override the defaults. Check them with bind and fish_key_reader.


Core features at a glance#

Feature Description
Syntax highlighting Real-time coloring as you type: valid commands in blue, invalid commands in red, paths underlined, and quotes in yellow
Autosuggestion Gray text suggests matching commands from history; press → or Ctrl+f to accept
Tab completion A navigable, searchable menu of completions
Abbreviations (Abbr) Type an abbreviation → press Space to expand it automatically into the full command
Web configuration Use fish_config to choose themes and change the prompt in a browser
Man page shortcut Alt+h opens the current command’s manual

Common shortcuts (shared by Emacs and Vi modes)#

Completion

Shortcut Action
Tab / Ctrl+i Complete the current token
Shift+Tab Complete and open search results
Ctrl+Space Insert a space without expanding abbreviations

Cursor movement

Shortcut Action
← / → Move one character; press → at the end of the line to accept the autosuggestion
Alt+← / Alt+→ Move one argument/word; browse directory history on an empty line
Ctrl+← / Ctrl+→ Move one word; accept one word of the suggestion at the end of the line
Shift+← / Shift+→ Move one "big word" (without stopping at punctuation)

History search

Shortcut Action
↑ / ↓ / Ctrl+p / Ctrl+n Search history using the current input
Alt+↑ / Alt+↓ Search history using the token under the cursor
Shift+Delete Delete the current entry/autosuggestion from history

Deleting and cutting

Shortcut Action
Ctrl+u Delete from the start of the line to the cursor (→ kill ring)
Ctrl+w Delete the previous path component (delimited by / : @ → kill ring)
Alt+d Delete the next word (→ kill ring)
Ctrl+Delete Delete the next word (→ kill ring; the next argument on macOS)
Alt+Delete Delete the next argument (→ kill ring; the next word on macOS)

Clipboard

Shortcut Action
Ctrl+x Copy the current command line to the system clipboard
Ctrl+v Paste from the system clipboard
Ctrl+y Paste from the kill ring (yank)
Alt+y After pasting, cycle to the previous kill-ring entry (yank-pop)

Useful operations

Shortcut Action
Alt+h / F1 Show the current command’s man page
Alt+l List the current directory; if the cursor is on a directory argument, list that directory
Alt+o Open the file under the cursor in a pager; if the cursor is on a script command, open that script with $EDITOR
Alt+p Append `& to the job under the cursor
Alt+w Show a brief description of the command under the cursor (whatis)
Alt+e / Alt+v Edit the current command line in an external editor
Alt+s Prepend sudo to the command (to the previous command if the line is empty)
Alt+Enter Insert a newline at the cursor
Ctrl+c Interrupt the current command
Ctrl+d Delete the character to the right of the cursor; exit fish on an empty line
Ctrl+l Clear the screen

Emacs mode (default)#

Moving and editing within a line

Shortcut Action
Home / Ctrl+a Move to the start of the line
End / Ctrl+e Move to the end of the line; accept the autosuggestion if already at the end
Ctrl+b Move one character left
Ctrl+f Move one character right/accept the autosuggestion
Alt+b Move one word left/accept one word; browse directory history forward on an empty line
Alt+f Move one word right/accept one word; browse directory history backward on an empty line
Alt+< Move to the start of the command line
Alt+> Move to the end of the command line

Deletion

Shortcut Action
Backspace / Ctrl+h Delete the previous character
Delete Delete the next character
Ctrl+Backspace Delete the previous word (the previous argument on macOS)
Alt+Backspace Delete the previous argument (the previous word on macOS)
Ctrl+k Delete to the end of the line

Case conversion

Shortcut Action
Alt+c Capitalize the current word
Alt+u Convert the current word to uppercase

Transposing characters/words

Shortcut Action
Ctrl+t Swap the last two characters
Alt+t Swap the last two words

Undo/redo

Shortcut Action
Ctrl+z / Ctrl+_ / Ctrl+/ Undo the most recent edit
Alt+/ / Ctrl+Shift+z Redo

History search

Shortcut Action
Ctrl+r Open the history pager; press again to search older entries
Ctrl+s Jump to newer entries in the pager (toggle search when outside the pager)

Canceling

Shortcut Action
Escape / Ctrl+g Cancel the current operation; undo completion

Vi mode#

Enable it in config.fish:

fish_vi_key_bindings

Startup usually enters Insert mode. The following is organized into three submodes: Normal (enter with Escape), Insert (i/a/o, etc.), and Visual (v).

Normal mode

Movement

Shortcut Action
h Move one character left
l Move one character right
k Search for the previous command in history (move the cursor up in multiline input)
j Search for the next command in history (move the cursor down in multiline input)
0 Move to the start of the line
Backspace Move one character left
g,g Move to the start of the command line
G Move to the end of the command line

Entering Insert mode

Shortcut Action
i Insert at the cursor
I Insert at the start of the line
a Insert after the cursor
A Insert at the end of the line
o Insert a new line below
O Insert a new line above

Deleting and pasting

Shortcut Action
d,d Delete the entire line (→ kill ring)
D Delete to the end of the line
p Paste the kill-ring contents

Undo/redo

Shortcut Action
u Undo
Ctrl+r Redo

Letter case

Shortcut Action
~ Toggle the current character’s case and move the cursor forward
g,u Convert to lowercase through the end of the word
g,U Convert to uppercase through the end of the word

History search

Shortcut Action
[ Search backward in history using the token under the cursor
] Search forward in history using the token under the cursor
/ Open the history pager

Exiting

Shortcut Action
:,q Exit fish

Insert mode

Shortcut Action
Escape Enter Normal mode
Backspace Delete the previous character
Ctrl+n Accept the autosuggestion

Visual mode

Shortcut Action
h / l Extend the selection (one character left/right)
k / j Extend the selection (up/down a line)
b / w Extend the selection (by word)
d / x Delete the selection → kill ring; return to Normal
c / s Delete the selection → Insert mode
y Copy the selection → kill ring; return to Normal
",*,y Copy the selection to the system clipboard; return to Normal
X Delete the entire line → kill ring; return to Normal
~ Toggle the selection’s case; return to Normal
g,u Convert the selection to lowercase; return to Normal
g,U Convert the selection to uppercase; return to Normal
Escape / Ctrl+c Return to Normal mode

The Tab completion system#

Basic operations

Shortcut Action
Tab Trigger completion/expand suggestions
Shift+Tab Complete and open pager search
Ctrl+s Search in the completion pager

Example completion rules

# 列出 systemctl 子命令补全
systemctl <Tab>          # → enable, disable, start, stop, status...

# 路径补全
ls ~/Doc<Tab>            # → ~/Documents/

# Git 分支/文件补全
git checkout <Tab>       # → 列出所有分支

# 命令选项补全
git commit -<Tab>        # → -m, -a, --amend, --no-verify...

# 进程 PID 补全
kill <Tab>               # → 列出所有进程 PID + 命令名

Common configuration (~/.config/fish/config.fish)#

Aliases → abbreviations

# 别名适合函数式包装
alias ga="git add"

# 缩写在输入时展开,展开后可见且可编辑;别名仍然有效
abbr -a ga "git add"
abbr -a gc "git commit"
abbr -a gco "git checkout"
abbr -a gp "git push"
abbr -a gst "git status"

Switching modes

# Vi 模式(vim 用户推荐)
fish_vi_key_bindings

# 改回 Emacs
# fish_default_key_bindings

# Vi 模式下光标形状
set -g fish_cursor_default block
set -g fish_cursor_insert line
set -g fish_cursor_replace_one underscore
set -g fish_cursor_visual block

Custom completion colors

# 让自动建议更低调
set -g fish_color_autosuggestion brblack

Greeting

# 禁用欢迎语
set -g fish_greeting

PATH management

# 前置新目录(自动去重)
fish_add_path ~/.local/bin

# 明确追加到 fish_user_paths 的尾部
fish_add_path --append ~/bin

# 已有目录也移到所选位置,而不是保持原位置
fish_add_path --move ~/bin

Event hooks

# 退出时执行
function on_exit --on-event fish_exit
    echo "Goodbye from" (hostname)
end

Private mode#

# 启动私有 session(不记录历史,不影响其他 session)
fish --private
# 或
fish -P

# 在运行中检查
echo $fish_private_mode   # 1 表示私有模式

Custom key bindings#

# 查看某个按键的转义序列名
fish_key_reader

# 绑定新快捷键
bind \cg 'echo "Ctrl+G pressed"'

# 在 Vi 模式特定子模式下绑定
bind --mode insert \cf 'echo "Insert mode specific"'

# 查看所有当前绑定
bind

# 恢复默认
bind --erase \cg

Quick reference for common built-in commands#

Command Purpose
fish_config Web UI configuration (themes, prompt, shortcuts)
fish_key_reader Diagnose key sequences
fish_add_path PATH management (automatic deduplication)
fish_update_completions Rebuild the completion cache
fish_default_key_bindings Switch to Emacs key bindings
fish_vi_key_bindings Switch to Vi key bindings
abbr -a Add an abbreviation
bind View/set key bindings
set -Ux Set a universal variable
set -gx Set a global variable
string String processing
functions View/manage functions
funced Edit a function interactively
funcsave Save a function
type Show the command type (function/builtin/external)

Prompt management#

# 在终端选择内置提示符
fish_config prompt choose disco

# 查看可用提示符
fish_config prompt show

# 保存选择
fish_config prompt save

References & further reading

  1. Fish Interactive Documentation ↗
  2. fish_add_path Ordering and move Behavior ↗

Adapted from technical notes. Examples use generic names.

Continue along a reading path

Shells, terminals, and sessions

  1. 01Fish: from key bindings to an editable command line
  2. 02Foot: the boundaries of search, selection, and configuration
  3. 03Zellij: does the session survive when the window closes?
CONTINUE READING / NEXT ARTICLEFoot: the boundaries of search, selection, and configuration

Distinguish keyboard modes, primary selection, font size, and the configuration lifecycle, with a complete key-binding reference.