Make word deletions less greedy (#37352)

Closes https://github.com/zed-industries/zed/issues/37144

Adjusts `editor::DeleteToPreviousWordStart`,
`editor::DeleteToNextWordEnd`, `editor::DeleteToNextSubwordEnd` and
`editor::DeleteToPreviousSubwordStart` actions to

* take whitespace sequences with length >= 2 into account and stop after
removing them (whilst movement would also include the word after such
sequences)

* take current language's brackets into account and stop after removing
the text before them

The latter is configurable and can be disabled with `"ignore_brackets":
true` parameter in the action.

Release Notes:

- Improved word deletions to consider whitespace sequences and brackets
by default
This commit is contained in:
Kirill Bulatov
2025-09-03 17:48:17 +03:00
committed by GitHub
parent 7327ef662b
commit 0cbacb8500
14 changed files with 509 additions and 48 deletions
+20 -4
View File
@@ -13153,11 +13153,17 @@ impl Editor {
this.change_selections(Default::default(), window, cx, |s| {
s.move_with(|map, selection| {
if selection.is_empty() {
let cursor = if action.ignore_newlines {
let mut cursor = if action.ignore_newlines {
movement::previous_word_start(map, selection.head())
} else {
movement::previous_word_start_or_newline(map, selection.head())
};
cursor = movement::adjust_greedy_deletion(
map,
selection.head(),
cursor,
action.ignore_brackets,
);
selection.set_head(cursor, SelectionGoal::None);
}
});
@@ -13178,7 +13184,9 @@ impl Editor {
this.change_selections(Default::default(), window, cx, |s| {
s.move_with(|map, selection| {
if selection.is_empty() {
let cursor = movement::previous_subword_start(map, selection.head());
let mut cursor = movement::previous_subword_start(map, selection.head());
cursor =
movement::adjust_greedy_deletion(map, selection.head(), cursor, false);
selection.set_head(cursor, SelectionGoal::None);
}
});
@@ -13254,11 +13262,17 @@ impl Editor {
this.change_selections(Default::default(), window, cx, |s| {
s.move_with(|map, selection| {
if selection.is_empty() {
let cursor = if action.ignore_newlines {
let mut cursor = if action.ignore_newlines {
movement::next_word_end(map, selection.head())
} else {
movement::next_word_end_or_newline(map, selection.head())
};
cursor = movement::adjust_greedy_deletion(
map,
selection.head(),
cursor,
action.ignore_brackets,
);
selection.set_head(cursor, SelectionGoal::None);
}
});
@@ -13278,7 +13292,9 @@ impl Editor {
this.change_selections(Default::default(), window, cx, |s| {
s.move_with(|map, selection| {
if selection.is_empty() {
let cursor = movement::next_subword_end(map, selection.head());
let mut cursor = movement::next_subword_end(map, selection.head());
cursor =
movement::adjust_greedy_deletion(map, selection.head(), cursor, false);
selection.set_head(cursor, SelectionGoal::None);
}
});