A floating vim.ui.input buffer that auto-resizes to fit its contents.
0

Configure Feed

Select the types of activity you want to include in your feed.

fix: return to original window with correct mode

r0nsha (Dec 20, 2025, 2:49 AM +0200) f5b0b8af 9dc75e73

+30 -8
+30 -8
lua/lib/input.lua
··· 15 15 ---@param on_confirm fun(input?: string) 16 16 function Input:new(config, opts, on_confirm) 17 17 local i = { 18 - config = vim.tbl_deep_extend("force", defaults, config, { win = { title = opts.prompt or "Input: " } }), 18 + config = vim.tbl_deep_extend("force", defaults, config, { 19 + win = { title = opts.prompt or "Input: " }, 20 + }), 19 21 default = opts.default or "", 20 22 on_confirm = on_confirm or function() end, 21 23 } ··· 26 28 27 29 ---@param default string 28 30 function Input:open(default) 31 + self.mode = vim.fn.mode() 32 + 29 33 -- Position window relative to the cursor, such that it doesn't overlap with the cursor's line. 30 - local curr_win = vim.api.nvim_get_current_win() 31 - local cursor_row = vim.api.nvim_win_get_cursor(curr_win)[1] 34 + self.parent_win = vim.api.nvim_get_current_win() 35 + local cursor_row = vim.api.nvim_win_get_cursor(self.parent_win)[1] 32 36 local win_config = (cursor_row <= 3) and { anchor = "NW", row = 1 } or { anchor = "SW", row = 0 } 33 37 self.config = vim.tbl_deep_extend("keep", self.config, { win = win_config }) 34 38 35 39 -- Create buffer and floating window. 36 40 self.bufnr = vim.api.nvim_create_buf(false, true) 37 - utils.set_options({ buftype = "prompt", bufhidden = "wipe" }, { buf = self.bufnr }) 41 + utils.set_options({ 42 + filetype = "multinput", 43 + buftype = "prompt", 44 + bufhidden = "wipe", 45 + modifiable = true, 46 + }, { buf = self.bufnr }) 38 47 vim.api.nvim_buf_set_var(self.bufnr, "completion", self.config.completion) 39 48 vim.fn.prompt_setprompt(self.bufnr, "") 40 49 41 50 self.winnr = vim.api.nvim_open_win(self.bufnr, true, self.config.win) 42 - utils.set_options({ wrap = true, linebreak = true, winhighlight = "Search:None" }, { win = self.winnr }) 51 + utils.set_options({ 52 + wrap = true, 53 + linebreak = true, 54 + winhighlight = "Search:None", 55 + }, { win = self.winnr }) 43 56 44 57 -- Write default value and put cursor at the end 45 58 vim.api.nvim_buf_set_lines(self.bufnr, 0, -1, true, { default }) ··· 57 70 function Input:close(result) 58 71 vim.cmd("stopinsert") 59 72 vim.api.nvim_win_close(self.winnr, true) 73 + if vim.api.nvim_win_is_valid(self.parent_win) then 74 + vim.api.nvim_set_current_win(self.parent_win) 75 + if self.mode == "i" then 76 + vim.cmd("startinsert") 77 + end 78 + end 60 79 self.on_confirm(result) 61 80 end 62 81 ··· 122 141 vim.keymap.set(mode, lhs, rhs, { buffer = self.bufnr }) 123 142 end 124 143 125 - map({ "n", "i", "v" }, "<cr>", function() 144 + local function confirm() 126 145 self:close(vim.api.nvim_buf_get_lines(self.bufnr, 0, 1, false)[1]) 127 - end) 146 + end 147 + 148 + map({ "n", "i", "v" }, "<cr>", confirm) 128 149 map({ "i" }, "<a-cr>", function() 129 - vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<cr>", true, false, true), "n", true) 150 + vim.cmd("stopinsert") 151 + confirm() 130 152 end) 131 153 132 154 map("n", "<esc>", function()