I’d like to propose adding a simple vi mode implementation directly in pyrepl which offers basic motion and editing functionality. This should reduce friction for users who prefer to use vi editing mode and are forced to rely on the old REPL for this. Achieving feature parity in this regard with the old REPL might also help fully removing the old implementation.
I’d definitely aim to keep the implementation simple and avoid adding anything more than the basic editing commands to reduce the maintenance burden – I think it would make sense to scope this roughly to match the feature set in readline .
There are a couple if interesting questions around the implementation:
How would users enable vi mode? In the PR linked to the issue a PYREPL_VI_MODE environment variable is used, but this might be the most user-friendly approach. The implementation could look at the EDITOR environment variable as well and check for vi, vim, nvim and similar to opt the user in, but also enable turning it off through PYREPL_VI_MODE.
If any configuration is exposed, where would that live? I think ideally no configuration should be exposed, but users might want to tweak settings or reuse existing .inputrc configuration.
I use vim pretty much exclusively and I have used the REPL many times (although I would usually use ipython) but I have no idea what you are referring to.
It’s a readline thing; here’s an exerpt from my ~/.inputrc:
$include /etc/inputrc
set editing-mode vi
set show-mode-in-prompt On
IPython also has something like this, though I seem to have broken it for myself by moving my ~/.inputrc to see if that’s what IPython was reading to configure it
I tried using that in .inputrc with the Python 3.10 REPL and it doesn’t seem to do anything. Should I expect Python 3.10 to pick this up from .inputrc?
What is an example of using this to do something useful?
Only if compiled with readline . I just confirmed it working in Fedora’s Python 3.10.
I mostly just use it for navigation and sometimes for editing. It starts in input mode (which with show-mode-in-prompt On should cause your prompt to look like (ins)>>> ); Esc to command mode and then use the regular vi navigation and editing commands.
I gave up using the REPL when Python 3.13 arrived without vi mode. I now run a tiny script which fires up zed editor in Python # %% interactive cell mode (as you can also do in VS Code). Or I run marimo new. These approaches all support vi mode and work so nicely that I doubt I’d go back to using the REPL.
I would use this, but vi modes are always disappointing. I wish they would start an actual Neovim session and use that for all commands. That would give me my familiar keybindings, working . command, working extensions, etc.
How about instead of vi mode, come up with a protocol for line editing and file an issue with Neovim to support calling into nvim with some arguments to edit a line? Then maybe we can convince my terminal to do the same thing.
There’s probably a (neo)vim plugin for something like that already. Of course, it’d be in (neo)vim and not the python repl directly, but if it’d require (neo)vim to be installed you might as well keep the solution in (neo)vim.
While I think this would be very cool, it’s a much bigger undertaking than adding a simple but robust vi implementation in pyrepl. I’d be curious to hear what you miss in a REPL from typical vi implementations as a data point to decide what features makes sense.
I also think that adding a potential dependency on an external editor would be detrimental to the adoption of such a feature; there are many other vi clones out there and having to install neovim just to get vi mode in pyrepl could be a issue for many users (e.g. in many environments users cannot even freely install 3rd party packages, or they might simply not want to manage a neovim installation just for this).
My intention is to implement vi mode in a way that it improves the basic editing experience for vi users and does not complicate pyrepl too much. My goal would be to roughly replicate the emacs-style editing features currently present in pyrepl (e.g. yank&paste, undo/redo, a couple of the more complex editing commands which operate on words and lines, etc.). This is purely intended as an alternative to the emacs editing mode currently present in pyrepl and a not a full vim editing experience.
The old REPL implementation supports vi mode through readline, which does not work anymore in pyrepl so users can see this as a regression where the new implementation removed functionality they relied on. Users explicitly mention that they set PYTHON_BASIC_REPL=1 to get the line editing functionality back and thus lock themselves to the old REPL implementation.
I think a line editing protocol is an overkill and I see very little reason to expose more functionality than what readline offers. I doubt anyone expects the Python REPL to become a full blown editing environment. This doesn’t attempt to do more than restore the previous functionality and implement analogues to the emacs-style editing commands which exist today in pyrepl and offer users the choice they enjoyed with the old REPL to switch between emacs or vi-style key bindings.