Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions lua/refjump/counter.lua
Original file line number Diff line number Diff line change
@@ -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
13 changes: 13 additions & 0 deletions lua/refjump/highlight.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -62,4 +63,16 @@ function M.auto_clear_reference_highlights()
})
end

function M.clear_on_escape()
local esc = vim.api.nvim_replace_termcodes('<Esc>', true, false, true)
local ctrl_c = vim.api.nvim_replace_termcodes('<C-c>', 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
19 changes: 19 additions & 0 deletions lua/refjump/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@ 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

---@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 = {
Expand All @@ -26,6 +32,11 @@ local options = {
highlights = {
enable = true,
auto_clear = true,
clear_on_escape = false,
},
counter = {
enable = true,
hl_group = 'WarningMsg',
},
integrations = {
demicolon = {
Expand Down Expand Up @@ -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

Expand Down
22 changes: 22 additions & 0 deletions lua/refjump/jump.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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[]
Expand All @@ -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
Expand Down