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.rs92
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,
- &regex,
- movement,
- direction,
- scrolloff,
- wrap_around,
- false,
- );
+ search_impl(cx.editor, &regex, 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,
- &regex,
- movement,
- direction,
- scrolloff,
- wrap_around,
- true,
- );
+ search_impl(cx.editor, &regex, 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) {