1function fish_vi_key_bindings --description 'vi-like key bindings for fish' 2 if contains -- -h $argv 3 or contains -- --help $argv 4 echo "Sorry but this function doesn't support -h or --help" 5 return 1 6 end 7 8 # Erase all bindings if not explicitly requested otherwise to 9 # allow for hybrid bindings. 10 # This needs to be checked here because if we are called again 11 # via the variable handler the argument will be gone. 12 set -l rebind true 13 if test "$argv[1]" = --no-erase 14 set rebind false 15 set -e argv[1] 16 else 17 bind --erase --all --preset # clear earlier bindings, if any 18 end 19 20 # Allow just calling this function to correctly set the bindings. 21 # Because it's a rather discoverable name, users will execute it 22 # and without this would then have subtly broken bindings. 23 if test "$fish_key_bindings" != fish_vi_key_bindings 24 and test "$rebind" = true 25 # Allow the user to set the variable universally. 26 set -q fish_key_bindings 27 or set -g fish_key_bindings 28 # This triggers the handler, which calls us again and ensures the user_key_bindings 29 # are executed. 30 set fish_key_bindings fish_vi_key_bindings 31 return 32 end 33 34 set -l init_mode insert 35 # These are only the special vi-style keys 36 # not end/home, we share those. 37 set -l eol_keys \$ g\$ 38 set -l bol_keys \^ 0 g\^ 39 40 if contains -- $argv[1] insert default visual 41 set init_mode $argv[1] 42 else if set -q argv[1] 43 # We should still go on so the bindings still get set. 44 echo "Unknown argument $argv" >&2 45 end 46 47 # Inherit shared key bindings. 48 # Do this first so vi-bindings win over default. 49 for mode in insert default visual 50 __fish_shared_key_bindings -s -M $mode 51 end 52 53 bind -s --preset -M insert \r execute 54 bind -s --preset -M insert \n execute 55 56 bind -s --preset -M insert "" self-insert 57 58 # Space and other command terminators expand abbrs _and_ inserts itself. 59 bind -s --preset -M insert " " self-insert expand-abbr 60 bind -s --preset -M insert ";" self-insert expand-abbr 61 bind -s --preset -M insert "|" self-insert expand-abbr 62 bind -s --preset -M insert "&" self-insert expand-abbr 63 bind -s --preset -M insert "^" self-insert expand-abbr 64 bind -s --preset -M insert ">" self-insert expand-abbr 65 bind -s --preset -M insert "<" self-insert expand-abbr 66 # Closing a command substitution expands abbreviations 67 bind -s --preset -M insert ")" self-insert expand-abbr 68 # Ctrl-space inserts space without expanding abbrs 69 bind -s --preset -M insert -k nul 'commandline -i " "' 70 71 # Add a way to switch from insert to normal (command) mode. 72 # Note if we are paging, we want to stay in insert mode 73 # See #2871 74 bind -s --preset -M insert \e "if commandline -P; commandline -f cancel; else; set fish_bind_mode default; commandline -f backward-char repaint-mode; end" 75 76 # Default (command) mode 77 bind -s --preset :q exit 78 bind -s --preset -m insert \cc cancel-commandline repaint-mode 79 bind -s --preset -M default h backward-char 80 bind -s --preset -M default l forward-char 81 bind -s --preset -m insert \n execute 82 bind -s --preset -m insert \r execute 83 bind -s --preset -m insert o insert-line-under repaint-mode 84 bind -s --preset -m insert O insert-line-over repaint-mode 85 bind -s --preset -m insert i repaint-mode 86 bind -s --preset -m insert I beginning-of-line repaint-mode 87 bind -s --preset -m insert a forward-single-char repaint-mode 88 bind -s --preset -m insert A end-of-line repaint-mode 89 bind -s --preset -m visual v begin-selection repaint-mode 90 91 #bind -s --preset -m insert o "commandline -a \n" down-line repaint-mode 92 #bind -s --preset -m insert O beginning-of-line "commandline -i \n" up-line repaint-mode # doesn't work 93 94 bind -s --preset gg beginning-of-buffer 95 bind -s --preset G end-of-buffer 96 97 for key in $eol_keys 98 bind -s --preset $key end-of-line 99 end 100 for key in $bol_keys 101 bind -s --preset $key beginning-of-line 102 end 103 104 bind -s --preset u undo 105 bind -s --preset \cr redo 106 107 bind -s --preset [ history-token-search-backward 108 bind -s --preset ] history-token-search-forward 109 110 bind -s --preset k up-or-search 111 bind -s --preset j down-or-search 112 bind -s --preset b backward-word 113 bind -s --preset B backward-bigword 114 bind -s --preset ge backward-word 115 bind -s --preset gE backward-bigword 116 bind -s --preset w forward-word forward-single-char 117 bind -s --preset W forward-bigword forward-single-char 118 bind -s --preset e forward-single-char forward-word backward-char 119 bind -s --preset E forward-bigword backward-char 120 121 # OS X SnowLeopard doesn't have these keys. Don't show an annoying error message. 122 # Vi/Vim doesn't support these keys in insert mode but that seems silly so we do so anyway. 123 bind -s --preset -M insert -k home beginning-of-line 2>/dev/null 124 bind -s --preset -M default -k home beginning-of-line 2>/dev/null 125 bind -s --preset -M insert -k end end-of-line 2>/dev/null 126 bind -s --preset -M default -k end end-of-line 2>/dev/null 127 128 # Vi moves the cursor back if, after deleting, it is at EOL. 129 # To emulate that, move forward, then backward, which will be a NOP 130 # if there is something to move forward to. 131 bind -s --preset -M default x delete-char forward-single-char backward-char 132 bind -s --preset -M default X backward-delete-char 133 bind -s --preset -M insert -k dc delete-char forward-single-char backward-char 134 bind -s --preset -M default -k dc delete-char forward-single-char backward-char 135 136 # Backspace deletes a char in insert mode, but not in normal/default mode. 137 bind -s --preset -M insert -k backspace backward-delete-char 138 bind -s --preset -M default -k backspace backward-char 139 bind -s --preset -M insert \ch backward-delete-char 140 bind -s --preset -M default \ch backward-char 141 bind -s --preset -M insert \x7f backward-delete-char 142 bind -s --preset -M default \x7f backward-char 143 bind -s --preset -M insert \e\[3\;2~ backward-delete-char # Mavericks Terminal.app shift-ctrl-delete 144 bind -s --preset -M default \e\[3\;2~ backward-delete-char # Mavericks Terminal.app shift-ctrl-delete 145 146 bind -s --preset dd kill-whole-line 147 bind -s --preset D kill-line 148 bind -s --preset d\$ kill-line 149 bind -s --preset d\^ backward-kill-line 150 bind -s --preset d0 backward-kill-line 151 bind -s --preset dw kill-word 152 bind -s --preset dW kill-bigword 153 bind -s --preset diw forward-single-char forward-single-char backward-word kill-word 154 bind -s --preset diW forward-single-char forward-single-char backward-bigword kill-bigword 155 bind -s --preset daw forward-single-char forward-single-char backward-word kill-word 156 bind -s --preset daW forward-single-char forward-single-char backward-bigword kill-bigword 157 bind -s --preset de kill-word 158 bind -s --preset dE kill-bigword 159 bind -s --preset db backward-kill-word 160 bind -s --preset dB backward-kill-bigword 161 bind -s --preset dge backward-kill-word 162 bind -s --preset dgE backward-kill-bigword 163 bind -s --preset df begin-selection forward-jump kill-selection end-selection 164 bind -s --preset dt begin-selection forward-jump backward-char kill-selection end-selection 165 bind -s --preset dF begin-selection backward-jump kill-selection end-selection 166 bind -s --preset dT begin-selection backward-jump forward-single-char kill-selection end-selection 167 bind -s --preset dh backward-char delete-char 168 bind -s --preset dl delete-char 169 bind -s --preset di backward-jump-till and repeat-jump-reverse and begin-selection repeat-jump kill-selection end-selection 170 bind -s --preset da backward-jump and repeat-jump-reverse and begin-selection repeat-jump kill-selection end-selection 171 bind -s --preset 'd;' begin-selection repeat-jump kill-selection end-selection 172 bind -s --preset 'd,' begin-selection repeat-jump-reverse kill-selection end-selection 173 174 bind -s --preset -m insert s delete-char repaint-mode 175 bind -s --preset -m insert S kill-whole-line repaint-mode 176 bind -s --preset -m insert cc kill-whole-line repaint-mode 177 bind -s --preset -m insert C kill-line repaint-mode 178 bind -s --preset -m insert c\$ kill-line repaint-mode 179 bind -s --preset -m insert c\^ backward-kill-line repaint-mode 180 bind -s --preset -m insert c0 backward-kill-line repaint-mode 181 bind -s --preset -m insert cw kill-word repaint-mode 182 bind -s --preset -m insert cW kill-bigword repaint-mode 183 bind -s --preset -m insert ciw forward-single-char forward-single-char backward-word kill-word repaint-mode 184 bind -s --preset -m insert ciW forward-single-char forward-single-char backward-bigword kill-bigword repaint-mode 185 bind -s --preset -m insert caw forward-single-char forward-single-char backward-word kill-word repaint-mode 186 bind -s --preset -m insert caW forward-single-char forward-single-char backward-bigword kill-bigword repaint-mode 187 bind -s --preset -m insert ce kill-word repaint-mode 188 bind -s --preset -m insert cE kill-bigword repaint-mode 189 bind -s --preset -m insert cb backward-kill-word repaint-mode 190 bind -s --preset -m insert cB backward-kill-bigword repaint-mode 191 bind -s --preset -m insert cge backward-kill-word repaint-mode 192 bind -s --preset -m insert cgE backward-kill-bigword repaint-mode 193 bind -s --preset -m insert cf begin-selection forward-jump kill-selection end-selection repaint-mode 194 bind -s --preset -m insert ct begin-selection forward-jump backward-char kill-selection end-selection repaint-mode 195 bind -s --preset -m insert cF begin-selection backward-jump kill-selection end-selection repaint-mode 196 bind -s --preset -m insert cT begin-selection backward-jump forward-single-char kill-selection end-selection repaint-mode 197 bind -s --preset -m insert ch backward-char begin-selection kill-selection end-selection repaint-mode 198 bind -s --preset -m insert cl begin-selection kill-selection end-selection repaint-mode 199 bind -s --preset -m insert ci backward-jump-till and repeat-jump-reverse and begin-selection repeat-jump kill-selection end-selection repaint-mode 200 bind -s --preset -m insert ca backward-jump and repeat-jump-reverse and begin-selection repeat-jump kill-selection end-selection repaint-mode 201 202 bind -s --preset '~' togglecase-char forward-single-char 203 bind -s --preset gu downcase-word 204 bind -s --preset gU upcase-word 205 206 bind -s --preset J end-of-line delete-char 207 bind -s --preset K 'man (commandline -t) 2>/dev/null; or echo -n \a' 208 209 bind -s --preset yy kill-whole-line yank 210 bind -s --preset Y kill-whole-line yank 211 bind -s --preset y\$ kill-line yank 212 bind -s --preset y\^ backward-kill-line yank 213 bind -s --preset y0 backward-kill-line yank 214 bind -s --preset yw kill-word yank 215 bind -s --preset yW kill-bigword yank 216 bind -s --preset yiw forward-single-char forward-single-char backward-word kill-word yank 217 bind -s --preset yiW forward-single-char forward-single-char backward-bigword kill-bigword yank 218 bind -s --preset yaw forward-single-char forward-single-char backward-word kill-word yank 219 bind -s --preset yaW forward-single-char forward-single-char backward-bigword kill-bigword yank 220 bind -s --preset ye kill-word yank 221 bind -s --preset yE kill-bigword yank 222 bind -s --preset yb backward-kill-word yank 223 bind -s --preset yB backward-kill-bigword yank 224 bind -s --preset yge backward-kill-word yank 225 bind -s --preset ygE backward-kill-bigword yank 226 bind -s --preset yf begin-selection forward-jump kill-selection yank end-selection 227 bind -s --preset yt begin-selection forward-jump-till kill-selection yank end-selection 228 bind -s --preset yF begin-selection backward-jump kill-selection yank end-selection 229 bind -s --preset yT begin-selection backward-jump-till kill-selection yank end-selection 230 bind -s --preset yh backward-char begin-selection kill-selection yank end-selection 231 bind -s --preset yl begin-selection kill-selection yank end-selection 232 bind -s --preset yi backward-jump-till and repeat-jump-reverse and begin-selection repeat-jump kill-selection yank end-selection 233 bind -s --preset ya backward-jump and repeat-jump-reverse and begin-selection repeat-jump kill-selection yank end-selection 234 235 bind -s --preset f forward-jump 236 bind -s --preset F backward-jump 237 bind -s --preset t forward-jump-till 238 bind -s --preset T backward-jump-till 239 bind -s --preset ';' repeat-jump 240 bind -s --preset , repeat-jump-reverse 241 242 # in emacs yank means paste 243 # in vim p means paste *after* current character, so go forward a char before pasting 244 # also in vim, P means paste *at* current position (like at '|' with cursor = line), 245 # \ so there's no need to go back a char, just paste it without moving 246 bind -s --preset p forward-char yank 247 bind -s --preset P yank 248 bind -s --preset gp yank-pop 249 250 # same vim 'pasting' note as upper 251 bind -s --preset '"*p' forward-char "commandline -i ( xsel -p; echo )[1]" 252 bind -s --preset '"*P' "commandline -i ( xsel -p; echo )[1]" 253 254 # 255 # Lowercase r, enters replace_one mode 256 # 257 bind -s --preset -m replace_one r repaint-mode 258 bind -s --preset -M replace_one -m default '' delete-char self-insert backward-char repaint-mode 259 bind -s --preset -M replace_one -m default \r 'commandline -f delete-char; commandline -i \n; commandline -f backward-char; commandline -f repaint-mode' 260 bind -s --preset -M replace_one -m default \e cancel repaint-mode 261 262 # 263 # Uppercase R, enters replace mode 264 # 265 bind -s --preset -m replace R repaint-mode 266 bind -s --preset -M replace '' delete-char self-insert 267 bind -s --preset -M replace -m insert \r execute repaint-mode 268 bind -s --preset -M replace -m default \e cancel repaint-mode 269 # in vim (and maybe in vi), <BS> deletes the changes 270 # but this binding just move cursor backward, not delete the changes 271 bind -s --preset -M replace -k backspace backward-char 272 273 # 274 # visual mode 275 # 276 bind -s --preset -M visual h backward-char 277 bind -s --preset -M visual l forward-char 278 279 bind -s --preset -M visual k up-line 280 bind -s --preset -M visual j down-line 281 282 bind -s --preset -M visual b backward-word 283 bind -s --preset -M visual B backward-bigword 284 bind -s --preset -M visual ge backward-word 285 bind -s --preset -M visual gE backward-bigword 286 bind -s --preset -M visual w forward-word 287 bind -s --preset -M visual W forward-bigword 288 bind -s --preset -M visual e forward-word 289 bind -s --preset -M visual E forward-bigword 290 bind -s --preset -M visual o swap-selection-start-stop repaint-mode 291 292 bind -s --preset -M visual f forward-jump 293 bind -s --preset -M visual t forward-jump-till 294 bind -s --preset -M visual F backward-jump 295 bind -s --preset -M visual T backward-jump-till 296 297 for key in $eol_keys 298 bind -s --preset -M visual $key end-of-line 299 end 300 for key in $bol_keys 301 bind -s --preset -M visual $key beginning-of-line 302 end 303 304 bind -s --preset -M visual -m insert c kill-selection end-selection repaint-mode 305 bind -s --preset -M visual -m insert s kill-selection end-selection repaint-mode 306 bind -s --preset -M visual -m default d kill-selection end-selection repaint-mode 307 bind -s --preset -M visual -m default x kill-selection end-selection repaint-mode 308 bind -s --preset -M visual -m default X kill-whole-line end-selection repaint-mode 309 bind -s --preset -M visual -m default y kill-selection yank end-selection repaint-mode 310 bind -s --preset -M visual -m default '"*y' "fish_clipboard_copy; commandline -f end-selection repaint-mode" 311 bind -s --preset -M visual -m default '~' togglecase-selection end-selection repaint-mode 312 313 bind -s --preset -M visual -m default \cc end-selection repaint-mode 314 bind -s --preset -M visual -m default \e end-selection repaint-mode 315 316 # Make it easy to turn an unexecuted command into a comment in the shell history. Also, remove 317 # the commenting chars so the command can be further edited then executed. 318 bind -s --preset -M default \# __fish_toggle_comment_commandline 319 bind -s --preset -M visual \# __fish_toggle_comment_commandline 320 bind -s --preset -M replace \# __fish_toggle_comment_commandline 321 322 # Set the cursor shape 323 # After executing once, this will have defined functions listening for the variable. 324 # Therefore it needs to be before setting fish_bind_mode. 325 fish_vi_cursor 326 327 set fish_bind_mode $init_mode 328 329end 330