From b3ec2f6ccc8a54d2082843e52072568b83b610d3 Mon Sep 17 00:00:00 2001 From: bhagwan Date: Tue, 3 Dec 2024 21:46:24 -0800 Subject: [PATCH] feat(previewer): cache scroll position - perf: do not clear cache on preview toggle - restored `` bind: resets preview pos --- README.md | 1 + lua/fzf-lua/defaults.lua | 1 + lua/fzf-lua/previewer/builtin.lua | 82 +++++++++---------------------- lua/fzf-lua/win.lua | 8 +-- 4 files changed, 29 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 55532854..0d2404bd 100644 --- a/README.md +++ b/README.md @@ -634,6 +634,7 @@ require'fzf-lua'.setup { -- Rotate preview clockwise/counter-clockwise [""] = "toggle-preview-ccw", [""] = "toggle-preview-cw", + [""] = "preview-reset", [""] = "preview-page-down", [""] = "preview-page-up", [""] = "preview-down", diff --git a/lua/fzf-lua/defaults.lua b/lua/fzf-lua/defaults.lua index ad22983a..8ccc4e26 100644 --- a/lua/fzf-lua/defaults.lua +++ b/lua/fzf-lua/defaults.lua @@ -95,6 +95,7 @@ M.defaults = { [""] = "toggle-preview", [""] = "toggle-preview-ccw", [""] = "toggle-preview-cw", + [""] = "preview-reset", [""] = "preview-page-down", [""] = "preview-page-up", [""] = "preview-down", diff --git a/lua/fzf-lua/previewer/builtin.lua b/lua/fzf-lua/previewer/builtin.lua index a494f83e..e3abe1b0 100644 --- a/lua/fzf-lua/previewer/builtin.lua +++ b/lua/fzf-lua/previewer/builtin.lua @@ -83,10 +83,12 @@ function Previewer.base:new(o, opts, fzf_win) return self end -function Previewer.base:close() +function Previewer.base:close(do_not_clear_cache) self:restore_winopts() self:clear_preview_buf() - self:clear_cached_buffers() + if not do_not_clear_cache then + self:clear_cached_buffers() + end self.winopts_orig = {} end @@ -407,6 +409,14 @@ function Previewer.base:scroll(direction) vim.wo[preview_winid].cursorline = false end end + -- HACK: Hijack cached bufnr value as last scroll position + if self.cached_bufnrs[tostring(self.preview_bufnr)] then + if direction == "reset" then + self.cached_bufnrs[tostring(self.preview_bufnr)] = true + else + self.cached_bufnrs[tostring(self.preview_bufnr)] = vim.api.nvim_win_get_cursor(preview_winid) + end + end self:update_render_markdown() self.win:update_scrollbar() end @@ -418,12 +428,9 @@ function Previewer.buffer_or_file:new(o, opts, fzf_win) return self end -function Previewer.buffer_or_file:close() - self:restore_winopts() - self:clear_preview_buf() - self:clear_cached_buffers() +function Previewer.buffer_or_file:close(do_not_clear_cache) + Previewer.base.close(self, do_not_clear_cache) self:stop_ueberzug() - self.winopts_orig = {} end function Previewer.buffer_or_file:parse_entry(entry_str) @@ -723,40 +730,6 @@ function Previewer.buffer_or_file:populate_preview_buf(entry_str) end end --- is treesitter available? -local __has_ts, __ts_configs, __ts_parsers - --- Attach ts highlighter, neovim v0.7/0.8 -local ts_attach_08 = function(bufnr, ft) - if not __has_ts then - __has_ts, _ = pcall(require, "nvim-treesitter") - if __has_ts then - _, __ts_configs = pcall(require, "nvim-treesitter.configs") - _, __ts_parsers = pcall(require, "nvim-treesitter.parsers") - end - end - - if not __has_ts or not ft or ft == "" then - return false - end - - local lang = __ts_parsers.ft_to_lang(ft) - if not __ts_configs.is_enabled("highlight", lang, bufnr) then - return false - end - - local config = __ts_configs.get_module "highlight" - vim.treesitter.highlighter.new(__ts_parsers.get_parser(bufnr, lang)) - local is_table = type(config.additional_vim_regex_highlighting) == "table" - if - config.additional_vim_regex_highlighting - and (not is_table or utils.tbl_contains(config.additional_vim_regex_highlighting, lang)) - then - vim.bo[bufnr].syntax = ft - end - return true -end - -- Attach ts highlighter, neovim >= v0.9 local ts_attach = function(bufnr, ft) local lang = vim.treesitter.language.get_lang(ft) @@ -813,12 +786,8 @@ function Previewer.buffer_or_file:do_syntax(entry) )) end if syntax_limit_reached == 0 then - -- 'vim.filetype' was added with v0.7 but panics with the below - -- limit treesitter manual attachment to 0.8 instead (0.7.2 also errs) - -- Error executing vim.schedule lua callback: - -- vim/filetype.lua:0: attempt to call method 'gsub' (a nil value) - local fallback = not utils.__HAS_NVIM_08 - if utils.__HAS_NVIM_08 then + local fallback = not utils.__HAS_NVIM_09 + if utils.__HAS_NVIM_09 then fallback = (function() local ft = entry.filetype or self.ext_ft_override and self.ext_ft_override[path.extension(entry.path)] @@ -838,17 +807,10 @@ function Previewer.buffer_or_file:do_syntax(entry) end return true end)() - local ts_success - if ts_enabled then - if utils.__HAS_NVIM_09 then - ts_success = ts_attach(bufnr, ft) - else - ts_success = ts_attach_08(bufnr, ft) - end - end - if not ts_enabled or not ts_success then + local ts_success = ts_enabled and ts_attach(bufnr, ft) + if not ts_success then pcall(function() vim.bo[bufnr].syntax = ft end) - elseif ts_enabled and ts_success then + else self:update_render_markdown(ft) end end)() @@ -891,16 +853,18 @@ function Previewer.buffer_or_file:set_cursor_hl(entry) end pcall(vim.api.nvim_win_call, self.win.preview_winid, function() + local cached_pos = self.cached_bufnrs[tostring(self.preview_bufnr)] + if type(cached_pos) ~= "table" then cached_pos = nil end local lnum, col = tonumber(entry.line), tonumber(entry.col) or 0 if not lnum or lnum < 1 then vim.wo.cursorline = false self.orig_pos = { 1, 0 } - api.nvim_win_set_cursor(0, self.orig_pos) + api.nvim_win_set_cursor(0, cached_pos or self.orig_pos) return end self.orig_pos = { lnum, math.max(0, col - 1) } - api.nvim_win_set_cursor(0, self.orig_pos) + api.nvim_win_set_cursor(0, cached_pos or self.orig_pos) fn.clearmatches() -- If regex is available (grep/lgrep), match on current line diff --git a/lua/fzf-lua/win.lua b/lua/fzf-lua/win.lua index cd822b3c..6a5cb430 100644 --- a/lua/fzf-lua/win.lua +++ b/lua/fzf-lua/win.lua @@ -31,7 +31,7 @@ local _preview_keymaps = { ["preview-page-down"] = { module = "win", fnc = "preview_scroll('page-down')" }, ["preview-half-page-up"] = { module = "win", fnc = "preview_scroll('half-page-up')" }, ["preview-half-page-down"] = { module = "win", fnc = "preview_scroll('half-page-down')" }, - ["preview-page-reset"] = { module = "win", fnc = "preview_scroll('reset')" }, + ["preview-reset"] = { module = "win", fnc = "preview_scroll('reset')" }, ["preview-top"] = { module = "win", fnc = "preview_scroll('top')" }, ["preview-bottom"] = { module = "win", fnc = "preview_scroll('bottom')" }, } @@ -862,9 +862,9 @@ function FzfWin:create() return self.fzf_bufnr end -function FzfWin:close_preview() +function FzfWin:close_preview(do_not_clear_cache) if self._previewer and self._previewer.close then - self._previewer:close() + self._previewer:close(do_not_clear_cache) end if self.border_winid and vim.api.nvim_win_is_valid(self.border_winid) then utils.nvim_win_close(self.border_winid, true) @@ -1243,7 +1243,7 @@ function FzfWin.toggle_preview() utils.feed_keys_termcodes(self._fzf_toggle_prev_bind) end if self.preview_hidden and self:validate_preview() then - self:close_preview() + self:close_preview(true) self:redraw_main() elseif not self.preview_hidden then self:redraw_main()