Vim key bindings not working in terminal python interpreter
MWE
To reproduce:
- Add
bindkey -v
to your~/.zshrc
. - Invoke python interpreter:
python
. - Type something into the prompt without hitting
ENTER
:this = "this" + "that"
. - Press
ESC
and try anyvim
bindings successively:bb
.
Problem
The behavior is not consistent. Sometimes the cursor highlighting does not match the mode (see Notes for code used), sometimes I have to press ESC
before each vim
key entry.
Notes
Using Arch Linux, st
terminal, zsh
, and python
3.10.9.
I am using the following code in my ~/.zshrc
to change the cursor to indicate mode:
# change cursor shape for different vi modes
cursor_mode() {
# See https://ttssh2.osdn.jp/manual/4/en/usage/tips/vim.html for cursor shapes
cursor_block='\e[2 q'
cursor_beam='\e[6 q'
function zle-keymap-select {
if [[ ${KEYMAP} == vicmd ]] ||
[[ $1 = 'block' ]]; then
echo -ne $cursor_block
elif [[ ${KEYMAP} == main ]] ||
[[ ${KEYMAP} == viins ]] ||
[[ ${KEYMAP} = '' ]] ||
[[ $1 = 'beam' ]]; then
echo -ne $cursor_beam
fi
}
zle-line-init() {
echo -ne $cursor_beam
}
zle -N zle-keymap-select
zle -N zle-line-init
}
cursor_mode
1 answer
The following users marked this post as Works for me:
User | Comment | Date |
---|---|---|
mcp |
Thread: Works for me Outstanding! Thanks! |
Feb 7, 2023 at 22:09 |
Python's interactive interpreter uses GNU Readline, so Bash's line interpreter, not Zle, which is Zsh's.
Therefore, when you enter python
, the cursor either won't change or will change accordingly to what you have in .inputrc
, which is GNU Readline's initialization file. Likewise for the Vi or Emacs input mode.
For a visual proof that zle-line-init
and zle-keymap-select
don't get to run while you are in Python, just modify the cursor variables to
#Warning: This will be annoying
cursor_block=a
cursor_beam=b
Restart Zsh and you will see that, while those characters are inserted as expected in the Zsh prompt, they are never inserted in the Python prompt.
Luckily, you can (at least according to my quick inspection) clone that Zle's behavior for GNU Readline:
# This goes in $HOME/.inputrc
set editing-mode vi
set show-mode-in-prompt on
set vi-cmd-mode-string "\1\e[2 q\2"
set vi-ins-mode-string "\1\e[6 q\2"
# Previous three lines are from https://stackoverflow.com/a/48449104
and then Python will behave consistently.
0 comment threads