fix: keep counted word deletions within the current line
Word deletion reused cross-line word motion destinations. Constrain token traversal and boundary fallbacks to each caret’s current row while preserving cross-line navigation.
This commit is contained in:
+19
-20
@@ -8220,11 +8220,8 @@ impl Editor {
|
||||
.map(|(index, target)| {
|
||||
let cursor = target.active;
|
||||
let end = match action {
|
||||
Action::DeleteWordForward => {
|
||||
self.word_destination(cursor, Action::WordNext, count)
|
||||
}
|
||||
Action::DeleteWordBackward => {
|
||||
self.word_destination(cursor, Action::WordPrevious, count)
|
||||
Action::DeleteWordForward | Action::DeleteWordBackward => {
|
||||
self.word_destination(cursor, action, count)
|
||||
}
|
||||
Action::SubstituteCharacter => Cursor {
|
||||
row: cursor.row,
|
||||
@@ -9313,9 +9310,16 @@ impl Editor {
|
||||
action,
|
||||
Action::BigWordNext | Action::BigWordPrevious | Action::BigWordEnd
|
||||
);
|
||||
let backward = matches!(action, Action::WordPrevious | Action::BigWordPrevious);
|
||||
let start = if backward { 0 } else { row };
|
||||
let end = if backward {
|
||||
let backward = matches!(
|
||||
action,
|
||||
Action::WordPrevious | Action::BigWordPrevious | Action::DeleteWordBackward
|
||||
);
|
||||
let line_local = matches!(
|
||||
action,
|
||||
Action::DeleteWordForward | Action::DeleteWordBackward
|
||||
);
|
||||
let start = if line_local || !backward { row } else { 0 };
|
||||
let end = if line_local || backward {
|
||||
row + 1
|
||||
} else {
|
||||
self.active.lines.len()
|
||||
@@ -9325,17 +9329,12 @@ impl Editor {
|
||||
.map(move |(_, byte, kind)| (source_row, byte, kind))
|
||||
});
|
||||
let destination = match action {
|
||||
Action::WordPrevious | Action::BigWordPrevious => {
|
||||
Action::WordPrevious | Action::BigWordPrevious | Action::DeleteWordBackward => {
|
||||
let mut tokens = tokens
|
||||
.rev()
|
||||
.skip_while(|(r, b, _)| (*r, *b) >= (row, byte))
|
||||
.peekable();
|
||||
let fallback = (
|
||||
self.navigable_rows(0, self.active.lines.len())
|
||||
.next()
|
||||
.unwrap_or(row),
|
||||
0,
|
||||
);
|
||||
let fallback = (self.navigable_rows(start, end).next().unwrap_or(row), 0);
|
||||
let mut destination = fallback;
|
||||
for _ in 0..count {
|
||||
let Some(mut first) = tokens.find(|(_, _, kind)| *kind != WordKind::Whitespace)
|
||||
@@ -9360,13 +9359,13 @@ impl Editor {
|
||||
return cursor;
|
||||
};
|
||||
let mut current = first.2;
|
||||
let last = self
|
||||
.navigable_rows(0, self.active.lines.len())
|
||||
.next_back()
|
||||
.unwrap_or(row);
|
||||
let last = self.navigable_rows(start, end).next_back().unwrap_or(row);
|
||||
let mut destination = (last, self.active.lines[last].len());
|
||||
for _ in 0..count {
|
||||
let next_start = matches!(action, Action::WordNext | Action::BigWordNext);
|
||||
let next_start = matches!(
|
||||
action,
|
||||
Action::WordNext | Action::BigWordNext | Action::DeleteWordForward
|
||||
);
|
||||
if next_start && current != WordKind::EmptyLine {
|
||||
while tokens.peek().is_some_and(|(_, _, kind)| *kind == current) {
|
||||
tokens.next();
|
||||
|
||||
Reference in New Issue
Block a user