From 519dbf067bc54a19f5bd57fa86dedecf13bfb1fe Mon Sep 17 00:00:00 2001 From: bhagwan Date: Thu, 30 Jun 2022 08:45:17 -0700 Subject: [PATCH] feat(preview): toggle cursorline hl when scrolling (#462) Other changes: - preview: added new highlight setting `CursorLineNr` - internal changes to preview command shellescape --- README.md | 1 + doc/fzf-lua.txt | 1 + lua/fzf-lua/config.lua | 1 + lua/fzf-lua/core.lua | 6 ++---- lua/fzf-lua/previewer/builtin.lua | 23 +++++++++++++++++------ lua/fzf-lua/previewer/fzf.lua | 12 ++++++------ lua/fzf-lua/providers/buffers.lua | 5 ----- lua/fzf-lua/providers/colorschemes.lua | 25 +++++++++++++------------ lua/fzf-lua/providers/git.lua | 4 +--- lua/fzf-lua/providers/helptags.lua | 1 - lua/fzf-lua/providers/manpages.lua | 1 - lua/fzf-lua/providers/nvim.lua | 5 ----- lua/fzf-lua/providers/ui_select.lua | 6 +++--- lua/fzf-lua/shell.lua | 8 +++++++- lua/fzf-lua/win.lua | 8 ++++++-- 15 files changed, 58 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 8a364eb..9bd982d 100644 --- a/README.md +++ b/README.md @@ -296,6 +296,7 @@ require'fzf-lua'.setup { -- Only valid with the builtin previewer: cursor = 'Cursor', -- cursor highlight (grep/LSP matches) cursorline = 'CursorLine', -- cursor line + cursorlinenr = 'CursorLineNr', -- cursor line number search = 'IncSearch', -- search matches (ctags|help) -- title = 'Normal', -- preview border title (file/buffer) -- scrollbar_f = 'PmenuThumb', -- scrollbar "full" section highlight diff --git a/doc/fzf-lua.txt b/doc/fzf-lua.txt index 41e3931..9d89af8 100644 --- a/doc/fzf-lua.txt +++ b/doc/fzf-lua.txt @@ -335,6 +335,7 @@ Consult the list below for available settings: -- Only valid with the builtin previewer: cursor = 'Cursor', -- cursor highlight (grep/LSP matches) cursorline = 'CursorLine', -- cursor line + cursorlinenr = 'CursorLineNr', -- cursor line number search = 'IncSearch', -- search matches (ctags) -- title = 'Normal', -- preview border title (file/buffer) -- scrollbar_f = 'PmenuThumb', -- scrollbar "full" section highlight diff --git a/lua/fzf-lua/config.lua b/lua/fzf-lua/config.lua index 2808dac..82dc303 100644 --- a/lua/fzf-lua/config.lua +++ b/lua/fzf-lua/config.lua @@ -41,6 +41,7 @@ M.globals = { -- builtin preview only cursor = 'Cursor', cursorline = 'CursorLine', + cursorlinenr = 'CursorLineNr', search = 'IncSearch', -- title = 'Normal', -- scrollbar_f = 'PmenuThumb', diff --git a/lua/fzf-lua/core.lua b/lua/fzf-lua/core.lua index a9523e3..be2d8df 100644 --- a/lua/fzf-lua/core.lua +++ b/lua/fzf-lua/core.lua @@ -181,10 +181,8 @@ M.fzf = function(opts, contents) previewer = preview_opts._ctor()(preview_opts, opts, fzf_win) end if previewer then - -- we use fzf_opts because previewer:cmdline is already - -- shellescaped, clear opts.preview so it doesn't override - opts.preview = nil - opts.fzf_opts['--preview'] = previewer:cmdline() + -- Set the preview command line + opts.preview = previewer:cmdline() if type(previewer.preview_window) == 'function' then -- do we need to override the preview_window args? -- this can happen with the builtin previewer diff --git a/lua/fzf-lua/previewer/builtin.lua b/lua/fzf-lua/previewer/builtin.lua index 5617224..406ee73 100644 --- a/lua/fzf-lua/previewer/builtin.lua +++ b/lua/fzf-lua/previewer/builtin.lua @@ -208,7 +208,7 @@ function Previewer.base:display_entry(entry_str) end -function Previewer.base:action(_) +function Previewer.base:cmdline(_) local act = shell.raw_action(function (items, _, _) self:display_entry(items[1]) return "" @@ -216,11 +216,6 @@ function Previewer.base:action(_) return act end -function Previewer.base:cmdline(_) - return vim.fn.shellescape(self:action()) - -- return 'true' -end - function Previewer.base:preview_window(_) if self.win and not self.win.winopts.split then return 'nohidden:right:0' @@ -267,6 +262,22 @@ function Previewer.base:scroll(direction) '%d, function() vim.cmd("norm! %s") vim.cmd("startinsert") end)'): format(tonumber(preview_winid), input)) end + -- 'cursorline' is effectively our match highlight, once the + -- user scrolls, the highlight is no longer relevenat (#462) + -- conditionally toggle 'cursorline' based on cursor position + if self.orig_pos and self.winopts.cursorline then + local wininfo = vim.fn.getwininfo(preview_winid) + if wininfo and wininfo[1] and + self.orig_pos[1] >= wininfo[1].topline and + self.orig_pos[1] <= wininfo[1].botline then + -- reset cursor pos even when it's already there, no bigggie + -- local curpos = vim.api.nvim_win_get_cursor(preview_winid) + vim.api.nvim_win_set_cursor(preview_winid, self.orig_pos) + vim.api.nvim_win_set_option(preview_winid, 'cursorline', true) + else + vim.api.nvim_win_set_option(preview_winid, 'cursorline', false) + end + end self.win:update_scrollbar() end diff --git a/lua/fzf-lua/previewer/fzf.lua b/lua/fzf-lua/previewer/fzf.lua index 6c9faab..6e541fa 100644 --- a/lua/fzf-lua/previewer/fzf.lua +++ b/lua/fzf-lua/previewer/fzf.lua @@ -103,7 +103,7 @@ function Previewer.bat:cmdline(o) if self.opts.line_field_index then highlight_line = string.format("--highlight-line={%d}", self.opts.line_field_index) end - return vim.fn.shellescape(self:sh_wrap(self.cmd, self.args, o.action, highlight_line)) + return self:sh_wrap(self.cmd, self.args, o.action, highlight_line) end -- Specialized head previewer @@ -122,7 +122,7 @@ function Previewer.head:cmdline(o) -- if self.opts.line_field_index then -- lines = string.format("--lines={%d}", self.opts.line_field_index) -- end - return vim.fn.shellescape(self:sh_wrap(self.cmd, self.args, o.action, lines)) + return self:sh_wrap(self.cmd, self.args, o.action, lines) end -- new async_action from nvim-fzf @@ -192,7 +192,7 @@ end function Previewer.cmd_async:cmdline(o) o = o or {} - local act = shell.preview_action_cmd(function(items) + local act = shell.raw_preview_action_cmd(function(items) local filepath, _, errcmd = self:parse_entry_and_verify(items[1]) local cmd = errcmd or ('%s %s %s'):format( self.cmd, self.args, vim.fn.shellescape(filepath)) @@ -213,7 +213,7 @@ end function Previewer.bat_async:cmdline(o) o = o or {} - local act = shell.preview_action_cmd(function(items, fzf_lines) + local act = shell.raw_preview_action_cmd(function(items, fzf_lines) local filepath, entry, errcmd = self:parse_entry_and_verify(items[1]) local line_range = '' if entry.ctag then @@ -260,7 +260,7 @@ end function Previewer.git_diff:cmdline(o) o = o or {} - local act = shell.preview_action_cmd(function(items, fzf_lines, fzf_columns) + local act = shell.raw_preview_action_cmd(function(items, fzf_lines, fzf_columns) if not items or vim.tbl_isempty(items) then utils.warn("shell error while running preview action.") return @@ -321,7 +321,7 @@ end function Previewer.man_pages:cmdline(o) o = o or {} - local act = shell.preview_action_cmd(function(items) + local act = shell.raw_preview_action_cmd(function(items) -- local manpage = require'fzf-lua.providers.manpages'.getmanpage(items[1]) local manpage = items[1]:match("[^[,( ]+") local cmd = ("%s %s %s"):format( diff --git a/lua/fzf-lua/providers/buffers.lua b/lua/fzf-lua/providers/buffers.lua index ca669f0..b1cd997 100644 --- a/lua/fzf-lua/providers/buffers.lua +++ b/lua/fzf-lua/providers/buffers.lua @@ -253,8 +253,6 @@ M.buffer_lines = function(opts) end end - opts.fzf_opts["--preview-window"] = 'hidden:right:0' - if opts.search and #opts.search>0 then opts.fzf_opts['--query'] = vim.fn.shellescape(opts.search) end @@ -324,9 +322,6 @@ M.tabs = function(opts) cb(nil) end - -- opts.fzf_opts["--no-multi"] = '' - opts.fzf_opts["--preview-window"] = 'hidden:right:0' - opts = core.set_fzf_field_index(opts, 3, "{}") core.fzf_exec(contents, opts) diff --git a/lua/fzf-lua/providers/colorschemes.lua b/lua/fzf-lua/providers/colorschemes.lua index a7c6fcc..9283bb4 100644 --- a/lua/fzf-lua/providers/colorschemes.lua +++ b/lua/fzf-lua/providers/colorschemes.lua @@ -19,25 +19,25 @@ M.colorschemes = function(opts) opts = config.normalize_opts(opts, config.globals.colorschemes) if not opts then return end - local prev_act = shell.action(function (args) - if opts.live_preview and args then - local colorscheme = args[1] - vim.cmd("colorscheme " .. colorscheme) - end - end, nil, opts.debug) local current_colorscheme = get_current_colorscheme() local current_background = vim.o.background local colors = vim.list_extend(opts.colors or {}, vim.fn.getcompletion('', 'color')) - -- must add ':nohidden' or fzf ignore the preview action - -- disabling our live preview of colorschemes - opts.fzf_opts['--preview'] = prev_act opts.fzf_opts['--no-multi'] = '' - opts.fzf_opts['--preview-window'] = 'nohidden:right:0' - core.fzf_wrap(opts, colors, function(selected) + if opts.live_preview then + -- must add ':nohidden' or fzf ignores the preview action + opts.fzf_opts['--preview-window'] = 'nohidden:right:0' + opts.preview = shell.raw_action(function (args) + if opts.live_preview and args then + local colorscheme = args[1] + vim.cmd("colorscheme " .. colorscheme) + end + end, nil, opts.debug) + end + opts.fn_selected = function(selected) -- reset color scheme if live_preview is enabled -- and nothing or non-default action was selected if opts.live_preview and (not selected or #selected[1]>0) then @@ -53,8 +53,9 @@ M.colorschemes = function(opts) if opts.post_reset_cb then opts.post_reset_cb() end + end - end)() + core.fzf_exec(colors, opts) end diff --git a/lua/fzf-lua/providers/git.lua b/lua/fzf-lua/providers/git.lua index 0fcbd0f..17108a9 100644 --- a/lua/fzf-lua/providers/git.lua +++ b/lua/fzf-lua/providers/git.lua @@ -124,9 +124,7 @@ M.branches = function(opts) if not opts then return end opts.fzf_opts["--no-multi"] = '' opts.__preview = path.git_cwd(opts.preview, opts) - -- nullify 'opts.preview' doesn't take priority over '--preview' - opts.preview = nil - opts.fzf_opts["--preview"] = shell.preview_action_cmd(function(items) + opts.preview = shell.raw_preview_action_cmd(function(items) local branch = items[1]:gsub("%*", "") -- remove the * from current branch if branch:find("%)") ~= nil then -- (HEAD detached at origin/master) diff --git a/lua/fzf-lua/providers/helptags.lua b/lua/fzf-lua/providers/helptags.lua index 430b839..5f7b4a1 100644 --- a/lua/fzf-lua/providers/helptags.lua +++ b/lua/fzf-lua/providers/helptags.lua @@ -92,7 +92,6 @@ M.helptags = function(opts) if not opts then return end opts.fzf_opts['--no-multi'] = '' - opts.fzf_opts['--preview-window'] = 'hidden:right:0' core.fzf_exec(fzf_fn, opts) diff --git a/lua/fzf-lua/providers/manpages.lua b/lua/fzf-lua/providers/manpages.lua index 43c5e14..876b9bd 100644 --- a/lua/fzf-lua/providers/manpages.lua +++ b/lua/fzf-lua/providers/manpages.lua @@ -17,7 +17,6 @@ M.manpages = function(opts) end opts.fzf_opts['--no-multi'] = '' - opts.fzf_opts['--preview-window'] = 'hidden:right:0' core.fzf_exec(opts.cmd, opts) end diff --git a/lua/fzf-lua/providers/nvim.lua b/lua/fzf-lua/providers/nvim.lua index 9d3a1f2..165c1f7 100644 --- a/lua/fzf-lua/providers/nvim.lua +++ b/lua/fzf-lua/providers/nvim.lua @@ -57,7 +57,6 @@ local history = function(opts, str) end opts.fzf_opts['--no-multi'] = '' - opts.fzf_opts['--preview-window'] = 'hidden:right:0' core.fzf_exec(entries, opts) end @@ -329,7 +328,6 @@ M.spell_suggest = function(opts) if vim.tbl_isempty(entries) then return end opts.fzf_opts['--no-multi'] = '' - opts.fzf_opts['--preview-window'] = 'hidden:right:0' core.fzf_exec(entries, opts) @@ -344,7 +342,6 @@ M.filetypes = function(opts) if vim.tbl_isempty(entries) then return end opts.fzf_opts['--no-multi'] = '' - opts.fzf_opts['--preview-window'] = 'hidden:right:0' core.fzf_exec(entries, opts) @@ -360,7 +357,6 @@ M.packadd = function(opts) if vim.tbl_isempty(entries) then return end opts.fzf_opts['--no-multi'] = '' - opts.fzf_opts['--preview-window'] = 'hidden:right:0' core.fzf_exec(entries, opts) @@ -397,7 +393,6 @@ M.menus = function(opts) end opts.fzf_opts['--no-multi'] = '' - opts.fzf_opts['--preview-window'] = 'hidden:right:0' core.fzf_exec(entries, opts) diff --git a/lua/fzf-lua/providers/ui_select.lua b/lua/fzf-lua/providers/ui_select.lua index ebfa152..3df795c 100644 --- a/lua/fzf-lua/providers/ui_select.lua +++ b/lua/fzf-lua/providers/ui_select.lua @@ -105,8 +105,7 @@ M.ui_select = function(items, opts, on_choice) config.set_action_helpstr(_opts.actions['default'], "accept-item") - core.fzf_wrap(_opts, entries, function(selected) - + _opts.fn_selected = function(selected) config.set_action_helpstr(_opts.actions['default'], nil) if not selected then @@ -118,8 +117,9 @@ M.ui_select = function(items, opts, on_choice) if _opts.post_action_cb then _opts.post_action_cb() end + end - end)() + core.fzf_exec(entries, _opts) end diff --git a/lua/fzf-lua/shell.lua b/lua/fzf-lua/shell.lua index e2b7347..bcfc392 100644 --- a/lua/fzf-lua/shell.lua +++ b/lua/fzf-lua/shell.lua @@ -107,8 +107,14 @@ function M.action(fn, fzf_field_expression ,debug) end M.preview_action_cmd = function(fn, fzf_field_expression, debug) + local action_string, id = + M.raw_preview_action_cmd(fn, fzf_field_expression, debug) + return vim.fn.shellescape(action_string), id +end + +M.raw_preview_action_cmd = function(fn, fzf_field_expression, debug) - return M.async_action(function(pipe, ...) + return M.raw_async_action(function(pipe, ...) local function on_finish(_, _) if pipe and not uv.is_closing(pipe) then diff --git a/lua/fzf-lua/win.lua b/lua/fzf-lua/win.lua index 7c869d2..0fdfae9 100644 --- a/lua/fzf-lua/win.lua +++ b/lua/fzf-lua/win.lua @@ -295,8 +295,12 @@ end function FzfWin:reset_win_highlights(win, is_border) local hl = ("Normal:%s,FloatBorder:%s"):format( self.winopts.hl.normal, self.winopts.hl.border) - if self._previewer and self.winopts.hl.cursorline then - hl = hl .. (",CursorLine:%s"):format(self.winopts.hl.cursorline) + if self._previewer then + for _, h in ipairs({ 'CursorLine', 'CursorLineNr' }) do + if self.winopts.hl[h:lower()] then + hl = hl .. (",%s:%s"):format(h, self.winopts.hl[h:lower()]) + end + end end if is_border then -- our border is manuually drawn so we need