mirror of
https://github.com/chenasraf/input-form.nvim.git
synced 2026-05-17 17:38:01 +00:00
93 lines
2.4 KiB
Lua
93 lines
2.4 KiB
Lua
--- Single-line text input component.
|
|
|
|
local utils = require("input-form.utils")
|
|
|
|
local M = {}
|
|
M.__index = M
|
|
|
|
--- Create a new text input from its spec.
|
|
---@param spec table { name, label, default? }
|
|
---@return table
|
|
function M.new(spec)
|
|
return setmetatable({
|
|
type = "text",
|
|
name = spec.name,
|
|
label = spec.label or spec.name,
|
|
_value = spec.default or "",
|
|
buf = nil,
|
|
win = nil,
|
|
}, M)
|
|
end
|
|
|
|
--- Number of content rows (excluding the label line) this input occupies.
|
|
function M:height()
|
|
return 1
|
|
end
|
|
|
|
function M:is_bordered()
|
|
return true
|
|
end
|
|
|
|
--- Create the backing buffer and floating window.
|
|
---@param layout table { row, col, width }
|
|
function M:mount(layout)
|
|
self.buf = vim.api.nvim_create_buf(false, true)
|
|
vim.bo[self.buf].buftype = "nofile"
|
|
vim.bo[self.buf].bufhidden = "wipe"
|
|
vim.bo[self.buf].swapfile = false
|
|
utils.mark_form_buffer(self.buf)
|
|
vim.api.nvim_buf_set_lines(self.buf, 0, -1, false, { self._value })
|
|
|
|
local win_cfg = {
|
|
relative = "editor",
|
|
row = layout.row,
|
|
col = layout.col,
|
|
width = layout.width,
|
|
height = 1,
|
|
style = "minimal",
|
|
focusable = true,
|
|
zindex = 50,
|
|
}
|
|
if layout.border then
|
|
win_cfg.border = layout.border
|
|
win_cfg.title = " " .. self.label .. " "
|
|
win_cfg.title_pos = "left"
|
|
end
|
|
self.win = vim.api.nvim_open_win(self.buf, false, win_cfg)
|
|
vim.wo[self.win].winhl =
|
|
"NormalFloat:InputFormField,FloatBorder:InputFormFieldBorder,FloatTitle:InputFormFieldTitle"
|
|
end
|
|
|
|
--- Return current value (from the buffer if mounted, otherwise the cached value).
|
|
function M:value()
|
|
if self.buf and vim.api.nvim_buf_is_valid(self.buf) then
|
|
local lines = vim.api.nvim_buf_get_lines(self.buf, 0, -1, false)
|
|
return lines[1] or ""
|
|
end
|
|
return self._value
|
|
end
|
|
|
|
--- Close the window and buffer, caching the current value.
|
|
function M:unmount()
|
|
self._value = self:value()
|
|
if self.win and vim.api.nvim_win_is_valid(self.win) then
|
|
vim.api.nvim_win_close(self.win, true)
|
|
end
|
|
if self.buf and vim.api.nvim_buf_is_valid(self.buf) then
|
|
vim.api.nvim_buf_delete(self.buf, { force = true })
|
|
end
|
|
self.win = nil
|
|
self.buf = nil
|
|
end
|
|
|
|
--- Give this input focus and enter insert mode at the end of the line.
|
|
function M:focus()
|
|
if self.win and vim.api.nvim_win_is_valid(self.win) then
|
|
vim.api.nvim_set_current_win(self.win)
|
|
local line = self:value()
|
|
vim.api.nvim_win_set_cursor(self.win, { 1, #line })
|
|
end
|
|
end
|
|
|
|
return M
|