feat(lsp): initial support for textDocument/rename

flow keybinds: changes f2 from toggle_input_mode to rename_symbol and
moves toggle_input_mode command to ctrl+shift+f2 (since ctrl+f2 is
already bound to insert_command_name)

the replacement text is hard coded for now. i've checked that replace
works with zls and pylsp which send WorkspaceEdit response messages in
different shapes - zls sends shape `{"changes": {}}` while pylsp sends
`{"documentChanges": []}`.

currently the 'rename_symbol_item' commands are sent one at a time.
however they should be buffered and be performed between one
buf_for_update, update_buf pair.  this will be addressed in a follow up.
This commit is contained in:
Travis Staloch 2025-01-12 14:00:48 -08:00 committed by CJ van den Berg
parent 7558a63819
commit 1fd4455adb
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9
5 changed files with 172 additions and 1 deletions

View file

@ -4222,6 +4222,13 @@ pub const Editor = struct {
}
pub const completion_meta = .{ .description = "Language: Show completions at cursor" };
pub fn rename_symbol(self: *Self, _: Context) Result {
const file_path = self.file_path orelse return;
const primary = self.get_primary();
return project_manager.rename_symbol(file_path, primary.cursor.row, primary.cursor.col);
}
pub const rename_symbol_meta = .{ .description = "Language: Rename symbol at cursor" };
pub fn hover(self: *Self, _: Context) Result {
const primary = self.get_primary();
return self.hover_at(primary.cursor.row, primary.cursor.col);
@ -4316,6 +4323,15 @@ pub const Editor = struct {
self.need_render();
}
pub fn rename_symbol_item(self: *Self, sel: Selection, new_text: []const u8) Result {
self.get_primary().selection = sel;
const buf = try self.buf_for_update();
const r1 = try self.delete_selection(buf.root, self.get_primary(), self.allocator);
const r2 = try self.insert(r1, self.get_primary(), new_text, self.allocator);
try self.update_buf(r2);
self.need_render();
}
pub fn select(self: *Self, ctx: Context) Result {
var sel: Selection = .{};
if (!try ctx.args.match(.{ tp.extract(&sel.begin.row), tp.extract(&sel.begin.col), tp.extract(&sel.end.row), tp.extract(&sel.end.col) }))