Match user selection when renaming (#10748)

Initial state:
<img width="337" alt="Screenshot 2024-04-19 at 01 35 34"
src="https://github.com/zed-industries/zed/assets/2690773/1720d06c-54ed-4479-b694-ea478ac5a55a">

Before the fix:
<img width="319" alt="Screenshot 2024-04-19 at 01 35 39"
src="https://github.com/zed-industries/zed/assets/2690773/64429088-e75b-44c3-b5d4-31a841e69a1d">

After:
<img width="336" alt="Screenshot 2024-04-19 at 01 36 43"
src="https://github.com/zed-industries/zed/assets/2690773/c523e549-c546-4a70-aa33-629912598466">
 

Release Notes:

- Improved rename selections to match the user ones
This commit is contained in:
Kirill Bulatov 2024-04-19 01:49:14 +03:00 committed by GitHub
parent 6d1ea782a4
commit 2602fc47bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 69 additions and 2 deletions

View File

@ -736,12 +736,60 @@ async fn test_collaborating_with_renames(cx_a: &mut TestAppContext, cx_b: &mut T
6..9 6..9
); );
rename.editor.update(cx, |rename_editor, cx| { rename.editor.update(cx, |rename_editor, cx| {
let rename_selection = rename_editor.selections.newest::<usize>(cx);
assert_eq!(
rename_selection.range(),
0..3,
"Rename that was triggered from zero selection caret, should propose the whole word."
);
rename_editor.buffer().update(cx, |rename_buffer, cx| { rename_editor.buffer().update(cx, |rename_buffer, cx| {
rename_buffer.edit([(0..3, "THREE")], None, cx); rename_buffer.edit([(0..3, "THREE")], None, cx);
}); });
}); });
}); });
// Cancel the rename, and repeat the same, but use selections instead of cursor movement
editor_b.update(cx_b, |editor, cx| {
editor.cancel(&editor::actions::Cancel, cx);
});
let prepare_rename = editor_b.update(cx_b, |editor, cx| {
editor.change_selections(None, cx, |s| s.select_ranges([7..8]));
editor.rename(&Rename, cx).unwrap()
});
fake_language_server
.handle_request::<lsp::request::PrepareRenameRequest, _, _>(|params, _| async move {
assert_eq!(params.text_document.uri.as_str(), "file:///dir/one.rs");
assert_eq!(params.position, lsp::Position::new(0, 8));
Ok(Some(lsp::PrepareRenameResponse::Range(lsp::Range::new(
lsp::Position::new(0, 6),
lsp::Position::new(0, 9),
))))
})
.next()
.await
.unwrap();
prepare_rename.await.unwrap();
editor_b.update(cx_b, |editor, cx| {
use editor::ToOffset;
let rename = editor.pending_rename().unwrap();
let buffer = editor.buffer().read(cx).snapshot(cx);
let lsp_rename_start = rename.range.start.to_offset(&buffer);
let lsp_rename_end = rename.range.end.to_offset(&buffer);
assert_eq!(lsp_rename_start..lsp_rename_end, 6..9);
rename.editor.update(cx, |rename_editor, cx| {
let rename_selection = rename_editor.selections.newest::<usize>(cx);
assert_eq!(
rename_selection.range(),
1..2,
"Rename that was triggered from a selection, should have the same selection range in the rename proposal"
);
rename_editor.buffer().update(cx, |rename_buffer, cx| {
rename_buffer.edit([(0..lsp_rename_end - lsp_rename_start, "THREE")], None, cx);
});
});
});
let confirm_rename = editor_b.update(cx_b, |editor, cx| { let confirm_rename = editor_b.update(cx_b, |editor, cx| {
Editor::confirm_rename(editor, &ConfirmRename, cx).unwrap() Editor::confirm_rename(editor, &ConfirmRename, cx).unwrap()
}); });

View File

@ -8094,7 +8094,7 @@ impl Editor {
.buffer .buffer
.read(cx) .read(cx)
.text_anchor_for_position(selection.head(), cx)?; .text_anchor_for_position(selection.head(), cx)?;
let (tail_buffer, _) = self let (tail_buffer, cursor_buffer_position_end) = self
.buffer .buffer
.read(cx) .read(cx)
.text_anchor_for_position(selection.tail(), cx)?; .text_anchor_for_position(selection.tail(), cx)?;
@ -8104,6 +8104,7 @@ impl Editor {
let snapshot = cursor_buffer.read(cx).snapshot(); let snapshot = cursor_buffer.read(cx).snapshot();
let cursor_buffer_offset = cursor_buffer_position.to_offset(&snapshot); let cursor_buffer_offset = cursor_buffer_position.to_offset(&snapshot);
let cursor_buffer_offset_end = cursor_buffer_position_end.to_offset(&snapshot);
let prepare_rename = project.update(cx, |project, cx| { let prepare_rename = project.update(cx, |project, cx| {
project.prepare_rename(cursor_buffer.clone(), cursor_buffer_offset, cx) project.prepare_rename(cursor_buffer.clone(), cursor_buffer_offset, cx)
}); });
@ -8132,6 +8133,8 @@ impl Editor {
let rename_buffer_range = rename_range.to_offset(&snapshot); let rename_buffer_range = rename_range.to_offset(&snapshot);
let cursor_offset_in_rename_range = let cursor_offset_in_rename_range =
cursor_buffer_offset.saturating_sub(rename_buffer_range.start); cursor_buffer_offset.saturating_sub(rename_buffer_range.start);
let cursor_offset_in_rename_range_end =
cursor_buffer_offset_end.saturating_sub(rename_buffer_range.start);
this.take_rename(false, cx); this.take_rename(false, cx);
let buffer = this.buffer.read(cx).read(cx); let buffer = this.buffer.read(cx).read(cx);
@ -8160,7 +8163,23 @@ impl Editor {
editor.buffer.update(cx, |buffer, cx| { editor.buffer.update(cx, |buffer, cx| {
buffer.edit([(0..0, old_name.clone())], None, cx) buffer.edit([(0..0, old_name.clone())], None, cx)
}); });
let rename_selection_range = match cursor_offset_in_rename_range
.cmp(&cursor_offset_in_rename_range_end)
{
Ordering::Equal => {
editor.select_all(&SelectAll, cx); editor.select_all(&SelectAll, cx);
return editor;
}
Ordering::Less => {
cursor_offset_in_rename_range..cursor_offset_in_rename_range_end
}
Ordering::Greater => {
cursor_offset_in_rename_range_end..cursor_offset_in_rename_range
}
};
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
s.select_ranges([rename_selection_range]);
});
editor editor
}); });