From f1ed042c84fedebc1eff91d00c9c58477e912edc Mon Sep 17 00:00:00 2001 From: WindSoilder Date: Wed, 29 Dec 2021 17:21:20 +0800 Subject: [PATCH] Fix: when goto normal mode, only want to remove indentation if the line is blank with no text following (#1349) * when opened new line contains other characters after current position, don't dedent * abstract checking logic --- helix-term/src/commands.rs | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 139e7ceb1..9d7d11eb1 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3776,26 +3776,30 @@ fn normal_mode(cx: &mut Context) { } fn try_restore_indent(doc: &mut Document, view_id: ViewId) { - let doc_changes = doc.changes().changes(); - let text = doc.text().slice(..); - let pos = doc.selection(view_id).primary().cursor(text); - let mut can_restore_indent = false; - - // Removes trailing whitespace if insert mode is exited after starting a blank new line. use helix_core::chars::char_is_whitespace; use helix_core::Operation; - if let [Operation::Retain(move_pos), Operation::Insert(ref inserted_str), Operation::Retain(_)] = - doc_changes - { - if move_pos + inserted_str.len32() as usize == pos - && inserted_str.starts_with('\n') - && inserted_str.chars().skip(1).all(char_is_whitespace) + + fn inserted_a_new_blank_line(changes: &[Operation], pos: usize, line_end_pos: usize) -> bool { + if let [Operation::Retain(move_pos), Operation::Insert(ref inserted_str), Operation::Retain(_)] = + changes { - can_restore_indent = true; + move_pos + inserted_str.len32() as usize == pos + && inserted_str.starts_with('\n') + && inserted_str.chars().skip(1).all(char_is_whitespace) + && pos == line_end_pos // ensure no characters exists after current position + } else { + false } } - if can_restore_indent { + let doc_changes = doc.changes().changes(); + let text = doc.text().slice(..); + let range = doc.selection(view_id).primary(); + let pos = range.cursor(text); + let line_end_pos = line_end_char_index(&text, range.cursor_line(text)); + + if inserted_a_new_blank_line(doc_changes, pos, line_end_pos) { + // Removes tailing whitespaces. let transaction = Transaction::change_by_selection(doc.text(), doc.selection(view_id), |range| { let line_start_pos = text.line_to_char(range.cursor_line(text));