Video

Want to see the full-length video right now for free?

Sign In with GitHub for Free Access

Notes

Here we have a fresh Neovim instance. I'm going to open up two split windows side by side, with a terminal buffer in each one.

:split | terminal
:vsplit | terminal

If we want to run a command in either of these terminals, we could do so directly by activating that split window, switching to Terminal mode, and typing the command right there. But Neovim also lets us manipulate these terminal buffers programatically, via the jobsend() command.

:help jobsend()

This takes two arguments: the jobid, and the data to be sent to that job. We can discover the jobid of our two existing terminal buffers by inspecting their b:terminal_job_id variables.

:echo b:terminal_job_id

Here we've got job numbers one and two. Let's feed those job ids into the jobsend() function.

:call jobsend(1, "echo 'Hello from terminal one'\n")
:call jobsend(2, "echo 'Hello from terminal two'\n")

And those commands are run in their respective terminal buffers.

You probably don't want to be calling the jobsend() command by hand in this manner. But you could create custom commands and mappings that call this function under the hood. Let's have a look at a plugin that does just that.

Meet Neoterm

The Neoterm plugin, by Kassio Borges, adds some extra convenience around Neovim's built-in terminal buffers. I've already installed the neoterm plugin, so let's run through a demonstration.

We can open a new Neoterm by running:

:Tnew

The terminal can be identified by the neoterm-1 title. Then we can send commands to the Neoterm using the big-T command:

:T pwd
:T ls
:T echo 'Hello Neoterm!'

We can clear the Neoterm with:

:Tclear

And we can close it with:

:Tclose

That closes the window and hides the terminal buffer, but the terminal buffer is still there and we can send commands to it while it's hidden.

:ls 
:T echo 'Commands can run in the background'

Then we can open the Neoterm again with:

:Topen

As you can see, the echo command ran just fine while the terminal was hidden.

tab completion

The big-T command is convenient, because it lets you run commands directly from Vim's commandline mode. But it does have one notible weakness: you don't get the same tab complete behaviour as you would in the shell. For example, if I use big-T then type out an incomplete git command, pressing the tab key doesn't provide any useful suggestions.

:T git checkout fea<Tab>

To get around this, we can activate the neoterm buffer and switch to terminal mode. This time, if I type out the same git command, pressing the tab key provides useful suggestions.

git checkout fea<Tab>

Getting the path of the current buffer

In Ex commands, we can use the % symbol as a shorthand for the path of the buffer that is currently active.

:help cmdline-special

This works nicely with the big-T command. For example, we can run "cat percent" to output the contents of a file:

:e fib.rb
:T cat %

The resulting commandline replaces the % symbol with the filepath of the active buffer. We could just as easily execute the file:

:T ruby %

Neoterm really comes into its own when you want to run a command that uses the filepath or contents of the buffer that's currently active.

REPL

We can use Neoterm to send the contents of a buffer to a REPL. Here, I've got a ruby file open.

:e scratch.rb

We can run the command:

:TREPLSendFile

Neoterm has detected that the current file is a ruby file, so it automatically launches an IRB session.

We could send the current line of code only to the REPL using:

:TREPLSendLine

Or we could send selected text only to the REPL using:

:TREPLSendSelection

If you're using Neoterm with a repl like this, you'll probably want to create mappings for each of those commands to make things more convenient.

Test runner

Here we've got a ruby file containing tests. Running the current file via Neoterm is simple:

:T ruby %

You could set up a simple mapping to run this command.

Alternatively, I suggest installing another plugin: vim-test, by Janko Marohnić. This plugin integrates nicely with Neoterm.

Having installed the plugin, I can run the command:

:TestFile

The default strategy is to run the command using colon-bang.

But we can change the strategy to use Neoterm by running:

:let test#strategy='neoterm'

Now when we run the :TestFile command, the tests are run in the Neoterm buffer.

The vim-test plugin also provides a :TestNearest command, which runs the test closest to the cursor position.

And also a :TestLast command, which re-runs the most recent test (regardless of where your cursor is now).

The vim-test plugin supports lots of different languages and testing frameworks. And besides integrating with Neoterm, it supports a range of different strategies. It's a good one to add to your toolbox.