115

Currently in Bash I use set -o vi to enable vi mode in my bash prompt.

How do I get this going in ipython?

codeforester
  • 39,467
  • 16
  • 112
  • 140
gak
  • 32,061
  • 28
  • 119
  • 154

7 Answers7

211

In case someone's wandering in here recently, IPython 5.0 switched from readline to prompt_toolkit, so an updated answer to this question is to pass an option:

$ ipython --TerminalInteractiveShell.editing_mode=vi

... or to set it globally in the profile configuration (~/.ipython/profile_default/ipython_config.py; create it with ipython profile create if you don't have it) with:

c.TerminalInteractiveShell.editing_mode = 'vi'
imiric
  • 8,315
  • 4
  • 35
  • 39
  • 7
    Thanks. This is annoyingly difficult to find anywhere in the docs for IPython, Jupyter, or prompt_toolkit. – nth Jul 17 '16 at 17:13
  • 3
    Where do I add my custom key binding mappings? – Aravinda Jul 21 '16 at 12:17
  • My answer to [this question](http://stackoverflow.com/questions/38443907/how-does-one-set-specific-vim-bindings-in-ipython-5-0-0/38810821#38810821) shows one way to do add custom key bindings. – jellycola Aug 09 '16 at 23:16
  • One must upgrade ipython to 5.0 before this works: `pip install ipython --upgrade` – Peaceful Dec 20 '16 at 07:13
  • 3
    Is there any way to keep track of if I'm in normal mode or insert mode? – Peeyush Kushwaha Oct 04 '18 at 06:45
  • Great answer, thank you. Always reassuring when you read an easy answer like this to know you are dealing with a well-conceived tool that has your back. – arcseldon Feb 18 '19 at 15:55
  • `c.TerminalInteractiveShell.editing_mode = 'vi'` `c.TerminalInteractiveShell.editor = u'vim'` `c.TerminalInteractiveShell.extra_open_editor_shortcuts = True` – NeilG Jun 19 '20 at 12:01
  • To avoid emacs bindings messing with your `esc` behavior, set `c.TerminalInteractiveShell.emacs_bindings_in_vi_insert_mode = False` (on 8.0.0) – micimize Jan 12 '22 at 15:30
  • After leaving ipython, on 8.0.0, my terminal was messed up but upgrading to 8.11.0 has fixed it! ❤️ – HeyWatchThis Mar 26 '23 at 19:00
32

Looks like a solution works for many other readline compatible apps:

Set the following in your ~/.inputrc file:

set editing-mode vi
set keymap vi
set convert-meta on

Source: http://www.jukie.net/bart/blog/20040326082602

gak
  • 32,061
  • 28
  • 119
  • 154
  • 8
    Be *very* careful with `set convert-meta on`. It conflicts with unicode entry, so if you paste or type unicode, you can trigger various events, which may be surprising. For instance, try to type ü, and you will see an interesting result. – minrk May 01 '12 at 19:13
  • 4
    Do you know what the last two lines do? A quick check shows that just the first line gives basic vi keybindings - I wish I knew whether there was a reason to add the others. – weronika May 03 '12 at 01:56
  • 1
    @weronika It looks like [`set keymap vi` changes which keymap (i.e. mode) the following commands will affect](http://stackoverflow.com/a/10002721/84745), and [`set convert-meta on` changes how some keys behave](http://www.gnu.org/software/bash/manual/html_node/Readline-Init-File-Syntax.html). I'm not sure if you need them. – s4y Jul 05 '13 at 18:53
  • @weronika So, `set convert-meta on` (and anything below that line) will only apply to command mode, not insert mode. – s4y Jul 05 '13 at 18:55
  • 6
    Note: This no longer works as of IPython 5.0.0. See @imiric's answer below. – Jason Sundram Jul 16 '16 at 20:48
13

You can also interactively switch between Vi-mode and Emacs mode. According to the the readline docs to switch between them you are supposed to be able to use the 'Meta'+CTRL+j key combination but that only seems to allow me to switch to vi-mode - on my Mac (where ESC is used as the 'Meta' key) it is: ESC+CTRL+j. To switch back to Emacs mode one can use CTRL+e but that didn't appear to work for me - I had to instead do 'Meta'+CTRL+e - on my Mac it is: ESC+CTRL+e.

FYI my ~/.inputrc is set up as follows:

set meta-flag on
set input-meta on
set convert-meta off
set output-meta on
Pierz
  • 7,064
  • 52
  • 59
11

ipython uses the readline library and this is configurable using the ~/.inputrc file. You can add

set editing-mode vi

to that file to make all readline based applications use vi style keybindings instead of Emacs.

Noufal Ibrahim
  • 71,383
  • 13
  • 135
  • 169
10

I needed to be able to switch modes interactively in IPython 5 and I found you can do so by recreating the prompt manager on the fly:

a = get_ipython().configurables[0]; a.editing_mode='vi'; a.init_prompt_toolkit_cli()
Lexi
  • 1,670
  • 1
  • 19
  • 35
1

Adding the following two configs in ~/.ipython/profile_default/ipython_config.py will help you use vi bindings and prevent an annoying slowness issue (related to switching between vim modes):

c.TerminalInteractiveShell.editing_mode = 'vi'
c.TerminalInteractiveShell.emacs_bindings_in_vi_insert_mode = False
Harsh Verma
  • 529
  • 6
  • 10
0

You may set vi in your .ipython start-up config file. Create one if you don't have it by adding a file to ~/.ipython/profile_default/startup/ called something like start.py. Here's an example:

# Initializing script for ipython in ~/.ipython/profile_default/startup/
from IPython import get_ipython
ipython = get_ipython()

# If in ipython, set vi and load autoreload extension
if 'ipython' in globals():
    ipython.editing_mode = 'vi'
    ipython.magic('load_ext autoreload')
    ipython.magic('autoreload 2')
from Myapp.models import * 

That last line is if you use ipython with Django, and want to import all your models by default.

gregory
  • 10,969
  • 2
  • 30
  • 42