How to set and determine the command-line editing mode of Bash?

To set:

set -o vi

Or:

set -o emacs

(setting one unsets the other. You can do set -o vi +o vi to unset both)

To check:

if [[ -o emacs ]]; then
  echo emacs mode
elif [[ -o vi ]]; then
  echo vi mode
else
  echo neither
fi

That syntax comes from ksh. The set -o vi is POSIX. set -o emacs is not (as Richard Stallman objected to the emacs mode being specified by POSIX) but very common among shell implementations. Some shells support extra editing modes. [[ -o option ]] is not POSIX, but supported by ksh, bash and zsh. [ -o option ] is supported by bash, ksh and yash (note that -o is also a binary OR operator for [).


Since your question is specific about bash:

To set it permanently for every new session:

echo 'set -o vi' >> ~/.bashrc

or (recommended), add (or change) a line in ./inputrc:

set editing-mode vi

This will set the editing mode of readline which is used by several other programs beside bash.

It is easy to unset both options:

shopt -ou vi emacs

To set one, either:

set -o vi

Or

shopt -os vi

The same for emacs. Setting vi unsets emacs and viceversa.

To list the state:

$ shopt -op emacs
set +o emacs

$ shopt -op vi
set -o vi

Or both at once:

$ shopt -op emacs vi
set +o emacs
set -o vi

To test if vi is set:

shopt -oq vi      &&   echo vi is set

Or (ksh syntax):

[[ -o vi ]]        &&   echo vi is set

emacs:

shopt -oq emacs   &&   echo emacs is set

Or:

[[ -o emacs ]]    &&   echo emacs is set

or, to test that no option is set:

! ( shopt -oq emacs || shopt -oq vi ) && echo no option is set

There is also bind -V | grep editing-mode.

man bash is huge but well worth reading in depth.

Tags:

Vi

Emacs

Bash