on master help sign in
Reset mode when changing buffers (#5072)

* Reset mode when changing buffers This is similar to the change in e4c9d4082a139aac3aea4506918171b96e81f5b9: reset the editor to normal mode when changing buffers. Usually the editor is already in normal mode but it's possible to setup insert-mode keybindings that change buffers. * Move normal mode entering code to Editor This should be called internally in the Editor when changing documents (Editor::switch) or changing focuses (Editor::focus).

commitcdc54f50a2ceb62c9f1c38b939ca988ff0e96855 authorMichael Davis <mcarsondavis@gmail.com> dateSun 11 Dec 2022, 09:04 (4 years ago) parent70d7812
2 files changed+70−57
helix-term/src/commands.rs+1−56 helix-view/src/editor.rs+69−1
helix-term/src/commands.rs+1−56
@@ -2672,62 +2672,7 @@ fn open_above(cx: &mut Context) {
26722672}
26732673
26742674fn normal_mode(cx: &mut Context) {
2675− if cx.editor.mode == Mode::Normal {
2676− return;
2677− }
2678−
2679− cx.editor.mode = Mode::Normal;
2680− let (view, doc) = current!(cx.editor);
2681−
2682− try_restore_indent(doc, view);
2683−
2684− // if leaving append mode, move cursor back by 1
2685− if doc.restore_cursor {
2686− let text = doc.text().slice(..);
2687− let selection = doc.selection(view.id).clone().transform(|range| {
2688− Range::new(
2689− range.from(),
2690− graphemes::prev_grapheme_boundary(text, range.to()),
2691− )
2692− });
2693−
2694− doc.set_selection(view.id, selection);
2695− doc.restore_cursor = false;
2696− }
2697−}
2698−
2699−fn try_restore_indent(doc: &mut Document, view: &mut View) {
2700− use helix_core::chars::char_is_whitespace;
2701− use helix_core::Operation;
2702−
2703− fn inserted_a_new_blank_line(changes: &[Operation], pos: usize, line_end_pos: usize) -> bool {
2704− if let [Operation::Retain(move_pos), Operation::Insert(ref inserted_str), Operation::Retain(_)] =
2705− changes
2706− {
2707− move_pos + inserted_str.len() == pos
2708− && inserted_str.starts_with('\n')
2709− && inserted_str.chars().skip(1).all(char_is_whitespace)
2710− && pos == line_end_pos // ensure no characters exists after current position
2711− } else {
2712− false
2713− }
2714− }
2715−
2716− let doc_changes = doc.changes().changes();
2717− let text = doc.text().slice(..);
2718− let range = doc.selection(view.id).primary();
2719− let pos = range.cursor(text);
2720− let line_end_pos = line_end_char_index(&text, range.cursor_line(text));
2721−
2722− if inserted_a_new_blank_line(doc_changes, pos, line_end_pos) {
2723− // Removes tailing whitespaces.
2724− let transaction =
2725− Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
2726− let line_start_pos = text.line_to_char(range.cursor_line(text));
2727− (line_start_pos, pos, None)
2728− });
2729− apply_transaction(&transaction, doc, view);
2730− }
2675+ cx.editor.enter_normal_mode();
27312676}
27322677
27332678// Store a jump on the jumplist.
helix-view/src/editor.rs+69−1
@@ -1005,6 +1005,8 @@ impl Editor {
10051005 return;
10061006 }
10071007
1008+ self.enter_normal_mode();
1009+
10081010 match action {
10091011 Action::Replace => {
10101012 let (view, doc) = current_ref!(self);
@@ -1025,6 +1027,9 @@ impl Editor {
10251027 let (view, doc) = current!(self);
10261028 let view_id = view.id;
10271029
1030+ // Append any outstanding changes to history in the old document.
1031+ doc.append_changes_to_history(view);
1032+
10281033 if remove_empty_scratch {
10291034 // Copy `doc.id` into a variable before calling `self.documents.remove`, which requires a mutable
10301035 // borrow, invalidating direct access to `doc.id`.
@@ -1262,7 +1267,7 @@ impl Editor {
12621267 // if leaving the view: mode should reset and the cursor should be
12631268 // within view
12641269 if prev_id != view_id {
1265− self.mode = Mode::Normal;
1270+ self.enter_normal_mode();
12661271 self.ensure_cursor_in_view(view_id);
12671272
12681273 // Update jumplist selections with new document changes.
@@ -1427,4 +1432,67 @@ impl Editor {
14271432
14281433 Ok(())
14291434 }
1435+
1436+ /// Switches the editor into normal mode.
1437+ pub fn enter_normal_mode(&mut self) {
1438+ use helix_core::{graphemes, Range};
1439+
1440+ if self.mode == Mode::Normal {
1441+ return;
1442+ }
1443+
1444+ self.mode = Mode::Normal;
1445+ let (view, doc) = current!(self);
1446+
1447+ try_restore_indent(doc, view);
1448+
1449+ // if leaving append mode, move cursor back by 1
1450+ if doc.restore_cursor {
1451+ let text = doc.text().slice(..);
1452+ let selection = doc.selection(view.id).clone().transform(|range| {
1453+ Range::new(
1454+ range.from(),
1455+ graphemes::prev_grapheme_boundary(text, range.to()),
1456+ )
1457+ });
1458+
1459+ doc.set_selection(view.id, selection);
1460+ doc.restore_cursor = false;
1461+ }
1462+ }
1463+}
1464+
1465+fn try_restore_indent(doc: &mut Document, view: &mut View) {
1466+ use helix_core::{
1467+ chars::char_is_whitespace, line_ending::line_end_char_index, Operation, Transaction,
1468+ };
1469+
1470+ fn inserted_a_new_blank_line(changes: &[Operation], pos: usize, line_end_pos: usize) -> bool {
1471+ if let [Operation::Retain(move_pos), Operation::Insert(ref inserted_str), Operation::Retain(_)] =
1472+ changes
1473+ {
1474+ move_pos + inserted_str.len() == pos
1475+ && inserted_str.starts_with('\n')
1476+ && inserted_str.chars().skip(1).all(char_is_whitespace)
1477+ && pos == line_end_pos // ensure no characters exists after current position
1478+ } else {
1479+ false
1480+ }
1481+ }
1482+
1483+ let doc_changes = doc.changes().changes();
1484+ let text = doc.text().slice(..);
1485+ let range = doc.selection(view.id).primary();
1486+ let pos = range.cursor(text);
1487+ let line_end_pos = line_end_char_index(&text, range.cursor_line(text));
1488+
1489+ if inserted_a_new_blank_line(doc_changes, pos, line_end_pos) {
1490+ // Removes tailing whitespaces.
1491+ let transaction =
1492+ Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
1493+ let line_start_pos = text.line_to_char(range.cursor_line(text));
1494+ (line_start_pos, pos, None)
1495+ });
1496+ crate::apply_transaction(&transaction, doc, view);
1497+ }
14301498}