RRethy / vim-illuminate

illuminate.vim - (Neo)Vim plugin for automatically highlighting other uses of the word under the cursor using either LSP, Tree-sitter, or regex matching.
2.12k stars 44 forks source link

Feature Request: Only highlight when word occurs multiple times #142

Closed OddBloke closed 1 year ago

OddBloke commented 1 year ago

I would like to only highlight the word under the cursor if there is another usage of the word within the file, so that highlights indicate that a jump is possible. (This is distinct from under_cursor because I do want under-cursor highlighting if there are multiple instances of the word.)

(Perhaps an IlluminatedWordSolo or similar hilight could be added? That would allow me to configure my desired behaviour, but allow for flexibility for other users.)

Thanks for the plugin!

OddBloke commented 1 year ago

I've hacked together something which works for me locally:

diff --git a/lua/illuminate/highlight.lua b/lua/illuminate/highlight.lua
index 1ca45da..0ec07f0 100644
--- a/lua/illuminate/highlight.lua
+++ b/lua/illuminate/highlight.lua
@@ -6,7 +6,10 @@ local M = {}

 local HL_NAMESPACE = vim.api.nvim_create_namespace('illuminate.highlight')

-local function kind_to_hl_group(kind)
+local function kind_to_hl_group(kind, count)
+    if count == 1 then
+         return 'IlluminatedWordSolo'
+    end
     return kind == vim.lsp.protocol.DocumentHighlightKind.Text and 'IlluminatedWordText'
         or kind == vim.lsp.protocol.DocumentHighlightKind.Read and 'IlluminatedWordRead'
         or kind == vim.lsp.protocol.DocumentHighlightKind.Write and 'IlluminatedWordWrite'
@@ -15,19 +18,24 @@ end

 function M.buf_highlight_references(bufnr, references)
     local cursor_pos = util.get_cursor_pos()
+    local count = 0
+    for _, _ in ipairs(references) do
+        count = count + 1
+    end
     for _, reference in ipairs(references) do
         if config.under_cursor(bufnr) or not ref.is_pos_in_ref(cursor_pos, reference) then
             M.range(
                 bufnr,
                 reference[1],
                 reference[2],
-                reference[3]
+                reference[3],
+                count
             )
         end
     end
 end

-function M.range(bufnr, start, finish, kind)
+function M.range(bufnr, start, finish, kind, count)
     local region = vim.region(bufnr, start, finish, 'v', false)
     for linenr, cols in pairs(region) do
         local end_row
@@ -36,7 +44,7 @@ function M.range(bufnr, start, finish, kind)
             cols[2] = 0
         end
         vim.api.nvim_buf_set_extmark(bufnr, HL_NAMESPACE, linenr, cols[1], {
-            hl_group = kind_to_hl_group(kind),
+            hl_group = kind_to_hl_group(kind, count),
             end_row = end_row,
             end_col = cols[2],
             priority = 1000,

Let me know if you'd be interested in me polishing this up into a PR (and what changes you'd like to see if so!). :+1:

RRethy commented 1 year ago

I can put up a PR tmrw since I have something a bit different in mind, instead of using a hlgroup IlluminatedWordSolo I'd rather just disable highlighting if there's only a single result base on some config option.