on master help sign in
Make mode editor-wide rather than per-document
5c2b77bBlaž Hrastnik
helix-term/src/commands.rs+32−36
@@ -586,7 +586,7 @@ fn goto_line_end(cx: &mut Context) {
586 goto_line_end_impl(
586 goto_line_end_impl(
587 view,
587 view,
588 doc,
588 doc,
589− if doc.mode == Mode::Select {
589+ if cx.editor.mode == Mode::Select {
590 Movement::Extend
590 Movement::Extend
591 } else {
591 } else {
592 Movement::Move
592 Movement::Move
@@ -616,7 +616,7 @@ fn goto_line_end_newline(cx: &mut Context) {
616 goto_line_end_newline_impl(
616 goto_line_end_newline_impl(
617 view,
617 view,
618 doc,
618 doc,
619− if doc.mode == Mode::Select {
619+ if cx.editor.mode == Mode::Select {
620 Movement::Extend
620 Movement::Extend
621 } else {
621 } else {
622 Movement::Move
622 Movement::Move
@@ -647,7 +647,7 @@ fn goto_line_start(cx: &mut Context) {
647 goto_line_start_impl(
647 goto_line_start_impl(
648 view,
648 view,
649 doc,
649 doc,
650− if doc.mode == Mode::Select {
650+ if cx.editor.mode == Mode::Select {
651 Movement::Extend
651 Movement::Extend
652 } else {
652 } else {
653 Movement::Move
653 Movement::Move
@@ -752,7 +752,7 @@ fn goto_first_nonwhitespace(cx: &mut Context) {
752
752
753 if let Some(pos) = find_first_non_whitespace_char(text.line(line)) {
753 if let Some(pos) = find_first_non_whitespace_char(text.line(line)) {
754 let pos = pos + text.line_to_char(line);
754 let pos = pos + text.line_to_char(line);
755− range.put_cursor(text, pos, doc.mode == Mode::Select)
755+ range.put_cursor(text, pos, cx.editor.mode == Mode::Select)
756 } else {
756 } else {
757 range
757 range
758 }
758 }
@@ -952,7 +952,7 @@ where
952 let motion = move |editor: &mut Editor| {
952 let motion = move |editor: &mut Editor| {
953 let (view, doc) = current!(editor);
953 let (view, doc) = current!(editor);
954 let text = doc.text().slice(..);
954 let text = doc.text().slice(..);
955− let behavior = if doc.mode == Mode::Select {
955+ let behavior = if editor.mode == Mode::Select {
956 Movement::Extend
956 Movement::Extend
957 } else {
957 } else {
958 Movement::Move
958 Movement::Move
@@ -985,7 +985,7 @@ fn goto_file_start(cx: &mut Context) {
985 let selection = doc
985 let selection = doc
986 .selection(view.id)
986 .selection(view.id)
987 .clone()
987 .clone()
988− .transform(|range| range.put_cursor(text, 0, doc.mode == Mode::Select));
988+ .transform(|range| range.put_cursor(text, 0, cx.editor.mode == Mode::Select));
989 push_jump(view, doc);
989 push_jump(view, doc);
990 doc.set_selection(view.id, selection);
990 doc.set_selection(view.id, selection);
991 }
991 }
@@ -998,7 +998,7 @@ fn goto_file_end(cx: &mut Context) {
998 let selection = doc
998 let selection = doc
999 .selection(view.id)
999 .selection(view.id)
1000 .clone()
1000 .clone()
1001− .transform(|range| range.put_cursor(text, pos, doc.mode == Mode::Select));
1001+ .transform(|range| range.put_cursor(text, pos, cx.editor.mode == Mode::Select));
1002 push_jump(view, doc);
1002 push_jump(view, doc);
1003 doc.set_selection(view.id, selection);
1003 doc.set_selection(view.id, selection);
1004}
1004}
@@ -1375,7 +1375,7 @@ pub fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
1375 if line != cursor.row {
1375 if line != cursor.row {
1376 let head = pos_at_coords(text, Position::new(line, cursor.col), true); // this func will properly truncate to line end
1376 let head = pos_at_coords(text, Position::new(line, cursor.col), true); // this func will properly truncate to line end
1377
1377
1378− let anchor = if doc.mode == Mode::Select {
1378+ let anchor = if cx.editor.mode == Mode::Select {
1379 range.anchor
1379 range.anchor
1380 } else {
1380 } else {
1381 head
1381 head
@@ -2098,7 +2098,7 @@ fn delete_selection_impl(cx: &mut Context, op: Operation) {
2098 exit_select_mode(cx);
2098 exit_select_mode(cx);
2099 }
2099 }
2100 Operation::Change => {
2100 Operation::Change => {
2101− enter_insert_mode(doc);
2101+ enter_insert_mode(cx);
2102 }
2102 }
2103 }
2103 }
2104}
2104}
@@ -2167,14 +2167,14 @@ fn ensure_selections_forward(cx: &mut Context) {
2167 doc.set_selection(view.id, selection);
2167 doc.set_selection(view.id, selection);
2168}
2168}
2169
2169
2170−fn enter_insert_mode(doc: &mut Document) {
2170+fn enter_insert_mode(cx: &mut Context) {
2171− doc.mode = Mode::Insert;
2171+ cx.editor.mode = Mode::Insert;
2172}
2172}
2173
2173
2174// inserts at the start of each selection
2174// inserts at the start of each selection
2175fn insert_mode(cx: &mut Context) {
2175fn insert_mode(cx: &mut Context) {
2176+ enter_insert_mode(cx);
2176 let (view, doc) = current!(cx.editor);
2177 let (view, doc) = current!(cx.editor);
2177− enter_insert_mode(doc);
2178
2178
2179 log::trace!(
2179 log::trace!(
2180 "entering insert mode with sel: {:?}, text: {:?}",
2180 "entering insert mode with sel: {:?}, text: {:?}",
@@ -2192,8 +2192,8 @@ fn insert_mode(cx: &mut Context) {
2192
2192
2193// inserts at the end of each selection
2193// inserts at the end of each selection
2194fn append_mode(cx: &mut Context) {
2194fn append_mode(cx: &mut Context) {
2195+ enter_insert_mode(cx);
2195 let (view, doc) = current!(cx.editor);
2196 let (view, doc) = current!(cx.editor);
2196− enter_insert_mode(doc);
2197 doc.restore_cursor = true;
2197 doc.restore_cursor = true;
2198 let text = doc.text().slice(..);
2198 let text = doc.text().slice(..);
2199
2199
@@ -2421,9 +2421,9 @@ impl ui::menu::Item for MappableCommand {
2421pub fn command_palette(cx: &mut Context) {
2421pub fn command_palette(cx: &mut Context) {
2422 cx.callback = Some(Box::new(
2422 cx.callback = Some(Box::new(
2423 move |compositor: &mut Compositor, cx: &mut compositor::Context| {
2423 move |compositor: &mut Compositor, cx: &mut compositor::Context| {
2424− let doc = doc_mut!(cx.editor);
2425− let keymap =
2426− compositor.find::<ui::EditorView>().unwrap().keymaps.map()[&doc.mode].reverse_map();
2424+ let keymap = compositor.find::<ui::EditorView>().unwrap().keymaps.map()
2425+ [&cx.editor.mode]
2426+ .reverse_map();
2427
2427
2428 let mut commands: Vec<MappableCommand> = MappableCommand::STATIC_COMMAND_LIST.into();
2428 let mut commands: Vec<MappableCommand> = MappableCommand::STATIC_COMMAND_LIST.into();
2429 commands.extend(typed::TYPABLE_COMMAND_LIST.iter().map(|cmd| {
2429 commands.extend(typed::TYPABLE_COMMAND_LIST.iter().map(|cmd| {
@@ -2464,14 +2464,13 @@ fn last_picker(cx: &mut Context) {
2464// I inserts at the first nonwhitespace character of each line with a selection
2464// I inserts at the first nonwhitespace character of each line with a selection
2465fn prepend_to_line(cx: &mut Context) {
2465fn prepend_to_line(cx: &mut Context) {
2466 goto_first_nonwhitespace(cx);
2466 goto_first_nonwhitespace(cx);
2467− let doc = doc_mut!(cx.editor);
2468− enter_insert_mode(doc);
2467+ enter_insert_mode(cx);
2469}
2468}
2470
2469
2471// A inserts at the end of each line with a selection
2470// A inserts at the end of each line with a selection
2472fn append_to_line(cx: &mut Context) {
2471fn append_to_line(cx: &mut Context) {
2472+ enter_insert_mode(cx);
2473 let (view, doc) = current!(cx.editor);
2473 let (view, doc) = current!(cx.editor);
2474− enter_insert_mode(doc);
2475
2474
2476 let selection = doc.selection(view.id).clone().transform(|range| {
2475 let selection = doc.selection(view.id).clone().transform(|range| {
2477 let text = doc.text().slice(..);
2476 let text = doc.text().slice(..);
@@ -2527,8 +2526,8 @@ pub enum Open {
2527
2526
2528fn open(cx: &mut Context, open: Open) {
2527fn open(cx: &mut Context, open: Open) {
2529 let count = cx.count();
2528 let count = cx.count();
2529+ enter_insert_mode(cx);
2530 let (view, doc) = current!(cx.editor);
2530 let (view, doc) = current!(cx.editor);
2531− enter_insert_mode(doc);
2532
2531
2533 let text = doc.text().slice(..);
2532 let text = doc.text().slice(..);
2534 let contents = doc.text();
2533 let contents = doc.text();
@@ -2606,13 +2605,12 @@ fn open_above(cx: &mut Context) {
2606}
2605}
2607
2606
2608fn normal_mode(cx: &mut Context) {
2607fn normal_mode(cx: &mut Context) {
2609− let (view, doc) = current!(cx.editor);
2610−
2611− if doc.mode == Mode::Normal {
2608+ if cx.editor.mode == Mode::Normal {
2612 return;
2609 return;
2613 }
2610 }
2614
2611
2615− doc.mode = Mode::Normal;
2612+ cx.editor.mode = Mode::Normal;
2613+ let (view, doc) = current!(cx.editor);
2616
2614
2617 try_restore_indent(doc, view.id);
2615 try_restore_indent(doc, view.id);
2618
2616
@@ -2690,7 +2688,7 @@ fn goto_line_impl(editor: &mut Editor, count: Option<NonZeroUsize>) {
2690 let selection = doc
2688 let selection = doc
2691 .selection(view.id)
2689 .selection(view.id)
2692 .clone()
2690 .clone()
2693− .transform(|range| range.put_cursor(text, pos, doc.mode == Mode::Select));
2691+ .transform(|range| range.put_cursor(text, pos, editor.mode == Mode::Select));
2694
2692
2695 push_jump(view, doc);
2693 push_jump(view, doc);
2696 doc.set_selection(view.id, selection);
2694 doc.set_selection(view.id, selection);
@@ -2710,7 +2708,7 @@ fn goto_last_line(cx: &mut Context) {
2710 let selection = doc
2708 let selection = doc
2711 .selection(view.id)
2709 .selection(view.id)
2712 .clone()
2710 .clone()
2713− .transform(|range| range.put_cursor(text, pos, doc.mode == Mode::Select));
2711+ .transform(|range| range.put_cursor(text, pos, cx.editor.mode == Mode::Select));
2714
2712
2715 push_jump(view, doc);
2713 push_jump(view, doc);
2716 doc.set_selection(view.id, selection);
2714 doc.set_selection(view.id, selection);
@@ -2733,7 +2731,7 @@ fn goto_last_modification(cx: &mut Context) {
2733 let selection = doc
2731 let selection = doc
2734 .selection(view.id)
2732 .selection(view.id)
2735 .clone()
2733 .clone()
2736− .transform(|range| range.put_cursor(text, pos, doc.mode == Mode::Select));
2734+ .transform(|range| range.put_cursor(text, pos, cx.editor.mode == Mode::Select));
2737 doc.set_selection(view.id, selection);
2735 doc.set_selection(view.id, selection);
2738 }
2736 }
2739}
2737}
@@ -2770,13 +2768,12 @@ fn select_mode(cx: &mut Context) {
2770 });
2768 });
2771 doc.set_selection(view.id, selection);
2769 doc.set_selection(view.id, selection);
2772
2770
2773− doc_mut!(cx.editor).mode = Mode::Select;
2771+ cx.editor.mode = Mode::Select;
2774}
2772}
2775
2773
2776fn exit_select_mode(cx: &mut Context) {
2774fn exit_select_mode(cx: &mut Context) {
2777− let doc = doc_mut!(cx.editor);
2778− if doc.mode == Mode::Select {
2775+ if cx.editor.mode == Mode::Select {
2779− doc.mode = Mode::Normal;
2776+ cx.editor.mode = Mode::Normal;
2780 }
2777 }
2781}
2778}
2782
2779
@@ -3439,11 +3436,11 @@ fn paste_impl(values: &[String], doc: &mut Document, view: &View, action: Paste,
3439
3436
3440pub(crate) fn paste_bracketed_value(cx: &mut Context, contents: String) {
3437pub(crate) fn paste_bracketed_value(cx: &mut Context, contents: String) {
3441 let count = cx.count();
3438 let count = cx.count();
3442− let (view, doc) = current!(cx.editor);
3443− let paste = match doc.mode {
3439+ let paste = match cx.editor.mode {
3444 Mode::Insert | Mode::Select => Paste::Cursor,
3440 Mode::Insert | Mode::Select => Paste::Cursor,
3445 Mode::Normal => Paste::Before,
3441 Mode::Normal => Paste::Before,
3446 };
3442 };
3443+ let (view, doc) = current!(cx.editor);
3447 paste_impl(&[contents], doc, view, paste, count);
3444 paste_impl(&[contents], doc, view, paste, count);
3448}
3445}
3449
3446
@@ -3838,8 +3835,7 @@ pub fn completion(cx: &mut Context) {
3838 cx.callback(
3835 cx.callback(
3839 future,
3836 future,
3840 move |editor, compositor, response: Option<lsp::CompletionResponse>| {
3837 move |editor, compositor, response: Option<lsp::CompletionResponse>| {
3841− let doc = doc!(editor);
3842− if doc.mode() != Mode::Insert {
3838+ if editor.mode != Mode::Insert {
3843 // we're not in insert mode anymore
3839 // we're not in insert mode anymore
3844 return;
3840 return;
3845 }
3841 }
@@ -4046,7 +4042,7 @@ fn match_brackets(cx: &mut Context) {
4046 if let Some(pos) =
4042 if let Some(pos) =
4047 match_brackets::find_matching_bracket_fuzzy(syntax, doc.text(), range.cursor(text))
4043 match_brackets::find_matching_bracket_fuzzy(syntax, doc.text(), range.cursor(text))
4048 {
4044 {
4049− range.put_cursor(text, pos, doc.mode == Mode::Select)
4045+ range.put_cursor(text, pos, cx.editor.mode == Mode::Select)
4050 } else {
4046 } else {
4051 range
4047 range
4052 }
4048 }
helix-term/src/ui/editor.rs+16−16
@@ -122,7 +122,13 @@ impl EditorView {
122 let highlights: Box<dyn Iterator<Item = HighlightEvent>> = if is_focused {
122 let highlights: Box<dyn Iterator<Item = HighlightEvent>> = if is_focused {
123 Box::new(syntax::merge(
123 Box::new(syntax::merge(
124 highlights,
124 highlights,
125− Self::doc_selection_highlights(doc, view, theme, &editor.config().cursor_shape),
125+ Self::doc_selection_highlights(
126+ editor.mode(),
127+ doc,
128+ view,
129+ theme,
130+ &editor.config().cursor_shape,
131+ ),
126 ))
132 ))
127 } else {
133 } else {
128 Box::new(highlights)
134 Box::new(highlights)
@@ -297,6 +303,7 @@ impl EditorView {
297
303
298 /// Get highlight spans for selections in a document view.
304 /// Get highlight spans for selections in a document view.
299 pub fn doc_selection_highlights(
305 pub fn doc_selection_highlights(
306+ mode: Mode,
300 doc: &Document,
307 doc: &Document,
301 view: &View,
308 view: &View,
302 theme: &Theme,
309 theme: &Theme,
@@ -306,7 +313,6 @@ impl EditorView {
306 let selection = doc.selection(view.id);
313 let selection = doc.selection(view.id);
307 let primary_idx = selection.primary_index();
314 let primary_idx = selection.primary_index();
308
315
309− let mode = doc.mode();
310 let cursorkind = cursor_shape_config.from_mode(mode);
316 let cursorkind = cursor_shape_config.from_mode(mode);
311 let cursor_is_block = cursorkind == CursorKind::Block;
317 let cursor_is_block = cursorkind == CursorKind::Block;
312
318
@@ -775,17 +781,9 @@ impl EditorView {
775 let key_result = self.keymaps.get(mode, event);
781 let key_result = self.keymaps.get(mode, event);
776 cxt.editor.autoinfo = self.keymaps.sticky().map(|node| node.infobox());
782 cxt.editor.autoinfo = self.keymaps.sticky().map(|node| node.infobox());
777
783
778− // Track the currently open doc
779− let view = view!(cxt.editor);
780− let doc_id = view.doc;
781−
782 let mut execute_command = |command: &commands::MappableCommand| {
784 let mut execute_command = |command: &commands::MappableCommand| {
783 command.execute(cxt);
785 command.execute(cxt);
784− let doc = match cxt.editor.documents.get(&doc_id) {
786+ let current_mode = cxt.editor.mode();
785− Some(doc) => doc,
786− None => return,
787− };
788− let current_mode = doc.mode();
789 match (last_mode, current_mode) {
787 match (last_mode, current_mode) {
790 (Mode::Normal, Mode::Insert) => {
788 (Mode::Normal, Mode::Insert) => {
791 // HAXX: if we just entered insert mode from normal, clear key buf
789 // HAXX: if we just entered insert mode from normal, clear key buf
@@ -956,8 +954,8 @@ impl EditorView {
956
954
957 pub fn handle_idle_timeout(&mut self, cx: &mut crate::compositor::Context) -> EventResult {
955 pub fn handle_idle_timeout(&mut self, cx: &mut crate::compositor::Context) -> EventResult {
958 if self.completion.is_some()
956 if self.completion.is_some()
957+ || cx.editor.mode != Mode::Insert
959 || !cx.editor.config().auto_completion
958 || !cx.editor.config().auto_completion
960− || doc!(cx.editor).mode != Mode::Insert
961 {
959 {
962 return EventResult::Ignored(None);
960 return EventResult::Ignored(None);
963 }
961 }
@@ -1177,12 +1175,13 @@ impl Component for EditorView {
1177 cx.editor.count = None;
1175 cx.editor.count = None;
1178
1176
1179 let config = cx.editor.config();
1177 let config = cx.editor.config();
1178+ let mode = cx.editor.mode();
1180 let (view, doc) = current!(cx.editor);
1179 let (view, doc) = current!(cx.editor);
1181 view.ensure_cursor_in_view(doc, config.scrolloff);
1180 view.ensure_cursor_in_view(doc, config.scrolloff);
1182
1181
1183 // Store a history state if not in insert mode. Otherwise wait till we exit insert
1182 // Store a history state if not in insert mode. Otherwise wait till we exit insert
1184 // to include any edits to the paste in the history state.
1183 // to include any edits to the paste in the history state.
1185− if doc.mode() != Mode::Insert {
1184+ if mode != Mode::Insert {
1186 doc.append_changes_to_history(view.id);
1185 doc.append_changes_to_history(view.id);
1187 }
1186 }
1188
1187
@@ -1200,9 +1199,9 @@ impl Component for EditorView {
1200 // clear status
1199 // clear status
1201 cx.editor.status_msg = None;
1200 cx.editor.status_msg = None;
1202
1201
1202+ let mode = cx.editor.mode();
1203− let (view, doc) = current!(cx.editor);
1203+ let (view, _) = current!(cx.editor);
1204 let focus = view.id;
1204 let focus = view.id;
1205− let mode = doc.mode();
1206
1205
1207 if let Some(on_next_key) = self.on_next_key.take() {
1206 if let Some(on_next_key) = self.on_next_key.take() {
1208 // if there's a command waiting input, do that first
1207 // if there's a command waiting input, do that first
@@ -1265,6 +1264,7 @@ impl Component for EditorView {
1265 return EventResult::Ignored(None);
1264 return EventResult::Ignored(None);
1266 }
1265 }
1267 let config = cx.editor.config();
1266 let config = cx.editor.config();
1267+ let mode = cx.editor.mode();
1268 let view = cx.editor.tree.get_mut(focus);
1268 let view = cx.editor.tree.get_mut(focus);
1269 let doc = cx.editor.documents.get_mut(&view.doc).unwrap();
1269 let doc = cx.editor.documents.get_mut(&view.doc).unwrap();
1270
1270
@@ -1272,7 +1272,7 @@ impl Component for EditorView {
1272
1272
1273 // Store a history state if not in insert mode. This also takes care of
1273 // Store a history state if not in insert mode. This also takes care of
1274 // committing changes when leaving insert mode.
1274 // committing changes when leaving insert mode.
1275− if doc.mode() != Mode::Insert {
1275+ if mode != Mode::Insert {
1276 doc.append_changes_to_history(view.id);
1276 doc.append_changes_to_history(view.id);
1277 }
1277 }
1278
1278
helix-term/src/ui/statusline.rs+2−2
@@ -160,7 +160,7 @@ where
160 format!(
160 format!(
161 " {} ",
161 " {} ",
162 if visible {
162 if visible {
163− match context.doc.mode() {
163+ match context.editor.mode() {
164 Mode::Insert => "INS",
164 Mode::Insert => "INS",
165 Mode::Select => "SEL",
165 Mode::Select => "SEL",
166 Mode::Normal => "NOR",
166 Mode::Normal => "NOR",
@@ -171,7 +171,7 @@ where
171 }
171 }
172 ),
172 ),
173 if visible && context.editor.config().color_modes {
173 if visible && context.editor.config().color_modes {
174− match context.doc.mode() {
174+ match context.editor.mode() {
175 Mode::Insert => Some(context.editor.theme.get("ui.statusline.insert")),
175 Mode::Insert => Some(context.editor.theme.get("ui.statusline.insert")),
176 Mode::Select => Some(context.editor.theme.get("ui.statusline.select")),
176 Mode::Select => Some(context.editor.theme.get("ui.statusline.select")),
177 Mode::Normal => Some(context.editor.theme.get("ui.statusline.normal")),
177 Mode::Normal => Some(context.editor.theme.get("ui.statusline.normal")),
helix-view/src/document.rs−9
@@ -90,8 +90,6 @@ pub struct Document {
90 path: Option<PathBuf>,
90 path: Option<PathBuf>,
91 encoding: &'static encoding::Encoding,
91 encoding: &'static encoding::Encoding,
92
92
93− /// Current editing mode.
94− pub mode: Mode,
95 pub restore_cursor: bool,
93 pub restore_cursor: bool,
96
94
97 /// Current indent style.
95 /// Current indent style.
@@ -133,7 +131,6 @@ impl fmt::Debug for Document {
133 .field("selections", &self.selections)
131 .field("selections", &self.selections)
134 .field("path", &self.path)
132 .field("path", &self.path)
135 .field("encoding", &self.encoding)
133 .field("encoding", &self.encoding)
136− .field("mode", &self.mode)
137 .field("restore_cursor", &self.restore_cursor)
134 .field("restore_cursor", &self.restore_cursor)
138 .field("syntax", &self.syntax)
135 .field("syntax", &self.syntax)
139 .field("language", &self.language)
136 .field("language", &self.language)
@@ -349,7 +346,6 @@ impl Document {
349 selections: HashMap::default(),
346 selections: HashMap::default(),
350 indent_style: DEFAULT_INDENT,
347 indent_style: DEFAULT_INDENT,
351 line_ending: DEFAULT_LINE_ENDING,
348 line_ending: DEFAULT_LINE_ENDING,
352− mode: Mode::Normal,
353 restore_cursor: false,
349 restore_cursor: false,
354 syntax: None,
350 syntax: None,
355 language: None,
351 language: None,
@@ -925,11 +921,6 @@ impl Document {
925 self.last_saved_revision = current_revision;
921 self.last_saved_revision = current_revision;
926 }
922 }
927
923
928− /// Current editing mode for the [`Document`].
929− pub fn mode(&self) -> Mode {
930− self.mode
931− }
932−
933 /// Corresponding language scope name. Usually `source.<lang>`.
924 /// Corresponding language scope name. Usually `source.<lang>`.
934 pub fn language_scope(&self) -> Option<&str> {
925 pub fn language_scope(&self) -> Option<&str> {
935 self.language
926 self.language
helix-view/src/editor.rs+11−5
@@ -595,6 +595,8 @@ pub struct Breakpoint {
595}
595}
596
596
597pub struct Editor {
597pub struct Editor {
598+ /// Current editing mode.
599+ pub mode: Mode,
598 pub tree: Tree,
600 pub tree: Tree,
599 pub next_document_id: DocumentId,
601 pub next_document_id: DocumentId,
600 pub documents: BTreeMap<DocumentId, Document>,
602 pub documents: BTreeMap<DocumentId, Document>,
@@ -677,6 +679,7 @@ impl Editor {
677 area.height -= 1;
679 area.height -= 1;
678
680
679 Self {
681 Self {
682+ mode: Mode::Normal,
680 tree: Tree::new(area),
683 tree: Tree::new(area),
681 next_document_id: DocumentId::default(),
684 next_document_id: DocumentId::default(),
682 documents: BTreeMap::new(),
685 documents: BTreeMap::new(),
@@ -708,6 +711,11 @@ impl Editor {
708 }
711 }
709 }
712 }
710
713
714+ /// Current editing mode for the [`Editor`].
715+ pub fn mode(&self) -> Mode {
716+ self.mode
717+ }
718+
711 pub fn config(&self) -> DynGuard<Config> {
719 pub fn config(&self) -> DynGuard<Config> {
712 self.config.load()
720 self.config.load()
713 }
721 }
@@ -1103,8 +1111,7 @@ impl Editor {
1103
1111
1104 // if leaving the view: mode should reset
1112 // if leaving the view: mode should reset
1105 if prev_id != view_id {
1113 if prev_id != view_id {
1106− let doc_id = self.tree.get(prev_id).doc;
1107− self.documents.get_mut(&doc_id).unwrap().mode = Mode::Normal;
1114+ self.mode = Mode::Normal;
1108 }
1115 }
1109 }
1116 }
1110
1117
@@ -1115,8 +1122,7 @@ impl Editor {
1115
1122
1116 // if leaving the view: mode should reset
1123 // if leaving the view: mode should reset
1117 if prev_id != id {
1124 if prev_id != id {
1118− let doc_id = self.tree.get(prev_id).doc;
1119− self.documents.get_mut(&doc_id).unwrap().mode = Mode::Normal;
1125+ self.mode = Mode::Normal;
1120 }
1126 }
1121 }
1127 }
1122
1128
@@ -1187,7 +1193,7 @@ impl Editor {
1187 let inner = view.inner_area();
1193 let inner = view.inner_area();
1188 pos.col += inner.x as usize;
1194 pos.col += inner.x as usize;
1189 pos.row += inner.y as usize;
1195 pos.row += inner.y as usize;
1190− let cursorkind = config.cursor_shape.from_mode(doc.mode());
1196+ let cursorkind = config.cursor_shape.from_mode(self.mode);
1191 (Some(pos), cursorkind)
1197 (Some(pos), cursorkind)
1192 } else {
1198 } else {
1193 (None, CursorKind::default())
1199 (None, CursorKind::default())
helix-view/src/gutter.rs+1−1
@@ -72,7 +72,7 @@ pub fn line_numbers<'doc>(
72 .char_to_line(doc.selection(view.id).primary().cursor(text));
72 .char_to_line(doc.selection(view.id).primary().cursor(text));
73
73
74 let line_number = editor.config().line_number;
74 let line_number = editor.config().line_number;
75− let mode = doc.mode;
75+ let mode = editor.mode;
76
76
77 Box::new(move |line: usize, selected: bool, out: &mut String| {
77 Box::new(move |line: usize, selected: bool, out: &mut String| {
78 if line == last_line && !draw_last {
78 if line == last_line && !draw_last {