Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-term/src/commands.rs')
| -rw-r--r-- | helix-term/src/commands.rs | 92 |
1 files changed, 43 insertions, 49 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index cc7b84c4..15164b42 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -59,7 +59,7 @@ use movement::Movement; use crate::{ args, compositor::{self, Component, Compositor}, - filter_picker_entry, + events, filter_picker_entry, job::Callback, keymap::ReverseKeymap, ui::{self, menu::Item, overlay::overlaid, Picker, Popup, Prompt, PromptEvent}, @@ -142,6 +142,45 @@ impl<'a> Context<'a> { pub fn count(&self) -> usize { self.count.map_or(1, |v| v.get()) } + + pub fn execute<F: FnOnce(&mut Self)>(&mut self, execute_fn: F) { + self.execute_impl(execute_fn) + } + + pub fn execute_command(&mut self, command: &MappableCommand) { + self.execute_impl(|cx| { + command.execute(cx); + helix_event::dispatch(events::PostCommand { command, cx }); + }) + } + + fn execute_impl<F: FnOnce(&mut Self)>(&mut self, execute_fn: F) { + let pre_command_mode = self.editor.mode(); + if pre_command_mode != Mode::Insert { + let (view, doc) = current!(self.editor); + doc.append_changes_to_history(view); + } + + execute_fn(self); + + let post_command_mode = self.editor.mode(); + if post_command_mode != pre_command_mode { + helix_event::dispatch(events::OnModeSwitch { + old_mode: pre_command_mode, + new_mode: post_command_mode, + cx: self, + }); + } + + if !self.editor.tree.is_empty() { + let scrolloff = self.editor.config().scrolloff; + let (view, doc) = current!(self.editor); + if post_command_mode != Mode::Insert { + doc.append_changes_to_history(view); + } + view.ensure_cursor_in_view(doc, scrolloff); + } + } } #[inline] @@ -1981,7 +2020,6 @@ fn search_impl( regex: &rope::Regex, movement: Movement, direction: Direction, - scrolloff: usize, wrap_around: bool, show_warnings: bool, ) { @@ -2054,7 +2092,6 @@ fn search_impl( }; doc.set_selection(view.id, selection); - view.ensure_cursor_in_view_center(doc, scrolloff); }; } @@ -2078,7 +2115,6 @@ fn rsearch(cx: &mut Context) { fn searcher(cx: &mut Context, direction: Direction) { let reg = cx.register.unwrap_or('/'); let config = cx.editor.config(); - let scrolloff = config.scrolloff; let wrap_around = config.search.wrap_around; let movement = if cx.editor.mode() == Mode::Select { Movement::Extend @@ -2106,15 +2142,7 @@ fn searcher(cx: &mut Context, direction: Direction) { } else if event != PromptEvent::Update { return; } - search_impl( - cx.editor, - ®ex, - movement, - direction, - scrolloff, - wrap_around, - false, - ); + search_impl(cx.editor, ®ex, movement, direction, wrap_around, false); }, ); } @@ -2125,7 +2153,6 @@ fn search_next_or_prev_impl(cx: &mut Context, movement: Movement, direction: Dir .register .unwrap_or(cx.editor.registers.last_search_register); let config = cx.editor.config(); - let scrolloff = config.scrolloff; if let Some(query) = cx.editor.registers.first(register, cx.editor) { let search_config = &config.search; let case_insensitive = if search_config.smart_case { @@ -2143,15 +2170,7 @@ fn search_next_or_prev_impl(cx: &mut Context, movement: Movement, direction: Dir .build(&query) { for _ in 0..count { - search_impl( - cx.editor, - ®ex, - movement, - direction, - scrolloff, - wrap_around, - true, - ); + search_impl(cx.editor, ®ex, movement, direction, wrap_around, true); } } else { let error = format!("Invalid regex: {}", query); @@ -3188,22 +3207,8 @@ pub fn command_palette(cx: &mut Context) { on_next_key_callback: None, jobs: cx.jobs, }; - let focus = view!(ctx.editor).id; - - command.execute(&mut ctx); - - if ctx.editor.tree.contains(focus) { - let config = ctx.editor.config(); - let mode = ctx.editor.mode(); - let view = view_mut!(ctx.editor, focus); - let doc = doc_mut!(ctx.editor, &view.doc); - view.ensure_cursor_in_view(doc, config.scrolloff); - - if mode != Mode::Insert { - doc.append_changes_to_history(view); - } - } + ctx.execute_command(command); }); compositor.push(Box::new(overlaid(picker))); }, @@ -4329,7 +4334,6 @@ fn replace_with_yanked_impl(editor: &mut Editor, register: char, count: usize) { return; }; let values: Vec<_> = values.map(|value| value.to_string()).collect(); - let scrolloff = editor.config().scrolloff; let (view, doc) = current!(editor); let repeat = std::iter::repeat( @@ -4352,8 +4356,6 @@ fn replace_with_yanked_impl(editor: &mut Editor, register: char, count: usize) { }); doc.apply(&transaction, view.id); - doc.append_changes_to_history(view); - view.ensure_cursor_in_view(doc, scrolloff); } fn replace_selections_with_clipboard(cx: &mut Context) { @@ -5037,7 +5039,6 @@ fn match_brackets(cx: &mut Context) { fn jump_forward(cx: &mut Context) { let count = cx.count(); - let config = cx.editor.config(); let view = view_mut!(cx.editor); let doc_id = view.doc; @@ -5051,13 +5052,11 @@ fn jump_forward(cx: &mut Context) { } doc.set_selection(view.id, selection); - view.ensure_cursor_in_view_center(doc, config.scrolloff); }; } fn jump_backward(cx: &mut Context) { let count = cx.count(); - let config = cx.editor.config(); let (view, doc) = current!(cx.editor); let doc_id = doc.id(); @@ -5071,7 +5070,6 @@ fn jump_backward(cx: &mut Context) { } doc.set_selection(view.id, selection); - view.ensure_cursor_in_view_center(doc, config.scrolloff); }; } @@ -5789,10 +5787,6 @@ fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) { doc.apply(&transaction, view.id); doc.append_changes_to_history(view); } - - // after replace cursor may be out of bounds, do this to - // make sure cursor is in view and update scroll as well - view.ensure_cursor_in_view(doc, config.scrolloff); } fn shell_prompt(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBehavior) { |