From 0a40c2da2e32a631a166553349a2b92fd1357ade Mon Sep 17 00:00:00 2001 From: Stephan Badragan Date: Wed, 8 May 2024 15:58:26 -0700 Subject: [PATCH] making go to location work --- lua/grug-far/actions/gotoLocation.lua | 108 +------------------------- lua/grug-far/farBuffer.lua | 9 ++- lua/grug-far/opts.lua | 2 +- lua/grug-far/render/resultsList.lua | 42 +++++----- 4 files changed, 29 insertions(+), 132 deletions(-) diff --git a/lua/grug-far/actions/gotoLocation.lua b/lua/grug-far/actions/gotoLocation.lua index 4a160d6f..bc856da9 100644 --- a/lua/grug-far/actions/gotoLocation.lua +++ b/lua/grug-far/actions/gotoLocation.lua @@ -7,11 +7,13 @@ local resultsList = require('grug-far/render/resultsList') -- 5. reference resultLocationByExmarkId[extmarkId], open file in side buffer, navigate to row, col local function gotoLocation(params) + local win = params.win local buf = params.buf local context = params.context - local cursor_row = vim.api.nvim_win_get_cursor(buf) - 1 - local location = resultsList.getClosestResultLocation(cursor_row, buf, context) + local cursor_row = unpack(vim.api.nvim_win_get_cursor(win)) + local location = resultsList.getResultLocation(cursor_row - 1, buf, context) + P(location) if not location then return end @@ -25,105 +27,3 @@ local function gotoLocation(params) end return gotoLocation - --- state.target_winid = api.nvim_get_current_win() before the FAR buffer is created --- M.select_entry = function() --- local t = M.get_current_entry() --- if t == nil then --- return nil --- end --- if config.is_open_target_win and state.target_winid ~= nil then --- open_file(t.filename, t.lnum, t.col, state.target_winid) --- else --- open_file(t.filename, t.lnum, t.col) --- end --- end --- --- local open_file = function(filename, lnum, col, winid) --- if winid ~= nil then --- vim.fn.win_gotoid(winid) --- end --- vim.api.nvim_command([[execute "normal! m` "]]) --- local escaped_filename = vim.fn.fnameescape(filename) --- vim.cmd('e ' .. escaped_filename) --- api.nvim_win_set_cursor(0, { lnum, col }) --- end - - --- https://github.com/kevinhwang91/nvim-bqf/blob/7751b6ef9fbc3907478eaf23e866c4316a2ed1b4/lua/bqf/qfwin/handler.lua#L233 ----@param close boolean ----@param jumpCmd boolean ----@param qwinid number ----@param idx number --- function open(close, jumpCmd, qwinid, idx) --- doEdit(qwinid, idx, close, function(bufnr) --- if jumpCmd then --- local fname = fn.fnameescape(api.nvim_buf_get_name(bufnr)) --- if jumpCmd == 'drop' then --- local bufInfo = fn.getbufinfo(bufnr) --- if fname == '' or #bufInfo == 1 and #bufInfo[1].windows == 0 then --- api.nvim_set_current_buf(bufnr) --- return --- end --- end --- cmd(('%s %s'):format(jumpCmd, fname)) --- else --- api.nvim_set_current_buf(bufnr) --- end --- end) --- end --- --- local function doEdit(qwinid, idx, close, action) --- qwinid = qwinid or api.nvim_get_current_win() --- local qs = qfs:get(qwinid) --- local pwinid = qs:previousWinid() --- local qlist = qs:list() --- local size = qlist:getQfList({ size = 0 }).size --- if size <= 0 then --- api.nvim_err_writeln('E42: No Errors') --- return false --- end --- if not utils.isWinValid(pwinid) then --- vim.notify('file window is invalid', vim.log.levels.WARN) --- cmd([[exe "norm! \"]]) --- api.nvim_win_set_height(qwinid, math.min(10, size)) --- return false --- end --- --- idx = idx or api.nvim_win_get_cursor(qwinid)[1] --- qlist:changeIdx(idx) --- local entry = qlist:item(idx) --- local bufnr, lnum, col = entry.bufnr, entry.lnum, entry.col --- if bufnr == 0 then --- api.nvim_err_writeln('Buffer not found') --- return --- end --- --- if close then --- api.nvim_win_close(qwinid, true) --- end --- --- api.nvim_set_current_win(pwinid) --- --- local lastBufnr = api.nvim_get_current_buf() --- local lastBufname = api.nvim_buf_get_name(lastBufnr) --- local lastBufoff = api.nvim_buf_get_offset(0, 1) --- if action and not utils.isUnNameBuf(lastBufnr, lastBufname, lastBufoff) then --- action(bufnr) --- else --- api.nvim_set_current_buf(bufnr) --- end --- --- vim.bo.buflisted = true --- pcall(api.nvim_win_set_cursor, 0, { lnum, math.max(0, col - 1) }) --- --- if vim.wo.foldenable and vim.o.fdo:match('quickfix') then --- cmd('norm! zv') --- end --- utils.zz() --- --- if utils.isUnNameBuf(lastBufnr, lastBufname, lastBufoff) then --- api.nvim_buf_delete(lastBufnr, {}) --- end --- return true --- end diff --git a/lua/grug-far/farBuffer.lua b/lua/grug-far/farBuffer.lua index 8bcc9b2d..ea293ee9 100644 --- a/lua/grug-far/farBuffer.lua +++ b/lua/grug-far/farBuffer.lua @@ -1,6 +1,7 @@ local render = require("grug-far/render") local replace = require("grug-far/actions/replace") local qflist = require("grug-far/actions/qflist") +local gotoLocation = require("grug-far/actions/gotoLocation") local close = require("grug-far/actions/close") local M = {} @@ -13,7 +14,7 @@ local function setBufKeymap(buf, modes, desc, lhs, callback) end end -local function setupKeymap(buf, context) +local function setupKeymap(win, buf, context) local keymaps = context.options.keymaps if keymaps.replace then setBufKeymap(buf, 'ni', 'Grug Far: apply replacements', keymaps.replace, function() @@ -26,8 +27,8 @@ local function setupKeymap(buf, context) end) end if keymaps.gotoLocation then - setBufKeymap(buf, 'n', 'Grug Far: go to location', keymaps.qflist, function() - qflist({ buf = buf, context = context }) + setBufKeymap(buf, 'n', 'Grug Far: go to location', keymaps.gotoLocation, function() + gotoLocation({ win = win, buf = buf, context = context }) end) end if keymaps.close then @@ -55,7 +56,7 @@ end function M.createBuffer(win, context) local buf = vim.api.nvim_create_buf(true, true) - setupKeymap(buf, context) + setupKeymap(win, buf, context) setupRenderer(win, buf, context) vim.api.nvim_win_set_buf(win, buf) diff --git a/lua/grug-far/opts.lua b/lua/grug-far/opts.lua index 41a4848d..9b046e96 100644 --- a/lua/grug-far/opts.lua +++ b/lua/grug-far/opts.lua @@ -18,7 +18,7 @@ local defaultOptions = { -- buffer line numbers + match line numbers can get a bit visually overwhelming -- turn this off if you still like to see the line numbers - disableBufferLineNumbers = true, + disableBufferLineNumbers = false, -- maximum number of search chars to show in buffer and quickfix list titles -- zero disables showing it diff --git a/lua/grug-far/render/resultsList.lua b/lua/grug-far/render/resultsList.lua index dccb9eec..20804655 100644 --- a/lua/grug-far/render/resultsList.lua +++ b/lua/grug-far/render/resultsList.lua @@ -17,47 +17,42 @@ function M.appendResultsChunk(buf, context, data) -- compute result locations based on highlights and add location marks -- those are used for actions like quickfix list and go to location - local resultsLocations = context.state.resultsLocations - local resultLocationByExtmarkId = context.state.resultLocationByExtmarkId - local lastLocation = resultsLocations[#resultsLocations] + local state = context.state + local resultLocationByExtmarkId = state.resultLocationByExtmarkId + local resultsLocations = state.resultsLocations + local lastLocation = nil for i = 1, #data.highlights do local highlight = data.highlights[i] local hl = highlight.hl local line = data.lines[highlight.start_line + 1] if hl == 'GrugFarResultsPath' then - lastLocation = { filename = string.sub(line, highlight.start_col + 1, highlight.end_col + 1) } - table.insert(resultsLocations, lastLocation) + state.resultsLastFilename = string.sub(line, highlight.start_col + 1, highlight.end_col + 1) local markId = vim.api.nvim_buf_set_extmark(buf, context.locationsNamespace, lastline + highlight.start_line, 0, {}) - resultLocationByExtmarkId[markId] = { filename = lastLocation.filename } + resultLocationByExtmarkId[markId] = { filename = state.resultsLastFilename } elseif hl == 'GrugFarResultsLineNo' then -- omit ending ':' + lastLocation = { filename = state.resultsLastFilename } + table.insert(resultsLocations, lastLocation) + local markId = vim.api.nvim_buf_set_extmark(buf, context.locationsNamespace, lastline + highlight.start_line, 0, {}) + resultLocationByExtmarkId[markId] = lastLocation + lastLocation.lnum = tonumber(string.sub(line, highlight.start_col + 1, highlight.end_col)) - elseif hl == 'GrugFarResultsLineColumn' and not lastLocation.col then + elseif hl == 'GrugFarResultsLineColumn' and lastLocation and not lastLocation.col then -- omit ending ':', use first match on that line lastLocation.col = tonumber(string.sub(line, highlight.start_col + 1, highlight.end_col)) - - local markId = vim.api.nvim_buf_set_extmark(buf, context.locationsNamespace, lastline + highlight.start_line, 0, {}) - resultLocationByExtmarkId[markId] = lastLocation end end end -- note: row is zero-based -function M.getClosestResultLocation(row, buf, context) - local currentRow = row - while currentRow > context.state.headerRow do - local marks = vim.api.nvim_buf_get_extmarks(buf, context.locationsNamespace, - { currentRow, 0 }, { currentRow, 0 }, { limit = 1 }) - if #marks > 0 then - local mark = marks[1] - local location = context.state.resultLocationByExmarkId[mark.extmark_id] - if location then - return location - end - end - currentRow = currentRow - 1 +function M.getResultLocation(row, buf, context) + local marks = vim.api.nvim_buf_get_extmarks(buf, context.locationsNamespace, + { row, 0 }, { row, 0 }, { limit = 1 }) + if #marks > 0 then + local markId = unpack(marks[1]) + return context.state.resultLocationByExtmarkId[markId] end return nil @@ -84,6 +79,7 @@ function M.clear(buf, context) vim.api.nvim_buf_clear_namespace(buf, context.locationsNamespace, 0, -1) context.state.resultLocationByExtmarkId = {} context.state.resultsLocations = {} + context.state.resultsLastFilename = nil end return M