From 941b3fc80fe08662cbae7be09f752c636cb965c1 Mon Sep 17 00:00:00 2001 From: rayx Date: Fri, 17 Dec 2021 08:54:36 +1100 Subject: [PATCH] vim.ui.select adapt native codeaction and codelens apply actions (#117) * doc update for lsp-installer * use vim.ui.select and guihua ui patch * adjust null-ls sequence --- README.md | 11 ++ lua/navigator/codeAction.lua | 294 +++++++++++++++------------- lua/navigator/codelens.lua | 252 +++++++++++++----------- lua/navigator/gui.lua | 4 + lua/navigator/lspclient/clients.lua | 7 +- lua/navigator/lspclient/mapping.lua | 2 +- lua/navigator/lspwrapper.lua | 158 ++++++++------- lua/navigator/rename.lua | 46 +---- 8 files changed, 410 insertions(+), 364 deletions(-) diff --git a/README.md b/README.md index 019181b..2af950e 100644 --- a/README.md +++ b/README.md @@ -490,6 +490,17 @@ cmd = { "/Users/username/.local/share/nvim/lsp_servers/python/node_modules/.bin/ ``` +The lsp servers installed by nvim-lsp-installer is in following dir +```lua +local path = require 'nvim-lsp-installer.path' +local install_root_dir = path.concat {vim.fn.stdpath 'data', 'lsp_servers'} + +``` + +And you can setup binary full path to this: (e.g. with gopls) +`install_root_dir .. '/go/gopls'` + + ## Usage Please refer to lua/navigator/lspclient/mapping.lua on key mappings. Should be able to work out-of-box. diff --git a/lua/navigator/codeAction.lua b/lua/navigator/codeAction.lua index 54b3902..dcd88ca 100644 --- a/lua/navigator/codeAction.lua +++ b/lua/navigator/codeAction.lua @@ -5,133 +5,14 @@ local code_action = {} local gui = require "navigator.gui" local config = require("navigator").config_values() local api = vim.api --- trace = log +trace = log local sign_name = "NavigatorLightBulb" --- `codeAction/resolve` -- from neovim buf.lua, change vim.ui.select to gui -local function on_code_action_results(results, ctx) - local trace = log - local action_tuples = {} - - local data = {"  Auto Fix Apply Exit"} - - for client_id, result in pairs(results) do - for i, action in pairs(result.result or {}) do - local title = 'apply action' - trace(action) - if action.edit and action.edit.title then - local edit = action.edit - title = edit.title:gsub("\r\n", " ↳ ") - title = title:gsub("\n", " ↳ ") - elseif action.title then - title = action.title:gsub("\r\n", " ↳ ") - title = title:gsub("\n", " ↳ ") - elseif action.command and action.command.title then - title = action.command.title:gsub("\n", " ↳ ") - title = title:gsub("\n", " ↳ ") - end - - local edit = action.edit or {} - -- trace(edit.documentChanges) - if edit.documentChanges or edit.changes then - local changes = edit.documentChanges or edit.changes - -- trace(action.edit.documentChanges) - for _, change in pairs(changes or {}) do - -- trace(change) - if change.edits then - title = title .. " [newText:]" - for _, ed in pairs(change.edits) do - -- trace(ed) - if ed.newText and ed.newText ~= "" then - local newText = ed.newText:gsub("\n\t", " ↳ ") - newText = newText:gsub("\n", "↳") - title = title .. " (" .. newText - if ed.range then - title = title .. " line: " .. tostring(ed.range.start.line) .. ")" - else - title = title .. ")" - end - end - end - elseif change.newText and change.newText ~= "" then - local newText = change.newText:gsub("\"\n\t\"", " ↳ ") - newText = newText:gsub("\n", "↳") - title = title .. " (newText: " .. newText - if change.range then - title = title .. " line: " .. tostring(change.range.start.line) .. ")" - else - title = title .. ")" - end - end - - end - end - - title = string.format("[%d] %s", i, title) - table.insert(data, title) - table.insert(action_tuples, {client_id, action, title, i}) - end - end - - log(action_tuples) - log(data) - - if #action_tuples == 0 then - vim.notify('No code actions available', vim.log.levels.INFO) - return - end - local width = 42 - for _, str in ipairs(data) do - if #str > width then - width = #str - end - end - - local divider = string.rep('─', width + 2) - - table.insert(data, 2, divider) - - local listview = gui.new_list_view { - items = data, - width = width + 4, - loc = "top_center", - relative = "cursor", - rawdata = true, - data = data, - on_confirm = function(item) - trace(item) - local action_chosen = nil - for _, value in pairs(action_tuples) do - if value[3] == item then - action_chosen = value - return require('navigator.lspwrapper').on_user_choice(action_chosen, ctx) - end - end - end, - on_move = function(pos) - trace(pos) - return pos - end - } - - log("new buffer", listview.bufnr) - vim.api.nvim_buf_add_highlight(listview.bufnr, -1, 'Title', 0, 0, -1) - - -- let move down 2 pos - ListViewCtrl:on_next() - ListViewCtrl:on_next() -end local diagnostic = vim.diagnostic or vim.lsp.diagnostic -code_action.code_action_handler = util.mk_handler(function(err, results, ctx, cfg) - if err ~= nil then - log("code action err", err, results, ctx, cfg) - return - end - on_code_action_results(results, ctx) -end) -- https://github.com/glepnir/lspsaga.nvim/blob/main/lua/lspsaga/codeaction.lua -- lspsaga has a clever design to inject code action indicator @@ -254,21 +135,21 @@ local code_action_req = function(_call_back_fn, diagnostics) vim.lsp.buf_request(0, "textDocument/codeAction", params, callback) end -local function code_action_request(params) - local bufnr = vim.api.nvim_get_current_buf() - local method = 'textDocument/codeAction' - vim.lsp.buf_request_all(bufnr, method, params, function(results) - on_code_action_results(results, {bufnr = bufnr, method = method, params = params}) - end) -end code_action.code_action = function() - local diagnostics = vim.lsp.diagnostic.get_line_diagnostics() - local context = {diagnostics = diagnostics} - local params = vim.lsp.util.make_range_params() - params.context = context - -- vim.lsp.buf_request(0, "textDocument/codeAction", params, code_action.code_action_handler) - code_action_request(params) + + local original_select = vim.ui.select + vim.ui.select = require("guihua.gui").select + + log('codeaction') + + vim.lsp.buf.code_action() + vim.defer_fn( + function () + vim.ui.select = original_select + end, 1000 + ) + end code_action.range_code_action = function(startpos, endpos) @@ -276,7 +157,17 @@ code_action.range_code_action = function(startpos, endpos) context.diagnostics = vim.lsp.diagnostic.get_line_diagnostics() local params = util.make_given_range_params(startpos, endpos) params.context = context - code_action_request(params) + + + local original_select = vim.ui.select + vim.ui.select = require("guihua.gui").select + + vim.lsp.buf.range_code_action(context, startpos, endpos) + vim.defer_fn( + function () + vim.ui.select = original_select + end, 1000 + ) end code_action.code_action_prompt = function() @@ -301,3 +192,138 @@ code_action.code_action_prompt = function() end return code_action + + + +--[[ + +code_action.code_action_handler = util.mk_handler(function(err, results, ctx, cfg) + log(ctx) + if err ~= nil then + log("code action err", err, results, ctx, cfg) + return + end + on_code_action_results(results, ctx) +end) +local function code_action_request(params) + local bufnr = vim.api.nvim_get_current_buf() + local method = 'textDocument/codeAction' + vim.lsp.buf_request_all(bufnr, method, params, function(results) + on_code_action_results(results, {bufnr = bufnr, method = method, params = params}) + end) +end + + +local function on_code_action_results(results, ctx, client) + local trace = log + local action_tuples = {} + + local data = {"  Auto Fix Apply Exit"} + + for client_id, result in pairs(results) do + for i, action in pairs(result.result or {}) do + local title = 'apply action' + trace(action) + if action.edit and action.edit.title then + local edit = action.edit + title = edit.title:gsub("\r\n", " ↳ ") + title = title:gsub("\n", " ↳ ") + elseif action.title then + title = action.title:gsub("\r\n", " ↳ ") + title = title:gsub("\n", " ↳ ") + elseif action.command and action.command.title then + title = action.command.title:gsub("\n", " ↳ ") + title = title:gsub("\n", " ↳ ") + end + + local edit = action.edit or {} + -- trace(edit.documentChanges) + if edit.documentChanges or edit.changes then + local changes = edit.documentChanges or edit.changes + -- trace(action.edit.documentChanges) + for _, change in pairs(changes or {}) do + -- trace(change) + if change.edits then + title = title .. " [newText:]" + for _, ed in pairs(change.edits) do + -- trace(ed) + if ed.newText and ed.newText ~= "" then + local newText = ed.newText:gsub("\n\t", " ↳ ") + newText = newText:gsub("\n", "↳") + title = title .. " (" .. newText + if ed.range then + title = title .. " line: " .. tostring(ed.range.start.line) .. ")" + else + title = title .. ")" + end + end + end + elseif change.newText and change.newText ~= "" then + local newText = change.newText:gsub("\"\n\t\"", " ↳ ") + newText = newText:gsub("\n", "↳") + title = title .. " (newText: " .. newText + if change.range then + title = title .. " line: " .. tostring(change.range.start.line) .. ")" + else + title = title .. ")" + end + end + + end + end + + title = string.format("[%d] %s", i, title) + table.insert(data, title) + table.insert(action_tuples, {client_id, action, title, i}) + end + end + + log(action_tuples) + log(data) + + if #action_tuples == 0 then + vim.notify('No code actions available', vim.log.levels.INFO) + return + end + local width = 42 + for _, str in ipairs(data) do + if #str > width then + width = #str + end + end + + local divider = string.rep('─', width + 2) + + table.insert(data, 2, divider) + + local listview = gui.new_list_view { + items = data, + width = width + 4, + loc = "top_center", + relative = "cursor", + rawdata = true, + data = data, + on_confirm = function(item) + trace(item) + local action_chosen = nil + for _, value in pairs(action_tuples) do + if value[3] == item then + action_chosen = value + return require('navigator.lspwrapper').on_user_choice(action_chosen, ctx) + end + end + end, + on_move = function(pos) + trace(pos) + return pos + end + } + + log("new buffer", listview.bufnr) + vim.api.nvim_buf_add_highlight(listview.bufnr, -1, 'Title', 0, 0, -1) + + -- let move down 2 pos + ListViewCtrl:on_next() + ListViewCtrl:on_next() +end +]] diff --git a/lua/navigator/codelens.lua b/lua/navigator/codelens.lua index f7eedf0..bda5178 100644 --- a/lua/navigator/codelens.lua +++ b/lua/navigator/codelens.lua @@ -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 lua require('navigator.codelens').refresh()") + vim.cmd("autocmd BufEnter,CursorHold,InsertLeave 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 Apply 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 Apply 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 +-- diff --git a/lua/navigator/gui.lua b/lua/navigator/gui.lua index 00582bd..fb6bf8f 100644 --- a/lua/navigator/gui.lua +++ b/lua/navigator/gui.lua @@ -38,6 +38,10 @@ function M.new_list_view(opts) return require('guihua.gui').new_list_view(opts) end +function M.select(items, opts, on_choice) + return +end + return M -- Doc diff --git a/lua/navigator/lspclient/clients.lua b/lua/navigator/lspclient/clients.lua index ae3455d..b25a624 100644 --- a/lua/navigator/lspclient/clients.lua +++ b/lua/navigator/lspclient/clients.lua @@ -554,7 +554,12 @@ local function lsp_startup(ft, retry, user_lsp_opts) if nulls_cfg then local cfg = {} cfg = vim.tbl_deep_extend('keep', cfg, nulls_cfg) - lspconfig['null-ls'].setup(cfg) + vim.defer_fn( + function () + lspconfig['null-ls'].setup(cfg) -- adjust null_ls startup timing + end, + 1000 + ) log('null-ls loading') _NG_Loaded['null-ls'] = true configs['null-ls'] = cfg diff --git a/lua/navigator/lspclient/mapping.lua b/lua/navigator/lspclient/mapping.lua index 5be93d7..a181dce 100644 --- a/lua/navigator/lspclient/mapping.lua +++ b/lua/navigator/lspclient/mapping.lua @@ -241,7 +241,7 @@ function M.setup(user_opts) end vim.lsp.handlers["textDocument/references"] = require"navigator.reference".reference_handler - vim.lsp.handlers["textDocument/codeAction"] = require"navigator.codeAction".code_action_handler + -- vim.lsp.handlers["textDocument/codeAction"] = require"navigator.codeAction".code_action_handler vim.lsp.handlers["textDocument/definition"] = require"navigator.definition".definition_handler if cap.declaration then diff --git a/lua/navigator/lspwrapper.lua b/lua/navigator/lspwrapper.lua index 412904d..ccd3659 100644 --- a/lua/navigator/lspwrapper.lua +++ b/lua/navigator/lspwrapper.lua @@ -417,82 +417,6 @@ function M.locations_to_items(locations, max_items) return items, width + 24, second_part -- TODO handle long line? end -function M.apply_action(action, ctx, client) - if client == nil then - client = vim.lsp.get_client_by_id(ctx.client_id or 1) - end - assert(action ~= nil, 'action must not be nil') - if action.edit then - vim.lsp.util.apply_workspace_edit(action.edit) - end - if action.command then - local command = type(action.command) == 'table' and action.command or action - local fn = client.commands[command.command] or (vim.lsp.commands and vim.lsp.commands[command.command]) - if fn then - local enriched_ctx = vim.deepcopy(ctx) - enriched_ctx.client_id = client.id - fn(command, enriched_ctx) - else - M.execute_command(command) - end - end - log(action) -end - -local function apply_action(action, client, ctx) - log(action, client) - if action.edit then - require('vim.lsp.util').apply_workspace_edit(action.edit) - end - if action.command then - local command = type(action.command) == 'table' and action.command or action - local fn = vim.lsp.commands and vim.lsp.commands[command.command] - if fn then - local enriched_ctx = vim.deepcopy(ctx) - enriched_ctx.client_id = client.id - fn(command, ctx) - else - require('vim.lsp.buf').execute_command(command) - end - end -end - -function M.on_user_choice(action_tuple, ctx) - if not action_tuple then - return - end - log(action_tuple) - -- textDocument/codeAction can return either Command[] or CodeAction[] - -- - -- CodeAction - -- ... - -- edit?: WorkspaceEdit -- <- must be applied before command - -- command?: Command - -- - -- Command: - -- title: string - -- command: string - -- arguments?: any[] - -- - local client = vim.lsp.get_client_by_id(action_tuple[1]) - local action = action_tuple[2] - if - not action.edit - and client - and type(client.resolved_capabilities.code_action) == 'table' - and client.resolved_capabilities.code_action.resolveProvider - then - client.request('codeAction/resolve', action, function(err, resolved_action) - if err then - vim.notify(err.code .. ': ' .. err.message, vim.log.levels.ERROR) - return - end - apply_action(resolved_action, client, ctx) - end) - else - apply_action(action, client, ctx) - end -end function M.symbol_to_items(locations) if not locations or vim.tbl_isempty(locations) then @@ -536,3 +460,85 @@ function M.request(method, hdlr) -- e.g textDocument/reference end return M + +-- local function apply_action(action, client) +-- -- local client = vim.lsp.get_client_by_id(ctx.client_id) +-- log(action) +-- +-- assert(action ~= nil, 'action must not be nil') +-- if action.edit then +-- require('vim.lsp.util').apply_workspace_edit(action.edit) +-- end +-- if action.command then +-- local command = type(action.command) == 'table' and action.command or action +-- local fn = vim.lsp.commands and vim.lsp.commands[command.command] +-- if fn then +-- local enriched_ctx = vim.deepcopy(ctx) +-- enriched_ctx.client_id = client.id +-- fn(command, ctx) +-- else +-- require('vim.lsp.buf').execute_command(command) +-- end +-- end +-- end +-- +-- M.apply_action = apply_action +-- +-- function M.on_user_choice(action_tuple, ctx) +-- log(ctx) +-- if not action_tuple then +-- return +-- end +-- log(action_tuple) +-- -- textDocument/codeAction can return either Command[] or CodeAction[] +-- -- +-- -- CodeAction +-- -- ... +-- -- edit?: WorkspaceEdit -- <- must be applied before command +-- -- command?: Command +-- -- +-- -- Command: +-- -- title: string +-- -- command: string +-- -- arguments?: any[] +-- -- +-- local function apply_code_action(action, client) +-- if action.edit then +-- util.apply_workspace_edit(action.edit) +-- end +-- if action.command then +-- local command = type(action.command) == 'table' and action.command or action +-- local fn = client.commands[command.command] or vim.lsp.commands[command.command] +-- if fn then +-- local enriched_ctx = vim.deepcopy(ctx) +-- enriched_ctx.client_id = client.id +-- fn(command, enriched_ctx) +-- else +-- M.execute_command(command) +-- end +-- end +-- end +-- +-- if action_tuple[1] ~= nil then +-- ctx.client_id = action_tuple[1] +-- end +-- local client = vim.lsp.get_client_by_id(ctx.client_id) +-- local action = action_tuple[2] +-- if +-- not action.edit +-- and client +-- and type(client.resolved_capabilities.code_action) == 'table' +-- and client.resolved_capabilities.code_action.resolveProvider +-- then +-- client.request('codeAction/resolve', action, function(err, resolved_action, c) +-- log(resolved_action, c) +-- if err then +-- vim.notify(err.code .. ': ' .. err.message, vim.log.levels.ERROR) +-- return +-- end +-- apply_code_action(resolved_action, client) +-- end) +-- else +-- apply_action(action, client) +-- end +-- end diff --git a/lua/navigator/rename.lua b/lua/navigator/rename.lua index 820461e..74981e9 100644 --- a/lua/navigator/rename.lua +++ b/lua/navigator/rename.lua @@ -1,44 +1,16 @@ -- https://github.com/lukas-reineke/dotfiles/blob/master/vim/lua/lsp/rename.lua local M = {} -local util = require "navigator.util" -local rename_prompt = "Rename -> " +local util = require('navigator.util') +-- local rename_prompt = 'Rename -> ' M.rename = function() - local current_name = vim.fn.expand("") - local bufnr = vim.api.nvim_create_buf(false, true) - vim.api.nvim_buf_set_option(bufnr, "buftype", "prompt") - vim.api.nvim_buf_set_option(bufnr, "bufhidden", "wipe") - vim.api.nvim_buf_add_highlight(bufnr, -1, "NGPreviewTitle", 0, 0, #rename_prompt) - vim.fn.prompt_setprompt(bufnr, rename_prompt) - local width = #current_name + #rename_prompt + 10 - local winnr = vim.api.nvim_open_win(bufnr, true, { - relative = "cursor", - width = width, - height = 1, - row = -3, - col = 1, - style = "minimal", - border = "single" - }) - vim.api.nvim_win_set_option(winnr, "winhl", "Normal:Floating") - vim.api.nvim_buf_set_option(bufnr, "filetype", "guihua") - util.map("n", "", "bd!", {silent = true, buffer = true}) - util.map({"n", "i"}, "", "lua require('navigator.rename').callback()", - {silent = true, buffer = true}) - util.map({"n", "i"}, "", [["_cl]], {silent = true, buffer = true}) - vim.cmd(string.format("normal i%s", current_name)) -end + local input = vim.ui.input -M.callback = function() - local new_name = vim.trim(vim.fn.getline("."):sub(#rename_prompt + 1, -1)) - vim.cmd [[stopinsert]] - vim.cmd [[bd!]] - if #new_name == 0 or new_name == vim.fn.expand("") then - return - end - local params = vim.lsp.util.make_position_params() - params.newName = new_name - vim.lsp.buf_request(0, "textDocument/rename", params) + vim.ui.input = require('guihua.floating').input + vim.lsp.buf.rename() + vim.defer_fn(function() + vim.ui.input = input + end, 1000) end --- M.callback() + return M