Tman.nvim is a terminal manager for Neovim, focused on running commands, tests, etc.
Inspird by ThePrimeagen/harpoon
and emacs compilation-mode
.
Works really well with the vim-test
plugin as a custom stratergy to run tests using a single terminal buffer.
Add this to your packer or Lazy config
{
'Bhanukamax/tman.nvim',
}
local tman = require('tman')
-- setup how the terminal buffer is displayed
-- Note: you don't need to do this if you are okay with using the defaults
tman.setup {
split = "bottom", -- supported values: "bottom", "right"
-- set width and height as a percentage of the terminal width and height
-- should be a integer between 1 to 100
width = 50, -- default is 50
height = 40, -- default is 40
}
-- This is my favourite way to toggle tman terminal, you don't have to care which mode you are in the terminal, just one keybind to toggle back and forth
vim.keymap.set("n", "<A-;>", function () tman.toggleLast({insert = true}) end)
vim.keymap.set("t", "<A-;>", tman.toggleLast)
Have a look at :help tman.nvim
for complete API docs
toggle terminal from a specific side
-- toggle terminal from a specific side
vim.keymap.set("n", "<leader>tr", tman.toggleRight)
vim.keymap.set("n", "<leader>tb", tman.toggleBottom)
-- toggle terminal from the last open side
vim.keymap.set("n", "<leader>tt", tman.toggleLast)
:TmanCmd
:TmanCmdLast
These commands are useful when you want to run things like build commands, test runner commands, for example: cargo build
, go build
, etc.
- When you run
:TmanCmd
it'll propmt for you to enter a command. - Once you type in the command and press enter it'll open the Tman terminal and run the command you entered.
- You can also run
:TmanCmdLast
to resend the last command you ran.
One nice thing about using these commands is that you never have to go to insert mode in the terminal buffer, so you can just use these to run commands and navigate/visual select/yank text on terminal buffer without ever worrying about going between modes in the terminal buffer.
And they works best with some nice remaps like these:
vim.keymap.set("n", "<leader>tc", ":TmanCmd<CR>")
vim.keymap.set("n", "<leader>tn", ":TmanCmdLast<CR>") -- <leader>tl or <leader>tr would be a better mnemonic binding
call to send some command to the terminal buffer
require("tman").sendCommand(cmd, opts)
cmd: string -> command to send
opts: table
- opts.split: "right" or "bottom": pass a split possition to override default when the command is executed
- opts.open: bool -> if true, open the terminal buffer (always opens if there is no previous terminal buffer)
- opts.pre: string -> a command to excute before the currend
cmd
- opts.scrollTop: bool (default: true) -> scroll the prompt to top before executing the currently sent command, this is works better than sending
clear
as thepre
command.
local gitk_file = function()
local filename = vim.fn.expand('%')
local cmd = "gitk " .. filename .. "\r"
require("tman").sendCommand(cmd, {})
end
-- ~/.config/nvim/plugins/vim-test.lua (if using lazy.nvim as your plugin manager)
vim.cmd[[
function! Tman(cmd)
let g:cmd = a:cmd . "\n"
lua require("tman").sendCommand(vim.g.cmd, {open = true, split = "last"})
endfunction
let g:test#custom_strategies = {'tman': function('Tman')}
let g:test#strategy = 'tman'
]]
vim.keymap.set("n", "<leader>tf", ":TestFile<CR>")
vim.keymap.set("n", "<leader>ts", ":TestNearest<CR>")
vim.keymap.set("n", "<leader>tl", ":TestLast<CR>")
return {
'vim-test/vim-test',
cmd = {'TestNearest', 'TestFile', 'TestLast'},
dependencies = {
'Bhanukamax/tman.nvim',
}
}
local open_magit_status = function ()
tman.sendCommand('emacsclient -cn -e "(magit-status)" \r', {})
end
vim.keymap.set("n", "<leader>cgg", open_magit_status)
neotermman
uses the neovim terminal,- by defualt terminal buffer will open in the
terminal
mode which is similar tonormal
mode. - to interact with the terminal you need to go into insert mode by pressing
i
key.
- to exit out of the insert mode in the terminal, you need to use the neovim terminal escape key sequence which is
<C-\><C-N>
. - since above key sequence is not very easy, you can rebind it to something else.
- I have found that C-x works best for me for this.
vim.keymap.set("t", "<C-x>", "<C-\\><C-N>", {})