A small floating terminal plugin for Neovim.
float-term.nvim provides a reusable terminal window with floating, horizontal, and vertical layouts, persistent terminal sessions, configurable keymaps, and colorscheme-aware highlights.
- Floating terminal window.
- Horizontal terminal layout.
- Vertical terminal layout.
- Persistent terminal session.
- Toggle open/close behavior.
- Hide the terminal window without killing the shell.
- Kill the terminal session explicitly.
- Configurable terminal keymaps.
- Colorscheme-aware highlights.
- Optional transparent background.
- User commands for common actions.
- Dead terminal detection and cleanup.
- Minimal Lua-only implementation.
- Neovim 0.10+
{
"dfdezmonteiro/float-term.nvim",
config = function()
require("float-term").setup()
end,
}Default-style configuration:
require("float-term").setup({
width = 0.8,
height = 0.8,
border = "rounded",
title = " Terminal ",
title_pos = "center",
keymap = "<leader>tt",
winblend = 0,
transparent = false,
mode = "float", -- "float" | "horizontal" | "vertical"
horizontal_size = 15,
vertical_size = 80,
persist = true,
clear_on_open = false,
insert_on_open = true,
start_in_insert = nil,
terminal_keymaps = {
exit_insert = "jk",
exit_insert_alt = "<Esc>",
close = "q",
left = "<C-h>",
down = "<C-j>",
up = "<C-k>",
right = "<C-l>",
},
highlights = {
normal = "NormalFloat",
border = "FloatBorder",
title = "FloatTitle",
},
})Toggle the terminal:
<leader>tt
Default terminal-mode behavior:
jk exit terminal mode
<Esc> exit terminal mode
q writes q normally
exit kills the shell, closes the window, and clears the terminal buffer
Default normal-mode behavior while focused on the terminal buffer:
q hides the terminal window without killing the shell
Open the terminal again:
<leader>tt
When persist = true, the same terminal session is reused.
:FloatTerm
:FloatTermOpen
:FloatTermClose
:FloatTermKill
:FloatTermToggle
:FloatTermFloat
:FloatTermHorizontal
:FloatTermVerticalCommand behavior:
:FloatTerm Toggle the terminal
:FloatTermOpen Open the terminal
:FloatTermClose Hide the terminal window
:FloatTermKill Kill the terminal session and clear state
:FloatTermToggle Toggle the terminal
:FloatTermFloat Toggle terminal using floating layout
:FloatTermHorizontal Toggle terminal using horizontal layout
:FloatTermVertical Toggle terminal using vertical layout
require("float-term").open()
require("float-term").close()
require("float-term").kill()
require("float-term").toggle()Examples:
vim.keymap.set("n", "<leader>tt", function()
require("float-term").toggle()
end, {
desc = "Toggle floating terminal",
})Open with a specific layout:
require("float-term").toggle({ mode = "float" })
require("float-term").toggle({ mode = "horizontal" })
require("float-term").toggle({ mode = "vertical" })float-term.nvim separates hiding the terminal window from killing the terminal process.
close() -> hides the terminal window
kill() -> kills/clears the terminal session and resets internal state
toggle() -> opens if closed, closes if open
exit -> shell exits, plugin closes the window and clears the buffer
With the default configuration:
persist = trueclosing the window keeps the shell process alive.
This means:
q hides the terminal window
<leader>tt opens the same session again
exit terminates the shell and clears the terminal state
require("float-term").toggle({ mode = "float" })Or:
:FloatTermFloatrequire("float-term").toggle({ mode = "horizontal" })Or:
:FloatTermHorizontalrequire("float-term").toggle({ mode = "vertical" })Or:
:FloatTermVertical| Option | Type | Default | Description |
|---|---|---|---|
width |
number |
0.8 |
Floating window width ratio. |
height |
number |
0.8 |
Floating window height ratio. |
border |
string |
"rounded" |
Floating window border style. |
title |
string |
" Terminal " |
Floating window title. |
title_pos |
string |
"center" |
Floating window title position. |
keymap |
string|false |
"<leader>tt" |
Normal-mode toggle keymap. |
winblend |
number |
0 |
Floating window blend/transparency. |
transparent |
boolean |
false |
Use transparent background for plugin highlight groups. |
mode |
string |
"float" |
Default layout: float, horizontal, or vertical. |
horizontal_size |
number |
15 |
Height of the horizontal terminal. |
vertical_size |
number |
80 |
Width of the vertical terminal. |
persist |
boolean |
true |
Keep terminal session alive when hiding the window. |
clear_on_open |
boolean |
false |
Clear terminal when opened. |
insert_on_open |
boolean |
true |
Enter terminal mode when opened. |
start_in_insert |
boolean|nil |
nil |
Alias override for insert_on_open. |
terminal_keymaps |
table|false |
table | Terminal-related keymaps. |
highlights |
table |
table | Source highlight groups used to derive plugin highlights. |
Default:
terminal_keymaps = {
exit_insert = "jk",
exit_insert_alt = "<Esc>",
close = "q",
left = "<C-h>",
down = "<C-j>",
up = "<C-k>",
right = "<C-l>",
}Meaning:
jk exits terminal mode
<Esc> exits terminal mode
q closes the terminal window only from normal mode inside the terminal buffer
<C-h> move to left window
<C-j> move to lower window
<C-k> move to upper window
<C-l> move to right window
Disable terminal keymaps:
require("float-term").setup({
terminal_keymaps = false,
})Customize terminal keymaps:
require("float-term").setup({
terminal_keymaps = {
exit_insert = "jk",
exit_insert_alt = "<Esc>",
close = "q",
left = "<C-h>",
down = "<C-j>",
up = "<C-k>",
right = "<C-l>",
},
})The plugin defines these highlight groups:
FloatTermNormal
FloatTermBorder
FloatTermTitle
By default, they are derived from:
highlights = {
normal = "NormalFloat",
border = "FloatBorder",
title = "FloatTitle",
}The plugin listens to ColorScheme and refreshes its highlight groups automatically.
Use transparent background:
require("float-term").setup({
transparent = true,
})Use custom source highlight groups:
require("float-term").setup({
highlights = {
normal = "Normal",
border = "FloatBorder",
title = "Title",
},
})float-term.nvim does not control the cursor shape. Cursor shape is a global Neovim preference.
Recommended guicursor configuration:
vim.opt.guicursor = table.concat({
"n-v-c:block",
"i-ci-ve:ver25",
"t:ver25",
"r-cr:hor20",
"o:block",
"a:blinkon0",
}, ",")This gives:
Normal mode -> block cursor
Insert mode -> vertical bar
Terminal mode -> vertical bar
No blinking
float-term.nvim/
├── README.md
├── LICENSE
├── stylua.toml
└── lua/
└── float-term/
└── init.lua
- The plugin manages one terminal session.
- Rounded borders are terminal-cell characters, not graphical GUI borders.
- Terminal ANSI color rendering depends on Neovim and terminal emulator configuration.
- The plugin does not currently provide multiple named terminals.
- The plugin does not currently provide project-root detection.
- The plugin does not currently provide a command runner API.
Possible future improvements:
- Multiple named terminals.
- Project-root terminal mode.
- Shell configuration.
- Command runner API.
- Healthcheck support.
- Better terminal ANSI color palette handling.
Contributions are welcome.
MIT