|
|
|
@ -3,55 +3,62 @@
|
|
|
|
|
-- https://github.com/neovim/neovim/blob/master/runtime/lua/vim/lsp/codelens.lua
|
|
|
|
|
local codelens = require('vim.lsp.codelens')
|
|
|
|
|
|
|
|
|
|
local log = require"navigator.util".log
|
|
|
|
|
local mk_handler = require"navigator.util".mk_handler
|
|
|
|
|
local nvim_0_6 = require"navigator.util".nvim_0_6
|
|
|
|
|
local trace = require"navigator.util".trace
|
|
|
|
|
local log = require('navigator.util').log
|
|
|
|
|
local mk_handler = require('navigator.util').mk_handler
|
|
|
|
|
local nvim_0_6 = require('navigator.util').nvim_0_6
|
|
|
|
|
local trace = require('navigator.util').trace
|
|
|
|
|
|
|
|
|
|
local lsphelper = require "navigator.lspwrapper"
|
|
|
|
|
local lsphelper = require('navigator.lspwrapper')
|
|
|
|
|
local api = vim.api
|
|
|
|
|
local gui = require "navigator.gui"
|
|
|
|
|
local gui = require('navigator.gui')
|
|
|
|
|
local M = {}
|
|
|
|
|
|
|
|
|
|
local config = require("navigator").config_values()
|
|
|
|
|
local sign_name = "NavigatorCodeLensLightBulb"
|
|
|
|
|
local config = require('navigator').config_values()
|
|
|
|
|
local sign_name = 'NavigatorCodeLensLightBulb'
|
|
|
|
|
if vim.tbl_isempty(vim.fn.sign_getdefined(sign_name)) then
|
|
|
|
|
vim.fn.sign_define(sign_name,
|
|
|
|
|
{text = config.icons.code_lens_action_icon, texthl = "LspDiagnosticsSignHint"})
|
|
|
|
|
vim.fn.sign_define(sign_name, { text = config.icons.code_lens_action_icon, texthl = 'LspDiagnosticsSignHint' })
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local sign_group = "nvcodelensaction"
|
|
|
|
|
local sign_group = 'nvcodelensaction'
|
|
|
|
|
|
|
|
|
|
local get_current_winid = require('navigator.util').get_current_winid
|
|
|
|
|
|
|
|
|
|
local is_enabled = true
|
|
|
|
|
local code_lens_action = {}
|
|
|
|
|
|
|
|
|
|
local function _update_sign(line)
|
|
|
|
|
trace("update sign at line ", line)
|
|
|
|
|
trace('update sign at line ', line)
|
|
|
|
|
local winid = get_current_winid()
|
|
|
|
|
if code_lens_action[winid] == nil then
|
|
|
|
|
code_lens_action[winid] = {}
|
|
|
|
|
end
|
|
|
|
|
if code_lens_action[winid].lightbulb_line ~= 0 then
|
|
|
|
|
vim.fn.sign_unplace(sign_group, {id = code_lens_action[winid].lightbulb_line, buffer = "%"})
|
|
|
|
|
vim.fn.sign_unplace(sign_group, { id = code_lens_action[winid].lightbulb_line, buffer = '%' })
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if line then
|
|
|
|
|
-- log("updatasign", line, sign_group, sign_name)
|
|
|
|
|
vim.fn.sign_place(line, sign_group, sign_name, "%",
|
|
|
|
|
{lnum = line + 1, priority = config.lsp.code_lens_action.sign_priority})
|
|
|
|
|
vim.fn.sign_place(
|
|
|
|
|
line,
|
|
|
|
|
sign_group,
|
|
|
|
|
sign_name,
|
|
|
|
|
'%',
|
|
|
|
|
{ lnum = line + 1, priority = config.lsp.code_lens_action.sign_priority }
|
|
|
|
|
)
|
|
|
|
|
code_lens_action[winid].lightbulb_line = line
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local codelens_hdlr = mk_handler(function(err, result, ctx, cfg)
|
|
|
|
|
log(ctx, result)
|
|
|
|
|
M.codelens_ctx = ctx
|
|
|
|
|
if err or result == nil then
|
|
|
|
|
if err then
|
|
|
|
|
log("lsp code lens", vim.inspect(err), ctx, cfg)
|
|
|
|
|
log('lsp code lens', vim.inspect(err), ctx, cfg)
|
|
|
|
|
end
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
trace("codelenes result", result)
|
|
|
|
|
trace('codelenes result', result)
|
|
|
|
|
for _, v in pairs(result) do
|
|
|
|
|
_update_sign(v.range.start.line)
|
|
|
|
|
end
|
|
|
|
@ -65,120 +72,58 @@ function M.setup()
|
|
|
|
|
|
|
|
|
|
vim.cmd('augroup navigator.codelenses')
|
|
|
|
|
vim.cmd(' autocmd!')
|
|
|
|
|
vim.cmd(
|
|
|
|
|
"autocmd BufEnter,CursorHold,InsertLeave <buffer> lua require('navigator.codelens').refresh()")
|
|
|
|
|
vim.cmd("autocmd BufEnter,CursorHold,InsertLeave <buffer> lua require('navigator.codelens').refresh()")
|
|
|
|
|
vim.cmd('augroup end')
|
|
|
|
|
local on_codelens = vim.lsp.handlers["textDocument/codeLens"]
|
|
|
|
|
vim.lsp.handlers["textDocument/codeLens"] = mk_handler(
|
|
|
|
|
function(err, result, ctx, cfg)
|
|
|
|
|
-- trace(err, result, ctx.client_id, ctx.bufnr, cfg or {})
|
|
|
|
|
cfg = cfg or {}
|
|
|
|
|
ctx = ctx or {bufnr = vim.api.nvim_get_current_buf()}
|
|
|
|
|
if nvim_0_6() then
|
|
|
|
|
on_codelens(err, result, ctx, cfg)
|
|
|
|
|
codelens_hdlr(err, result, ctx, cfg)
|
|
|
|
|
else
|
|
|
|
|
on_codelens(err, ctx.method, result, ctx.client_id, ctx.bufnr)
|
|
|
|
|
codelens_hdlr(err, _, result, ctx.client_id or 0, ctx.bufnr or 0)
|
|
|
|
|
end
|
|
|
|
|
end)
|
|
|
|
|
local on_codelens = vim.lsp.handlers['textDocument/codeLens']
|
|
|
|
|
vim.lsp.handlers['textDocument/codeLens'] = mk_handler(function(err, result, ctx, cfg)
|
|
|
|
|
-- trace(err, result, ctx.client_id, ctx.bufnr, cfg or {})
|
|
|
|
|
cfg = cfg or {}
|
|
|
|
|
ctx = ctx or { bufnr = vim.api.nvim_get_current_buf() }
|
|
|
|
|
if nvim_0_6() then
|
|
|
|
|
on_codelens(err, result, ctx, cfg)
|
|
|
|
|
codelens_hdlr(err, result, ctx, cfg)
|
|
|
|
|
else
|
|
|
|
|
on_codelens(err, ctx.method, result, ctx.client_id, ctx.bufnr)
|
|
|
|
|
codelens_hdlr(err, nil, result, ctx.client_id or 0, ctx.bufnr or 0)
|
|
|
|
|
end
|
|
|
|
|
end)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
M.lsp_clients = {}
|
|
|
|
|
|
|
|
|
|
function M.refresh()
|
|
|
|
|
if #vim.lsp.buf_get_clients() < 1 then
|
|
|
|
|
log("Must have a client running to use lsp code action")
|
|
|
|
|
log('Must have a client running to use lsp code action')
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
if not lsphelper.check_capabilities("code_lens") then
|
|
|
|
|
if not lsphelper.check_capabilities('code_lens') then
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
vim.lsp.codelens.refresh()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function M.run_action()
|
|
|
|
|
log("run code len action")
|
|
|
|
|
local virtual_types_ns = api.nvim_create_namespace('ng_virtual_types')
|
|
|
|
|
|
|
|
|
|
assert(#vim.lsp.buf_get_clients() > 0, "Must have a client running to use lsp code action")
|
|
|
|
|
if not lsphelper.check_capabilities("code_lens") then
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local line = api.nvim_win_get_cursor(0)[1]
|
|
|
|
|
local bufnr = api.nvim_get_current_buf()
|
|
|
|
|
|
|
|
|
|
local lenses = codelens.get(bufnr)
|
|
|
|
|
log(lenses)
|
|
|
|
|
if lenses == nil or #lenses == 0 then
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
local width = 40
|
|
|
|
|
|
|
|
|
|
local data = {
|
|
|
|
|
" " .. _NgConfigValues.icons.code_lens_action_icon .. " CodeLens Action <C-o> Apply <C-e> Exit"
|
|
|
|
|
}
|
|
|
|
|
local idx = 1
|
|
|
|
|
for i, lens in pairs(lenses) do
|
|
|
|
|
if lens.range.start.line == (line - 1) then
|
|
|
|
|
local title = lens.command.title:gsub("\r\n", "\\r\\n")
|
|
|
|
|
title = title:gsub("\n", "\\n")
|
|
|
|
|
title = string.format("[%d] %s", idx, title)
|
|
|
|
|
table.insert(data, title)
|
|
|
|
|
lenses[i].display_title = title
|
|
|
|
|
width = math.max(width, #lens.command.title)
|
|
|
|
|
idx = idx + 1
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
local apply = require('navigator.lspwrapper').apply_action
|
|
|
|
|
local function apply_action(action)
|
|
|
|
|
local action_chosen = nil
|
|
|
|
|
for key, value in pairs(lenses) do
|
|
|
|
|
if value.display_title == action then
|
|
|
|
|
action_chosen = value
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
if action_chosen == nil then
|
|
|
|
|
log("no match for ", action, lenses)
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
apply(action_chosen)
|
|
|
|
|
end
|
|
|
|
|
function M.disable()
|
|
|
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
|
|
|
vim.api.nvim_buf_clear_namespace(bufnr, virtual_types_ns, 0, -1)
|
|
|
|
|
is_enabled = false
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local divider = string.rep('─', width + 2)
|
|
|
|
|
|
|
|
|
|
table.insert(data, 2, divider)
|
|
|
|
|
if #data > 2 then
|
|
|
|
|
local lv = gui.new_list_view {
|
|
|
|
|
items = data,
|
|
|
|
|
width = width + 4,
|
|
|
|
|
loc = "top_center",
|
|
|
|
|
relative = "cursor",
|
|
|
|
|
rawdata = true,
|
|
|
|
|
data = data,
|
|
|
|
|
on_confirm = function(pos)
|
|
|
|
|
log(pos)
|
|
|
|
|
apply_action(pos)
|
|
|
|
|
end,
|
|
|
|
|
on_move = function(pos)
|
|
|
|
|
log(pos)
|
|
|
|
|
return pos
|
|
|
|
|
end
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vim.api.nvim_buf_add_highlight(lv.bufnr, -1, 'Title', 0, 0, -1)
|
|
|
|
|
else
|
|
|
|
|
print('no codelense in current line')
|
|
|
|
|
function M.run_action()
|
|
|
|
|
local original_select = vim.ui.select
|
|
|
|
|
vim.ui.select = require("guihua.gui").select
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
log('codeaction')
|
|
|
|
|
|
|
|
|
|
local virtual_types_ns = api.nvim_create_namespace("ng_virtual_types");
|
|
|
|
|
codelens.run()
|
|
|
|
|
vim.defer_fn(
|
|
|
|
|
function ()
|
|
|
|
|
vim.ui.select = original_select
|
|
|
|
|
end, 1000
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
function M.disable()
|
|
|
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
|
|
|
vim.api.nvim_buf_clear_namespace(bufnr, virtual_types_ns, 0, -1)
|
|
|
|
|
is_enabled = false
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
M.inline = function()
|
|
|
|
@ -195,7 +140,7 @@ M.inline = function()
|
|
|
|
|
|
|
|
|
|
local bufnr = api.nvim_get_current_buf()
|
|
|
|
|
local parameter = lsp.util.make_position_params()
|
|
|
|
|
local response = lsp.buf_request_sync(bufnr, "textDocument/codeLens", parameter)
|
|
|
|
|
local response = lsp.buf_request_sync(bufnr, 'textDocument/codeLens', parameter)
|
|
|
|
|
|
|
|
|
|
-- Clear previous highlighting
|
|
|
|
|
api.nvim_buf_clear_namespace(bufnr, virtual_types_ns, 0, -1)
|
|
|
|
@ -222,16 +167,93 @@ M.inline = function()
|
|
|
|
|
|
|
|
|
|
log(msg)
|
|
|
|
|
api.nvim_buf_set_extmark(bufnr, virtual_types_ns, start_line, -1, {
|
|
|
|
|
virt_text = {{msg, "LspCodeLensText"}},
|
|
|
|
|
virt_text = { { msg, 'LspCodeLensText' } },
|
|
|
|
|
virt_text_pos = 'overlay',
|
|
|
|
|
hl_mode = 'combine'
|
|
|
|
|
hl_mode = 'combine',
|
|
|
|
|
})
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
-- else
|
|
|
|
|
-- api.nvim_command("echohl WarningMsg | echo 'VirtualTypes: No response' | echohl None")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return M
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- function M.run_action()
|
|
|
|
|
-- log('run code len action')
|
|
|
|
|
--
|
|
|
|
|
-- assert(#vim.lsp.buf_get_clients() > 0, 'Must have a client running to use lsp code action')
|
|
|
|
|
-- if not lsphelper.check_capabilities('code_lens') then
|
|
|
|
|
-- return
|
|
|
|
|
-- end
|
|
|
|
|
--
|
|
|
|
|
-- local line = api.nvim_win_get_cursor(0)[1]
|
|
|
|
|
-- local bufnr = api.nvim_get_current_buf()
|
|
|
|
|
--
|
|
|
|
|
-- local lenses = codelens.get(bufnr)
|
|
|
|
|
-- log(lenses)
|
|
|
|
|
-- if lenses == nil or #lenses == 0 then
|
|
|
|
|
-- return
|
|
|
|
|
-- end
|
|
|
|
|
-- local width = 40
|
|
|
|
|
--
|
|
|
|
|
-- local data = {
|
|
|
|
|
-- ' ' .. _NgConfigValues.icons.code_lens_action_icon .. ' CodeLens Action <C-o> Apply <C-e> Exit',
|
|
|
|
|
-- }
|
|
|
|
|
-- local idx = 1
|
|
|
|
|
-- for i, lens in pairs(lenses) do
|
|
|
|
|
-- if lens.range.start.line == (line - 1) then
|
|
|
|
|
-- local title = lens.command.title:gsub('\r\n', '\\r\\n')
|
|
|
|
|
-- title = title:gsub('\n', '\\n')
|
|
|
|
|
-- title = string.format('[%d] %s', idx, title)
|
|
|
|
|
-- table.insert(data, title)
|
|
|
|
|
-- lenses[i].display_title = title
|
|
|
|
|
-- width = math.max(width, #lens.command.title)
|
|
|
|
|
-- idx = idx + 1
|
|
|
|
|
-- end
|
|
|
|
|
-- end
|
|
|
|
|
-- local apply = require('navigator.lspwrapper').apply_action
|
|
|
|
|
-- local function apply_action(action)
|
|
|
|
|
-- local action_chosen = nil
|
|
|
|
|
-- for key, value in pairs(lenses) do
|
|
|
|
|
-- if value.display_title == action then
|
|
|
|
|
-- action_chosen = value
|
|
|
|
|
-- end
|
|
|
|
|
-- end
|
|
|
|
|
-- if action_chosen == nil then
|
|
|
|
|
-- log('no match for ', action, lenses)
|
|
|
|
|
-- return
|
|
|
|
|
-- end
|
|
|
|
|
-- apply(action_chosen, M.codelens_ctx)
|
|
|
|
|
-- end
|
|
|
|
|
--
|
|
|
|
|
-- local divider = string.rep('─', width + 2)
|
|
|
|
|
--
|
|
|
|
|
-- table.insert(data, 2, divider)
|
|
|
|
|
-- if #data > 2 then
|
|
|
|
|
-- local lv = gui.new_list_view({
|
|
|
|
|
-- items = data,
|
|
|
|
|
-- width = width + 4,
|
|
|
|
|
-- loc = 'top_center',
|
|
|
|
|
-- relative = 'cursor',
|
|
|
|
|
-- rawdata = true,
|
|
|
|
|
-- data = data,
|
|
|
|
|
-- on_confirm = function(pos)
|
|
|
|
|
-- log(pos)
|
|
|
|
|
-- apply_action(pos)
|
|
|
|
|
-- end,
|
|
|
|
|
-- on_move = function(pos)
|
|
|
|
|
-- log(pos)
|
|
|
|
|
-- return pos
|
|
|
|
|
-- end,
|
|
|
|
|
-- })
|
|
|
|
|
--
|
|
|
|
|
-- vim.api.nvim_buf_add_highlight(lv.bufnr, -1, 'Title', 0, 0, -1)
|
|
|
|
|
-- else
|
|
|
|
|
-- print('no codelense in current line')
|
|
|
|
|
-- end
|
|
|
|
|
-- end
|
|
|
|
|
--
|
|
|
|
|