spacevim/bundle/nui.nvim/lua/nui/input/init.lua
JIe 2bb7059579
Some checks failed
Detach Plugins / check (FlyGrep.vim) (push) Has been cancelled
Detach Plugins / check (GitHub.vim) (push) Has been cancelled
Detach Plugins / check (JavaUnit.vim) (push) Has been cancelled
Detach Plugins / check (SourceCounter.vim) (push) Has been cancelled
Detach Plugins / check (cpicker.nvim) (push) Has been cancelled
Detach Plugins / check (dein-ui.vim) (push) Has been cancelled
Detach Plugins / check (git.vim) (push) Has been cancelled
Detach Plugins / check (iedit.vim) (push) Has been cancelled
Detach Plugins / check (scrollbar.vim) (push) Has been cancelled
Detach Plugins / check (vim-chat) (push) Has been cancelled
Detach Plugins / check (vim-cheat) (push) Has been cancelled
Detach Plugins / check (vim-todo) (push) Has been cancelled
Detach Plugins / check (xmake.vim) (push) Has been cancelled
test / Linux (nvim, nightly) (push) Has been cancelled
test / Linux (nvim, v0.3.8) (push) Has been cancelled
test / Linux (nvim, v0.4.0) (push) Has been cancelled
test / Linux (nvim, v0.4.2) (push) Has been cancelled
test / Linux (nvim, v0.4.3) (push) Has been cancelled
test / Linux (nvim, v0.4.4) (push) Has been cancelled
test / Linux (nvim, v0.5.0) (push) Has been cancelled
test / Linux (nvim, v0.5.1) (push) Has been cancelled
test / Linux (nvim, v0.6.0) (push) Has been cancelled
test / Linux (nvim, v0.6.1) (push) Has been cancelled
test / Linux (nvim, v0.7.0) (push) Has been cancelled
test / Linux (nvim, v0.7.2) (push) Has been cancelled
test / Linux (nvim, v0.8.0) (push) Has been cancelled
test / Linux (nvim, v0.8.1) (push) Has been cancelled
test / Linux (nvim, v0.8.2) (push) Has been cancelled
test / Linux (nvim, v0.8.3) (push) Has been cancelled
test / Linux (nvim, v0.9.0) (push) Has been cancelled
test / Linux (nvim, v0.9.1) (push) Has been cancelled
test / Linux (true, vim, v7.4.052) (push) Has been cancelled
test / Linux (true, vim, v7.4.1689) (push) Has been cancelled
test / Linux (true, vim, v7.4.629) (push) Has been cancelled
test / Linux (true, vim, v8.0.0027) (push) Has been cancelled
test / Linux (true, vim, v8.0.0183) (push) Has been cancelled
test / Linux (vim, nightly) (push) Has been cancelled
test / Linux (vim, v8.0.0184) (push) Has been cancelled
test / Linux (vim, v8.0.1453) (push) Has been cancelled
test / Linux (vim, v8.1.2269) (push) Has been cancelled
test / Linux (vim, v8.2.2434) (push) Has been cancelled
test / Linux (vim, v8.2.3995) (push) Has been cancelled
test / Windows (nvim, nightly) (push) Has been cancelled
test / Windows (nvim, v0.3.8) (push) Has been cancelled
test / Windows (nvim, v0.4.2) (push) Has been cancelled
test / Windows (nvim, v0.4.3) (push) Has been cancelled
test / Windows (nvim, v0.4.4) (push) Has been cancelled
test / Windows (nvim, v0.5.0) (push) Has been cancelled
test / Windows (nvim, v0.5.1) (push) Has been cancelled
test / Windows (nvim, v0.6.0) (push) Has been cancelled
test / Windows (nvim, v0.6.1) (push) Has been cancelled
test / Windows (nvim, v0.7.0) (push) Has been cancelled
test / Windows (nvim, v0.7.2) (push) Has been cancelled
test / Windows (nvim, v0.8.0) (push) Has been cancelled
test / Windows (nvim, v0.8.1) (push) Has been cancelled
test / Windows (nvim, v0.8.2) (push) Has been cancelled
test / Windows (nvim, v0.8.3) (push) Has been cancelled
test / Windows (nvim, v0.9.0) (push) Has been cancelled
test / Windows (nvim, v0.9.1) (push) Has been cancelled
test / Windows (vim, nightly) (push) Has been cancelled
test / Windows (vim, v7.4.1185) (push) Has been cancelled
test / Windows (vim, v7.4.1689) (push) Has been cancelled
test / Windows (vim, v8.0.0027) (push) Has been cancelled
test / Windows (vim, v8.0.1453) (push) Has been cancelled
test / Windows (vim, v8.1.2269) (push) Has been cancelled
test / Windows (vim, v8.2.2434) (push) Has been cancelled
test / Windows (vim, v8.2.3995) (push) Has been cancelled
docker / docker (push) Has been cancelled
mirror / check (coding) (push) Has been cancelled
mirror / check (gitee) (push) Has been cancelled
mirror / check (gitlab) (push) Has been cancelled
init
2024-08-21 14:17:26 +08:00

144 lines
4.0 KiB
Lua

local Popup = require("nui.popup")
local Text = require("nui.text")
local defaults = require("nui.utils").defaults
local is_type = require("nui.utils").is_type
local event = require("nui.utils.autocmd").event
-- exiting insert mode places cursor one character backward,
-- so patch the cursor position to one character forward
-- when unmounting input.
---@param target_cursor number[]
---@param force? boolean
local function patch_cursor_position(target_cursor, force)
local cursor = vim.api.nvim_win_get_cursor(0)
if target_cursor[2] == cursor[2] and force then
-- didn't exit insert mode yet, but it's gonna
vim.api.nvim_win_set_cursor(0, { cursor[1], cursor[2] + 1 })
elseif target_cursor[2] - 1 == cursor[2] then
-- already exited insert mode
vim.api.nvim_win_set_cursor(0, { cursor[1], cursor[2] + 1 })
end
end
---@alias nui_input_internal nui_popup_internal|{ default_value: string, prompt: NuiText }
---@class NuiInput: NuiPopup
---@field private _ nui_input_internal
local Input = Popup:extend("NuiInput")
---@param popup_options table
---@param options table
function Input:init(popup_options, options)
popup_options.enter = true
popup_options.buf_options = defaults(popup_options.buf_options, {})
popup_options.buf_options.buftype = "prompt"
if not is_type("table", popup_options.size) then
popup_options.size = {
width = popup_options.size,
}
end
popup_options.size.height = 1
Input.super.init(self, popup_options)
self._.default_value = defaults(options.default_value, "")
self._.prompt = Text(defaults(options.prompt, ""))
self._.disable_cursor_position_patch = defaults(options.disable_cursor_position_patch, false)
local props = {}
self.input_props = props
props.on_submit = function(value)
local target_cursor = vim.api.nvim_win_get_cursor(self._.position.win)
local prompt_normal_mode = vim.fn.mode() == "n"
self:unmount()
vim.schedule(function()
if prompt_normal_mode then
-- NOTE: on prompt-buffer normal mode <CR> causes neovim to enter insert mode.
-- ref: https://github.com/neovim/neovim/blob/d8f5f4d09078/src/nvim/normal.c#L5327-L5333
vim.api.nvim_command("stopinsert")
end
if not self._.disable_cursor_position_patch then
patch_cursor_position(target_cursor, prompt_normal_mode)
end
if options.on_submit then
options.on_submit(value)
end
end)
end
props.on_close = function()
local target_cursor = vim.api.nvim_win_get_cursor(self._.position.win)
self:unmount()
vim.schedule(function()
if vim.fn.mode() == "i" then
vim.api.nvim_command("stopinsert")
end
if not self._.disable_cursor_position_patch then
patch_cursor_position(target_cursor)
end
if options.on_close then
options.on_close()
end
end)
end
if options.on_change then
props.on_change = function()
local value_with_prompt = vim.api.nvim_buf_get_lines(self.bufnr, 0, 1, false)[1]
local value = string.sub(value_with_prompt, self._.prompt:length() + 1)
options.on_change(value)
end
end
end
function Input:mount()
local props = self.input_props
Input.super.mount(self)
if props.on_change then
vim.api.nvim_buf_attach(self.bufnr, false, {
on_lines = props.on_change,
})
end
if #self._.default_value then
self:on(event.InsertEnter, function()
vim.api.nvim_feedkeys(self._.default_value, "t", true)
end, { once = true })
end
vim.fn.prompt_setprompt(self.bufnr, self._.prompt:content())
if self._.prompt:length() > 0 then
vim.schedule(function()
self._.prompt:highlight(self.bufnr, self.ns_id, 1, 0)
end)
end
vim.fn.prompt_setcallback(self.bufnr, props.on_submit)
vim.fn.prompt_setinterrupt(self.bufnr, props.on_close)
vim.api.nvim_command("startinsert!")
end
---@alias NuiInput.constructor fun(popup_options: table, options: table): NuiInput
---@type NuiInput|NuiInput.constructor
local NuiInput = Input
return NuiInput