Want to see the full-length video right now for free?
Sign In with GitHub for Free AccessHere 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.
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.
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>
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.
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.
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.