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 = {}
|
local M = {}
|
||||||
|
|
||||||
---@type "eol" | "right_align" | "inline"
|
---@alias ow.lsp.codelens.Position "eol" | "right_align" | "inline" | "above"
|
||||||
M.virt_text_pos = "eol"
|
|
||||||
M.separator = " | "
|
---@type ow.lsp.codelens.Position
|
||||||
|
local position = "above"
|
||||||
|
local separator = " | "
|
||||||
|
|
||||||
---@type table<integer, ow.lsp.codelens.State>
|
---@type table<integer, ow.lsp.codelens.State>
|
||||||
local state_by_buf = {}
|
local state_by_buf = {}
|
||||||
@@ -69,12 +71,38 @@ function Row:render(buf)
|
|||||||
for i, lens in ipairs(self.ready) do
|
for i, lens in ipairs(self.ready) do
|
||||||
table.insert(parts, { lens.command.title, "LspCodeLens" })
|
table.insert(parts, { lens.command.title, "LspCodeLens" })
|
||||||
if i < #self.ready then
|
if i < #self.ready then
|
||||||
table.insert(parts, { M.separator, "LspCodeLensSeparator" })
|
table.insert(parts, { separator, "LspCodeLensSeparator" })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local col = M.virt_text_pos == "inline"
|
|
||||||
and self.ready[1].range.start.character
|
local col, opts
|
||||||
or 0
|
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
|
-- 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
|
-- prior refreshes can end up on the same row; pick the first and drop
|
||||||
@@ -95,22 +123,21 @@ function Row:render(buf)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if
|
if primary and primary.col == col and primary.details then
|
||||||
primary
|
local d = primary.details --[[@as vim.api.keyset.extmark_details]]
|
||||||
and primary.col == col
|
local same = opts.virt_lines
|
||||||
and primary.details
|
and vim.deep_equal(d.virt_lines, opts.virt_lines)
|
||||||
and primary.details.virt_text_pos == M.virt_text_pos
|
and d.virt_lines_above == opts.virt_lines_above
|
||||||
and vim.deep_equal(primary.details.virt_text, parts)
|
or not opts.virt_lines
|
||||||
then
|
and d.virt_text_pos == opts.virt_text_pos
|
||||||
return
|
and vim.deep_equal(d.virt_text, opts.virt_text)
|
||||||
|
if same then
|
||||||
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.api.nvim_buf_set_extmark(buf, NS, self.row, col, {
|
opts.id = primary and primary.id or nil
|
||||||
id = primary and primary.id or nil,
|
vim.api.nvim_buf_set_extmark(buf, NS, self.row, col, opts)
|
||||||
virt_text = parts,
|
|
||||||
virt_text_pos = M.virt_text_pos,
|
|
||||||
hl_mode = "combine",
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---@class ow.lsp.codelens.State
|
---@class ow.lsp.codelens.State
|
||||||
@@ -292,7 +319,20 @@ function M.toggle(buf)
|
|||||||
get_state(buf):toggle()
|
get_state(buf):toggle()
|
||||||
end
|
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" }, {
|
vim.api.nvim_create_autocmd({ "BufEnter", "LspAttach" }, {
|
||||||
group = GROUP,
|
group = GROUP,
|
||||||
callback = function(ev)
|
callback = function(ev)
|
||||||
|
|||||||
Reference in New Issue
Block a user