Skip to content

VioletJewel/vimterm.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 

Repository files navigation

vimterm.nvim

About

Make neovim's :term become vim's :term.

This plugin:

  • adds a 'termwinkey' to neovim
    • eg, <C-w>p navigates to the previous window just like in normal mode
    • terminal mode automatically resumes when moving back to a terminal window
  • automatically starts terminal mode on TermOpen
  • provides the :Sterminal user command that works like vim's :term (see Split Terminals)
  • automatically closes the terminal window when the default 'shell' terminates "successfully"
  • sets b:vimterm_name to a nicer name for use with 'statusline' (see Statusline Name)

tl;dr instead of <C-\><C-n><C-w>p{do-work}<C-w>pi, just do <C-w>p{do-work}<C-w>p. <C-w> just works as expected™.

See nvim vs vim Terminal Differences and Typical Workflow.

Installation

Ie, with lazy.nvim:

{
  'VioletJewel/vimterm.nvim',
  config = { ... }
}

Alternatively, install it with a package manager, and then do something like the following once it is loaded:

local vtok, vimterm = pcall(require, 'vimterm')
if vtok then
  vimterm.setup{ ... }
end

Note: Replace ... with some or all of the modified Default Config below (or leave it empty).

Note: You must call vimterm.setup() directly (eg, require'vimterm'.setup()) or indirectly (eg, lazy.nvim's config = {}).

Default Config

{
  termwinkey = '<C-w>',
  autoclose = true,
  autostartinsert = true,
  abbrevhack = true,
}
Option Description
termwinkey similar to vim's 'termwinkey'
autoclose should the terminal close if the default shell exited successfully
autostartinsert should the terminal automatically :startinsert after opening
abbrevhack should vimtern.vim auto-expand :term and :vterm to :Sterm and :vert Sterm using cabbrev hack

Split Terminals

:Sterminal opens a split terminal. This is how :terminal behaves in vim.

You can pass {mods} like vertical, belowright, aboveleft, tab, etc. See :command-modifiers.

{cmd} is an optional command that is forwarded to :terminal. See the help for more info about {cmd}

Example Description
:Sterm opens the default 'shell' in a horizontally split terminal
:below vert Sterm opens the default 'shell' vertically split terminal on the right
:Sterm python opens a python repl in a horizontally split terminal
:tab Sterm opens a terminal in a new tab page

Term and Vterm Hacks

:term and :vterm also automagically expand to :Sterm and :vert Sterm (resp.).

Notes:

  • after you type ":term" and a space, :term transforms instantly to :Sterm (because of using :cabbrev)
  • you cannot use {mods} like you can with :Sterminal (ie, :vert term won't expand)
  • these also have to be the first word in the cmdline (ie, neither : term nor :echo 'hi'|term will work).

Terminal Differences

Essentially, vim has a decent user experience out of the box, while neovim expects you to use a plugin or make custom maps. Although this plugin resolves these differences, there is some divergence.

Neovim Terminal

In neovim, :terminal opens in the current window (not a split) in normal mode. Also, neovim provides two terminal commands:

This is limited and would cause a very noisy workflow without any customization. Perhaps it is expected that you will use a plugin that manages terminals for you (such as a pop-up terminal or a terminal similar to vscode's terminal on the bottom) or use these two terminal commands to create your own custom mappings.

Vim Terminal

In vim, :terminal opens in a split window and starts terminal mode by default. Vim also has t_CTRL-\_CTRL-N (there is no t_CTRL-W_CTRL-O) but also provides a handy 'termwinkey'). By default, 'termwinkey' is <C-w>.

'termwinkey' is very handy because it allows you to perform actions from terminal mode, navigate quickly to other windows or tab pages and resume terminal mode when coming back to that terminal window, insert registers, and a few other handy maps to tie up some loose ends. Here are the features of 'termwinkey' (<C-w> used as 'termwinkey', but it can be changed) when in terminal mode:

Term Cmd Description Vim Help
<C-w>N same as <C-\><C-n> t_CTRL-W_N
<C-w><C-n> same as <C-\><C-n> and <C-w>N t_CTRL-W_N (same section as <C-w>N)
<C-w>:{cmd} issue one-off ex {cmd} t_CTRL-W_%
<C-w><C-w> move focus to the next window (replace this with any CTRL-W window command) t_CTRL-W_CTRL-W
<C-w>[{count}]"{reg} insert {reg} {count} times (eg, <C-w>2"+ to insert PRIMARY clipboard twice) t_CTRL-W_quote
<C-w>. insert literal <C-w> t_CTRL-W_.
<C-w><C-\> insert literal <C-\> t_CTRL-W_N
<C-w>[{count}]gt go to next tab page {count} times t_CTRL-W_gt
<C-w>[{count}]gT go to previous tab page {count} times t_CTRL-W_gt

Statusline Name

The terminal name (%f in 'statusline') in neovim is unpleasant to look at . This plugin sets b:vimterm_name. You can set 'statusline' with the TermOpen autocmd or so. The following is somewhat robust yet simple:

local auid = vim.api.nvim_create_augroup('vimterm_config', {})
vim.api.nvim_create_autocmd('TermOpen', {
  group = auid,
  callback = function(evt)
    local wo = vim.wo[vim.fn.bufwinid(evt.buf)]
    -- replace first %f in statusline with b:vimterm_name
    wo.statusline = wo.statusline:gsub('%%f', '%{get(b:, 'vimterm_name', 'term')}', 1)
  end
})

Divergence

This plugin cannot completely mimic vim's :term. The main differences are detailed here:

  • :term is a hack and can't accept command modifiers
  • <C-w><C-c> doesn't terminate the job
  • <C-w>. accepts a count (eg, <C-w>4. inserts four literal <C-w> bytes)
  • <C-w><C-\> accepts a count
  • there is no 'termwinkey' in neovim, but it can be changed via the config

Typical Workflow

Using termwinkey = '<C-w>' (the default - see Default Config):

Cmd Description
:term open a split terminal [1][2]
<C-w>p switch to the previous window [3]
<C-w>:set winfixheight<CR> run the ex command :set winfixheight
<C-w>10_ set the terminal window's height to 10 lines
<C-w>= make all windows the same size [4]
<C-w>"+ insert the system's PRIMARY clipboard
  • [1] other examples could also be :vterm to open in a vertical split or :term python to open a python repl
  • [2] you'll already be in terminal mode, so just start typing
  • [3] when you come back, vimterm.nvim will :startinsert will be run automatically to put you back into terminal mode
  • [4] except we already set 'winfixheight' so the terminal window will remain only 10 lines tall

This is what it would look like otherwise:

  • :sp|term
  • <C-\><C-n><C-w>p (i when returning to the terminal window)
  • <C-\><C-o>:set winfixheight<CR>
  • <C-\><C-o>:wincmd 10_<CR>
  • <C-\><C-o>:wincmd =<CR>
  • <C-\><c-o>"+p

About

vim :term in neovim

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages