on master help sign in
Make mode editor-wide rather than per-document
commit5c2b77b41fadd0e65e02455d36d8509f622bc520 authorBlaž Hrastnik <blaz@mxxn.io> dateThu 1 Sep 2022, 16:14 (4 years ago) parent10d9355
6 files changed+62−69
helix-term/src/commands.rs+32−36 helix-term/src/ui/editor.rs+16−16 helix-term/src/ui/statusline.rs+2−2 helix-view/src/document.rs−9 helix-view/src/editor.rs+11−5 helix-view/src/gutter.rs+1−1
helix-term/src/commands.rs+32−36
@@ -586,7 +586,7 @@ fn goto_line_end(cx: &mut Context) {
586586 goto_line_end_impl(
587587 view,
588588 doc,
589− if doc.mode == Mode::Select {
589+ if cx.editor.mode == Mode::Select {
590590 Movement::Extend
591591 } else {
592592 Movement::Move
@@ -616,7 +616,7 @@ fn goto_line_end_newline(cx: &mut Context) {
616616 goto_line_end_newline_impl(
617617 view,
618618 doc,
619− if doc.mode == Mode::Select {
619+ if cx.editor.mode == Mode::Select {
620620 Movement::Extend
621621 } else {
622622 Movement::Move
@@ -647,7 +647,7 @@ fn goto_line_start(cx: &mut Context) {
647647 goto_line_start_impl(
648648 view,
649649 doc,
650− if doc.mode == Mode::Select {
650+ if cx.editor.mode == Mode::Select {
651651 Movement::Extend
652652 } else {
653653 Movement::Move
@@ -752,7 +752,7 @@ fn goto_first_nonwhitespace(cx: &mut Context) {
752752
753753 if let Some(pos) = find_first_non_whitespace_char(text.line(line)) {
754754 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)
756756 } else {
757757 range
758758 }
@@ -952,7 +952,7 @@ where
952952 let motion = move |editor: &mut Editor| {
953953 let (view, doc) = current!(editor);
954954 let text = doc.text().slice(..);
955− let behavior = if doc.mode == Mode::Select {
955+ let behavior = if editor.mode == Mode::Select {
956956 Movement::Extend
957957 } else {
958958 Movement::Move
@@ -985,7 +985,7 @@ fn goto_file_start(cx: &mut Context) {
985985 let selection = doc
986986 .selection(view.id)
987987 .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));
989989 push_jump(view, doc);
990990 doc.set_selection(view.id, selection);
991991 }
@@ -998,7 +998,7 @@ fn goto_file_end(cx: &mut Context) {
998998 let selection = doc
999999 .selection(view.id)
10001000 .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));
10021002 push_jump(view, doc);
10031003 doc.set_selection(view.id, selection);
10041004}
@@ -1375,7 +1375,7 @@ pub fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
13751375 if line != cursor.row {
13761376 let head = pos_at_coords(text, Position::new(line, cursor.col), true); // this func will properly truncate to line end
13771377
1378− let anchor = if doc.mode == Mode::Select {
1378+ let anchor = if cx.editor.mode == Mode::Select {
13791379 range.anchor
13801380 } else {
13811381 head
@@ -2098,7 +2098,7 @@ fn delete_selection_impl(cx: &mut Context, op: Operation) {
20982098 exit_select_mode(cx);
20992099 }
21002100 Operation::Change => {
2101− enter_insert_mode(doc);
2101+ enter_insert_mode(cx);
21022102 }
21032103 }
21042104}
@@ -2167,14 +2167,14 @@ fn ensure_selections_forward(cx: &mut Context) {
21672167 doc.set_selection(view.id, selection);
21682168}
21692169
2170−fn enter_insert_mode(doc: &mut Document) {
2171− doc.mode = Mode::Insert;
2170+fn enter_insert_mode(cx: &mut Context) {
2171+ cx.editor.mode = Mode::Insert;
21722172}
21732173
21742174// inserts at the start of each selection
21752175fn insert_mode(cx: &mut Context) {
2176+ enter_insert_mode(cx);
21762177 let (view, doc) = current!(cx.editor);
2177− enter_insert_mode(doc);
21782178
21792179 log::trace!(
21802180 "entering insert mode with sel: {:?}, text: {:?}",
@@ -2192,8 +2192,8 @@ fn insert_mode(cx: &mut Context) {
21922192
21932193// inserts at the end of each selection
21942194fn append_mode(cx: &mut Context) {
2195+ enter_insert_mode(cx);
21952196 let (view, doc) = current!(cx.editor);
2196− enter_insert_mode(doc);
21972197 doc.restore_cursor = true;
21982198 let text = doc.text().slice(..);
21992199
@@ -2421,9 +2421,9 @@ impl ui::menu::Item for MappableCommand {
24212421pub fn command_palette(cx: &mut Context) {
24222422 cx.callback = Some(Box::new(
24232423 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();
24272427
24282428 let mut commands: Vec<MappableCommand> = MappableCommand::STATIC_COMMAND_LIST.into();
24292429 commands.extend(typed::TYPABLE_COMMAND_LIST.iter().map(|cmd| {
@@ -2464,14 +2464,13 @@ fn last_picker(cx: &mut Context) {
24642464// I inserts at the first nonwhitespace character of each line with a selection
24652465fn prepend_to_line(cx: &mut Context) {
24662466 goto_first_nonwhitespace(cx);
2467− let doc = doc_mut!(cx.editor);
2468− enter_insert_mode(doc);
2467+ enter_insert_mode(cx);
24692468}
24702469
24712470// A inserts at the end of each line with a selection
24722471fn append_to_line(cx: &mut Context) {
2472+ enter_insert_mode(cx);
24732473 let (view, doc) = current!(cx.editor);
2474− enter_insert_mode(doc);
24752474
24762475 let selection = doc.selection(view.id).clone().transform(|range| {
24772476 let text = doc.text().slice(..);
@@ -2527,8 +2526,8 @@ pub enum Open {
25272526
25282527fn open(cx: &mut Context, open: Open) {
25292528 let count = cx.count();
2529+ enter_insert_mode(cx);
25302530 let (view, doc) = current!(cx.editor);
2531− enter_insert_mode(doc);
25322531
25332532 let text = doc.text().slice(..);
25342533 let contents = doc.text();
@@ -2606,13 +2605,12 @@ fn open_above(cx: &mut Context) {
26062605}
26072606
26082607fn 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 {
26122609 return;
26132610 }
26142611
2615− doc.mode = Mode::Normal;
2612+ cx.editor.mode = Mode::Normal;
2613+ let (view, doc) = current!(cx.editor);
26162614
26172615 try_restore_indent(doc, view.id);
26182616
@@ -2690,7 +2688,7 @@ fn goto_line_impl(editor: &mut Editor, count: Option<NonZeroUsize>) {
26902688 let selection = doc
26912689 .selection(view.id)
26922690 .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));
26942692
26952693 push_jump(view, doc);
26962694 doc.set_selection(view.id, selection);
@@ -2710,7 +2708,7 @@ fn goto_last_line(cx: &mut Context) {
27102708 let selection = doc
27112709 .selection(view.id)
27122710 .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));
27142712
27152713 push_jump(view, doc);
27162714 doc.set_selection(view.id, selection);
@@ -2733,7 +2731,7 @@ fn goto_last_modification(cx: &mut Context) {
27332731 let selection = doc
27342732 .selection(view.id)
27352733 .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));
27372735 doc.set_selection(view.id, selection);
27382736 }
27392737}
@@ -2770,13 +2768,12 @@ fn select_mode(cx: &mut Context) {
27702768 });
27712769 doc.set_selection(view.id, selection);
27722770
2773− doc_mut!(cx.editor).mode = Mode::Select;
2771+ cx.editor.mode = Mode::Select;
27742772}
27752773
27762774fn exit_select_mode(cx: &mut Context) {
2777− let doc = doc_mut!(cx.editor);
2778− if doc.mode == Mode::Select {
2779− doc.mode = Mode::Normal;
2775+ if cx.editor.mode == Mode::Select {
2776+ cx.editor.mode = Mode::Normal;
27802777 }
27812778}
27822779
@@ -3439,11 +3436,11 @@ fn paste_impl(values: &[String], doc: &mut Document, view: &View, action: Paste,
34393436
34403437pub(crate) fn paste_bracketed_value(cx: &mut Context, contents: String) {
34413438 let count = cx.count();
3442− let (view, doc) = current!(cx.editor);
3443− let paste = match doc.mode {
3439+ let paste = match cx.editor.mode {
34443440 Mode::Insert | Mode::Select => Paste::Cursor,
34453441 Mode::Normal => Paste::Before,
34463442 };
3443+ let (view, doc) = current!(cx.editor);
34473444 paste_impl(&[contents], doc, view, paste, count);
34483445}
34493446
@@ -3838,8 +3835,7 @@ pub fn completion(cx: &mut Context) {
38383835 cx.callback(
38393836 future,
38403837 move |editor, compositor, response: Option<lsp::CompletionResponse>| {
3841− let doc = doc!(editor);
3842− if doc.mode() != Mode::Insert {
3838+ if editor.mode != Mode::Insert {
38433839 // we're not in insert mode anymore
38443840 return;
38453841 }
@@ -4046,7 +4042,7 @@ fn match_brackets(cx: &mut Context) {
40464042 if let Some(pos) =
40474043 match_brackets::find_matching_bracket_fuzzy(syntax, doc.text(), range.cursor(text))
40484044 {
4049− range.put_cursor(text, pos, doc.mode == Mode::Select)
4045+ range.put_cursor(text, pos, cx.editor.mode == Mode::Select)
40504046 } else {
40514047 range
40524048 }
helix-term/src/ui/editor.rs+16−16
@@ -122,7 +122,13 @@ impl EditorView {
122122 let highlights: Box<dyn Iterator<Item = HighlightEvent>> = if is_focused {
123123 Box::new(syntax::merge(
124124 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+ ),
126132 ))
127133 } else {
128134 Box::new(highlights)
@@ -297,6 +303,7 @@ impl EditorView {
297303
298304 /// Get highlight spans for selections in a document view.
299305 pub fn doc_selection_highlights(
306+ mode: Mode,
300307 doc: &Document,
301308 view: &View,
302309 theme: &Theme,
@@ -306,7 +313,6 @@ impl EditorView {
306313 let selection = doc.selection(view.id);
307314 let primary_idx = selection.primary_index();
308315
309− let mode = doc.mode();
310316 let cursorkind = cursor_shape_config.from_mode(mode);
311317 let cursor_is_block = cursorkind == CursorKind::Block;
312318
@@ -775,17 +781,9 @@ impl EditorView {
775781 let key_result = self.keymaps.get(mode, event);
776782 cxt.editor.autoinfo = self.keymaps.sticky().map(|node| node.infobox());
777783
778− // Track the currently open doc
779− let view = view!(cxt.editor);
780− let doc_id = view.doc;
781−
782784 let mut execute_command = |command: &commands::MappableCommand| {
783785 command.execute(cxt);
784− let doc = match cxt.editor.documents.get(&doc_id) {
785− Some(doc) => doc,
786− None => return,
787− };
788− let current_mode = doc.mode();
786+ let current_mode = cxt.editor.mode();
789787 match (last_mode, current_mode) {
790788 (Mode::Normal, Mode::Insert) => {
791789 // HAXX: if we just entered insert mode from normal, clear key buf
@@ -956,8 +954,8 @@ impl EditorView {
956954
957955 pub fn handle_idle_timeout(&mut self, cx: &mut crate::compositor::Context) -> EventResult {
958956 if self.completion.is_some()
957+ || cx.editor.mode != Mode::Insert
959958 || !cx.editor.config().auto_completion
960− || doc!(cx.editor).mode != Mode::Insert
961959 {
962960 return EventResult::Ignored(None);
963961 }
@@ -1177,12 +1175,13 @@ impl Component for EditorView {
11771175 cx.editor.count = None;
11781176
11791177 let config = cx.editor.config();
1178+ let mode = cx.editor.mode();
11801179 let (view, doc) = current!(cx.editor);
11811180 view.ensure_cursor_in_view(doc, config.scrolloff);
11821181
11831182 // Store a history state if not in insert mode. Otherwise wait till we exit insert
11841183 // to include any edits to the paste in the history state.
1185− if doc.mode() != Mode::Insert {
1184+ if mode != Mode::Insert {
11861185 doc.append_changes_to_history(view.id);
11871186 }
11881187
@@ -1200,9 +1199,9 @@ impl Component for EditorView {
12001199 // clear status
12011200 cx.editor.status_msg = None;
12021201
1203− let (view, doc) = current!(cx.editor);
1202+ let mode = cx.editor.mode();
1203+ let (view, _) = current!(cx.editor);
12041204 let focus = view.id;
1205− let mode = doc.mode();
12061205
12071206 if let Some(on_next_key) = self.on_next_key.take() {
12081207 // if there's a command waiting input, do that first
@@ -1265,6 +1264,7 @@ impl Component for EditorView {
12651264 return EventResult::Ignored(None);
12661265 }
12671266 let config = cx.editor.config();
1267+ let mode = cx.editor.mode();
12681268 let view = cx.editor.tree.get_mut(focus);
12691269 let doc = cx.editor.documents.get_mut(&view.doc).unwrap();
12701270
@@ -1272,7 +1272,7 @@ impl Component for EditorView {
12721272
12731273 // Store a history state if not in insert mode. This also takes care of
12741274 // committing changes when leaving insert mode.
1275− if doc.mode() != Mode::Insert {
1275+ if mode != Mode::Insert {
12761276 doc.append_changes_to_history(view.id);
12771277 }
12781278
helix-term/src/ui/statusline.rs+2−2
@@ -160,7 +160,7 @@ where
160160 format!(
161161 " {} ",
162162 if visible {
163− match context.doc.mode() {
163+ match context.editor.mode() {
164164 Mode::Insert => "INS",
165165 Mode::Select => "SEL",
166166 Mode::Normal => "NOR",
@@ -171,7 +171,7 @@ where
171171 }
172172 ),
173173 if visible && context.editor.config().color_modes {
174− match context.doc.mode() {
174+ match context.editor.mode() {
175175 Mode::Insert => Some(context.editor.theme.get("ui.statusline.insert")),
176176 Mode::Select => Some(context.editor.theme.get("ui.statusline.select")),
177177 Mode::Normal => Some(context.editor.theme.get("ui.statusline.normal")),
helix-view/src/document.rs−9
@@ -90,8 +90,6 @@ pub struct Document {
9090 path: Option<PathBuf>,
9191 encoding: &'static encoding::Encoding,
9292
93− /// Current editing mode.
94− pub mode: Mode,
9593 pub restore_cursor: bool,
9694
9795 /// Current indent style.
@@ -133,7 +131,6 @@ impl fmt::Debug for Document {
133131 .field("selections", &self.selections)
134132 .field("path", &self.path)
135133 .field("encoding", &self.encoding)
136− .field("mode", &self.mode)
137134 .field("restore_cursor", &self.restore_cursor)
138135 .field("syntax", &self.syntax)
139136 .field("language", &self.language)
@@ -349,7 +346,6 @@ impl Document {
349346 selections: HashMap::default(),
350347 indent_style: DEFAULT_INDENT,
351348 line_ending: DEFAULT_LINE_ENDING,
352− mode: Mode::Normal,
353349 restore_cursor: false,
354350 syntax: None,
355351 language: None,
@@ -925,11 +921,6 @@ impl Document {
925921 self.last_saved_revision = current_revision;
926922 }
927923
928− /// Current editing mode for the [`Document`].
929− pub fn mode(&self) -> Mode {
930− self.mode
931− }
932−
933924 /// Corresponding language scope name. Usually `source.<lang>`.
934925 pub fn language_scope(&self) -> Option<&str> {
935926 self.language
helix-view/src/editor.rs+11−5
@@ -595,6 +595,8 @@ pub struct Breakpoint {
595595}
596596
597597pub struct Editor {
598+ /// Current editing mode.
599+ pub mode: Mode,
598600 pub tree: Tree,
599601 pub next_document_id: DocumentId,
600602 pub documents: BTreeMap<DocumentId, Document>,
@@ -677,6 +679,7 @@ impl Editor {
677679 area.height -= 1;
678680
679681 Self {
682+ mode: Mode::Normal,
680683 tree: Tree::new(area),
681684 next_document_id: DocumentId::default(),
682685 documents: BTreeMap::new(),
@@ -708,6 +711,11 @@ impl Editor {
708711 }
709712 }
710713
714+ /// Current editing mode for the [`Editor`].
715+ pub fn mode(&self) -> Mode {
716+ self.mode
717+ }
718+
711719 pub fn config(&self) -> DynGuard<Config> {
712720 self.config.load()
713721 }
@@ -1103,8 +1111,7 @@ impl Editor {
11031111
11041112 // if leaving the view: mode should reset
11051113 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;
11081115 }
11091116 }
11101117
@@ -1115,8 +1122,7 @@ impl Editor {
11151122
11161123 // if leaving the view: mode should reset
11171124 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;
11201126 }
11211127 }
11221128
@@ -1187,7 +1193,7 @@ impl Editor {
11871193 let inner = view.inner_area();
11881194 pos.col += inner.x as usize;
11891195 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);
11911197 (Some(pos), cursorkind)
11921198 } else {
11931199 (None, CursorKind::default())
helix-view/src/gutter.rs+1−1
@@ -72,7 +72,7 @@ pub fn line_numbers<'doc>(
7272 .char_to_line(doc.selection(view.id).primary().cursor(text));
7373
7474 let line_number = editor.config().line_number;
75− let mode = doc.mode;
75+ let mode = editor.mode;
7676
7777 Box::new(move |line: usize, selected: bool, out: &mut String| {
7878 if line == last_line && !draw_last {