Breaking: add support for virtual text

This commit is contained in:
Rob Wilson
2023-08-12 01:26:25 +01:00
parent 27f683daa8
commit cf004ab7e3
2 changed files with 123 additions and 47 deletions

View File

@@ -5,44 +5,63 @@
A Neovim plugin to show statusline information about the word under the cursor. A Neovim plugin to show statusline information about the word under the cursor.
Available statusline hints: Available statusline hints:
* go-to-definition (`gd`) is available
* reference list (`gr`) available / number of references - go-to-definition (`gd`) is available
- reference list (`gr`) available / number of references
## Installation ## Installation
### Lazy ### Lazy
``` lua ```lua
{ {
"roobert/statusline-action-hints.nvim", "roobert/statusline-action-hints.nvim",
config = function() config = function()
require("statusline-action-hints").setup({ require("statusline-action-hints").setup()
definition_identifier = "gd",
template = "%s ref:%s",
})
end, end,
}, },
``` ```
### Packer ### Packer
``` lua ```lua
use({ use({
"roobert/statusline-action-hints.nvim", "roobert/statusline-action-hints.nvim",
config = function() config = function()
require("statusline-action-hints").setup({ require("statusline-action-hints").setup()
definition_identifier = "gd",
template = "%s ref:%s",
})
end, end,
}) })
``` ```
## Configuration
```lua
{
"roobert/statusline-action-hints.nvim",
config = function()
require("statusline-action-hints").setup({
template = {
{ " ⊛", "StatuslineActionHintsDefinition" },
{ " ↱%s", "StatuslineActionHintsReferences" },
},
use_virtual_text = true,
})
end,
},
```
Adjust highlight colours for virtual text:
```
highlight StatuslineActionHintsDefinition guifg=#add8e6
highlight StatuslineActionHintsReferences guifg=#ff6666
```
## Usage ## Usage
As a lualine statusline component: As a lualine statusline component:
``` lua ```lua
require('lualine').setup { require('lualine').setup {
sections = { sections = {
lualine_x = { require("statusline-action-hints").statusline }, lualine_x = { require("statusline-action-hints").statusline },

View File

@@ -1,14 +1,20 @@
local M = {} local M = {}
M.config = { M.config = {
definition_identifier = "gd", template = {
template = "%s ref:%s", { "", "StatuslineActionHintsDefinition" },
{ " ↱%s", "StatuslineActionHintsReferences" },
},
use_virtual_text = false,
} }
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 last_virtual_text_line = nil
local function debounce(func, delay) local function debounce(func, delay)
local timer_id = nil local timer_id = nil
return function(...) return function(...)
@@ -22,53 +28,88 @@ local function debounce(func, delay)
end end
end end
local function get_current_context() local function set_virtual_text(bufnr, line, chunks)
local bufnr = vim.api.nvim_get_current_buf() if last_virtual_text_line then
local cursor = vim.api.nvim_win_get_cursor(0) vim.api.nvim_buf_clear_namespace(
local bufname = vim.api.nvim_buf_get_name(bufnr) bufnr,
return bufnr, { line = cursor[1] - 1, character = cursor[2] }, bufname references_namespace,
last_virtual_text_line,
last_virtual_text_line + 1
)
end
vim.api.nvim_buf_set_virtual_text(bufnr, references_namespace, line, chunks, {})
last_virtual_text_line = line
end end
local function lsp_request(method, params, callback) local function supports_method(method)
local bufnr, position, uri = get_current_context() local clients = vim.lsp.buf_get_clients()
params.textDocument = { uri = uri } for _, client in pairs(clients) do
params.position = position if client.server_capabilities[method] then
vim.lsp.buf_request(bufnr, method, params, callback) return true
end
end
return false
end end
local function references() local function references()
lsp_request("textDocument/references", { if not supports_method("referencesProvider") then
context = { includeDeclaration = true }, return
}, function(err, result, _, _) end
if err then local bufnr = vim.api.nvim_get_current_buf()
error(tostring(err)) local cursor = vim.api.nvim_win_get_cursor(0)
end local bufname = vim.api.nvim_buf_get_name(bufnr)
if not result or vim.tbl_count(result) == 0 then local params = {
textDocument = { uri = bufname },
position = { line = cursor[1] - 1, character = cursor[2] },
context = { includeDeclaration = true },
}
vim.lsp.buf_request(bufnr, "textDocument/references", params, function(err, result, _, _)
if err or not result then
M.references_available = false M.references_available = false
M.reference_count = 0 M.reference_count = 0
return false return false
end end
M.references_available = true if vim.tbl_count(result) > 0 then
M.reference_count = vim.tbl_count(result) - 1 M.references_available = true
return true M.reference_count = vim.tbl_count(result) - 1
return true
end
M.references_available = false
M.reference_count = 0
return false
end) end)
end end
local function definition() local function definition()
lsp_request("textDocument/definition", {}, function(err, result, _, _) if not supports_method("definitionProvider") then
if err then return
error(tostring(err)) end
end local bufnr = vim.api.nvim_get_current_buf()
local cursor = vim.api.nvim_win_get_cursor(0)
local bufname = vim.api.nvim_buf_get_name(bufnr)
if not result or vim.tbl_count(result) == 0 then local params = {
textDocument = { uri = bufname },
position = { line = cursor[1] - 1, character = cursor[2] },
}
vim.lsp.buf_request(bufnr, "textDocument/definition", params, function(err, result, _, _)
if err or not result then
M.definition_available = false M.definition_available = false
return false return false
end end
M.definition_available = true if vim.tbl_count(result) > 0 then
return true M.definition_available = true
return true
end
M.definition_available = false
return false
end) end)
end end
@@ -79,13 +120,25 @@ M.statusline = function()
debounced_references() debounced_references()
debounced_definition() debounced_definition()
local definition_status = "" local definition_status = M.definition_available and "" or ""
local reference_status = M.reference_count > 0 and "" .. tostring(M.reference_count) or ""
local chunks = {
{ definition_status, "StatuslineActionHintsDefinition" },
{ reference_status, "StatuslineActionHintsReferences" },
}
if M.definition_available then if M.config.use_virtual_text then
definition_status = M.config.definition_identifier 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 end
return string.format(M.config.template, definition_status, M.reference_count) local text = ""
for i, chunk in ipairs(chunks) do
text = text .. chunk[1]
end
return text
end end
M.setup = function(options) M.setup = function(options)
@@ -93,10 +146,14 @@ M.setup = function(options)
options = {} options = {}
end end
-- merge user supplied options with defaults.. -- Merge user supplied options with defaults
for k, v in pairs(options) do for k, v in pairs(options) do
M.config[k] = v M.config[k] = v
end end
-- Set default colors for StatuslineActionHintsDefinition and StatuslineActionHintsReferences
vim.api.nvim_command("highlight StatuslineActionHintsDefinition guifg=#add8e6")
vim.api.nvim_command("highlight StatuslineActionHintsReferences guifg=#ff6666")
end end
return M return M