diff --git a/skim/src/event.rs b/skim/src/event.rs index c4825a1a..74fd278a 100644 --- a/skim/src/event.rs +++ b/skim/src/event.rs @@ -52,6 +52,7 @@ pub enum Event { EvActPreviewPageDown(i32), EvActPreviousHistory, EvActRedraw, + EvActReload(Option), EvActRefreshCmd, EvActRefreshPreview, EvActRotateMode, @@ -129,6 +130,7 @@ pub fn parse_event(action: &str, arg: Option) -> Option { "previous-history" => Some(Event::EvActPreviousHistory), "refresh-cmd" => Some(Event::EvActRefreshCmd), "refresh-preview" => Some(Event::EvActRefreshPreview), + "reload" => Some(Event::EvActReload(arg.clone())), "scroll-left" => Some(Event::EvActScrollLeft(arg.and_then(|s|s.parse().ok()).unwrap_or(1))), "scroll-right" => Some(Event::EvActScrollRight(arg.and_then(|s|s.parse().ok()).unwrap_or(1))), "select-all" => Some(Event::EvActSelectAll), diff --git a/skim/src/model.rs b/skim/src/model.rs index f0fda614..a6ba85ac 100644 --- a/skim/src/model.rs +++ b/skim/src/model.rs @@ -436,6 +436,24 @@ impl Model { let _ = Command::new(shell).arg("-c").arg(cmd).status(); } + fn act_reload(&mut self, cmd_opt: Option) { + let cmd = match cmd_opt { + Some(s) => s, + None => self.query.get_cmd(), + }; + debug!("command to execute: [{}]", cmd); + let mut env = ModelEnv { + cmd: cmd.to_string(), + cmd_query: self.query.get_cmd_query(), + query: self.query.get_fz_query(), + clear_selection: ClearStrategy::ClearIfNotNull, + in_query_mode: self.query.in_query_mode(), + }; + + self.selection.clear(); + self.on_cmd_query_change(&mut env); + } + #[allow(clippy::trivial_regex)] fn act_append_and_select(&mut self, env: &mut ModelEnv) { let query = self.query.get_fz_query(); @@ -567,6 +585,10 @@ impl Model { self.act_execute_silent(cmd); } + Event::EvActReload(ref cmd) => { + self.act_reload(cmd.clone()); + } + Event::EvActAppendAndSelect => { self.act_append_and_select(&mut env); } diff --git a/skim/src/options.rs b/skim/src/options.rs index 00ffd21b..cd05df09 100644 --- a/skim/src/options.rs +++ b/skim/src/options.rs @@ -244,6 +244,7 @@ pub struct SkimOptions { /// preview-page-down /// preview-page-up /// previous-history (ctrl-p on --history or --cmd-history) + /// reload(...) /// select-all /// toggle /// toggle-all @@ -263,10 +264,11 @@ pub struct SkimOptions { /// /// sk --bind 'ctrl-a:select-all+accept' /// - /// With execute(...) action, you can execute arbitrary commands without leaving sk. For example, + /// With execute(...) and reload(...) action, you can execute arbitrary commands without leaving sk. For example, /// you can turn sk into a simple file browser by binding enter key to less command like follows. /// /// sk --bind "enter:execute(less {})" + /// Note: if no argument is supplied to reload, the default command is run. /// /// You can use the same placeholder expressions as in --preview. /// diff --git a/test/test_skim.py b/test/test_skim.py index 6523145c..6764448c 100644 --- a/test/test_skim.py +++ b/test/test_skim.py @@ -1226,6 +1226,27 @@ def test_issue_361_literal_space(self): # revert option back self.tmux.send_keys(f"""set -o histexpand""", Key('Enter')) + def test_reload_no_arg(self): + args = "--bind 'ctrl-a:reload'" + sk = self.sk(args).replace('SKIM_DEFAULT_COMMAND=', + "SKIM_DEFAULT_COMMAND='echo hello'") + + self.tmux.send_keys( + f"""echo -e 'a\\nb\\nc' | {sk}""", Key('Enter')) + self.tmux.until(lambda lines: lines.ready_with_matches(3)) + self.tmux.send_keys(Ctrl('a')) + self.tmux.until(lambda lines: lines.ready_with_matches(1)) + + def test_reload_arg(self): + args = "--bind 'ctrl-a:reload(echo hello)'" + sk = self.sk(args) + + self.tmux.send_keys( + f"""echo -e 'a\\nb\\nc' | {sk}""", Key('Enter')) + self.tmux.until(lambda lines: lines.ready_with_matches(3)) + self.tmux.send_keys(Ctrl('a')) + self.tmux.until(lambda lines: lines.ready_with_matches(1)) + def test_version(self): self.tmux.send_keys(self.sk('--version'), Key('Enter')) time.sleep(0.1)