UI Component Library for Neovim.
Install the plugins with your preferred plugin manager. For example, with vim-plug
:
Plug 'MunifTanjim/nui.nvim'
Quickly add highlighted text on the buffer.
Check Detailed Documentation for nui.text
Quickly add line containing highlighted text chunks on the buffer.
Check Detailed Documentation for nui.line
Quickly render table-like structured content on the buffer.
Check Detailed Documentation for nui.table
Quickly render tree-like structured content on the buffer.
Check Detailed Documentation for nui.tree
local Popup = require("nui.popup")
local Layout = require("nui.layout")
local popup_one, popup_two = Popup({
enter = true,
border = "single",
}), Popup({
border = "double",
})
local layout = Layout(
{
position = "50%",
size = {
width = 80,
height = "60%",
},
},
Layout.Box({
Layout.Box(popup_one, { size = "40%" }),
Layout.Box(popup_two, { size = "60%" }),
}, { dir = "row" })
)
local current_dir = "row"
popup_one:map("n", "r", function()
if current_dir == "col" then
layout:update(Layout.Box({
Layout.Box(popup_one, { size = "40%" }),
Layout.Box(popup_two, { size = "60%" }),
}, { dir = "row" }))
current_dir = "row"
else
layout:update(Layout.Box({
Layout.Box(popup_two, { size = "60%" }),
Layout.Box(popup_one, { size = "40%" }),
}, { dir = "col" }))
current_dir = "col"
end
end, {})
layout:mount()
Check Detailed Documentation for nui.layout
Check Wiki Page for nui.layout
local Popup = require("nui.popup")
local event = require("nui.utils.autocmd").event
local popup = Popup({
enter = true,
focusable = true,
border = {
style = "rounded",
},
position = "50%",
size = {
width = "80%",
height = "60%",
},
})
-- mount/open the component
popup:mount()
-- unmount component when cursor leaves buffer
popup:on(event.BufLeave, function()
popup:unmount()
end)
-- set content
vim.api.nvim_buf_set_lines(popup.bufnr, 0, 1, false, { "Hello World" })
Check Detailed Documentation for nui.popup
local Input = require("nui.input")
local event = require("nui.utils.autocmd").event
local input = Input({
position = "50%",
size = {
width = 20,
},
border = {
style = "single",
text = {
top = "[Howdy?]",
top_align = "center",
},
},
win_options = {
winhighlight = "Normal:Normal,FloatBorder:Normal",
},
}, {
prompt = "> ",
default_value = "Hello",
on_close = function()
print("Input Closed!")
end,
on_submit = function(value)
print("Input Submitted: " .. value)
end,
})
-- mount/open the component
input:mount()
-- unmount component when cursor leaves buffer
input:on(event.BufLeave, function()
input:unmount()
end)
Check Detailed Documentation for nui.input
local Menu = require("nui.menu")
local event = require("nui.utils.autocmd").event
local menu = Menu({
position = "50%",
size = {
width = 25,
height = 5,
},
border = {
style = "single",
text = {
top = "[Choose-an-Element]",
top_align = "center",
},
},
win_options = {
winhighlight = "Normal:Normal,FloatBorder:Normal",
},
}, {
lines = {
Menu.item("Hydrogen (H)"),
Menu.item("Carbon (C)"),
Menu.item("Nitrogen (N)"),
Menu.separator("Noble-Gases", {
char = "-",
text_align = "right",
}),
Menu.item("Helium (He)"),
Menu.item("Neon (Ne)"),
Menu.item("Argon (Ar)"),
},
max_width = 20,
keymap = {
focus_next = { "j", "<Down>", "<Tab>" },
focus_prev = { "k", "<Up>", "<S-Tab>" },
close = { "<Esc>", "<C-c>" },
submit = { "<CR>", "<Space>" },
},
on_close = function()
print("Menu Closed!")
end,
on_submit = function(item)
print("Menu Submitted: ", item.text)
end,
})
-- mount the component
menu:mount()
Check Detailed Documentation for nui.menu
local Split = require("nui.split")
local event = require("nui.utils.autocmd").event
local split = Split({
relative = "editor",
position = "bottom",
size = "20%",
})
-- mount/open the component
split:mount()
-- unmount component when cursor leaves buffer
split:on(event.BufLeave, function()
split:unmount()
end)
Check Detailed Documentation for nui.split
Each of the blocks and components can be extended to add new methods or change their behaviors.
local Timer = Popup:extend("Timer")
function Timer:init(popup_options)
local options = vim.tbl_deep_extend("force", popup_options or {}, {
border = "double",
focusable = false,
position = { row = 0, col = "100%" },
size = { width = 10, height = 1 },
win_options = {
winhighlight = "Normal:Normal,FloatBorder:SpecialChar",
},
})
Timer.super.init(self, options)
end
function Timer:countdown(time, step, format)
local function draw_content(text)
local gap_width = 10 - vim.api.nvim_strwidth(text)
vim.api.nvim_buf_set_lines(self.bufnr, 0, -1, false, {
string.format(
"%s%s%s",
string.rep(" ", math.floor(gap_width / 2)),
text,
string.rep(" ", math.ceil(gap_width / 2))
),
})
end
self:mount()
local remaining_time = time
draw_content(format(remaining_time))
vim.fn.timer_start(step, function()
remaining_time = remaining_time - step
draw_content(format(remaining_time))
if remaining_time <= 0 then
self:unmount()
end
end, { ["repeat"] = math.ceil(remaining_time / step) })
end
local timer = Timer()
timer:countdown(10000, 1000, function(time)
return tostring(time / 1000) .. "s"
end)
A small object library is bundled with nui.nvim
. It is, more or less, a clone of the
kikito/middleclass
library.
Check Wiki Page for nui.object
Licensed under the MIT License. Check the LICENSE file for details.