Skip to content

Commit dd032ee

Browse files
committed
refactor(lsp): update rename functionality for class files
1 parent 6faf2c7 commit dd032ee

File tree

1 file changed

+55
-43
lines changed

1 file changed

+55
-43
lines changed

lua/flutter-tools/lsp/rename.lua

Lines changed: 55 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -25,67 +25,46 @@ local function convert_to_file_name(class_name)
2525
return file_name .. ".dart"
2626
end
2727

28-
---@param old_name string
29-
---@param new_name string
30-
---@param callback function
31-
local function will_rename_files(old_name, new_name, callback)
32-
local params = lsp.util.make_position_params()
33-
if not new_name then return end
34-
local file_change = {
35-
newUri = vim.uri_from_fname(new_name),
36-
oldUri = vim.uri_from_fname(old_name),
37-
}
38-
params.files = { file_change }
39-
lsp.buf_request(0, "workspace/willRenameFiles", params, function(err, result)
40-
if err then
41-
return ui.notify(err.message or "Error on getting lsp rename results!", ui.ERROR)
42-
end
43-
callback(result)
44-
end)
45-
end
46-
4728
--- Call this function when you want rename class or anything else.
4829
--- If file will be renamed too, this function will update imports.
4930
--- This is a modified version of `vim.lsp.buf.rename()` function and can be used instead of it.
50-
--- Original version: https://github.com/neovim/neovim/blob/0bc323850410df4c3c1dd8fabded9d2000189270/runtime/lua/vim/lsp/buf.lua#L271
51-
function M.rename(new_name, options)
52-
options = options or {}
53-
local bufnr = options.bufnr or api.nvim_get_current_buf()
31+
--- Original version: https://github.com/neovim/neovim/blob/release-0.11/runtime/lua/vim/lsp/buf.lua#L640
32+
function M.rename(new_name, opts)
33+
opts = opts or {}
34+
local bufnr = vim._resolve_bufnr(opts.bufnr)
5435
local client = lsp_utils.get_dartls_client(bufnr)
5536
if not client or config.lsp.settings.renameFilesWithClasses ~= "always" then
5637
-- Fallback to default rename function if language server is not dartls
5738
-- or if user doesn't want to rename files on class rename.
58-
return lsp.buf.rename(new_name, options)
39+
return lsp.buf.rename(new_name, opts)
5940
end
6041

6142
local win = api.nvim_get_current_win()
6243

6344
-- Compute early to account for cursor movements after going async
64-
local word_under_cursor = fn.expand("<cword>")
45+
local cword = fn.expand("<cword>")
6546
local current_file_path = api.nvim_buf_get_name(bufnr)
6647
local current_file_name = fs.basename(current_file_path)
67-
local filename_from_class_name = convert_to_file_name(word_under_cursor)
48+
local filename_from_class_name = convert_to_file_name(cword)
6849
local is_file_rename = filename_from_class_name == current_file_name
6950

70-
---@param range table
71-
---@param offset_encoding string
72-
local function get_text_at_range(range, offset_encoding)
51+
---@param range lsp.Range
52+
---@param position_encoding string
53+
local function get_text_at_range(range, position_encoding)
7354
return api.nvim_buf_get_text(
7455
bufnr,
7556
range.start.line,
76-
-- Private method that may be not stable.
77-
-- Source in case of changes: https://github.com/neovim/neovim/blob/0bc323850410df4c3c1dd8fabded9d2000189270/runtime/lua/vim/lsp/util.lua#L2152
78-
util._get_line_byte_from_position(bufnr, range.start, offset_encoding),
57+
util._get_line_byte_from_position(bufnr, range.start, position_encoding),
7958
range["end"].line,
80-
util._get_line_byte_from_position(bufnr, range["end"], offset_encoding),
59+
util._get_line_byte_from_position(bufnr, range["end"], position_encoding),
8160
{}
8261
)[1]
8362
end
8463

8564
---@param name string the name of the thing
86-
---@param result lsp.Range | { range: lsp.Range, placeholder: string } | nil the result from the call to will rename
65+
---@param result table|nil the result from the call to will rename
8766
local function rename(name, result)
88-
local params = util.make_position_params(win, client.offset_encoding)
67+
local params = util.make_position_params(win, client.offset_encoding) --[[@as lsp.RenameParams]]
8968
params.newName = name
9069
local handler = client.handlers["textDocument/rename"] or lsp.handlers["textDocument/rename"]
9170
client.request("textDocument/rename", params, function(...)
@@ -100,29 +79,59 @@ function M.rename(new_name, options)
10079
local new_filename = convert_to_file_name(name)
10180
local new_file_path = path.join(fs.dirname(current_file_path), new_filename)
10281

103-
will_rename_files(current_file_path, new_file_path, function(result) rename(name, result) end)
82+
-- Create a custom params object for willRenameFiles request
83+
---@class WillRenameFilesParams
84+
local params = {
85+
files = {
86+
{
87+
oldUri = vim.uri_from_fname(current_file_path),
88+
newUri = vim.uri_from_fname(new_file_path),
89+
},
90+
},
91+
}
92+
93+
client.request("workspace/willRenameFiles", params, function(err, result)
94+
if err then
95+
ui.notify(err.message or "Error on getting lsp rename results!", ui.ERROR)
96+
return
97+
end
98+
rename(name, result)
99+
end, bufnr)
104100
else
105101
rename(name)
106102
end
107103
end
108104

105+
-- Try to use prepare rename first
109106
if client.supports_method("textDocument/prepareRename") then
110107
local params = util.make_position_params(win, client.offset_encoding)
111108
client.request("textDocument/prepareRename", params, function(err, result)
112-
if err then return ui.notify(("Error on prepareRename: %s"):format(err.message), ui.ERROR) end
113-
if not result then return ui.notify("Nothing to rename", ui.INFO) end
109+
if err or result == nil then
110+
if err then
111+
ui.notify(("Error on prepareRename: %s"):format(err.message), ui.ERROR)
112+
else
113+
ui.notify("Nothing to rename", ui.INFO)
114+
end
115+
return
116+
end
114117

115-
if new_name then return rename_fix_imports(new_name) end
118+
if new_name then
119+
rename_fix_imports(new_name)
120+
return
121+
end
116122

117-
local prompt_opts = { prompt = "New Name: " }
123+
local prompt_opts = {
124+
prompt = "New Name: ",
125+
}
126+
-- result: Range | { range: Range, placeholder: string }
118127
if result.placeholder then
119128
prompt_opts.default = result.placeholder
120129
elseif result.start then
121130
prompt_opts.default = get_text_at_range(result, client.offset_encoding)
122131
elseif result.range then
123132
prompt_opts.default = get_text_at_range(result.range, client.offset_encoding)
124133
else
125-
prompt_opts.default = word_under_cursor
134+
prompt_opts.default = cword
126135
end
127136
ui.input(prompt_opts, function(input)
128137
if not input or #input == 0 then return end
@@ -131,11 +140,14 @@ function M.rename(new_name, options)
131140
end, bufnr)
132141
else
133142
assert(client.supports_method("textDocument/rename"), "Client must support textDocument/rename")
134-
if new_name then return rename_fix_imports(new_name) end
143+
if new_name then
144+
rename_fix_imports(new_name)
145+
return
146+
end
135147

136148
local prompt_opts = {
137149
prompt = "New Name: ",
138-
default = word_under_cursor,
150+
default = cword,
139151
}
140152
ui.input(prompt_opts, function(input)
141153
if not input or #input == 0 then return end

0 commit comments

Comments
 (0)