UI Component Library for Neovim.
Install the plugins with your preferred plugin manager. For example, with vim-plug
:
Plug 'MunifTanjim/nui.nvim'
Popup is an abstraction layer on top of window.
Creates a new popup object (but does not mount it immediately).
local Popup = require("nui.popup")
local popup = Popup({
border = {
style = "rounded",
highlight = "FloatBorder",
},
position = "50%",
size = {
width = "80%",
height = "60%",
},
})
border
border
accepts a table with these keys: highlight
, padding
, style
, and text
.
border.highlight
can be a string denoting the highlight group name for the border characters.
border.padding
can be a list (table) with number of cells for top, right, bottom and left.
It behaves like CSS padding.
For example:
-- `1` for top/bottom and `2` for left/right
{ 1, 2 }
You can also use a map (table) to set padding at specific side. For example:
-- `1` for top, `0` for other sides
{ top = 1 }
border.style
can be one of the followings:
- Pre-defined style:
"double"
,"none"
,"rounded"
,"shadow"
,"single"
or"solid"
- List (table) of characters starting from the top-left corner and then clockwise. For example:
{ "╭", "─", "╮", "│", "╯", "─", "╰", "│" }
- Map (table) with named characters. For example:
{ top_left = "╭", top = "─", top_right = "╮", left = "│", right = "│" bottom_left = "╰", bottom = "─", bottom_right = "╯", }
border.text
can be an table with the following keys:
Key | Description |
---|---|
"top" |
top border text |
"top_align" |
top border text alignment |
"bottom" |
bottom border text |
"bottom_align" |
bottom border text alignment |
Possible values for "top_align"
and "bottom_align"
are: "left"
, "right"
or "center"
(default).
For example:
{
top = "Popup Title",
top_align = "center",
}
If you don't need all these options, you can also pass the value of border.style
to border
directly.
relative
This option affects how position
and size
is calculated.
Value | Description |
---|---|
"cursor" |
relative to cursor on current window |
"editor" |
relative to current editor screen |
"win" (default) |
relative to current window |
{ type = "win", winid = <winid> } |
relative to window with id <winid> |
{ type = "buf", position = <Position> } |
relative to buffer position <Position> |
Here <Position>
is a table with keys row
, col
and values are zero-indexed numbers.
position
If position
is number or percentage string, it applies to both row and col.
Or you can pass a table to set them separately.
Position is calculated from the top-left corner.
For percentage string, position is calculated according to the option relative
(if relative
is set to "buf"
or "cursor"
, percentage string is not allowed).
size
If size
is number or percentage string, it applies to both width and height.
Or you can pass a table to set them separately.
For percentage string, size is calculated according to the option relative
(if relative
is set to "buf"
or "cursor"
, window size is considered).
enter
If enter
is true
, the popup is entered immediately after mount.
focusable
If focusable
is false
, the popup can not be entered by user actions
(wincmds, mouse events).
zindex
zindex
is a number used to order the position of popups on z-axis.
Popup with higher zindex
goes on top of popups with lower zindex
.
buf_options
Table containing buffer options to set for this popup. For example:
{
modifiable = false,
readonly = true,
}
win_options
Table containing window options to set for this popup. For example:
{
winblend = 10,
winhighlight = "Normal:Normal",
}
Mounts the popup.
popup:mount()
Unmounts the popup.
popup:unmount()
Sets keymap for this popup. If keymap was already set and force
is not true
returns false
, otherwise returns true
.
For example:
local ok = popup:map("n", "<esc>", function(bufnr)
print("ESC pressed in Normal mode!")
end, { noremap = true })
Defines autocmd
to run on specific events for this popup. For example:
local event = require("nui.utils.autocmd").event
popup:on({ event.BufLeave }, function()
popup:unmount()
end, { once = true })
Removes autocmd
defined with popup:on(...)
. For example:
popup:off("*")
Sets the size of the popup. For example:
popup:set_size({ width = 80, height = 40 })
Sets border text. For example:
popup.border:set_text("bottom", "[Progress: 42%]", "right")
Input
is an abstraction layer on top of Popup
.
Creates a new input object (but does not mount it immediately).
local Input = require("nui.input")
local input = Input(popup_options, {
prompt = "> ",
default_value = "42",
on_close = function()
print("Input closed!")
end,
on_submit = function(value)
print("Value submitted: ", value)
end,
on_change = function(value)
print("Value changed: ", value)
end,
})
All the methods Popup
methods is also available for Input
. It uses
prompt buffer (check :h prompt-buffer
) for its popup window.
If you provide the on_change
function, it'll be run everytime value changes.
Pressing <CR>
runs the on_submit
callback function and closes the window.
Pressing <C-c>
runs the on_close
callback function and closes the window.
Of course, you can override the default keymaps and add more. For example:
-- close the input window by pressing `<Esc>` on normal mode
input:map("n", "<Esc>", input.input_props.on_close, { noremap = true })
Menu
is abstraction layer on top of Popup
.
Creates a new menu object (but does not mount it immediately).
local Menu = require("nui.menu")
local menu = Menu(popup_options, {
lines = {
Menu.item("Item 1"),
Menu.item("Item 2"),
Menu.separator("Menu Group"),
Menu.item("Item 3"),
},
max_width = 20,
separator = {
char = "-",
text_align = "right",
},
keymap = {
focus_next = { "j", "<Down>", "<Tab>" },
focus_prev = { "k", "<Up>", "<S-Tab>" },
close = { "<Esc>", "<C-c>" },
submit = { "<CR>", "<Space>" },
},
on_close = function()
print("CLOSED")
end,
on_submit = function(item)
print("SUBMITTED", vim.inspect(item))
end
})
Menu.item
is used to create an item object for the Menu
. You also get this
object when on_submit
is called.
Usage | Result |
---|---|
Menu.item("Name") |
{ text = "Name", type = "item" } |
Menu.item("Name", { id = 1 }) |
{ id = 1, text = "Name", type = "item" } |
Menu.item({ id = 1, text = "Name" }) |
{ id = 1, text = "Name", type = "item" } |
The Result is what you get as the argument of on_submit
callback function.
You can include whatever you want in the item object.
Split is can be used to split your current window or editor.
local Split = require("nui.split")
local split = Split({
relative = "editor",
position = "bottom",
size = "20%",
})
It has the usual :mount
, :unmount
, :map
, :on
and :off
methods.
relative
Value | Description |
---|---|
"editor" |
split current editor screen |
"win" (default) |
split current window |
This option also affects how size
is calculated.
position
position
can be one of: "top"
, "right"
, "bottom"
or "left"
.
size
size
can be number or percentage string.
For percentage string, size is calculated according to the option relative
.
buf_options
Table containing buffer options to set for this split.
win_options
Table containing window options to set for this split.
Hides the split window.
Shows the hidden split window.
Licensed under the MIT License. Check the LICENSE file for details.