From e9e1acc1027423bc5bbf58b16813202e6c02d163 Mon Sep 17 00:00:00 2001 From: bhagwan Date: Tue, 10 Dec 2024 01:16:36 -0800 Subject: [PATCH] WIP --- OPTIONS.md | 20 +++- README.md | 51 ++++------- doc/fzf-lua-opts.txt | 27 ++++-- lua/fzf-lua/config.lua | 18 ++++ lua/fzf-lua/defaults.lua | 88 +++++++++++------- lua/fzf-lua/init.lua | 24 ++--- lua/fzf-lua/profiles/fzf-tmux.lua | 2 + lua/fzf-lua/providers/buffers.lua | 147 +++++++++++++++++++----------- lua/fzf-lua/providers/grep.lua | 28 +++--- lua/fzf-lua/win.lua | 24 ++++- 10 files changed, 266 insertions(+), 163 deletions(-) diff --git a/OPTIONS.md b/OPTIONS.md index b5f3ef63..9420f4ff 100644 --- a/OPTIONS.md +++ b/OPTIONS.md @@ -554,25 +554,37 @@ Interactive headers description highlight group, e.g. ` to Disable .giti Type: `string`, Default: `FzfLuaPathLineNr` -Highlight group for the line part of paths, e.g. `file:::`, used in pickers such as `buffers`, `lines`, `quickfix`, `lsp`, `diagnostics`, etc. +Highlight group for the line part of paths, e.g. `file:::`, used in pickers such as `buffers`, `quickfix`, `lsp`, `diagnostics`, etc. #### globals.hls.path_colnr Type: `string`, Default: `FzfLuaPathColNr` -Highlight group for the column part of paths, e.g. `file:::`, used in pickers such as `buffers`, `lines`, `quickfix`, `lsp`, `diagnostics`, etc. +Highlight group for the column part of paths, e.g. `file:::`, used in pickers such as `buffers`, `quickfix`, `lsp`, `diagnostics`, etc. #### globals.hls.buf_name Type: `string`, Default: `FzfLuaBufName` -Highlight group for buffer name in `lines`. +Highlight group for buffer name (filepath) in `lines`. + +#### globals.hls.buf_id + +Type: `string`, Default: `FzfLuaBufId` + +Highlight group for buffer id (number) in `lines`. #### globals.hls.buf_nr Type: `string`, Default: `FzfLuaBufNr` -Highlight group for buffer number in buffer type pickers, i.e. `buffers`, `tabs`, `lines`. +Highlight group for buffer number in `buffers`, `tabs`. + +#### globals.hls.buf_linenr + +Type: `string`, Default: `FzfLuaBufLineNr` + +Highlight group for buffer line number in `lines`, `blines` and `treesitter`. #### globals.hls.buf_flag_cur diff --git a/README.md b/README.md index 43f1a0dd..bfc5f4e2 100644 --- a/README.md +++ b/README.md @@ -585,6 +585,14 @@ require'fzf-lua'.setup { -- title = "Title", -- title_pos = "center", -- 'left', 'center' or 'right' fullscreen = false, -- start fullscreen? + -- enable treesitter highlighting for the main fzf window will only have + -- effect when grep like results are present, i.e. "file:line:col:text" + -- due to highlight color collisions will also override `fzf_colors` + -- set `fzf_colors=false` or `fzf_colors.hl=...` to override + treesitter = { + enable = false, + fzf_colors = { ["hl"] = "-1:reverse", ["hl+"] = "-1:reverse" } + }, preview = { -- default = 'bat', -- override the default previewer? -- default uses the 'builtin' previewer @@ -1106,45 +1114,16 @@ require'fzf-lua'.setup { ["--with-nth"] = '2..', }, }, + -- `blines` has the same defaults as `lines` aside from prompt and `show_bufname` lines = { - previewer = "builtin", -- set to 'false' to disable prompt = 'Lines❯ ', + show_bufname = true, -- display buffer name show_unloaded = true, -- show unloaded buffers show_unlisted = false, -- exclude 'help' buffers no_term_buffers = true, -- exclude 'term' buffers fzf_opts = { -- do not include bufnr in fuzzy matching -- tiebreak by line no. - ["--delimiter"] = "[\\]:]", - ["--nth"] = '2..', - ["--tiebreak"] = 'index', - ["--tabstop"] = "1", - }, - -- actions inherit from 'actions.files' and merge - actions = { - ["enter"] = actions.buf_edit_or_qf, - ["alt-q"] = actions.buf_sel_to_qf, - ["alt-l"] = actions.buf_sel_to_ll - }, - }, - blines = { - previewer = "builtin", -- set to 'false' to disable - prompt = 'BLines❯ ', - show_unlisted = true, -- include 'help' buffers - no_term_buffers = false, -- include 'term' buffers - -- start = "cursor" -- start display from cursor? - fzf_opts = { - -- hide filename, tiebreak by line no. - ["--delimiter"] = "[:]", - ["--with-nth"] = '2..', - ["--tiebreak"] = 'index', - ["--tabstop"] = "1", - }, - -- actions inherit from 'actions.files' and merge - actions = { - ["enter"] = actions.buf_edit_or_qf, - ["alt-q"] = actions.buf_sel_to_qf, - ["alt-l"] = actions.buf_sel_to_ll }, }, tags = { @@ -1418,10 +1397,12 @@ temporarily overridden by its corresponding `winopts` option: |FzfLuaHelpBorder |FzfLuaBorder |`hls.help_border` |Help win border| |FzfLuaHeaderBind |*BlanchedAlmond |`hls.header_bind` |Header keybind| |FzfLuaHeaderText |*Brown1 |`hls.header_text` |Header text| -|FzfLuaPathColNr |*CadetBlue1 |`hls.path_colnr` |Path col nr (`lines,qf,lsp,diag`)| -|FzfLuaPathLineNr |*LightGreen |`hls.path_linenr` |Path line nr (`lines,qf,lsp,diag`)| -|FzfLuaBufName |*LightMagenta |`hls.buf_name` |Buffer name (`lines`)| -|FzfLuaBufNr |*BlanchedAlmond |`hls.buf_nr` |Buffer number (all buffers)| +|FzfLuaPathColNr |*CadetBlue1 |`hls.path_colnr` |Path col nr (`qf,lsp,diag`)| +|FzfLuaPathLineNr |*LightGreen |`hls.path_linenr` |Path line nr (`qf,lsp,diag`)| +|FzfLuaBufName |Directory |`hls.buf_name` |Buffer name (`lines`)| +|FzfLuaBufId |TabLine |`hls.buf_id` |Buffer ID (`lines`)| +|FzfLuaBufNr |*BlanchedAlmond |`hls.buf_nr` |Buffer number (`buffers,tabs`)| +|FzfLuaBufLineNr |LineNr |`hls.buf_linenr` |Buffer line nr (`lines,blines`)| |FzfLuaBufFlagCur |*Brown1 |`hls.buf_flag_cur` |Buffer line (`buffers`)| |FzfLuaBufFlagAlt |*CadetBlue1 |`hls.buf_flag_alt` |Buffer line (`buffers`)| |FzfLuaTabTitle |*LightSkyBlue1 |`hls.tab_title` |Tab title (`tabs`)| diff --git a/doc/fzf-lua-opts.txt b/doc/fzf-lua-opts.txt index 4892d794..a58c0594 100644 --- a/doc/fzf-lua-opts.txt +++ b/doc/fzf-lua-opts.txt @@ -1,4 +1,4 @@ -*fzf-lua-opts.txt* For Neovim >= 0.8.0 Last change: 2024 November 18 +*fzf-lua-opts.txt* For Neovim >= 0.8.0 Last change: 2024 December 10 ============================================================================== Table of Contents *fzf-lua-opts-table-of-contents* @@ -736,7 +736,7 @@ globals.hls.path_linenr *fzf-lua-opts-globals.hls.path_linenr* Type: `string`, Default: `FzfLuaPathLineNr` Highlight group for the line part of paths, e.g. `file:::`, used in -pickers such as `buffers`, `lines`, `quickfix`, `lsp`, `diagnostics`, etc. +pickers such as `buffers`, `quickfix`, `lsp`, `diagnostics`, etc. @@ -745,7 +745,7 @@ globals.hls.path_colnr *fzf-lua-opts-globals.hls.path_colnr* Type: `string`, Default: `FzfLuaPathColNr` Highlight group for the column part of paths, e.g. `file:::`, used -in pickers such as `buffers`, `lines`, `quickfix`, `lsp`, `diagnostics`, etc. +in pickers such as `buffers`, `quickfix`, `lsp`, `diagnostics`, etc. @@ -753,7 +753,15 @@ globals.hls.buf_name *fzf-lua-opts-globals.hls.buf_name* Type: `string`, Default: `FzfLuaBufName` -Highlight group for buffer name in `lines`. +Highlight group for buffer name (filepath) in `lines`. + + + +globals.hls.buf_id *fzf-lua-opts-globals.hls.buf_id* + +Type: `string`, Default: `FzfLuaBufId` + +Highlight group for buffer id (number) in `lines`. @@ -761,8 +769,15 @@ globals.hls.buf_nr *fzf-lua-opts-globals.hls.buf_nr* Type: `string`, Default: `FzfLuaBufNr` -Highlight group for buffer number in buffer type pickers, i.e. `buffers`, -`tabs`, `lines`. +Highlight group for buffer number in `buffers`, `tabs`. + + + +globals.hls.buf_linenr *fzf-lua-opts-globals.hls.buf_linenr* + +Type: `string`, Default: `FzfLuaBufLineNr` + +Highlight group for buffer line number in `lines`, `blines` and `treesitter`. diff --git a/lua/fzf-lua/config.lua b/lua/fzf-lua/config.lua index d978e38d..b99e4ac9 100644 --- a/lua/fzf-lua/config.lua +++ b/lua/fzf-lua/config.lua @@ -229,6 +229,24 @@ function M.normalize_opts(opts, globals, __resume_key) type(M.globals[k]) == "table" and utils.tbl_deep_clone(M.globals[k]) or {}) end + -- Adjust main fzf window treesitter settings + -- Set to `true`, will copy the defaults and add `enable=true` + -- Set to a table `enable=true` is assumed (i.e. `nil` equals `true`) + if opts.winopts.treesitter == true then + opts.winopts.treesitter = vim.tbl_deep_extend("force", + M.defaults.winopts.treesitter, { enable = true }) + end + -- Unless the caller specifically disables fuzzy matching colors will be + -- set to `reverse` which sets the background color for matches instead + -- NOTE: default `fzf_colors` are set in `defaults.winopts.treesitter` + if type(opts.winopts.treesitter) == "table" + and opts.winopts.treesitter.enable ~= false + and type(opts.winopts.treesitter.fzf_colors) == "table" then + opts.fzf_colors = vim.tbl_deep_extend("force", + opts.fzf_colors or {}, opts.winopts.treesitter.fzf_colors) + end + -- _G.dump(opts.winopts.treesitter, opts.fzf_colors) + -- backward compat: no-value flags should be set to `true`, in the past these -- would be set to an empty string which would now translate into a shell escaped -- string as we automatically shell escape all fzf_opts diff --git a/lua/fzf-lua/defaults.lua b/lua/fzf-lua/defaults.lua index d2e74922..0810520a 100644 --- a/lua/fzf-lua/defaults.lua +++ b/lua/fzf-lua/defaults.lua @@ -49,6 +49,11 @@ M.defaults = { zindex = 50, backdrop = 60, fullscreen = false, + treesitter = { + enable = false, + -- fzf_colors = { ["hl"] = "-1:reverse", ["hl+"] = "-1:reverse" } + fzf_colors = { ["hl"] = "reverse:underline", ["hl+"] = "reverse:underline" } + }, preview = { default = "builtin", border = "border", @@ -507,6 +512,17 @@ M.defaults.grep = { glob_separator = "%s%-%-", -- query separator pattern (lua): ' --' } +M.defaults.grep_curbuf = vim.tbl_deep_extend("force", M.defaults.grep, { + prompt = "RgBuffer> ", + rg_glob = false, -- meaningless for single file rg + exec_empty_query = true, -- makes sense to display lines immediately + fzf_opts = { + ["--delimiter"] = "[:]", + ["--with-nth"] = "2..", + ["--nth"] = "2..", + }, +}) + M.defaults.args = { previewer = M._default_previewer_fn, prompt = "Args> ", @@ -620,55 +636,54 @@ M.defaults.lines = { prompt = "Lines> ", file_icons = true and M._has_devicons, color_icons = true, + -- show_bufname = 120, + show_bufname = 0, show_unloaded = true, show_unlisted = false, no_term_buffers = true, + sort_lastused = true, fzf_opts = { ["--multi"] = true, - ["--delimiter"] = "[\\]:]", - ["--nth"] = "2..", + ["--delimiter"] = "[\t]", + ["--tabstop"] = "1", ["--tiebreak"] = "index", + ["--with-nth"] = "2..", + ["--nth"] = "4..", + }, + line_field_index = "{4}", + field_index_expr = "{}", -- For `_fmt.from` to work with `bat_native` + _cached_hls = { "buf_id", "buf_name", "buf_linenr" }, + _fmt = { + -- NOTE: `to` is not needed, we format at the source in `buffer_lines` + to = false, + from = function(s, _) + -- restore the format to something that `path.entry_to_file` can handle + local bufnr, lnum, text = s:match("%[(%d+)%].-(%d+) (.+)$") + if not bufnr then return "" end + return string.format("[%s]%s%s:%s:%s", + bufnr, utils.nbsp, + path.tail(vim.api.nvim_buf_get_name(tonumber(bufnr))), + lnum, text) + end }, - line_field_index = "{3}", _actions = function() return M.globals.actions.buffers or M.globals.actions.files end, - actions = { - ["enter"] = actions.buf_edit_or_qf, - ["alt-q"] = actions.buf_sel_to_qf, - ["alt-l"] = actions.buf_sel_to_ll - }, - _cached_hls = { "buf_name", "buf_nr", "path_linenr" }, } -M.defaults.blines = { - previewer = M._default_previewer_fn, - prompt = "BLines> ", - file_icons = false, - color_icons = false, - show_unlisted = true, - no_term_buffers = false, - fzf_opts = { - ["--multi"] = true, - ["--delimiter"] = "[:]", - ["--with-nth"] = "2..", - ["--tiebreak"] = "index", - }, - line_field_index = "{2}", - _actions = function() - return M.globals.actions.buffers or M.globals.actions.files - end, - actions = { - ["enter"] = actions.buf_edit_or_qf, - ["alt-q"] = actions.buf_sel_to_qf, - ["alt-l"] = actions.buf_sel_to_ll +M.defaults.blines = vim.tbl_deep_extend("force", M.defaults.lines, { + prompt = "BLines> ", + show_bufname = false, + fzf_opts = { + ["--with-nth"] = "4..", + ["--nth"] = "2..", }, - _cached_hls = { "buf_name", "buf_nr", "path_linenr" }, -} +}) M.defaults.treesitter = { previewer = M._default_previewer_fn, prompt = "Treesitter> ", + show_bufname = false, file_icons = false, color_icons = false, fzf_opts = { @@ -735,9 +750,10 @@ M.defaults.colorschemes = { } M.defaults.highlights = { - prompt = "Highlights> ", - fzf_opts = { ["--no-multi"] = true }, - previewer = { _ctor = previewers.builtin.highlights, }, + prompt = "Highlights> ", + fzf_opts = { ["--no-multi"] = true }, + fzf_colors = { ["hl"] = "-1:reverse", ["hl+"] = "-1:reverse" }, + previewer = { _ctor = previewers.builtin.highlights, }, } M.defaults.awesome_colorschemes = { @@ -1189,7 +1205,9 @@ M.defaults.__HLS = { path_colnr = "FzfLuaPathColNr", path_linenr = "FzfLuaPathLineNr", buf_name = "FzfLuaBufName", + buf_id = "FzfLuaBufId", buf_nr = "FzfLuaBufNr", + buf_linenr = "FzfLuaBufLineNr", buf_flag_cur = "FzfLuaBufFlagCur", buf_flag_alt = "FzfLuaBufFlagAlt", tab_title = "FzfLuaTabTitle", diff --git a/lua/fzf-lua/init.lua b/lua/fzf-lua/init.lua index 69a4dfb7..db0bb73d 100644 --- a/lua/fzf-lua/init.lua +++ b/lua/fzf-lua/init.lua @@ -81,24 +81,26 @@ function M.setup_highlights(override) { default = default, fg = is_light and "MediumSpringGreen" or "BlanchedAlmond" } }, { "FzfLuaHeaderText", "header_text", { default = default, fg = is_light and "Brown4" or "Brown1" } }, - { "FzfLuaPathColNr", "path_colnr", -- lines|blines|qf|diag|lsp + { "FzfLuaPathColNr", "path_colnr", -- qf|diag|lsp { default = default, fg = is_light and "CadetBlue4" or "CadetBlue1" } }, - { "FzfLuaPathLineNr", "path_linenr", -- lines|blines|qf|diag|lsp + { "FzfLuaPathLineNr", "path_linenr", -- qf|diag|lsp { default = default, fg = is_light and "MediumSpringGreen" or "LightGreen" } }, - { "FzfLuaLiveSym", "live_sym", + { "FzfLuaLiveSym", "live_sym", -- lsp_live_workspace_symbols query { default = default, fg = is_light and "Brown4" or "Brown1" } }, - -- Provider specific highlights - { "FzfLuaBufName", "buf_name", -- lines|blines (hidden) - { default = default, fg = is_light and "DarkOrchid3" or "LightMagenta" } }, - { "FzfLuaBufNr", "buf_nr", -- buffers|tabs|lines|blines + -- lines|blines|treesitter + { "FzfLuaBufId", "buf_id", { default = default, link = "TabLine" } }, + { "FzfLuaBufName", "buf_name", { default = default, link = "Directory" } }, + { "FzfLuaBufLineNr", "buf_linenr", { default = default, link = "LineNr" } }, + -- buffers|tabs + { "FzfLuaBufNr", "buf_nr", { default = default, fg = is_light and "AquaMarine3" or "BlanchedAlmond" } }, - { "FzfLuaBufFlagCur", "buf_flag_cur", -- buffers|tabs + { "FzfLuaBufFlagCur", "buf_flag_cur", { default = default, fg = is_light and "Brown4" or "Brown1" } }, - { "FzfLuaBufFlagAlt", "buf_flag_alt", -- buffers|tabs + { "FzfLuaBufFlagAlt", "buf_flag_alt", { default = default, fg = is_light and "CadetBlue4" or "CadetBlue1" } }, - { "FzfLuaTabTitle", "tab_title", -- tabs + { "FzfLuaTabTitle", "tab_title", -- tabs only { default = default, fg = is_light and "CadetBlue4" or "LightSkyBlue1", bold = true } }, - { "FzfLuaTabMarker", "tab_marker", -- tabs + { "FzfLuaTabMarker", "tab_marker", -- tabs only { default = default, fg = is_light and "MediumSpringGreen" or "BlanchedAlmond", bold = true } }, -- highlight groups for `fzf_colors=true` { "FzfLuaFzfNormal", "fzf.normal", { default = default, link = "FzfLuaNormal" } }, diff --git a/lua/fzf-lua/profiles/fzf-tmux.lua b/lua/fzf-lua/profiles/fzf-tmux.lua index cd31ffd9..c59b2adf 100644 --- a/lua/fzf-lua/profiles/fzf-tmux.lua +++ b/lua/fzf-lua/profiles/fzf-tmux.lua @@ -9,4 +9,6 @@ return { lsp = { code_actions = { previewer = "codeaction_native" } }, tags = { previewer = "bat" }, btags = { previewer = "bat" }, + lines = { ["winopts.treesitter"] = false }, + blines = { ["winopts.treesitter"] = false }, } diff --git a/lua/fzf-lua/providers/buffers.lua b/lua/fzf-lua/providers/buffers.lua index e9f7d6a3..3af03e68 100644 --- a/lua/fzf-lua/providers/buffers.lua +++ b/lua/fzf-lua/providers/buffers.lua @@ -59,49 +59,58 @@ local filter_buffers = function(opts, unfiltered) return bufnrs, excluded, max_bufnr end + +local getbuf = function(buf) + return { + bufnr = buf, + flag = (buf == core.CTX().bufnr and "%") + or (buf == core.CTX().alt_bufnr and "#") or " ", + info = utils.getbufinfo(buf), + readonly = vim.bo[buf].readonly + } +end + +-- switching buffers and opening 'buffers' in quick succession +-- can lead to incorrect sort as 'lastused' isn't updated fast +-- enough (neovim bug?), this makes sure the current buffer is +-- always on top (#646) +-- Hopefully this gets solved before the year 2100 +-- DON'T FORCE ME TO UPDATE THIS HACK NEOVIM LOL +local _FUTURE = os.time({ year = 2100, month = 1, day = 1, hour = 0, minute = 00 }) +local get_unixtime = function(buf) + if tonumber(buf) then + -- When called from `buffer_lines` + buf = getbuf(buf) + end + if buf.flag == "%" then + return _FUTURE + elseif buf.flag == "#" then + return _FUTURE - 1 + else + return buf.info.lastused + end +end + local populate_buffer_entries = function(opts, bufnrs, winid) local buffers = {} for _, bufnr in ipairs(bufnrs) do - local flag = (bufnr == core.CTX().bufnr and "%") - or (bufnr == core.CTX().alt_bufnr and "#") or " " - - local element = { - bufnr = bufnr, - flag = flag, - info = utils.getbufinfo(bufnr), - readonly = vim.bo[bufnr].readonly - } + local buf = getbuf(bufnr) -- Get the name for missing/quickfix/location list buffers -- NOTE: we get it here due to `gen_buffer_entry` called within a fast event - if not element.info.name or #element.info.name == 0 then - element.info.name = utils.nvim_buf_get_name(element.bufnr, element.info) + if not buf.info.name or #buf.info.name == 0 then + buf.info.name = utils.nvim_buf_get_name(buf.bufnr, buf.info) end -- get the correct lnum for tabbed buffers if winid then - element.info.lnum = vim.api.nvim_win_get_cursor(winid)[1] + buf.info.lnum = vim.api.nvim_win_get_cursor(winid)[1] end - table.insert(buffers, element) + table.insert(buffers, buf) end + if opts.sort_lastused then - -- switching buffers and opening 'buffers' in quick succession - -- can lead to incorrect sort as 'lastused' isn't updated fast - -- enough (neovim bug?), this makes sure the current buffer is - -- always on top (#646) - -- Hopefully this gets solved before the year 2100 - -- DON'T FORCE ME TO UPDATE THIS HACK NEOVIM LOL - local future = os.time({ year = 2100, month = 1, day = 1, hour = 0, minute = 00 }) - local get_unixtime = function(buf) - if buf.flag == "%" then - return future - elseif buf.flag == "#" then - return future - 1 - else - return buf.info.lastused - end - end table.sort(buffers, function(a, b) return get_unixtime(a) > get_unixtime(b) end) @@ -221,9 +230,6 @@ end M.buffer_lines = function(opts) if not opts then return end - -- formatter doesn't work with lines|blines as only filename is displayed - opts._fmt = false - opts.fn_pre_fzf = function() core.CTX(true) end opts.fn_pre_fzf() @@ -242,10 +248,28 @@ M.buffer_lines = function(opts) local buffers = filter_buffers(opts, opts.current_buffer_only and { core.CTX().bufnr } or core.CTX().buflist) + if opts.sort_lastused and utils.tbl_count(buffers) > 1 then + table.sort(buffers, function(a, b) + return get_unixtime(a) > get_unixtime(b) + end) + end + + local bnames = {} + local longest_bname = 0 + for _, b in ipairs(buffers) do + local bname = utils.nvim_buf_get_name(b) + if not bname:match("^%[") then + bname = path.shorten(vim.fn.fnamemodify(bname, ":~:.")) + end + longest_bname = math.max(longest_bname, string.len(bname)) + bnames[tostring(b)] = bname + end + local len_bufnames = math.min(15, longest_bname) + for _, bufnr in ipairs(buffers) do local data = {} - local bufname, buficon, hl - -- use vim.schedule to avoid + + -- Use vim.schedule to avoid -- E5560: vimL function must not be called in a lua loop callback vim.schedule(function() local filepath = vim.api.nvim_buf_get_name(bufnr) @@ -254,22 +278,35 @@ M.buffer_lines = function(opts) elseif vim.fn.filereadable(filepath) ~= 0 then data = vim.fn.readfile(filepath, "") end - bufname = path.basename(filepath) - if opts.file_icons then - buficon, hl = devicons.get_devicon(bufname) - if hl and opts.color_icons then - buficon = utils.ansi_from_rgb(hl, buficon) - end - end - if not bufname or #bufname == 0 then - bufname = utils.nvim_buf_get_name(bufnr) - end coroutine.resume(co) end) -- wait for vim.schedule coroutine.yield() + local bname, bicon = (function() + if not opts.show_bufname + or tonumber(opts.show_bufname) and tonumber(opts.show_bufname) > vim.o.columns + then + return + end + local bicon, hl = "", nil + local bname = bnames[tostring(bufnr)] + assert(bname) + + if string.len(bname) > len_bufnames + 1 then + bname = "…" .. bname:sub(#bname - len_bufnames + 2) + end + + if opts.file_icons then + bicon, hl = devicons.get_devicon(bname) + if hl and opts.color_icons then + bicon = utils.ansi_from_rgb(hl, bicon) + end + end + return bname, bicon and bicon .. utils.nbsp or nil + end)() + local offset, lines = 0, #data if opts.current_buffer_only and opts.start == "cursor" then -- start display from current line and wrap from bottom (#822) @@ -281,14 +318,20 @@ M.buffer_lines = function(opts) if lnum > lines then lnum = lnum % lines end - add_entry(string.format("[%s]%s%s%s%s:%s: %s", - utils.ansi_codes[opts.hls.buf_nr](tostring(bufnr)), - utils.nbsp, - buficon or "", - buficon and utils.nbsp or "", - utils.ansi_codes[opts.hls.buf_name](bufname), - utils.ansi_codes[opts.hls.path_linenr](tostring(lnum)), - data[lnum]), co) + + -- NOTE: Space after `lnum` is U+00A0 (decimal: 160) + add_entry(string.format("[%s]\t%s\t%s%s\t%s \t%s", + tostring(bufnr), + utils.ansi_codes[opts.hls.buf_id](string.format("%3d", bufnr)), + bicon or "", + not bname and "" or utils.ansi_codes[opts.hls.buf_name](string.format( + "%" + .. (opts.file_icons and "-" or "") + .. tostring(len_bufnames) .. "s", + bname)), + utils.ansi_codes[opts.hls.buf_linenr](string.format("%5d", lnum)), + data[lnum] + ), co) end end cb(nil) diff --git a/lua/fzf-lua/providers/grep.lua b/lua/fzf-lua/providers/grep.lua index 4ed1fa33..b98a2312 100644 --- a/lua/fzf-lua/providers/grep.lua +++ b/lua/fzf-lua/providers/grep.lua @@ -407,27 +407,25 @@ M.grep_project = function(opts) end M.grep_curbuf = function(opts, lgrep) - if type(opts) == "function" then - opts = opts() - elseif not opts then - opts = {} - end - opts.filename = vim.api.nvim_buf_get_name(0) + -- call `normalize_opts` here as we want to store all previous + -- options in the resume data store under the key "bgrep" + -- 3rd arg is an override for resume data store lookup key + opts = config.normalize_opts(opts, "grep_curbuf", "bgrep") + if not opts then return end + + opts.filename = vim.api.nvim_buf_get_name(core.CTX().bufnr) if #opts.filename == 0 or not uv.fs_stat(opts.filename) then utils.info("Rg current buffer requires file on disk") return else opts.filename = path.relative_to(opts.filename, uv.cwd()) end - -- rg globs are meaningless here since we searching a single file - opts.rg_glob = false - opts.exec_empty_query = opts.exec_empty_query == nil and true - opts.fzf_opts = vim.tbl_extend("keep", opts.fzf_opts or {}, config.globals.blines.fzf_opts) - -- call `normalize_opts` here as we want to store all previous - -- options in the resume data store under the key "bgrep" - -- 3rd arg is an override for resume data store lookup key - opts = config.normalize_opts(opts, "grep", "bgrep") - if not opts then return end + + -- Persist call options so we don't revert to global grep on `grep_lgrep` + opts.__call_opts = vim.tbl_deep_extend("keep", + opts.__call_opts or {}, config.globals.grep_curbuf) + opts.__call_opts.filename = opts.filename + if lgrep then return M.live_grep(opts) else diff --git a/lua/fzf-lua/win.lua b/lua/fzf-lua/win.lua index 2842ca7d..406b5c8e 100644 --- a/lua/fzf-lua/win.lua +++ b/lua/fzf-lua/win.lua @@ -826,7 +826,8 @@ function FzfWin:treesitter_attach() if not self._o.winopts.treesitter then return end local function trim(s) return (string.gsub(s, "^%s*(.-)%s*$", "%1")) end vim.api.nvim_buf_attach(self.fzf_bufnr, false, { - on_lines = function(_, bufnr, _, first_changed, last_changed, last_updated, bc) + -- on_lines = function(_, bufnr, _, first_changed, last_changed, last_updated, bc) + on_lines = function(_, bufnr) local lines = api.nvim_buf_get_lines(bufnr, 0, -1, false) local regions = {} local empty_regions = {} @@ -836,12 +837,25 @@ function FzfWin:treesitter_attach() -- file:line:col:text (grep_xxx) -- file:line:text (grep_project or missing "--column" flag) -- line:col:text (grep_curbuf) - -- line:text (blines) - local filepath, _lnum, text = line:match("(.-):?(%d+):(.+)$") + -- linetext (lines|blines) + local filepath, _lnum, text = line:match("(.-):?(%d+)[: ](.+)$") if not text or text == 0 then return end - filepath = trim(filepath) - local ft = #filepath == 0 and vim.bo[utils.CTX().bufnr].ft + text = text:gsub("^%d+:", "") -- remove col nr if exists + filepath = trim(filepath) -- trim spaces + + local ft_bufnr = (function() + -- blines|lines: U+00A0 (decimal: 160) follows the lnum + -- grep_curbuf: formats as line:col:text` thus `#filepath == 0` + if #filepath == 0 or string.byte(text, 1) == 160 then + if string.byte(text, 1) == 160 then text = text:sub(2) end -- remove A0+SPACE + if string.byte(text, 1) == 32 then text = text:sub(2) end -- remove leading SPACE + local b = filepath:match("^%d+") or utils.CTX().bufnr + return vim.api.nvim_buf_is_valid(tonumber(b)) and b or nil + end + end)() + + local ft = ft_bufnr and vim.bo[tonumber(ft_bufnr)].ft or vim.filetype.match({ filename = path.tail(filepath) }) if not ft then return end