feat(lsp): add 'above' codelens position and setup config
This commit is contained in:
+62
-22
@@ -6,9 +6,11 @@ local REFRESH_DEBOUNCE_MS = 200
|
||||
|
||||
local M = {}
|
||||
|
||||
---@type "eol" | "right_align" | "inline"
|
||||
M.virt_text_pos = "eol"
|
||||
M.separator = " | "
|
||||
---@alias ow.lsp.codelens.Position "eol" | "right_align" | "inline" | "above"
|
||||
|
||||
---@type ow.lsp.codelens.Position
|
||||
local position = "above"
|
||||
local separator = " | "
|
||||
|
||||
---@type table<integer, ow.lsp.codelens.State>
|
||||
local state_by_buf = {}
|
||||
@@ -69,12 +71,38 @@ function Row:render(buf)
|
||||
for i, lens in ipairs(self.ready) do
|
||||
table.insert(parts, { lens.command.title, "LspCodeLens" })
|
||||
if i < #self.ready then
|
||||
table.insert(parts, { M.separator, "LspCodeLensSeparator" })
|
||||
table.insert(parts, { separator, "LspCodeLensSeparator" })
|
||||
end
|
||||
end
|
||||
local col = M.virt_text_pos == "inline"
|
||||
and self.ready[1].range.start.character
|
||||
or 0
|
||||
|
||||
local col, opts
|
||||
if position == "above" then
|
||||
local line = vim.api.nvim_buf_get_lines(
|
||||
buf,
|
||||
self.row,
|
||||
self.row + 1,
|
||||
false
|
||||
)[1] or ""
|
||||
local indent = line:match("^%s*") or ""
|
||||
local chunks = parts
|
||||
if indent ~= "" then
|
||||
chunks = { { indent, "LspCodeLensSeparator" } }
|
||||
vim.list_extend(chunks, parts)
|
||||
end
|
||||
col = 0
|
||||
opts = {
|
||||
virt_lines = { chunks },
|
||||
virt_lines_above = true,
|
||||
hl_mode = "combine",
|
||||
}
|
||||
else
|
||||
col = position == "inline" and self.ready[1].range.start.character or 0
|
||||
opts = {
|
||||
virt_text = parts,
|
||||
virt_text_pos = position,
|
||||
hl_mode = "combine",
|
||||
}
|
||||
end
|
||||
|
||||
-- One extmark per row. Extmarks auto-shift with edits, so multiple from
|
||||
-- prior refreshes can end up on the same row; pick the first and drop
|
||||
@@ -95,22 +123,21 @@ function Row:render(buf)
|
||||
end
|
||||
end
|
||||
|
||||
if
|
||||
primary
|
||||
and primary.col == col
|
||||
and primary.details
|
||||
and primary.details.virt_text_pos == M.virt_text_pos
|
||||
and vim.deep_equal(primary.details.virt_text, parts)
|
||||
then
|
||||
return
|
||||
if primary and primary.col == col and primary.details then
|
||||
local d = primary.details --[[@as vim.api.keyset.extmark_details]]
|
||||
local same = opts.virt_lines
|
||||
and vim.deep_equal(d.virt_lines, opts.virt_lines)
|
||||
and d.virt_lines_above == opts.virt_lines_above
|
||||
or not opts.virt_lines
|
||||
and d.virt_text_pos == opts.virt_text_pos
|
||||
and vim.deep_equal(d.virt_text, opts.virt_text)
|
||||
if same then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
vim.api.nvim_buf_set_extmark(buf, NS, self.row, col, {
|
||||
id = primary and primary.id or nil,
|
||||
virt_text = parts,
|
||||
virt_text_pos = M.virt_text_pos,
|
||||
hl_mode = "combine",
|
||||
})
|
||||
opts.id = primary and primary.id or nil
|
||||
vim.api.nvim_buf_set_extmark(buf, NS, self.row, col, opts)
|
||||
end
|
||||
|
||||
---@class ow.lsp.codelens.State
|
||||
@@ -292,7 +319,20 @@ function M.toggle(buf)
|
||||
get_state(buf):toggle()
|
||||
end
|
||||
|
||||
function M.setup()
|
||||
---@class ow.lsp.codelens.SetupOpts
|
||||
---@field position? ow.lsp.codelens.Position
|
||||
---@field separator? string
|
||||
|
||||
---@param opts? ow.lsp.codelens.SetupOpts
|
||||
function M.setup(opts)
|
||||
opts = opts or {}
|
||||
if opts.position ~= nil then
|
||||
position = opts.position
|
||||
end
|
||||
if opts.separator ~= nil then
|
||||
separator = opts.separator
|
||||
end
|
||||
|
||||
vim.api.nvim_create_autocmd({ "BufEnter", "LspAttach" }, {
|
||||
group = GROUP,
|
||||
callback = function(ev)
|
||||
|
||||
Reference in New Issue
Block a user