diff --git a/lua/grug-far/actions/qflist.lua b/lua/grug-far/actions/qflist.lua new file mode 100644 index 00000000..72cd9b91 --- /dev/null +++ b/lua/grug-far/actions/qflist.lua @@ -0,0 +1,21 @@ +local utils = require('grug-far/utils') + +local function qflist(params) + local context = params.context + local state = context.state + local resultsLocations = state.resultsLocations + + if #resultsLocations == 0 then + return + end + + local search = state.inputs.search + + vim.fn.setqflist(resultsLocations, 'r') + vim.fn.setqflist({}, "a", + { title = "Grug FAR results" .. utils.strEllideAfter(search, context.options.maxSearchCharsInTitles, ' for: ') }) + -- open list below taking whole horizontal space + vim.cmd('botright copen | stopinsert') +end + +return qflist diff --git a/lua/grug-far/farBuffer.lua b/lua/grug-far/farBuffer.lua index fb5b4edb..41df3309 100644 --- a/lua/grug-far/farBuffer.lua +++ b/lua/grug-far/farBuffer.lua @@ -1,5 +1,6 @@ local render = require("grug-far/render") local replace = require("grug-far/actions/replace") +local qflist = require("grug-far/actions/qflist") local M = {} @@ -18,6 +19,11 @@ local function setupKeymap(buf, context) replace({ buf = buf, context = context }) end) end + if keymaps.qflist then + setBufKeymap(buf, 'niv', 'Grug Far: send results to quickfix list', keymaps.qflist, function() + qflist({ context = context }) + end) + end end local function setupRenderer(win, buf, context) diff --git a/lua/grug-far/opts.lua b/lua/grug-far/opts.lua index 052aa0e3..f618b601 100644 --- a/lua/grug-far/opts.lua +++ b/lua/grug-far/opts.lua @@ -20,6 +20,10 @@ local defaultOptions = { -- turn this off if you still like to see the line numbers disableBufferLineNumbers = true, + -- maximum number of search chars to show in buffer and quickfix list titles + -- zero disables showing it + maxSearchCharsInTitles = 30, + -- icons for UI, default ones depend on nerdfont icons = { -- whether to show icons @@ -45,7 +49,8 @@ local defaultOptions = { }, keymaps = { - replace = '', + replace = '', + qflist = '' } } diff --git a/lua/grug-far/render.lua b/lua/grug-far/render.lua index 00515a1f..4710689a 100644 --- a/lua/grug-far/render.lua +++ b/lua/grug-far/render.lua @@ -1,6 +1,7 @@ local renderHelp = require('grug-far/render/help') local renderInput = require('grug-far/render/input') local renderResults = require('grug-far/render/results') +local utils = require('grug-far/utils') local function render(params, context) local buf = params.buf @@ -17,7 +18,8 @@ local function render(params, context) placeholder = "ex: foo foo([a-z0-9]*) fun\\(", }, context) - vim.api.nvim_buf_set_name(buf, 'Grug FAR' .. (#inputs.search > 0 and ': ' .. inputs.search or '')) + vim.api.nvim_buf_set_name(buf, + 'Grug FAR' .. utils.strEllideAfter(inputs.search, context.options.maxSearchCharsInTitles, ': ')) inputs.replacement = renderInput({ buf = buf, diff --git a/lua/grug-far/render/resultsList.lua b/lua/grug-far/render/resultsList.lua index 362859af..65bf45cd 100644 --- a/lua/grug-far/render/resultsList.lua +++ b/lua/grug-far/render/resultsList.lua @@ -12,6 +12,26 @@ function M.appendResultsChunk(buf, context, data) j == highlight.end_line and highlight.end_col or -1) end end + + local resultsLocations = context.state.resultsLocations + local lastLocation = resultsLocations[#resultsLocations] + for i = 1, #data.highlights do + local highlight = data.highlights[i] + local hl = highlight.hl + local line = data.lines[highlight.start_line + 1] + + -- TODO (sbadragan): these could be number comparisons? + if hl == 'GrugFarResultsPath' then + lastLocation = { filename = string.sub(line, highlight.start_col + 1, highlight.end_col + 1) } + table.insert(resultsLocations, lastLocation) + elseif hl == 'GrugFarResultsLineNo' then + -- omit ending ':' + lastLocation.lnum = tonumber(string.sub(line, highlight.start_col + 1, highlight.end_col)) + elseif hl == 'GrugFarResultsLineColumn' then + -- omit ending ':' + lastLocation.col = tonumber(string.sub(line, highlight.start_col + 1, highlight.end_col)) + end + end end function M.setError(buf, context, error) @@ -31,6 +51,8 @@ function M.clear(buf, context) -- remove all lines after heading and add one blank line local headerRow = context.state.headerRow vim.api.nvim_buf_set_lines(buf, headerRow, -1, false, { "" }) + + context.state.resultsLocations = {} end return M diff --git a/lua/grug-far/utils.lua b/lua/grug-far/utils.lua index 2c94a294..33621508 100644 --- a/lua/grug-far/utils.lua +++ b/lua/grug-far/utils.lua @@ -45,4 +45,11 @@ function M.strFindLast(str, substr) return i, j end +function M.strEllideAfter(str, n, prefix) + if n == 0 then + return '' + end + return (prefix or '') .. (#str > n and string.sub(str, 1, n) .. '...' or str) +end + return M