Toggleterm.nvim
A neovim lua plugin to help easily manage multiple terminal windows
Install / Use
/learn @akinsho/Toggleterm.nvimREADME

Multiple orientations
- Float

- Vertical

- Tab

Send commands to different terminals
<!-- panvimdoc-ignore-start -->
Winbar (Experimental/Nightly ONLY)
<!-- panvimdoc-ignore-start --> <img width="1728" alt="image" src="https://user-images.githubusercontent.com/22454918/179199998-75ec16cb-8271-490e-925f-6c82c50ffc5d.png"> <!-- panvimdoc-ignore-end -->Requirements
This plugin only works in Neovim 0.7 or newer.
Installation
Using packer in lua
use {"akinsho/toggleterm.nvim", tag = '*', config = function()
require("toggleterm").setup()
end}
Using lazy.nvim in lua
{
-- amongst your other plugins
{'akinsho/toggleterm.nvim', version = "*", config = true}
-- or
{'akinsho/toggleterm.nvim', version = "*", opts = {--[[ things you want to change go here]]}}
}
Using vim-plug in vimscript
Plug 'akinsho/toggleterm.nvim', {'tag' : '*'}
lua require("toggleterm").setup()
You can/should specify a tag for the current major version of the plugin, to avoid breaking changes as this plugin evolves.
To use a version of this plugin compatible with nvim versions less than 0.7 please use the tag v1.*.
Notices
- 28/07/1990 — If using
persist_modeterminal mappings should be changed to usewincmdinstead otherwise persist mode will not work correctly. See here for details.
Why?
Neovim's terminal is a very cool, but not super ergonomic tool to use. I find that I often want to set a process going and leave it to continue to run in the background. I don't need to see it all the time. I just need to be able to refer back to it at intervals. I also sometimes want to create a new terminal and run a few commands.
Sometimes I want these side by side, and I really want these terminals to be easy to access.
I also want my terminal to look different from non-terminal buffers, so I use winhighlight to darken them based on the Normal
background colour.
This is the exact use case this was designed for. If that's your use case this might work for you.
Roadmap
All I really want this plugin to be is what I described above. A wrapper around the terminal functionality.
It basically (almost) does all that I need it to.
I won't be turning this into a REPL plugin or doing a bunch of complex stuff. If you find any issues, please consider a pull request not an issue. I'm also going to be pretty conservative about what I add.
Setup
This plugin must be explicitly enabled by using require("toggleterm").setup{}
Setting the open_mapping key to use for toggling the terminal(s) will set up mappings for normal mode. The open_mapping can be a key string or an array of key strings.
If you prefix the mapping with a number that particular terminal will be opened. Otherwise if a prefix is not set, then the last toggled terminal will be opened. In case there are multiple terminals opened they'll all be closed, and on the next mapping key they'll be restored.
If you set the insert_mappings key to true, the mapping will also take effect in insert mode; similarly setting terminal_mappings to true will have the mappings take effect in the opened terminal.
However you will not be able to use a count with the open mapping in terminal and insert modes. You can create buffer specific mappings to exit terminal mode and then use a count with the open mapping. Check Terminal window mappings for an example of how to do this.
alternatively you can do this manually (not recommended but, your prerogative)
" set
autocmd TermEnter term://*toggleterm#*
\ tnoremap <silent><c-t> <Cmd>exe v:count1 . "ToggleTerm"<CR>
" By applying the mappings this way you can pass a count to your
" mapping to open a specific window.
" For example: 2<C-t> will open terminal 2
nnoremap <silent><c-t> <Cmd>exe v:count1 . "ToggleTerm"<CR>
inoremap <silent><c-t> <Esc><Cmd>exe v:count1 . "ToggleTerm"<CR>
NOTE: Please ensure you have set hidden in your neovim config, otherwise the terminals will be discarded when closed.
WARNING: Please do not copy and paste this configuration! It is here to show what options are available. It is not written to be used as is.
require("toggleterm").setup{
-- size can be a number or function which is passed the current terminal
size = 20 | function(term)
if term.direction == "horizontal" then
return 15
elseif term.direction == "vertical" then
return vim.o.columns * 0.4
end
end,
open_mapping = [[<c-\>]], -- or { [[<c-\>]], [[<c-¥>]] } if you also use a Japanese keyboard.
on_create = fun(t: Terminal), -- function to run when the terminal is first created
on_open = fun(t: Terminal), -- function to run when the terminal opens
on_close = fun(t: Terminal), -- function to run when the terminal closes
on_stdout = fun(t: Terminal, job: number, data: string[], name: string) -- callback for processing output on stdout
on_stderr = fun(t: Terminal, job: number, data: string[], name: string) -- callback for processing output on stderr
on_exit = fun(t: Terminal, job: number, exit_code: number, name: string) -- function to run when terminal process exits
hide_numbers = true, -- hide the number column in toggleterm buffers
shade_filetypes = {},
autochdir = false, -- when neovim changes it current directory the terminal will change it's own when next it's opened
highlights = {
-- highlights which map to a highlight group name and a table of it's values
-- NOTE: this is only a subset of values, any group placed here will be set for the terminal window split
Normal = {
guibg = "<VALUE-HERE>",
},
NormalFloat = {
link = 'Normal'
},
FloatBorder = {
guifg = "<VALUE-HERE>",
guibg = "<VALUE-HERE>",
},
},
shade_terminals = true, -- NOTE: this option takes priority over highlights specified so if you specify Normal highlights you should set this to false
shading_factor = '<number>', -- the percentage by which to lighten dark terminal background, default: -30
shading_ratio = '<number>', -- the ratio of shading factor for light/dark terminal background, default: -3
start_in_insert = true,
insert_mappings = true, -- whether or not the open mapping applies in insert mode
terminal_mappings = true, -- whether or not the open mapping applies in the opened terminals
persist_size = true,
persist_mode = true, -- if set to true (default) the previous terminal mode will be remembered
direction = 'vertical' | 'horizontal' | 'tab' | 'float',
close_on_exit = true, -- close the terminal window when the process exits
clear_env = false, -- use only environmental variables from `env`, passed to jobstart()
-- Change the default shell. Can be a string or a function returning a string
shell = vim.o.shell,
auto_scroll = true, -- automatically scroll to the bottom on terminal output
-- This field is only relevant if direction is set to 'float'
float_opts = {
-- The border key is *almost* the same as 'nvim_open_win'
-- see :h nvim_open_win for details on borders however
-- the 'curved' border is a custom border type
-- not natively supported but implemented in this plugin.
border = 'single' | 'double' | 'shadow' | 'curved' | ... other options supported by win open
-- like `size`, width, height, row, and col can be a number or function which is passed the current terminal
width = <value>,
height = <value>,
row = <value>,
col = <value>,
winblend = 3,
zindex = <value>,
title_pos = 'left' | 'center' | 'right', position of the title of the floating window
},
winbar = {
enabled = false,
name_formatter = function(term) -- term: Terminal
return term.name
end
},
responsiveness = {
-- breakpoint in terms of `vim.o.columns` at which terminals will start to stack on top of each other
-- instead of next to each other
-- default = 0 which means the feature is turned off
horizontal_breakpoint = 135,
}
}
Usage
ToggleTerm
This is the command the mappings call under the hood. You can use it directly
and prefix it with a count to target a specific terminal. This function also takes
arguments size, dir, direction and name. e.g.
:ToggleTerm size=40 dir=~/Desktop direction=horizontal name=desktop
If dir is specified on creation toggle term will open at the specified directory.
If the terminal has already been opened at a particular directory it will remain in that directory.
The directory can also be specified as git_dir which toggleterm will then
use to try and derive the git rep
Related Skills
node-connect
339.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
339.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.8kCommit, push, and open a PR
