Russ Tokuyama

Neovim and REPLs

Last update: 07/05/2023
Back to home
Back to Posts

This is about sending code that you're editing in a buffer to another process running a REPL (interactive program) for the programming language you're working with. Hopefully, this should help put things in perspective.

My goal is to try to understand how the plugins go about doing their thing.

Disclaimer

I've used vim-slime in the past for some Python coding but am currently using Conjure. I've yet to use Conjure for Clojure coding. I've also submitted some PRs for tiny improvements to Python coding with Conjure. They take advantage of the Tree-sitter support in Neovim.

Various Plugins

There are Vim plugins that help with the goal of sending code to a REPL.

Plugin Implementation IPC Mechanism
Conjure Fennel, Lua uv.spawn(), uv.write()
iron.nvim Lua termopen(), chansend()
Uses bracketed paste mode when sending Python code.
vim-fireplace Vimscript, Python jobstart({cmd}), chansend()
where {cmd} is something like ['python', '.../pythonx/fireplace.py', 'nrepl://127.0.0.1:7888']
vim-slime Vimscript :sp term://{cmd}, chansend()

I haven't looked into these plugins.

Plugin Implementation IPC Mechanism
neoterm
vimcmdline
vim-simpl
vlime

Sending Code to a Sub-process

These are the facilities in Neovim that let one send stuff to a child process spawned by the main Neovim process. For more information about the IPC Mechanism, see the Neovim help (:help <topic>; for example: :he luv).

IPC Mechanism Create Sub-process Send To Sub-process Read From Sub-process
luv uv.spawn() (Lua) uv.write() Via callback on handles for stdout and stderr.
terminal-emulator termopen() (Vimscript) chansend() Via callbacks: on_stdout only (see :he jobstart-options).
terminal-emulator :sp term://{cmd} (Command-line mode) chansend() Not available
job-control jobstart() (Vimscript) chansend() Via callbacks: on_stdout and on_stderr.

About the Terminal-Emulator

There are at least two ways to start a terminal emulator Sub-process. termopen() and :sp term://{cmd}. The difference between the two is how they are typically used. The latter is generally invoke in command-line mode. However, Neovim provides the mechanism to use both programmatically.

While termopen() and jobstart() take the same arguments, termopen() is more specialized than jobstart(). termopen() automatically sets the pty option of the jobstart-options. Thus, the output of the program (cmd) running in the terminal-emulator is only available via stdout (combination of stdout and stderr).