minimal extui fuzzy finder for neovim

fix(view): structure api calls and use `noautocmd`

+43 -30
+43 -30
lua/artio/view.lua
··· 24 24 end 25 25 end 26 26 27 - local cmdbuff = "" ---@type string Stored cmdline used to calculate translation offset. 28 - local promptlen = 0 -- Current length of the last line in the prompt. 29 - local promptwidth = 0 -- Current width of the prompt in the cmdline buffer. 30 - local promptidx = 0 31 - --- Concatenate content chunks and set the text for the current row in the cmdline buffer. 32 - --- 33 - ---@param content CmdContent 34 - ---@param prompt string 35 - local function set_text(content, prompt) 36 - local lines = {} ---@type string[] 37 - for line in (prompt .. "\n"):gmatch("(.-)\n") do 38 - lines[#lines + 1] = vim.fn.strtrans(line) 39 - end 40 - 41 - promptlen = #lines[#lines] 42 - promptwidth = vim.fn.strdisplaywidth(lines[#lines]) 43 - 44 - cmdbuff = "" 45 - for _, chunk in ipairs(content) do 46 - cmdbuff = cmdbuff .. chunk[2] 47 - end 48 - lines[#lines] = ("%s%s"):format(lines[#lines], vim.fn.strtrans(cmdbuff)) 49 - vim.api.nvim_buf_set_lines(ext.bufs.cmd, promptidx, promptidx + 1, false, lines) 50 - end 51 - 52 27 ---@class artio.View 53 28 ---@field picker artio.Picker 54 29 ---@field closed boolean ··· 73 48 74 49 local prompthl_id = -1 75 50 51 + local cmdbuff = "" ---@type string Stored cmdline used to calculate translation offset. 52 + local promptlen = 0 -- Current length of the last line in the prompt. 53 + local promptwidth = 0 -- Current width of the prompt in the cmdline buffer. 54 + local promptidx = 0 55 + --- Concatenate content chunks and set the text for the current row in the cmdline buffer. 56 + --- 57 + ---@param content CmdContent 58 + ---@param prompt string 59 + function View:setprompttext(content, prompt) 60 + local lines = {} ---@type string[] 61 + for line in (prompt .. "\n"):gmatch("(.-)\n") do 62 + lines[#lines + 1] = vim.fn.strtrans(line) 63 + end 64 + 65 + promptlen = #lines[#lines] 66 + promptwidth = vim.fn.strdisplaywidth(lines[#lines]) 67 + 68 + cmdbuff = "" 69 + for _, chunk in ipairs(content) do 70 + cmdbuff = cmdbuff .. chunk[2] 71 + end 72 + lines[#lines] = ("%s%s"):format(lines[#lines], vim.fn.strtrans(cmdbuff)) 73 + self:setlines(promptidx, promptidx + 1, lines) 74 + end 75 + 76 76 --- Set the cmdline buffer text and cursor position. 77 77 --- 78 78 ---@param content CmdContent ··· 103 103 self:showmatches() 104 104 105 105 self:promptpos() 106 - set_text(content, ("%s%s%s"):format(firstc, prompt, (" "):rep(indent))) 106 + self:setprompttext(content, ("%s%s%s"):format(firstc, prompt, (" "):rep(indent))) 107 107 self:updatecursor(pos) 108 108 109 109 local height = math.max(1, vim.api.nvim_win_text_height(ext.wins.cmd, {}).all) ··· 192 192 193 193 vim.api.nvim_create_autocmd("TextChangedI", { 194 194 group = self.augroup, 195 + buffer = ext.bufs.cmd, 195 196 callback = function() 196 197 self:update() 197 198 end, ··· 199 200 200 201 vim.api.nvim_create_autocmd("CursorMovedI", { 201 202 group = self.augroup, 203 + buffer = ext.bufs.cmd, 202 204 callback = function() 203 205 self:updatecursor() 204 206 end, ··· 305 307 function View:clear() 306 308 cmdline.srow = self.picker.opts.bottom and 0 or 1 307 309 cmdline.erow = 0 308 - vim.api.nvim_buf_set_lines(ext.bufs.cmd, 0, -1, false, {}) 310 + self:setlines(0, -1, {}) 309 311 end 310 312 311 313 function View:promptpos() 312 314 promptidx = self.picker.opts.bottom and cmdline.erow or 0 315 + end 316 + 317 + function View:setlines(posstart, posend, lines) 318 + vim._with({ noautocmd = true }, function() 319 + vim.api.nvim_buf_set_lines(ext.bufs.cmd, posstart, posend, false, lines) 320 + end) 313 321 end 314 322 315 323 local view_ns = vim.api.nvim_create_namespace("artio:view:ns") ··· 325 333 ---@param opts vim.api.keyset.set_extmark 326 334 ---@return integer 327 335 function View:mark(line, col, opts) 328 - local ok, result = pcall(vim.api.nvim_buf_set_extmark, ext.bufs.cmd, view_ns, line, col, opts) 336 + local ok, result 337 + vim._with({ noautocmd = true }, function() 338 + ok, result = pcall(vim.api.nvim_buf_set_extmark, ext.bufs.cmd, view_ns, line, col, opts) 339 + end) 329 340 if not ok then 330 341 vim.notify(("Failed to add extmark %d:%d"):format(line, col), vim.log.levels.ERROR) 331 342 return -1 ··· 412 423 end 413 424 end 414 425 cmdline.erow = cmdline.srow + #lines 415 - vim.api.nvim_buf_set_lines(ext.bufs.cmd, cmdline.srow, cmdline.erow, false, lines) 426 + self:setlines(cmdline.srow, cmdline.erow, lines) 416 427 417 428 for i = 1, #lines do 418 429 local has_icon = icons[i] and icons[i][1] and true ··· 455 466 456 467 function View:hlselect() 457 468 if self.select_ext then 458 - vim.api.nvim_buf_del_extmark(ext.bufs.cmd, view_ns, self.select_ext) 469 + vim._with({ noautocmd = true }, function() 470 + vim.api.nvim_buf_del_extmark(ext.bufs.cmd, view_ns, self.select_ext) 471 + end) 459 472 end 460 473 461 474 self:softupdatepreview()