From 02a437de9ac859752e67026f7d932100afc49159 Mon Sep 17 00:00:00 2001 From: Ferrari Martino Giordano Date: Wed, 10 Jul 2024 18:16:40 +0200 Subject: [PATCH 1/8] feat: added initial support to refactoring symbols --- init.lua | 50 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/init.lua b/init.lua index 8768ec8..ec5b6b5 100644 --- a/init.lua +++ b/init.lua @@ -1723,7 +1723,6 @@ end ---@param new_name string function lsp.request_symbol_rename(doc, line, col, new_name) if not doc.lsp_open then return end - local servers_found = false for _, name in pairs(lsp.get_active_servers(doc.filename, true)) do servers_found = true @@ -1736,12 +1735,25 @@ function lsp.request_symbol_rename(doc, line, col, new_name) callback = function(server, response) if response.result and #response.result.changes then for file_uri, changes in pairs(response.result.changes) do - core.log(file_uri .. " " .. #changes) - -- TODO: Finish implement textDocument/rename + file_uri = string.sub(file_uri, 8) + local buff = core.open_doc(file_uri) + core.root_view:open_doc(buff) + for i, change in ipairs(changes) do + local l1, c1 = change.range.start.line + 1, change.range.start.character + 1 + local l2, c2 = change.range['end'].line + 1, change.range['end'].character + 1 + if #buff.selections > 1 then + buff:add_selection(l1, c1, l2, c2) + else + buff:set_selection(l1, c1, l2, c2) + end + end + for i, change in ipairs(changes) do + local l1, c1 = change.range.start.line + 1, change.range.start.character + 1 + local l2, c2 = change.range['end'].line + 1, change.range['end'].character + 1 + buff:replace_cursor(i, l1, c1, l2, c2, function(old) return new_name, true end) + end end end - - core.log("%s", json.prettify(json.encode(response))) end }) return @@ -2469,18 +2481,22 @@ command.add( end, ["lsp:rename-symbol"] = function(doc) - local symbol = doc:get_text(doc:get_selection()) - local line1, col1, line2 = doc:get_selection() - if #symbol > 0 and line1 == line2 then - core.command_view:enter("New Symbol Name", { - text = symbol, - submit = function(new_name) - lsp.request_symbol_rename(doc, line1, col1, new_name) - end - }) - else - core.log("Please select a symbol on the document to rename.") - end + local symbol = doc:get_text(doc:get_selection()) + local line1, col1, line2, col2 = doc:get_selection() + if #symbol == 0 then + line1, col1, line2, col2 = get_token_range(doc, line1, col1) + symbol = doc:get_text(line1, col1, line2, col2) + end + if #symbol > 0 and line1 == line2 then + core.command_view:enter("New Symbol Name", { + text = symbol, + submit = function(new_name) + lsp.request_symbol_rename(doc, line1, col1, new_name) + end + }) + else + core.log("Please select a symbol on the document to rename.") + end end, ["lsp:find-references"] = function(doc) From 6de58d535caa470ef551c1c91aed94a20966c048 Mon Sep 17 00:00:00 2001 From: Ferrari Martino Giordano Date: Fri, 12 Jul 2024 12:34:11 +0200 Subject: [PATCH 2/8] fix: workaround for getting current token without spaces --- init.lua | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/init.lua b/init.lua index ec5b6b5..ed08ca8 100644 --- a/init.lua +++ b/init.lua @@ -2410,6 +2410,28 @@ if autocomplete.add_icon then end end +local function get_current_symbol_info(doc) + local line1, col1, line2, col2 = doc:get_selection() + local symbol = doc:get_text(line1, col1, line2,col2) + if #symbol == 0 then + line1, col1, line2, col2 = get_token_range(doc, line1, col1) + if line1 ~= line2 then + core.error("Impossible to get current symbol") + return nil, line1, col1, line2, col2 + end + symbol = doc:get_text(line1, col1, line2, col2) + while #symbol > 0 and string.byte(symbol, 1) == 32 do + symbol = string.sub(symbol, 2) + col1 = col1 + 1 + end + while #symbol > 0 and string.byte(symbol, #symbol) == 32 do + symbol = string.sub(symbol, 1, #symbol-1) + col2 = col2 -1 + end + end + return symbol, line1, col1, line2, col2 +end + -- -- Commands -- @@ -2481,12 +2503,7 @@ command.add( end, ["lsp:rename-symbol"] = function(doc) - local symbol = doc:get_text(doc:get_selection()) - local line1, col1, line2, col2 = doc:get_selection() - if #symbol == 0 then - line1, col1, line2, col2 = get_token_range(doc, line1, col1) - symbol = doc:get_text(line1, col1, line2, col2) - end + local symbol, line1, col1, line2, _ = get_current_symbol_info(doc) if #symbol > 0 and line1 == line2 then core.command_view:enter("New Symbol Name", { text = symbol, From 17be68eb2a9ac34e5077fec9d74ce8193da6d568 Mon Sep 17 00:00:00 2001 From: Ferrari Martino Giordano Date: Fri, 12 Jul 2024 14:59:13 +0200 Subject: [PATCH 3/8] feat: support different reply and support to apply_changes --- init.lua | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/init.lua b/init.lua index ed08ca8..8169b7b 100644 --- a/init.lua +++ b/init.lua @@ -1716,6 +1716,25 @@ function lsp.request_call_hierarchy(doc, line, col) core.log("[LSP] Call hierarchy not supported.") end +local function parse_rename_result(result) + local changes = {} + if result.changes then + for uri, doc_change_list in pairs(result.changes) do + + changes[util.tofilename(uri)]= doc_change_list + end + elseif result.documentChanges then + for _, obj in ipairs(result.documentChanges) do + if obj.edits and obj.textDocument and obj.textDocument.uri then + changes[util.tofilename(obj.textDocument.uri)]= obj.edits + end + end + else + core.warning("LSP symbol rename result is not supported") + end + return changes +end + ---Sends a request to applicable LSP servers to rename a symbol. ---@param doc core.doc ---@param line integer @@ -1733,24 +1752,13 @@ function lsp.request_symbol_rename(doc, line, col, new_name) server:push_request('textDocument/rename', { params = request_params, callback = function(server, response) - if response.result and #response.result.changes then - for file_uri, changes in pairs(response.result.changes) do - file_uri = string.sub(file_uri, 8) - local buff = core.open_doc(file_uri) + if response.result then + local changes = parse_rename_result(response.result) + for file_path, edits in pairs(changes) do + local buff = core.open_doc(file_path) core.root_view:open_doc(buff) - for i, change in ipairs(changes) do - local l1, c1 = change.range.start.line + 1, change.range.start.character + 1 - local l2, c2 = change.range['end'].line + 1, change.range['end'].character + 1 - if #buff.selections > 1 then - buff:add_selection(l1, c1, l2, c2) - else - buff:set_selection(l1, c1, l2, c2) - end - end - for i, change in ipairs(changes) do - local l1, c1 = change.range.start.line + 1, change.range.start.character + 1 - local l2, c2 = change.range['end'].line + 1, change.range['end'].character + 1 - buff:replace_cursor(i, l1, c1, l2, c2, function(old) return new_name, true end) + for i = #edits, 1, -1 do + apply_edit(server, buff, edits[i], false, false) end end end From 16c3819d2a15c7402bd0d47ef6535c3b7117f252 Mon Sep 17 00:00:00 2001 From: Ferrari Martino Giordano Date: Sat, 13 Jul 2024 14:16:33 +0200 Subject: [PATCH 4/8] checking symbol is not nil --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index 8169b7b..e5edfbd 100644 --- a/init.lua +++ b/init.lua @@ -2512,7 +2512,7 @@ command.add( ["lsp:rename-symbol"] = function(doc) local symbol, line1, col1, line2, _ = get_current_symbol_info(doc) - if #symbol > 0 and line1 == line2 then + if symbol and #symbol > 0 and line1 == line2 then core.command_view:enter("New Symbol Name", { text = symbol, submit = function(new_name) From 3d516abba2c68d85003def28aa51c8e0f2525143 Mon Sep 17 00:00:00 2001 From: Ferrari Martino Giordano Date: Sun, 14 Jul 2024 18:27:45 +0200 Subject: [PATCH 5/8] fix: using regex for cleaning symbol string --- init.lua | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/init.lua b/init.lua index e5edfbd..ed775a4 100644 --- a/init.lua +++ b/init.lua @@ -2423,19 +2423,15 @@ local function get_current_symbol_info(doc) local symbol = doc:get_text(line1, col1, line2,col2) if #symbol == 0 then line1, col1, line2, col2 = get_token_range(doc, line1, col1) - if line1 ~= line2 then + if line1 ~= line2 then core.error("Impossible to get current symbol") return nil, line1, col1, line2, col2 end symbol = doc:get_text(line1, col1, line2, col2) - while #symbol > 0 and string.byte(symbol, 1) == 32 do - symbol = string.sub(symbol, 2) - col1 = col1 + 1 - end - while #symbol > 0 and string.byte(symbol, #symbol) == 32 do - symbol = string.sub(symbol, 1, #symbol-1) - col2 = col2 -1 - end + local space_start, space_end = '','' + space_start, symbol, space_end = string.match(symbol, "^(%s*)(.-)(%s*)$") + col1 = col1 + #space_start + col2 = col2 - #space_end end return symbol, line1, col1, line2, col2 end From 3ceee49ccf38e67dcce9b7aff59580342716dd09 Mon Sep 17 00:00:00 2001 From: Ferrari Martino Giordano Date: Thu, 18 Jul 2024 13:58:13 +0200 Subject: [PATCH 6/8] added rename capability --- server.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server.lua b/server.lua index 6d294bc..200b478 100644 --- a/server.lua +++ b/server.lua @@ -467,10 +467,10 @@ function Server:initialize(workspace, editor_name, editor_version) -- tooltipSupport = true -- }, -- colorProvider = {dynamicRegistration = false}, -- not supported - -- rename = { - -- dynamicRegistration = false, -- not supported - -- prepareSupport = false - -- }, + rename = { + dynamicRegistration = false, -- not supported + -- prepareSupport = false + }, publishDiagnostics = { relatedInformation = true, tagSupport = { From 4e1170f84b0edf9483515f3e71a093ac3e7590f2 Mon Sep 17 00:00:00 2001 From: Ferrari Martino Giordano Date: Thu, 18 Jul 2024 13:58:21 +0200 Subject: [PATCH 7/8] added menu entry --- init.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/init.lua b/init.lua index ed775a4..46e8553 100644 --- a/init.lua +++ b/init.lua @@ -1765,6 +1765,7 @@ function lsp.request_symbol_rename(doc, line, col, new_name) end }) return + else core.log("[LSP] ".. "Server does not have rename capabilty") end end @@ -2629,7 +2630,8 @@ if menu_found then { text = "Show Symbol Info in Tab", command = "lsp:show-symbol-info-in-tab" }, { text = "Goto Definition", command = "lsp:goto-definition" }, { text = "Goto Implementation", command = "lsp:goto-implementation" }, - { text = "Find References", command = "lsp:find-references" } + { text = "Find References", command = "lsp:find-references" }, + { text = "Rename Symbol", command = "lsp:rename-symbol" }, }) menu:register(lsp_predicate, { From c33582c0294000a135eb30fb4b5b52833ec9d796 Mon Sep 17 00:00:00 2001 From: Ferrari Martino Giordano Date: Thu, 18 Jul 2024 14:01:26 +0200 Subject: [PATCH 8/8] checking error response --- init.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/init.lua b/init.lua index 46e8553..a37d2c3 100644 --- a/init.lua +++ b/init.lua @@ -1762,6 +1762,9 @@ function lsp.request_symbol_rename(doc, line, col, new_name) end end end + if response.error then + log(server, "Error renaming symbol: " .. response.error.message) + end end }) return