I use vi editing mode in bash. I have "show-mode-in-prompt" set to "on" in ~/.inputrc.
show-mode-in-prompt (Off)
If set to On, add a string to the beginning of the prompt indicating the editing mode: emacs, vi command, or vi insertion. The mode strings are user-settable (e.g., emacs-mode-string).
So now I can see the editing mode at the beginning of my prompt.
i:$ # This is ins mode
c?$ # This is cmd mode
i:$ cat ~/.inputrc
set editing-mode vi
set show-mode-in-prompt on
set vi-ins-mode-string "\1\e[1;32m\2i:\1\e[0m\2"
set vi-cmd-mode-string "\1\e[1;31m\2c?\1\e[0m\2"
set colored-stats on
i:$ echo $PS1
$
I'd really like this at the end of my prompt though, and prepend the current directory, i.e.
/current/dir/here $ i:
But I"m not sure if this is achievable. My first thought was to use a carriage return in PS1, but unfortunately this overwrites the mode string.
i:$ PS1='\r\w $ '
~/projects $
My second thought was to somehow get the mode string and just insert it into $PROMPT_COMMAND, instead of letting readline write it to the prompt. I can get the current mode with:
i:$ bind -v | grep keymap | awk '{print $3}'
vi-insert
But the PROMPT_COMMAND value is only executed before the prompt is issued, so I wouldn't see the mode change.
Attempt number 3 included padding my mode strings so there's room for the directory. This could work, but I don't know how I'd make the amount of space variable. Also the prompt is going to start before the mode string, the mode string will get overwritten by my command, and if I switch modes the text I've typed gets replaced by the whole mode string, effectively clearing it out due to the spaces.
i: cat ~/.inputrc
set editing-mode vi
set show-mode-in-prompt on
set vi-ins-mode-string " \1\e[1;32m\2i:\1\e[0m\2"
set vi-cmd-mode-string " \1\e[1;31m\2c?\1\e[0m\2"
set colored-stats on
i: PS1="\r\w $ "
~/projects $ i:
~/projects $ # typing stuff i:
~/projects $ # typing more stuff overwrites the mode line
~/projects $ c?verwrites the mode line
Is there some other clever way to do this? Maybe a control character like carriage return that jumps to the beginning of the line but does not overwrite the existing characters?
i:$ echo $BASH_VERSION
5.0.7(1)-release