NeoVim :terminal is not the default, to use it you will have to add this line to your .vimrc
:
let g:slime_target = "neovim"
When you invoke vim-slime
for the first time, :SlimeConfig
or one of the send functions, you will be prompted for more configuration.
If the global variable g:slime_suggest_default
is:
-
Nonzero (logical True): The last terminal you opened before calling vim-slime will determine which job ID is presented as default. If that terminal is closed, one of the previously opened terminals will be suggested on subsequent configurations. The user can tab through a popup menu of valid configuration values.
-
0
(logical False), or nonexistent: No default will be suggested.
In either case, in Neovim's default configuration, menu-based completion can be activated with <Tab>
/<S-Tab>
, and the menu can be navigated with <Tab>
/<S-Tab
or <C-n>
/<C-p>
. Autocompletion plugins such as nvim-cmp can interfere with this.
To use the terminal's PID as input instead of Neovim's internal job ID of the terminal:
let g:slime_input_pid=1
The PID
is included in the terminal buffers' name, visible in the default terminal window status bar.
To be prompted with a numbered menu of all available terminals which the user can select from by inputting a number, or, if the mouse is enabled, clicking on an entry, set g:slime_menu_config
to a nonzero value.
let g:slime_menu_config=1
This takes precedence over g:slime_input_pid
.
The default order of fields in each terminal description in the menu is
pid
The system process identifier of the shell.jobid
The Neovim internal job number of the terminal.term_title
Usually either the systemname, username, and current directory of the shell, or the name of the currently running process in that shell. (unlabeled by default)name
The name of the terminal buffer (unlabeled by default).
The user can reorder these items and set their labels in the menu in the menu by setting a global variable, g:slime_neovim_menu_order
, that should be an array of dictionaries. Keys should be exactly the names of the fields, shown above, and the values (which should be strings) will be the labels in the menu, according to user preference. Use empty strings for no label. The dictionaries in the array can be in the user's preferred order.
For example:
let g:slime_neovim_menu_order = [{'name': 'buffer name: '}, {'pid': 'shell process identifier: '}, {'jobid': 'neovim internal job identifier: '}, {'term_title': 'process or pwd: '}]
The user can also set the delimiter (including whitespace) string between the fields (,
by default) with g:slime_neovim_menu_delimiter
.
let g:slime_neovim_menu_delimiter = ' | '
No validation is performed on these customization values so be sure they are properly set.
By default Slime can send send text to unlisted terminals (such as those created by toggleterm.nvim.
To disable this capability, and prevent unisted terminals from being shown in menu configuration and from being suggested as a default set g:slime_neovim_ignore_unlisted = 1
(or to any other logically true value). Setting g:slime_neovim_ignore_unlisted = 0
preserves the default of being able to send to unlisted terminals.
As mentioned earlier, the PID
of a process is included in the name of a terminal buffer.
To manually check the right value of the terminal job ID:
:echo &channel
To manually check the right value of the terminal job PID:
:echo jobpid(&channel)
from the buffer running your terminal.
Another way to easily see the PID
and job ID is to override the status bar of terminals to show the job ID and PID.
" in case an external process kills the terminal's shell and &channel doesn't exist anymore
function! Safe_jobpid(channel_in)
let pid_out = ""
" in case an external process kills the terminal's shell; jobpid will error
try
let pid_out = string(jobpid(a:channel_in))
catch /^Vim\%((\a\+)\)\=:E900/
endtry
return pid_out
endfunction
autocmd TermOpen * setlocal statusline=%{bufname()}%=id:\ %{&channel}\ pid:\ %{Safe_jobpid(&channel)}
See h:statusline
in Neovim's documentation for more details.
If you are using a plugin to manage your status line, see that plugin's documentation to see how to configure the status line to display &channel
and jobpid(&channel)
.
Many status line plugins for Neovim are configured in lua.
A useful Lua function to return the Job ID of a terminal is:
local function get_chan_jobid()
return vim.api.nvim_eval('&channel > 0 ? &channel : ""')
end
A useful Lua function to return the Job PID of a terminal is:
local function get_chan_jobpid()
local out = vim.api.nvim_exec2([[
let pid_out = ""
try
let pid_out = string(jobpid(&channel))
" in case an external process kills the terminal's shell; jobpid will error
catch /^Vim\%((\a\+)\)\=:E900/
endtry
echo pid_out
]], {output = true})
return out["output"] --returns as string
end
Those confused by the syntax of the vimscript string passed as an argument to vim.api.nvim_eval
should consult :h ternary
.
Here is an example snippet of vimscript to set the status line for buffers that are configured to send code to a terminal:
" Function to safely check for b:slime_config and return the job ID
function! GetSlimeJobId()
if exists("b:slime_config") && type(b:slime_config) == v:t_dict && has_key(b:slime_config, 'jobid') && !empty(b:slime_config['jobid'])
return ' | jobid: ' . b:slime_config['jobid'] . ' '
endif
return ''
endfunction
" Function to safely check for b:slime_config and return the pid
function! GetSlimePid()
if exists("b:slime_config") && type(b:slime_config) == v:t_dict && has_key(b:slime_config, 'pid') && !empty(b:slime_config['pid'])
return 'pid: ' . b:slime_config['pid']
endif
return ''
endfunction
"default statuslin with :set ruler
set statusline=%<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %P
" Append the custom function outputs to the right side of the status line, with " | " as a separator
Can be useful for status line plugins:
local function get_slime_jobid()
if vim.b.slime_config and vim.b.slime_config.jobid then
return vim.b.slime_config.jobid
else
return ""
end
end
local function get_slime_pid()
if vim.b.slime_config and vim.b.slime_config.pid then
return vim.b.slime_config.pid
else
return ""
end
end
Instead of the prompted job ID input method detailed above, you can specify a lua function that will automatically configure vim-slime with a job id:
vim.g.slime_get_jobid = function()
-- some way to select and return job ID
end
The details of how to implement this are left to the user.
This is not possible or straightforward to do in pure vimscript due to capitalization rules of functions stored as variables in Vimscript.
vim.api.nvim_eval
(see :h nvim_eval()
) and other Neovim API functions are available to access all or almost all vimscript capabilities from Lua.
Example Installation and Configuration with lazy.nvim
{
"jpalardy/vim-slime",
init = function()
-- these two should be set before the plugin loads
vim.g.slime_target = "neovim"
vim.g.slime_no_mappings = true
end,
config = function()
vim.g.slime_input_pid = false
vim.g.slime_suggest_default = true
vim.g.slime_menu_config = false
vim.g.slime_neovim_ignore_unlisted = false
-- options not set here are g:slime_neovim_menu_order, g:slime_neovim_menu_delimiter, and g:slime_get_jobid
-- see the documentation above to learn about those options
-- called MotionSend but works with textobjects as well
vim.keymap.set("n", "gz", "<Plug>SlimeMotionSend", { remap = true, silent = false })
vim.keymap.set("n", "gzz", "<Plug>SlimeLineSend", { remap = true, silent = false })
vim.keymap.set("x", "gz", "<Plug>SlimeRegionSend", { remap = true, silent = false })
vim.keymap.set("n", "gzc", "<Plug>SlimeConfig", { remap = true, silent = false })
end,
}