editor: Fix DeleteToPreviousWordStart and DeleteToNextWordEnd interaction with newlines (#16848)
Closes #5285, #14389 Changes: - `DeleteToPreviousWordStart` now deletes '\n' separately from preceding words and whitespace. - `DeleteToNextWordEnd` now deletes '\n' and any following whitespace separately from subsequent words. - Added an `ignore_newlines` flag to both actions to optionally retain the old behavior. These modifications align the behavior more closely with other popular editors like VSCode and Sublime: - `DeleteToPreviousWordStart` now matches the default <Ctrl+Backspace> action in those editors. - `DeleteToNextWordEnd` becomes more intuitive and closely resembles the default <Ctrl+Delete> behavior in those editors. Release Notes: - Improved `DeleteToPreviousWordStart` and `DeleteToNextWordEnd` interactions around newlines. You can opt-in into the previous behavior by adding {"ignore_newlines": true} to either action's binds in your keymap. ([#5285](https://github.com/zed-industries/zed/issues/5285), [#14389](https://github.com/zed-industries/zed/issues/14389))
This commit is contained in:
parent
a3d8dcda36
commit
96b592f00d
4 changed files with 151 additions and 8 deletions
|
@ -270,6 +270,19 @@ pub fn previous_word_start(map: &DisplaySnapshot, point: DisplayPoint) -> Displa
|
|||
})
|
||||
}
|
||||
|
||||
/// Returns a position of the previous word boundary, where a word character is defined as either
|
||||
/// uppercase letter, lowercase letter, '_' character, language-specific word character (like '-' in CSS) or newline.
|
||||
pub fn previous_word_start_or_newline(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
|
||||
let raw_point = point.to_point(map);
|
||||
let classifier = map.buffer_snapshot.char_classifier_at(raw_point);
|
||||
|
||||
find_preceding_boundary_display_point(map, point, FindRange::MultiLine, |left, right| {
|
||||
(classifier.kind(left) != classifier.kind(right) && !right.is_whitespace())
|
||||
|| left == '\n'
|
||||
|| right == '\n'
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a position of the previous subword boundary, where a subword is defined as a run of
|
||||
/// word characters of the same "subkind" - where subcharacter kinds are '_' character,
|
||||
/// lowerspace characters and uppercase characters.
|
||||
|
@ -299,6 +312,24 @@ pub fn next_word_end(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint
|
|||
})
|
||||
}
|
||||
|
||||
/// Returns a position of the next word boundary, where a word character is defined as either
|
||||
/// uppercase letter, lowercase letter, '_' character, language-specific word character (like '-' in CSS) or newline.
|
||||
pub fn next_word_end_or_newline(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
|
||||
let raw_point = point.to_point(map);
|
||||
let classifier = map.buffer_snapshot.char_classifier_at(raw_point);
|
||||
|
||||
let mut on_starting_row = true;
|
||||
find_boundary(map, point, FindRange::MultiLine, |left, right| {
|
||||
if left == '\n' {
|
||||
on_starting_row = false;
|
||||
}
|
||||
(classifier.kind(left) != classifier.kind(right)
|
||||
&& ((on_starting_row && !left.is_whitespace())
|
||||
|| (!on_starting_row && !right.is_whitespace())))
|
||||
|| right == '\n'
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a position of the next subword boundary, where a subword is defined as a run of
|
||||
/// word characters of the same "subkind" - where subcharacter kinds are '_' character,
|
||||
/// lowerspace characters and uppercase characters.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue