editor: Expand selection to word under cursor before expanding to next enclosing syntax node (#28864)

Closes #27995

For strings in any language and Markdown, `select_larger_syntax_node`
will first select the word and then expand from there if:
- The cursor is on the word.
- The selection is inside the word.

It will not select the word and will directly proceed to expand if:
- The word is already selected.
- Multiple partial words are selected.

Todo:
- [x] Tests

Release Notes:

- Fixed `select_larger_syntax_node` to first expand to the word within a
string, and then to the larger syntax node.
This commit is contained in:
Smit Barmase 2025-04-16 20:52:26 +05:30 committed by GitHub
parent cb79420773
commit 0d8f77b5de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 220 additions and 1 deletions

View file

@ -12519,6 +12519,45 @@ impl Editor {
.iter()
.map(|selection| {
let old_range = selection.start..selection.end;
if let Some((node, _)) = buffer.syntax_ancestor(old_range.clone()) {
// manually select word at selection
if ["string_content", "inline"].contains(&node.kind()) {
let word_range = {
let display_point = buffer
.offset_to_point(old_range.start)
.to_display_point(&display_map);
let Range { start, end } =
movement::surrounding_word(&display_map, display_point);
start.to_point(&display_map).to_offset(&buffer)
..end.to_point(&display_map).to_offset(&buffer)
};
// ignore if word is already selected
if !word_range.is_empty() && old_range != word_range {
let last_word_range = {
let display_point = buffer
.offset_to_point(old_range.end)
.to_display_point(&display_map);
let Range { start, end } =
movement::surrounding_word(&display_map, display_point);
start.to_point(&display_map).to_offset(&buffer)
..end.to_point(&display_map).to_offset(&buffer)
};
// only select word if start and end point belongs to same word
if word_range == last_word_range {
selected_larger_node = true;
return Selection {
id: selection.id,
start: word_range.start,
end: word_range.end,
goal: SelectionGoal::None,
reversed: selection.reversed,
};
}
}
}
}
let mut new_range = old_range.clone();
let mut new_node = None;
while let Some((node, containing_range)) = buffer.syntax_ancestor(new_range.clone())