diff --git a/lua/refjump/counter.lua b/lua/refjump/counter.lua new file mode 100644 index 0000000..c8cab2d --- /dev/null +++ b/lua/refjump/counter.lua @@ -0,0 +1,58 @@ +local M = {} + +---Namespace for counter virtual text extmarks +local counter_namespace = vim.api.nvim_create_namespace('RefjumpCounter') + +---Name of the highlight group for the counter +local counter_hl_name = 'RefjumpCounter' + +---Create fallback highlight group if it doesn't exist +function M.create_fallback_hl_group(fallback_hl) + local hl = vim.api.nvim_get_hl(0, { name = counter_hl_name }) + + if vim.tbl_isempty(hl) then + -- Create a distinctive highlight: yellow/orange text on dark background + -- with bold for extra visibility + vim.api.nvim_set_hl(0, counter_hl_name, { + fg = '#FFA500', -- Orange/yellow color + bold = true, + default = true, + }) + end +end + +---Show virtual text counter at the end of the current line +---@param current_index integer Current reference index (1-based) +---@param total_count integer Total number of references +---@param bufnr integer Buffer number +function M.show(current_index, total_count, bufnr) + if not require('refjump').get_options().counter.enable then + return + end + + -- Get current cursor position + local cursor = vim.api.nvim_win_get_cursor(0) + local line = cursor[1] - 1 -- Convert to 0-indexed + + -- Clear any existing counter in this buffer + M.clear(bufnr) + + -- Format the counter text + local text = string.format(' [%d/%d]', current_index, total_count) + + -- Add virtual text at end of line + vim.api.nvim_buf_set_extmark(bufnr, counter_namespace, line, 0, { + virt_text = { { text, counter_hl_name } }, + virt_text_pos = 'eol', + priority = 100, + }) +end + +---Clear counter virtual text from buffer +---@param bufnr integer Buffer number (0 for current buffer) +function M.clear(bufnr) + bufnr = bufnr or 0 + vim.api.nvim_buf_clear_namespace(bufnr, counter_namespace, 0, -1) +end + +return M diff --git a/lua/refjump/highlight.lua b/lua/refjump/highlight.lua index d302dca..7222b1c 100644 --- a/lua/refjump/highlight.lua +++ b/lua/refjump/highlight.lua @@ -51,6 +51,7 @@ end function M.disable() if not highlight_references then vim.api.nvim_buf_clear_namespace(0, highlight_namespace, 0, -1) + require('refjump.counter').clear(0) else highlight_references = false end @@ -62,4 +63,16 @@ function M.auto_clear_reference_highlights() }) end +function M.clear_on_escape() + local esc = vim.api.nvim_replace_termcodes('', true, false, true) + local ctrl_c = vim.api.nvim_replace_termcodes('', true, false, true) + + vim.on_key(function(key) + -- Listen for escape or ctrl-c without blocking them + if key == esc or key == ctrl_c then + M.disable() + end + end, vim.api.nvim_create_namespace('refjump_escape_listener')) +end + return M diff --git a/lua/refjump/init.lua b/lua/refjump/init.lua index cffc23a..dde61d0 100644 --- a/lua/refjump/init.lua +++ b/lua/refjump/init.lua @@ -8,6 +8,11 @@ local M = {} ---@class RefjumpHighlightOptions ---@field enable? boolean Highlight the LSP references on jump ---@field auto_clear boolean Automatically clear highlights when cursor moves +---@field clear_on_escape? boolean Listen for escape key to clear highlights (non-intrusive) + +---@class RefjumpCounterOptions +---@field enable? boolean Show virtual text counter at end of line +---@field hl_group? string Highlight group for counter text ---@class RefjumpIntegrationOptions ---@field demicolon? { enable?: boolean } Make `]r`/`[r` repeatable with `;`/`,` using demicolon.nvim @@ -15,6 +20,7 @@ local M = {} ---@class RefjumpOptions ---@field keymaps? RefjumpKeymapOptions ---@field highlights? RefjumpHighlightOptions +---@field counter? RefjumpCounterOptions ---@field integrations? RefjumpIntegrationOptions ---@field verbose? boolean Print message if no reference is found local options = { @@ -26,6 +32,11 @@ local options = { highlights = { enable = true, auto_clear = true, + clear_on_escape = false, + }, + counter = { + enable = true, + hl_group = 'WarningMsg', }, integrations = { demicolon = { @@ -54,6 +65,14 @@ function M.setup(opts) if options.highlights.auto_clear then require('refjump.highlight').auto_clear_reference_highlights() end + + if options.highlights.clear_on_escape then + require('refjump.highlight').clear_on_escape() + end + end + + if options.counter.enable then + require('refjump.counter').create_fallback_hl_group(options.counter.hl_group) end end diff --git a/lua/refjump/jump.lua b/lua/refjump/jump.lua index 66c4eb6..183f84b 100644 --- a/lua/refjump/jump.lua +++ b/lua/refjump/jump.lua @@ -63,6 +63,20 @@ local function jump_to(next_reference) vim.cmd('normal! zv') end +---Find the index of a reference in the references list +---@param reference RefjumpReference +---@param references RefjumpReference[] +---@return integer|nil +local function find_reference_index(reference, references) + for i, ref in ipairs(references) do + if ref.range.start.line == reference.range.start.line + and ref.range.start.character == reference.range.start.character then + return i + end + end + return nil +end + ---@param next_reference RefjumpReference ---@param forward boolean ---@param references RefjumpReference[] @@ -74,6 +88,14 @@ local function jump_to_next_reference(next_reference, forward, references) if next_reference then jump_to(next_reference) + + -- Display current index and total count + local current_index = find_reference_index(next_reference, references) + if current_index then + local total_count = #references + local bufnr = vim.api.nvim_get_current_buf() + require('refjump.counter').show(current_index, total_count, bufnr) + end else vim.notify('refjump.nvim: Could not find the next reference', vim.log.levels.WARN) end