Skip to content

Vi (Vim) editing mode

Koichi Murase edited this page Oct 22, 2017 · 30 revisions

Note: Here functionalities in the branch support-vi-mode are explained. These functionalities are not yet in master.

1. Enabling vi/vim editing mode

Vi/vim editing mode will be enabled by one of the following settings.

With a inputrc setting

In ~/.inputrc

$if Bash

  set editing-mode vi

$endif

With set -o vi in ~/.bashrc

Another way is to use set -o vi in ~/.bashrc.

if [[ $- == *i* ]]; then # in interactive session
  set -o vi
fi

With bind in ~/.bashrc

Or, the following setting also enables the vi/vim mode.

if [[ $- == *i* ]]; then # in interactive session
  bind 'set editing-mode vi'
fi

With ble.sh setting in ~/.bashrc

After the load of the ble.sh, the following setting also enables the vi/vim mode. This setting overwrites all the other settings presented so far, i.e., settings like set -o emacs, etc. will be overwritten.

if [[ $- == *i* ]]; then # in interactive session

  # ... after the load of ble.sh ...

  bleopt default_keymap=vi
fi

2. Setting timeout for ESC

The total timeout for ESC is the sum of all the timeouts on the route from your terminal to Bash. Each timeout can be configured as shown here:

Timeout of stty

The timeout in pseudo-terminal handler can be configured by stty. Usually the default timeout is 0. The timeout can be changed by the following command. The unit is 1/10 second.

# in ~/.bashrc
stty time 0

Timeout of Bash-4.3

In Bash-4.3 or later, the timeout for Readline can be configured by readline variable keyseq-timeout. The readline variable can be specified in ~/.inputrc file. The unit is millisecond.

# in ~/.inputrc
$if Bash
  set keyseq-timeout 1
$endif

Instead of specifying in ~/.inputrc, the variable can also be changed in ~/.bashrc with the following command.

# in ~/.bashrc
bind 'set keyseq-timeout 1'

Timeout of screen

If you use terminal multiplexers, they also have timeouts. The timeout for GNU Screen can be configured in ~/.screenrc as follows. The unit is millisecond.

# in ~/.screenrc
maptimeout 1

Timeout of tmux

The timeout for tmux can be configured in ~/.tmux.conf. The unit is millisecond.

# in ~/.tmux.conf
set -sg escape-time 1

3. Possible preferences

Mode name for the normal mode

In vi/vim mode mode names, such as -- INSERT -- (for insert mode) or ~ (for normal mode), are shown. The mode name for the normal mode can be change by keymap_vi_normal_mode_name option:

bleopt keymap_vi_normal_mode_name:=$'\e[1m-- NORMAL --\e[m'

If you don't want to show a mode name in the normal mode, please add the following instead:

bleopt keymap_vi_normal_mode_name:=

(Insert mode) SP: magic-space / insert space

The default mapping of SP is magic-space which performs history expansion before inserting a space. If you want to have just a space without history expansion, please add the following setting.

ble-bind -m vi_insert -f 'SP' 'self-insert'

(Insert mode) C-k: kill-forward-line / digraphs

The default mapping of C-k is kill-forward-line. If you want to input digraphs with <C-k>{char1}{char2}, please add the following setting:

ble-bind -m vi_insert -f 'C-k' 'vi-insert/insert-digraph'

(Insert mode) C-o: single-command-mode / accept-and-next

The default mapping of C-o is vi-insert/single-command-mode. If you want to execute the current command line and load the next history entry with C-o, please add the following setting:

ble-bind -m vi_insert -f 'C-o' 'accept-and-next'

Or you may like C-@, instead of C-o, bound to accept-and-next:

ble-bind -m vi_insert -f 'C-@' 'accept-and-next'

surround.vim

Some of the functionalities are imported from github.com:tpope/vim-surround. To use them add the following line after loading ble.sh:

source "$_ble_base/lib/vim-surround.sh"

Currently only ys, yss, yS, ySS, cs, ds, vS, vgS are supported.

The implementation vim-surround.sh supports configurable replacements used by ys and cs with bleopt variables. The following codes show example configuration.

bleopt vim_surround_45:=$'$( \r )' # for ysiw-
bleopt vim_surround_61:=$'$(( \r ))' # for ysiw=
bleopt vim_surround_q:=\' # for ysiwq
bleopt vim_surround_Q:=\" # for ysiwQ

The variables of the form vim_surround_{number} is the setting for the Unicode character {number} specified in decimal. The variables of the form vim_surround_{alpha} is the setting for the character {alpha}. The form vim_surround_{alpha} is selected if both forms are defined for a character. If the value contains CR ($'\r' in bash scripts), the value is split into two parts with the first CR; the first and second part is used for the left and right enclosing delimiters, respectively. If the value does not contain CR, the value is directly used for both of the left and right delimiters.