mirror of
https://github.com/tiyn/action-hints.nvim.git
synced 2025-11-13 13:59:45 +01:00
Switch to cursor movement update approach
This commit is contained in:
@@ -1,20 +1,29 @@
|
|||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
|
local default_definition_color
|
||||||
|
local default_references_color
|
||||||
|
|
||||||
|
if vim.o.termguicolors then
|
||||||
|
default_definition_color = "#add8e6"
|
||||||
|
default_references_color = "#ff6666"
|
||||||
|
else
|
||||||
|
default_definition_color = "blue"
|
||||||
|
default_references_color = "red"
|
||||||
|
end
|
||||||
|
|
||||||
M.config = {
|
M.config = {
|
||||||
template = {
|
template = {
|
||||||
{ " ⊛", "ActionHintsDefinition" },
|
definition = { text = " ⊛", color = default_definition_color },
|
||||||
{ " ↱%s", "ActionHintsReferences" },
|
references = { text = " ↱%s", color = default_references_color },
|
||||||
},
|
},
|
||||||
use_virtual_text = false,
|
use_virtual_text = false,
|
||||||
definition_color = "#add8e6",
|
|
||||||
reference_color = "#ff6666",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
M.references_available = false
|
M.references_available = false
|
||||||
M.reference_count = 0
|
M.reference_count = 0
|
||||||
M.definition_available = false
|
M.definition_available = false
|
||||||
|
|
||||||
local references_namespace = vim.api.nvim_create_namespace("references")
|
local references_namespace = vim.api.nvim_create_namespace("action_hints_references")
|
||||||
local last_virtual_text_line = nil
|
local last_virtual_text_line = nil
|
||||||
|
|
||||||
local function debounce(func, delay)
|
local function debounce(func, delay)
|
||||||
@@ -30,35 +39,81 @@ local function debounce(func, delay)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function set_virtual_text(bufnr, line, chunks)
|
M.supports_method = function(method)
|
||||||
if last_virtual_text_line then
|
local clients = vim.lsp.buf_get_clients()
|
||||||
vim.api.nvim_buf_clear_namespace(
|
for _, client in pairs(clients) do
|
||||||
bufnr,
|
if client.server_capabilities[method] then
|
||||||
references_namespace,
|
return true
|
||||||
last_virtual_text_line,
|
end
|
||||||
last_virtual_text_line + 1
|
end
|
||||||
)
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function set_virtual_text(bufnr, line, chunks)
|
||||||
|
-- Clear the virtual text from the previous line
|
||||||
|
if last_virtual_text_line then
|
||||||
|
vim.api.nvim_buf_clear_namespace(bufnr, references_namespace, last_virtual_text_line, last_virtual_text_line + 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check for conditions where you might want to exit early
|
||||||
if
|
if
|
||||||
vim.api.nvim_buf_get_option(bufnr, "buftype") ~= ""
|
vim.api.nvim_buf_get_option(bufnr, "buftype") ~= ""
|
||||||
or vim.api.nvim_buf_get_option(bufnr, "filetype") == "help"
|
or vim.api.nvim_buf_get_option(bufnr, "filetype") == "help"
|
||||||
or vim.fn.bufname(bufnr) == ""
|
or vim.fn.bufname(bufnr) == ""
|
||||||
then
|
then
|
||||||
|
-- Reset the last virtual text line to ensure it gets cleared next time
|
||||||
|
last_virtual_text_line = nil
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.api.nvim_buf_set_virtual_text(bufnr, references_namespace, line, chunks, {})
|
-- Prepare the virtual text with proper highlight groups
|
||||||
|
local virtual_text_chunks = {}
|
||||||
|
for _, chunk in ipairs(chunks) do
|
||||||
|
table.insert(virtual_text_chunks, { chunk[1], chunk[2] })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set the virtual text for the current line
|
||||||
|
vim.api.nvim_buf_set_virtual_text(bufnr, references_namespace, line, virtual_text_chunks, {})
|
||||||
last_virtual_text_line = line
|
last_virtual_text_line = line
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function update_virtual_text()
|
||||||
|
if M.config.use_virtual_text then
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
local cursor = vim.api.nvim_win_get_cursor(0)
|
||||||
|
local definition_status = M.definition_available and M.config.template.definition.text or ""
|
||||||
|
local reference_status = M.reference_count > 0
|
||||||
|
and string.format(M.config.template.references.text, tostring(M.reference_count))
|
||||||
|
or ""
|
||||||
|
local chunks = {
|
||||||
|
{ definition_status, "ActionHintsDefinition" },
|
||||||
|
{ reference_status, "ActionHintsReferences" },
|
||||||
|
}
|
||||||
|
|
||||||
|
set_virtual_text(bufnr, cursor[1] - 1, chunks)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function is_cursor_on_whitespace()
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
local cursor = vim.api.nvim_win_get_cursor(0)
|
||||||
|
local line = vim.api.nvim_buf_get_lines(bufnr, cursor[1] - 1, cursor[1], false)[1]
|
||||||
|
local char = line:sub(cursor[2] + 1, cursor[2] + 1)
|
||||||
|
return char:match("^%s$") ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
local function references()
|
local function references()
|
||||||
if not M.supports_method("referencesProvider") then
|
if not M.supports_method("referencesProvider") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if is_cursor_on_whitespace() then
|
||||||
|
M.clear_virtual_text()
|
||||||
|
end
|
||||||
|
|
||||||
local bufnr = vim.api.nvim_get_current_buf()
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
local cursor = vim.api.nvim_win_get_cursor(0)
|
local cursor = vim.api.nvim_win_get_cursor(0)
|
||||||
local bufname = vim.api.nvim_buf_get_name(bufnr)
|
local bufname = vim.uri_from_bufnr(bufnr)
|
||||||
|
|
||||||
local params = {
|
local params = {
|
||||||
textDocument = { uri = bufname },
|
textDocument = { uri = bufname },
|
||||||
@@ -70,18 +125,20 @@ local function references()
|
|||||||
if err or not result then
|
if err or not result then
|
||||||
M.references_available = false
|
M.references_available = false
|
||||||
M.reference_count = 0
|
M.reference_count = 0
|
||||||
return false
|
M.clear_virtual_text()
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if vim.tbl_count(result) > 0 then
|
if vim.tbl_count(result) > 0 then
|
||||||
M.references_available = true
|
M.references_available = true
|
||||||
M.reference_count = vim.tbl_count(result) - 1
|
M.reference_count = vim.tbl_count(result) - 1
|
||||||
return true
|
update_virtual_text()
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
M.references_available = false
|
M.references_available = false
|
||||||
M.reference_count = 0
|
M.reference_count = 0
|
||||||
return false
|
M.clear_virtual_text()
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -89,9 +146,14 @@ local function definition()
|
|||||||
if not M.supports_method("definitionProvider") then
|
if not M.supports_method("definitionProvider") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if is_cursor_on_whitespace() then
|
||||||
|
M.clear_virtual_text()
|
||||||
|
end
|
||||||
|
|
||||||
local bufnr = vim.api.nvim_get_current_buf()
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
local cursor = vim.api.nvim_win_get_cursor(0)
|
local cursor = vim.api.nvim_win_get_cursor(0)
|
||||||
local bufname = vim.api.nvim_buf_get_name(bufnr)
|
local bufname = vim.uri_from_bufnr(bufnr)
|
||||||
|
|
||||||
local params = {
|
local params = {
|
||||||
textDocument = { uri = bufname },
|
textDocument = { uri = bufname },
|
||||||
@@ -101,28 +163,28 @@ local function definition()
|
|||||||
vim.lsp.buf_request(bufnr, "textDocument/definition", params, function(err, result, _, _)
|
vim.lsp.buf_request(bufnr, "textDocument/definition", params, function(err, result, _, _)
|
||||||
if err or not result then
|
if err or not result then
|
||||||
M.definition_available = false
|
M.definition_available = false
|
||||||
return false
|
M.clear_virtual_text()
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if vim.tbl_count(result) > 0 then
|
if vim.tbl_count(result) > 0 then
|
||||||
M.definition_available = true
|
M.definition_available = true
|
||||||
return true
|
update_virtual_text()
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
M.clear_virtual_text()
|
||||||
M.definition_available = false
|
M.definition_available = false
|
||||||
return false
|
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
M.supports_method = function(method)
|
M.clear_virtual_text = function()
|
||||||
local clients = vim.lsp.buf_get_clients()
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
for _, client in pairs(clients) do
|
if last_virtual_text_line then
|
||||||
if client.server_capabilities[method] then
|
vim.api.nvim_buf_clear_namespace(bufnr, references_namespace, last_virtual_text_line, last_virtual_text_line + 1)
|
||||||
return true
|
last_virtual_text_line = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local debounced_references = debounce(references, 100)
|
local debounced_references = debounce(references, 100)
|
||||||
local debounced_definition = debounce(definition, 100)
|
local debounced_definition = debounce(definition, 100)
|
||||||
@@ -133,44 +195,52 @@ M.update = function()
|
|||||||
end
|
end
|
||||||
|
|
||||||
M.statusline = function()
|
M.statusline = function()
|
||||||
local definition_status = M.definition_available and string.format(M.config.template[1][1], "") or ""
|
local definition_status = M.definition_available and M.config.template.definition.text or ""
|
||||||
local reference_status = M.reference_count > 0
|
local reference_status = M.reference_count > 0
|
||||||
and string.format(M.config.template[2][1], tostring(M.reference_count))
|
and string.format(M.config.template.references.text, tostring(M.reference_count))
|
||||||
or ""
|
or ""
|
||||||
local chunks = {
|
local chunks = {
|
||||||
{ definition_status, M.config.template[1][2] },
|
{ definition_status, "ActionHintsDefinition" },
|
||||||
{ reference_status, M.config.template[2][2] },
|
{ reference_status, "ActionHintsReferences" },
|
||||||
}
|
}
|
||||||
|
|
||||||
if M.config.use_virtual_text then
|
|
||||||
local bufnr = vim.api.nvim_get_current_buf()
|
|
||||||
local cursor = vim.api.nvim_win_get_cursor(0)
|
|
||||||
set_virtual_text(bufnr, cursor[1] - 1, chunks)
|
|
||||||
end
|
|
||||||
|
|
||||||
local text = ""
|
local text = ""
|
||||||
for i, chunk in ipairs(chunks) do
|
for _, chunk in ipairs(chunks) do
|
||||||
text = text .. chunk[1]
|
text = text .. chunk[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
return text
|
return text
|
||||||
end
|
end
|
||||||
|
|
||||||
|
M.set_highlight = function()
|
||||||
|
if vim.o.termguicolors then
|
||||||
|
vim.api.nvim_command("highlight ActionHintsDefinition ctermfg=NONE guifg=" .. M.config.template.definition.color)
|
||||||
|
vim.api.nvim_command("highlight ActionHintsReferences ctermfg=NONE guifg=" .. M.config.template.references.color)
|
||||||
|
else
|
||||||
|
vim.api.nvim_command("highlight ActionHintsDefinition guifg=NONE ctermfg=" .. M.config.template.definition.color)
|
||||||
|
vim.api.nvim_command("highlight ActionHintsReferences guifg=NONE ctermfg=" .. M.config.template.references.color)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
M.setup = function(options)
|
M.setup = function(options)
|
||||||
if options == nil then
|
if options == nil then
|
||||||
options = {}
|
options = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Merge keys
|
||||||
for k, v in pairs(options) do
|
for k, v in pairs(options) do
|
||||||
|
if k == "template" and type(v) == "table" then
|
||||||
|
for tk, tv in pairs(v) do
|
||||||
|
M.config.template[tk] = tv
|
||||||
|
end
|
||||||
|
else
|
||||||
M.config[k] = v
|
M.config[k] = v
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local defColor = M.config.definition_color
|
M.set_highlight()
|
||||||
local refColor = M.config.reference_color
|
|
||||||
|
|
||||||
vim.api.nvim_command("highlight ActionHintsDefinition guifg=" .. defColor)
|
|
||||||
vim.api.nvim_command("highlight ActionHintsReferences guifg=" .. refColor)
|
|
||||||
|
|
||||||
|
vim.api.nvim_command([[autocmd OptionSet termguicolors lua require("action-hints").set_highlight()]])
|
||||||
vim.api.nvim_command([[autocmd CursorMoved * lua require("action-hints").update()]])
|
vim.api.nvim_command([[autocmd CursorMoved * lua require("action-hints").update()]])
|
||||||
vim.api.nvim_command([[autocmd CursorMovedI * lua require("action-hints").update()]])
|
vim.api.nvim_command([[autocmd CursorMovedI * lua require("action-hints").update()]])
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user