Skip to content

Commit 07326bb

Browse files
committed
fix(global): different previewer class for tags (#2184)
1 parent 098d50b commit 07326bb

7 files changed

Lines changed: 110 additions & 58 deletions

File tree

lua/fzf-lua/core.lua

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -350,23 +350,10 @@ M.fzf = function(contents, opts)
350350
-- setup the fzf window and preview layout
351351
local fzf_win = win:new(opts)
352352
-- instantiate the previewer
353-
local previewer, preview_opts = nil, nil
354-
if opts.previewer and type(opts.previewer) == "string" then
355-
preview_opts = config.globals.previewers[opts.previewer]
356-
if not preview_opts then
357-
utils.warn(("invalid previewer '%s'"):format(opts.previewer))
358-
end
359-
elseif opts.previewer and type(opts.previewer) == "table" then
360-
preview_opts = opts.previewer
361-
end
362-
if preview_opts and type(preview_opts.new) == "function" then
363-
previewer = preview_opts:new(preview_opts, opts, fzf_win)
364-
elseif preview_opts and type(preview_opts._new) == "function" then
365-
previewer = preview_opts._new()(preview_opts, opts, fzf_win)
366-
elseif preview_opts and type(preview_opts._ctor) == "function" then
367-
previewer = preview_opts._ctor()(preview_opts, opts, fzf_win)
368-
end
353+
local previewer = require("fzf-lua.previewer").new(opts.previewer, opts)
369354
if previewer then
355+
-- Attach the previewer to the windows
356+
fzf_win:attach_previewer(previewer)
370357
-- Set the preview command line
371358
opts.preview = previewer:cmdline()
372359
-- fzf 0.40 added 'zero' event for when there's no match
@@ -398,7 +385,6 @@ M.fzf = function(contents, opts)
398385
opts.fzf_opts["--preview-window"] = "hidden:right:0"
399386
end
400387

401-
fzf_win:attach_previewer(previewer)
402388
local fzf_bufnr = fzf_win:create()
403389
local selected, exit_code = fzf.raw_fzf(contents, M.build_fzf_cli(opts, fzf_win),
404390
{

lua/fzf-lua/defaults.lua

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,10 +367,10 @@ M.defaults.global = vim.tbl_deep_extend("force", M.defaults.files,
367367
pickers = function()
368368
local clients = utils.lsp_get_clients({ bufnr = FzfLua.core.CTX().bufnr })
369369
local doc_sym_supported = vim.iter(clients):any(function(client)
370-
return client.supports_method("textDocument/documentSymbol")
370+
return client:supports_method("textDocument/documentSymbol")
371371
end)
372372
local wks_sym_supported = vim.iter(clients):any(function(client)
373-
return client.supports_method("workspace/symbol")
373+
return client:supports_method("workspace/symbol")
374374
end)
375375
return {
376376
{ "files", desc = "Files" },
@@ -380,6 +380,7 @@ M.defaults.global = vim.tbl_deep_extend("force", M.defaults.files,
380380
desc = "Tags (buf)",
381381
prefix = "@",
382382
opts = {
383+
previewer = { _ctor = previewers.builtin.tags },
383384
fn_transform = [[return require("fzf-lua.make_entry").tag]],
384385
}
385386
},
@@ -389,6 +390,7 @@ M.defaults.global = vim.tbl_deep_extend("force", M.defaults.files,
389390
desc = "Tags (project)",
390391
prefix = "#",
391392
opts = {
393+
previewer = { _ctor = previewers.builtin.tags },
392394
fn_transform = [[return require("fzf-lua.make_entry").tag]],
393395
rg_opts = "--no-heading --color=always --smart-case",
394396
grep_opts = "--color=auto --perl-regexp",

lua/fzf-lua/previewer/builtin.lua

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,8 @@ Previewer.base = Object:extend()
145145

146146
---@param o table
147147
---@param opts table
148-
---@param fzf_win fzf-lua.Win
149148
---@return fzf-lua.previewer.Builtin
150-
function Previewer.base:new(o, opts, fzf_win)
149+
function Previewer.base:new(o, opts)
151150
local function default(var, def)
152151
if var ~= nil then
153152
return var
@@ -159,16 +158,11 @@ function Previewer.base:new(o, opts, fzf_win)
159158
o = o or {}
160159
self.type = "builtin"
161160
self.opts = opts;
162-
self.win = fzf_win
163-
self.delay = self.win.winopts.preview.delay or 100
164-
self.title = self.win.winopts.preview.title
165-
self.title_pos = self.win.winopts.preview.title_pos
166161
self.title_fnamemodify = o.title_fnamemodify
167162
self.render_markdown = type(o.render_markdown) == "table" and o.render_markdown or {}
168163
self.render_markdown.filetypes =
169164
type(self.render_markdown.filetypes) == "table" and self.render_markdown.filetypes or {}
170165
self.snacks_image = type(o.snacks_image) == "table" and o.snacks_image or {}
171-
self.winopts = self.win.winopts.preview.winopts
172166
self.syntax = default(o.syntax, true)
173167
self.syntax_delay = tonumber(default(o.syntax_delay, 0))
174168
self.syntax_limit_b = tonumber(default(o.syntax_limit_b, 1024 * 1024))
@@ -178,7 +172,6 @@ function Previewer.base:new(o, opts, fzf_win)
178172
self.treesitter = type(o.treesitter) == "table" and o.treesitter or {}
179173
self.toggle_behavior = o.toggle_behavior
180174
self.winopts_orig = {}
181-
self.winblend = self.winblend or self.winopts.winblend or vim.o.winblend
182175
-- convert extension map to lower case
183176
if o.extensions then
184177
self.extensions = {}
@@ -454,6 +447,8 @@ function Previewer.base:cmdline(_)
454447
-- NOTE: see comment regarding {n} in `core.convert_exec_silent_actions`
455448
-- convert empty string to nil
456449
if not tonumber(idx) then entry = nil end
450+
-- upvalue incase previewer was detached/re-attached (global picker)
451+
self = self.win._previewer or self
457452
-- on windows, query may not be expanded to a string: #1887
458453
self.opts._last_query = query or ""
459454
self:display_entry(entry)
@@ -594,8 +589,8 @@ end
594589
---@field super fzf-lua.previewer.Builtin
595590
Previewer.buffer_or_file = Previewer.base:extend()
596591

597-
function Previewer.buffer_or_file:new(o, opts, fzf_win)
598-
Previewer.buffer_or_file.super.new(self, o, opts, fzf_win)
592+
function Previewer.buffer_or_file:new(o, opts)
593+
Previewer.buffer_or_file.super.new(self, o, opts)
599594
return self
600595
end
601596

@@ -1350,8 +1345,8 @@ end
13501345
---@field super fzf-lua.previewer.BufferOrFile
13511346
Previewer.help_tags = Previewer.buffer_or_file:extend()
13521347

1353-
function Previewer.help_tags:new(o, opts, fzf_win)
1354-
Previewer.help_tags.super.new(self, o, opts, fzf_win)
1348+
function Previewer.help_tags:new(o, opts)
1349+
Previewer.help_tags.super.new(self, o, opts)
13551350
return self
13561351
end
13571352

@@ -1422,8 +1417,8 @@ function Previewer.man_pages:gen_winopts()
14221417
return vim.tbl_extend("keep", winopts, self.winopts)
14231418
end
14241419

1425-
function Previewer.man_pages:new(o, opts, fzf_win)
1426-
Previewer.man_pages.super.new(self, o, opts, fzf_win)
1420+
function Previewer.man_pages:new(o, opts)
1421+
Previewer.man_pages.super.new(self, o, opts)
14271422
self.filetype = "man"
14281423
self.cmd = o.cmd or "man -c %s | col -bx"
14291424
self.cmd = type(self.cmd) == "function" and self.cmd() or self.cmd
@@ -1452,8 +1447,8 @@ end
14521447
---@field super fzf-lua.previewer.BufferOrFile,{}
14531448
Previewer.marks = Previewer.buffer_or_file:extend()
14541449

1455-
function Previewer.marks:new(o, opts, fzf_win)
1456-
Previewer.marks.super.new(self, o, opts, fzf_win)
1450+
function Previewer.marks:new(o, opts)
1451+
Previewer.marks.super.new(self, o, opts)
14571452
return self
14581453
end
14591454

@@ -1495,8 +1490,8 @@ end
14951490
---@field super fzf-lua.previewer.BufferOrFile,{}
14961491
Previewer.jumps = Previewer.buffer_or_file:extend()
14971492

1498-
function Previewer.jumps:new(o, opts, fzf_win)
1499-
Previewer.jumps.super.new(self, o, opts, fzf_win)
1493+
function Previewer.jumps:new(o, opts)
1494+
Previewer.jumps.super.new(self, o, opts)
15001495
return self
15011496
end
15021497

@@ -1527,8 +1522,8 @@ end
15271522
---@field super fzf-lua.previewer.BufferOrFile,{}
15281523
Previewer.tags = Previewer.buffer_or_file:extend()
15291524

1530-
function Previewer.tags:new(o, opts, fzf_win)
1531-
Previewer.tags.super.new(self, o, opts, fzf_win)
1525+
function Previewer.tags:new(o, opts)
1526+
Previewer.tags.super.new(self, o, opts)
15321527
return self
15331528
end
15341529

@@ -1568,8 +1563,8 @@ function Previewer.highlights:gen_winopts()
15681563
return vim.tbl_extend("keep", winopts, self.winopts)
15691564
end
15701565

1571-
function Previewer.highlights:new(o, opts, fzf_win)
1572-
Previewer.highlights.super.new(self, o, opts, fzf_win)
1566+
function Previewer.highlights:new(o, opts)
1567+
Previewer.highlights.super.new(self, o, opts)
15731568
self.ns_previewer = vim.api.nvim_create_namespace("fzf-lua.previewer.hl")
15741569
return self
15751570
end
@@ -1654,8 +1649,8 @@ function Previewer.quickfix:gen_winopts()
16541649
return vim.tbl_extend("keep", winopts, self.winopts)
16551650
end
16561651

1657-
function Previewer.quickfix:new(o, opts, fzf_win)
1658-
Previewer.quickfix.super.new(self, o, opts, fzf_win)
1652+
function Previewer.quickfix:new(o, opts)
1653+
Previewer.quickfix.super.new(self, o, opts)
16591654
return self
16601655
end
16611656

@@ -1695,8 +1690,8 @@ end
16951690
---@field super fzf-lua.previewer.BufferOrFile,{}
16961691
Previewer.autocmds = Previewer.buffer_or_file:extend()
16971692

1698-
function Previewer.autocmds:new(o, opts, fzf_win)
1699-
Previewer.autocmds.super.new(self, o, opts, fzf_win)
1693+
function Previewer.autocmds:new(o, opts)
1694+
Previewer.autocmds.super.new(self, o, opts)
17001695
return self
17011696
end
17021697

@@ -1737,8 +1732,8 @@ end
17371732
---@field super fzf-lua.previewer.BufferOrFile,{}
17381733
Previewer.keymaps = Previewer.buffer_or_file:extend()
17391734

1740-
function Previewer.autocmds:keymaps(o, opts, fzf_win)
1741-
Previewer.autocmds.super.new(self, o, opts, fzf_win)
1735+
function Previewer.autocmds:keymaps(o, opts)
1736+
Previewer.autocmds.super.new(self, o, opts)
17421737
return self
17431738
end
17441739

@@ -1773,8 +1768,8 @@ end
17731768
---@field super fzf-lua.previewer.Builtin,{}
17741769
Previewer.nvim_options = Previewer.base:extend()
17751770

1776-
function Previewer.nvim_options:new(o, opts, fzf_win)
1777-
Previewer.nvim_options.super.new(self, o, opts, fzf_win)
1771+
function Previewer.nvim_options:new(o, opts)
1772+
Previewer.nvim_options.super.new(self, o, opts)
17781773
local paths = vim.fn.globpath(vim.o.rtp, "doc/options.txt", false, true)
17791774
self.lines = vim.fn.readfile(paths[1])
17801775
return self

lua/fzf-lua/previewer/init.lua

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,31 @@ Previewer.builtin.keymaps = function() return require "fzf-lua.previewer.builtin
2727
Previewer.builtin.nvim_options = function() return require "fzf-lua.previewer.builtin".nvim_options end
2828
Previewer.builtin.codeaction = function() return require "fzf-lua.previewer.codeaction".builtin end
2929

30+
31+
---Instantiate previewer from spec
32+
---@param spec table
33+
---@param opts table
34+
---@return fzf-lua.previewer?
35+
Previewer.new = function(spec, opts)
36+
if not spec then return end
37+
local previewer, preview_opts = nil, nil
38+
if type(spec) == "string" then
39+
preview_opts = FzfLua.config.globals.previewers[spec]
40+
if not preview_opts then
41+
FzfLua.utils.warn(("invalid previewer '%s'"):format(spec))
42+
end
43+
elseif type(spec) == "table" then
44+
preview_opts = spec
45+
end
46+
-- Backward compat: can instantiate with `_ctor|new|_new`
47+
if preview_opts and type(preview_opts.new) == "function" then
48+
previewer = preview_opts:new(preview_opts, opts)
49+
elseif preview_opts and type(preview_opts._new) == "function" then
50+
previewer = preview_opts._new()(preview_opts, opts)
51+
elseif preview_opts and type(preview_opts._ctor) == "function" then
52+
previewer = preview_opts._ctor()(preview_opts, opts)
53+
end
54+
return previewer
55+
end
56+
3057
return Previewer

lua/fzf-lua/providers/meta.lua

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -168,21 +168,38 @@ M.global = function(opts)
168168
for _, t in ipairs(opts.pickers) do
169169
local name = t[1]
170170
if FzfLua[name] then
171+
local def
172+
local function gen_def(n, o)
173+
local wrapped = { FzfLua[n](o) }
174+
return {
175+
name = n,
176+
opts = wrapped[3],
177+
contents = wrapped[2],
178+
}
179+
end
171180
if not t.prefix then
172181
-- Default picker opts set the tone for this picker options
173182
-- this way convert reload / exec_silent actions will use a consistent
174183
-- opts ref in the callbacks so we can later modify internal values
175-
pickers[name] = { FzfLua[name](opts) }
184+
def = gen_def(name, opts)
185+
pickers[name] = def
176186
-- Override opts with the return opts and store a copy of `pickers[]`
177187
-- as we patch the opts when switching a picker in the change event
178-
opts = pickers[name][3]
188+
opts = def.opts
179189
opts._start = nil -- remove the start suppression
180-
pickers[name][3] = vim.deepcopy(opts)
190+
def.opts = vim.deepcopy(opts)
181191
else
182192
-- Each subsequent picker gets a fresh copy of the original opts
183193
-- (unmodified by the default picker)
184-
pickers[name] = { FzfLua[name](t.opts and
185-
vim.tbl_deep_extend("force", {}, opts_copy, t.opts) or opts_copy) }
194+
def = gen_def(name, t.opts
195+
and vim.tbl_deep_extend("force", {}, opts_copy, t.opts)
196+
or opts_copy)
197+
pickers[name] = def
198+
end
199+
-- Instantiate the previewer, opts isn't guaranteed if the picker
200+
-- isn't avilable, e.g. `tags` when not tags file exists
201+
if def.opts and def.opts.previewer then
202+
def.previewer = require("fzf-lua.previewer").new(def.opts.previewer, def.opts)
186203
end
187204
else
188205
utils.warn(string.format("invalid picker '%s', ignoring.", name))
@@ -222,13 +239,24 @@ M.global = function(opts)
222239
if start or new_picker and new_picker ~= cur_picker then
223240
-- New picker requested, reload the contents and transform
224241
-- the search string to exclude the picker prefix
225-
cur_sub = new_sub
226-
cur_picker = new_picker
227242
-- Patch the opts refs with important values for path parsing
228243
-- e.g. formatter, path_shorten, etc
244+
cur_picker = cur_picker or new_picker
229245
-- TODO: is there a better way to override the callback opts ref?
230-
opts.__alt_opts = new_picker[3]
231-
reload = string.format("reload(%s)+", new_picker[2])
246+
opts.__alt_opts = new_picker.opts
247+
-- Attach a new previewer if exists
248+
local win = FzfLua.utils.fzf_winobj()
249+
if win
250+
and new_picker.previewer
251+
and new_picker.previewer ~= cur_picker.previewer
252+
then
253+
win:close_preview()
254+
win:attach_previewer(new_picker.previewer)
255+
win:redraw_preview()
256+
end
257+
reload = string.format("reload(%s)+", new_picker.contents)
258+
cur_sub = new_sub
259+
cur_picker = new_picker
232260
end
233261
return reload .. string.format("search(%s)", q:sub(cur_sub))
234262
end, opts, "{q}")

lua/fzf-lua/types.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ _G.FzfLua = require("fzf-lua")
66
---@class fzf-lua.Config
77
---@field [string] any
88

9+
---@class fzf-lua.previewer
10+
---@field new function
11+
---@field zero function?
12+
---@field cmdline function?
13+
---@field fzf_delimiter function?
14+
---@field preview_window function?
15+
---@field _preview_offset function?
16+
917
---@class fzf-lua.previewer.Builtin
1018
---@field type "builtin"
1119
---@field opts table

lua/fzf-lua/win.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,12 @@ end
726726

727727
---@param previewer fzf-lua.previewer.Builtin
728728
function FzfWin:attach_previewer(previewer)
729+
previewer.win = self
730+
previewer.delay = self.winopts.preview.delay or 100
731+
previewer.title = self.winopts.preview.title
732+
previewer.title_pos = self.winopts.preview.title_pos
733+
previewer.winopts = self.winopts.preview.winopts
734+
previewer.winblend = previewer.winblend or previewer.winopts.winblend or vim.o.winblend
729735
-- clear the previous previewer if existed
730736
if self._previewer and self._previewer.close then
731737
-- if we press ctrl-g too quickly 'previewer.preview_bufnr' will be nil

0 commit comments

Comments
 (0)