From 0584a43c7c1b009c1182832bc6ad1ce8e67f538a Mon Sep 17 00:00:00 2001 From: Arijit Basu Date: Fri, 7 May 2021 19:56:03 +0530 Subject: [PATCH] Add SwitchModeBuiltin and SwitchModeCustom Also, use a better prompt symbol. Ref: https://github.com/sayanarijit/xplr/issues/107 --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/app.rs | 105 +++++++++++++++++++++++++++++++++++-------------- src/config.rs | 14 ++++++- src/config.yml | 102 +++++++++++++++++++++++------------------------ 5 files changed, 140 insertions(+), 85 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2ded3aa..d66673b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1630,7 +1630,7 @@ dependencies = [ [[package]] name = "xplr" -version = "0.5.12" +version = "0.5.13" dependencies = [ "anyhow", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 8ae1060..10f87ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "xplr" -version = "0.5.12" # Update config.yml, config.rs and default.nix +version = "0.5.13" # Update config.yml, config.rs and default.nix authors = ["Arijit Basu "] edition = "2018" description = "A hackable, minimal, fast TUI file explorer" diff --git a/src/app.rs b/src/app.rs index 79b992c..c61d4ff 100644 --- a/src/app.rs +++ b/src/app.rs @@ -966,7 +966,7 @@ pub enum ExternalMsg { /// Focus on the `n`th node relative to the current focus where `n` is a given value. /// - /// Example: `FocusNextByRelativeIndex: 2` + /// **Example:** `FocusNextByRelativeIndex: 2` FocusNextByRelativeIndex(usize), /// Focus on the `n`th node relative to the current focus where `n` is read from @@ -978,7 +978,7 @@ pub enum ExternalMsg { /// Focus on the `-n`th node relative to the current focus where `n` is a given value. /// - /// Example: `FocusPreviousByRelativeIndex: 2` + /// **Example:** `FocusPreviousByRelativeIndex: 2` FocusPreviousByRelativeIndex(usize), /// Focus on the `-n`th node relative to the current focus where `n` is read from @@ -993,7 +993,7 @@ pub enum ExternalMsg { /// Focus on the given path. /// - /// Example: `FocusPath: /tmp` + /// **Example:** `FocusPath: /tmp` FocusPath(String), /// Focus on the path read from input buffer. @@ -1001,7 +1001,7 @@ pub enum ExternalMsg { /// Focus on the absolute `n`th node where `n` is a given value. /// - /// Example: `FocusByIndex: 2` + /// **Example:** `FocusByIndex: 2` FocusByIndex(usize), /// Focus on the absolute `n`th node where `n` is read from the input buffer. @@ -1009,12 +1009,12 @@ pub enum ExternalMsg { /// Focus on the file by name from the present working directory. /// - /// Example: `FocusByFileName: README.md` + /// **Example:** `FocusByFileName: README.md` FocusByFileName(String), /// Change the present working directory ($PWD) /// - /// Example: `ChangeDirectory: /tmp` + /// **Example:** `ChangeDirectory: /tmp` ChangeDirectory(String), /// Enter into the currently focused path if it's a directory. @@ -1034,7 +1034,7 @@ pub enum ExternalMsg { /// Append/buffer the given string into the input buffer. /// - /// Example: `BufferInput: foo` + /// **Example:** `BufferInput: foo` BufferInput(String), /// Append/buffer the characted read from a keyboard input into the @@ -1045,7 +1045,7 @@ pub enum ExternalMsg { /// When the input buffer is not-null (even if empty string) /// it will show in the UI. /// - /// Example: `SetInputBuffer: foo` + /// **Example:** `SetInputBuffer: foo` SetInputBuffer(String), /// Remove input buffer's last character. @@ -1060,34 +1060,49 @@ pub enum ExternalMsg { /// Switch input mode. /// This will reset the input buffer and call `Refresh` automatically. /// - /// Example: `SwitchMode: default` + /// > **NOTE:** To be specific about which mode to switch to, use `SwitchModeBuiltin` or + /// `SwitchModeCustom` instead. + /// + /// **Example:** `SwitchMode: default` SwitchMode(String), + /// Switch to a builtin mode. + /// This will reset the input buffer and call `Refresh` automatically. + /// + /// **Example:** `SwitchModeBuiltin: default` + SwitchModeBuiltin(String), + + /// Switch to a custom mode. + /// This will reset the input buffer and call `Refresh` automatically. + /// + /// **Example:** `SwitchModeCustom: my_custom_mode` + SwitchModeCustom(String), + /// Call a shell command with the given arguments. /// Note that the arguments will be shell-escaped. /// So to read the variables, the `-c` option of the shell /// can be used. /// You may need to pass `Refresh` or `Explore` depening on the expectation. /// - /// Example: `Call: {command: bash, args: ["-c", "read -p test"]}` + /// **Example:** `Call: {command: bash, args: ["-c", "read -p test"]}` Call(Command), /// Like `Call` but without the flicker. The stdin, stdout /// stderr will be piped to null. So it's non-interactive. /// - /// Example: `CallSilently: {command: tput, args: ["bell"]}` + /// **Example:** `CallSilently: {command: tput, args: ["bell"]}` CallSilently(Command), /// An alias to `Call: {command: bash, args: ["-c", "${command}"], silent: false}` /// where ${command} is the given value. /// - /// Example: `BashExec: "read -p test"` + /// **Example:** `BashExec: "read -p test"` BashExec(String), /// Like `BashExec` but without the flicker. The stdin, stdout /// stderr will be piped to null. So it's non-interactive. /// - /// Example: `BashExecSilently: "tput bell"` + /// **Example:** `BashExecSilently: "tput bell"` BashExecSilently(String), /// Select the focused node. @@ -1098,7 +1113,7 @@ pub enum ExternalMsg { /// Select the given path. /// - /// Example: `SelectPath: "/tmp"` + /// **Example:** `SelectPath: "/tmp"` SelectPath(String), /// Unselect the focused node. @@ -1109,7 +1124,7 @@ pub enum ExternalMsg { /// UnSelect the given path. /// - /// Example: `UnSelectPath: "/tmp"` + /// **Example:** `UnSelectPath: "/tmp"` UnSelectPath(String), /// Toggle selection on the focused node. @@ -1120,7 +1135,7 @@ pub enum ExternalMsg { /// Toggle selection by file path. /// - /// Example: `ToggleSelectionByPath: "/tmp"` + /// **Example:** `ToggleSelectionByPath: "/tmp"` ToggleSelectionByPath(String), /// Clear the selection. @@ -1128,27 +1143,27 @@ pub enum ExternalMsg { /// Add a filter to exclude nodes while exploring directories. /// - /// Example: `AddNodeFilter: {filter: RelativePathDoesStartWith, input: foo}` + /// **Example:** `AddNodeFilter: {filter: RelativePathDoesStartWith, input: foo}` AddNodeFilter(NodeFilterApplicable), /// Remove an existing filter. /// - /// Example: `RemoveNodeFilter: {filter: RelativePathDoesStartWith, input: foo}` + /// **Example:** `RemoveNodeFilter: {filter: RelativePathDoesStartWith, input: foo}` RemoveNodeFilter(NodeFilterApplicable), /// Remove a filter if it exists, else, add a it. /// - /// Example: `ToggleNodeFilter: {filter: RelativePathDoesStartWith, input: foo}` + /// **Example:** `ToggleNodeFilter: {filter: RelativePathDoesStartWith, input: foo}` ToggleNodeFilter(NodeFilterApplicable), /// Add a node filter reading the input from the buffer. /// - /// Example: `AddNodeFilterFromInput: RelativePathDoesStartWith` + /// **Example:** `AddNodeFilterFromInput: RelativePathDoesStartWith` AddNodeFilterFromInput(NodeFilter), /// Remove a node filter reading the input from the buffer. /// - /// Example: `RemoveNodeFilterFromInput: RelativePathDoesStartWith` + /// **Example:** `RemoveNodeFilterFromInput: RelativePathDoesStartWith` RemoveNodeFilterFromInput(NodeFilter), /// Remove the last node filter. @@ -1162,22 +1177,22 @@ pub enum ExternalMsg { /// Add a sorter to sort nodes while exploring directories. /// - /// Example: `AddNodeSorter: {sorter: ByRelativePath, reverse: false}` + /// **Example:** `AddNodeSorter: {sorter: ByRelativePath, reverse: false}` AddNodeSorter(NodeSorterApplicable), /// Remove an existing sorter. /// - /// Example: `RemoveNodeSorter: ByRelativePath` + /// **Example:** `RemoveNodeSorter: ByRelativePath` RemoveNodeSorter(NodeSorter), /// Reverse a node sorter. /// - /// Example: `ReverseNodeSorter: ByRelativePath` + /// **Example:** `ReverseNodeSorter: ByRelativePath` ReverseNodeSorter(NodeSorter), /// Remove a sorter if it exists, else, add a it. /// - /// Example: `ToggleSorterSorter: {sorter: ByRelativePath, reverse: false}` + /// **Example:** `ToggleSorterSorter: {sorter: ByRelativePath, reverse: false}` ToggleNodeSorter(NodeSorterApplicable), /// Reverse the node sorters. @@ -1194,17 +1209,17 @@ pub enum ExternalMsg { /// Log information message. /// - /// Example: `LogInfo: launching satellite` + /// **Example:** `LogInfo: launching satellite` LogInfo(String), /// Log a success message. /// - /// Example: `LogSuccess: satellite reached destination`. + /// **Example:** `LogSuccess: satellite reached destination`. LogSuccess(String), /// Log an error message. /// - /// Example: `LogError: satellite crashed` + /// **Example:** `LogError: satellite crashed` LogError(String), /// Quit with returncode zero (success). @@ -1560,6 +1575,8 @@ impl App { ExternalMsg::RemoveInputBufferLastWord => self.remove_input_buffer_last_word(), ExternalMsg::ResetInputBuffer => self.reset_input_buffer(), ExternalMsg::SwitchMode(mode) => self.switch_mode(&mode), + ExternalMsg::SwitchModeBuiltin(mode) => self.switch_mode_builtin(&mode), + ExternalMsg::SwitchModeCustom(mode) => self.switch_mode_custom(&mode), ExternalMsg::Call(cmd) => self.call(cmd), ExternalMsg::CallSilently(cmd) => self.call_silently(cmd), ExternalMsg::BashExec(cmd) => self.bash_exec(cmd), @@ -1900,8 +1917,36 @@ impl App { .to_owned() .sanitized(self.config().general().read_only().unwrap_or_default()); self.msg_out.push_back(MsgOut::Refresh); - }; - Ok(self) + Ok(self) + } else { + self.log_error(format!("Mode not found: {}", mode)) + } + } + + fn switch_mode_builtin(mut self, mode: &str) -> Result { + if let Some(mode) = self.config().modes().clone().get_builtin(mode) { + self.input_buffer = None; + self.mode = mode + .to_owned() + .sanitized(self.config().general().read_only().unwrap_or_default()); + self.msg_out.push_back(MsgOut::Refresh); + Ok(self) + } else { + self.log_error(format!("Builtin mode not found: {}", mode)) + } + } + + fn switch_mode_custom(mut self, mode: &str) -> Result { + if let Some(mode) = self.config().modes().clone().get(mode) { + self.input_buffer = None; + self.mode = mode + .to_owned() + .sanitized(self.config().general().read_only().unwrap_or_default()); + self.msg_out.push_back(MsgOut::Refresh); + Ok(self) + } else { + self.log_error(format!("Custom mode not found: {}", mode)) + } } fn call(mut self, command: Command) -> Result { diff --git a/src/config.rs b/src/config.rs index be0e0a5..466851b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -948,8 +948,16 @@ pub struct ModesConfig { } impl ModesConfig { + pub fn get_builtin(&self, name: &str) -> Option<&Mode> { + self.builtin.get(name) + } + + pub fn get_custom(&self, name: &str) -> Option<&Mode> { + self.custom.get(name) + } + pub fn get(&self, name: &str) -> Option<&Mode> { - self.builtin.get(name).or_else(|| self.custom.get(name)) + self.get_builtin(name).or_else(|| self.get_custom(name)) } pub fn extend(mut self, other: Self) -> Self { @@ -1020,6 +1028,7 @@ impl Config { pub fn is_compatible(&self) -> Result { let result = match self.parsed_version()? { + (0, 5, 13) => true, (0, 5, 12) => true, (0, 5, 11) => true, (0, 5, 10) => true, @@ -1041,7 +1050,8 @@ impl Config { pub fn upgrade_notification(&self) -> Result> { let result = match self.parsed_version()? { - (0, 5, 12) => None, + (0, 5, 13) => None, + (0, 5, 12) => Some("App version updated. Added new messages for switching mode."), (0, 5, 11) => Some("App version updated. Fixed changing directory on focus using argument"), (0, 5, 10) => Some("App version updated. Added xplr desktop icon and search navigation"), (0, 5, 9) => Some("App version updated. Fixed pipes not updating properly"), diff --git a/src/config.yml b/src/config.yml index 0295af2..e19b8bf 100644 --- a/src/config.yml +++ b/src/config.yml @@ -1,4 +1,4 @@ -version: v0.5.12 +version: v0.5.13 general: show_hidden: false read_only: false @@ -311,7 +311,7 @@ modes: echo Explore >> "${XPLR_PIPE_MSG_IN:?}" echo ClearSelection >> "${XPLR_PIPE_MSG_IN:?}" read -p "[enter to continue]" - - SwitchMode: default + - SwitchModeBuiltin: default m: help: move here @@ -326,7 +326,7 @@ modes: done < "${XPLR_PIPE_SELECTION_OUT:?}") echo Explore >> "${XPLR_PIPE_MSG_IN:?}" read -p "[enter to continue]" - - SwitchMode: default + - SwitchModeBuiltin: default ctrl-c: help: terminate @@ -335,7 +335,7 @@ modes: default: messages: - - SwitchMode: default + - SwitchModeBuiltin: default create_file: name: create file @@ -357,7 +357,7 @@ modes: echo "LogError: Failed to create $PTH" >> "${XPLR_PIPE_MSG_IN:?}" echo Refresh >> "${XPLR_PIPE_MSG_IN:?}" fi - - SwitchMode: default + - SwitchModeBuiltin: default backspace: help: remove last character messages: @@ -373,7 +373,7 @@ modes: esc: help: cancel messages: - - SwitchMode: default + - SwitchModeBuiltin: default ctrl-c: help: terminate messages: @@ -402,7 +402,7 @@ modes: echo "LogError: Failed to create $PTH" >> "${XPLR_PIPE_MSG_IN:?}" echo Refresh >> "${XPLR_PIPE_MSG_IN:?}" fi - - SwitchMode: default + - SwitchModeBuiltin: default backspace: help: remove last character @@ -422,7 +422,7 @@ modes: esc: help: cancel messages: - - SwitchMode: default + - SwitchModeBuiltin: default ctrl-c: help: terminate @@ -447,16 +447,16 @@ modes: d: help: create directory messages: - - SwitchMode: create directory + - SwitchModeBuiltin: create directory - SetInputBuffer: '' esc: help: cancel messages: - - SwitchMode: default + - SwitchModeBuiltin: default f: help: create file messages: - - SwitchMode: create file + - SwitchModeBuiltin: create file - SetInputBuffer: '' on_alphabet: null on_number: null @@ -464,7 +464,7 @@ modes: default: help: null messages: - - SwitchMode: default + - SwitchModeBuiltin: default rename: name: rename help: null @@ -485,7 +485,7 @@ modes: else echo "LogError: Failed to rename $SRC to $TARGET" >> "${XPLR_PIPE_MSG_IN:?}" fi - - SwitchMode: default + - SwitchModeBuiltin: default backspace: help: remove last character @@ -505,7 +505,7 @@ modes: esc: help: cancel messages: - - SwitchMode: default + - SwitchModeBuiltin: default ctrl-c: help: terminate @@ -544,12 +544,12 @@ modes: enter: help: apply filter messages: - - SwitchMode: default + - SwitchModeBuiltin: default esc: help: cancel messages: - RemoveNodeFilterFromInput: IRelativePathDoesNotContain - - SwitchMode: default + - SwitchModeBuiltin: default - Explore ctrl-c: help: terminate @@ -590,12 +590,12 @@ modes: enter: help: apply filter messages: - - SwitchMode: default + - SwitchModeBuiltin: default esc: help: cancel messages: - RemoveNodeFilterFromInput: IRelativePathDoesContain - - SwitchMode: default + - SwitchModeBuiltin: default - Explore ctrl-c: help: terminate @@ -621,14 +621,14 @@ modes: r: help: relative does contain messages: - - SwitchMode: relative_path_does_contain + - SwitchModeBuiltin: relative_path_does_contain - SetInputBuffer: "" - AddNodeFilterFromInput: IRelativePathDoesContain - Explore R: help: relative does not contain messages: - - SwitchMode: relative_path_does_not_contain + - SwitchModeBuiltin: relative_path_does_not_contain - SetInputBuffer: "" - AddNodeFilterFromInput: IRelativePathDoesNotContain - Explore @@ -648,7 +648,7 @@ modes: - Terminate default: messages: - - SwitchMode: default + - SwitchModeBuiltin: default sort: name: sort @@ -759,7 +759,7 @@ modes: - Terminate default: messages: - - SwitchMode: default + - SwitchModeBuiltin: default default: name: default @@ -783,11 +783,11 @@ modes: s: help: sort messages: - - SwitchMode: sort + - SwitchModeBuiltin: sort f: help: filter messages: - - SwitchMode: filter + - SwitchModeBuiltin: filter .: help: show hidden messages: @@ -798,7 +798,7 @@ modes: ':': help: action messages: - - SwitchMode: action + - SwitchModeBuiltin: action '?': help: global help menu messages: @@ -820,13 +820,13 @@ modes: ctrl-f: help: search messages: - - SwitchMode: search + - SwitchModeBuiltin: search - SetInputBuffer: '' - Explore d: help: delete messages: - - SwitchMode: delete + - SwitchModeBuiltin: delete down: help: down messages: @@ -838,7 +838,7 @@ modes: g: help: go to messages: - - SwitchMode: go to + - SwitchModeBuiltin: go to left: help: back messages: @@ -846,7 +846,7 @@ modes: r: help: rename messages: - - SwitchMode: rename + - SwitchModeBuiltin: rename - BashExecSilently: | echo "SetInputBuffer: $(basename ${XPLR_FOCUS_PATH})" >> "${XPLR_PIPE_MSG_IN:?}" right: @@ -894,13 +894,13 @@ modes: help: input messages: - ResetInputBuffer - - SwitchMode: number + - SwitchModeBuiltin: number - BufferInputFromKey on_special_character: null default: help: null messages: - - SwitchMode: default + - SwitchModeBuiltin: default go_to: name: go to help: null @@ -916,12 +916,12 @@ modes: help: top messages: - FocusFirst - - SwitchMode: default + - SwitchModeBuiltin: default f: help: follow symlink messages: - FollowSymlink - - SwitchMode: default + - SwitchModeBuiltin: default x: help: open in gui messages: @@ -937,7 +937,7 @@ modes: fi fi $OPENER "${XPLR_FOCUS_PATH:?}" &> /dev/null & - - SwitchMode: default + - SwitchModeBuiltin: default - ClearScreen - Refresh @@ -947,7 +947,7 @@ modes: default: help: null messages: - - SwitchMode: default + - SwitchModeBuiltin: default number: name: number @@ -978,17 +978,17 @@ modes: help: to down messages: - FocusNextByRelativeIndexFromInput - - SwitchMode: default + - SwitchModeBuiltin: default enter: help: to index messages: - FocusByIndexFromInput - - SwitchMode: default + - SwitchModeBuiltin: default up: help: to up messages: - FocusPreviousByRelativeIndexFromInput - - SwitchMode: default + - SwitchModeBuiltin: default on_alphabet: null on_number: help: input @@ -998,7 +998,7 @@ modes: default: help: null messages: - - SwitchMode: default + - SwitchModeBuiltin: default delete: name: delete help: null @@ -1028,7 +1028,7 @@ modes: done < "${XPLR_PIPE_RESULT_OUT:?}") echo Explore >> "${XPLR_PIPE_MSG_IN:?}" read -p "[enter to continue]" - - SwitchMode: default + - SwitchModeBuiltin: default D: help: force delete @@ -1044,7 +1044,7 @@ modes: done < "${XPLR_PIPE_RESULT_OUT:?}") echo Explore >> "${XPLR_PIPE_MSG_IN:?}" read -p "[enter to continue]" - - SwitchMode: default + - SwitchModeBuiltin: default - Explore ctrl-c: @@ -1054,7 +1054,7 @@ modes: default: messages: - - SwitchMode: default + - SwitchModeBuiltin: default action: name: action to @@ -1066,7 +1066,7 @@ modes: help: go to index messages: - ResetInputBuffer - - SwitchMode: number + - SwitchModeBuiltin: number - BufferInputFromKey on_key: @@ -1078,24 +1078,24 @@ modes: args: - "-i" - Explore - - SwitchMode: default + - SwitchModeBuiltin: default c: help: create messages: - - SwitchMode: create + - SwitchModeBuiltin: create e: help: open in editor messages: - BashExec: | ${EDITOR:-vi} -- "${XPLR_FOCUS_PATH:?}" - - SwitchMode: default + - SwitchModeBuiltin: default s: help: selection operations messages: - - SwitchMode: selection ops + - SwitchModeBuiltin: selection ops l: help: logs @@ -1103,7 +1103,7 @@ modes: - BashExec: | cat -- "${XPLR_PIPE_LOGS_OUT}" read -p "[enter to continue]" - - SwitchMode: default + - SwitchModeBuiltin: default ctrl-c: help: terminate @@ -1112,7 +1112,7 @@ modes: default: messages: - - SwitchMode: default + - SwitchModeBuiltin: default search: name: search help: null @@ -1155,13 +1155,13 @@ modes: help: focus messages: - RemoveNodeFilterFromInput: IRelativePathDoesContain - - SwitchMode: default + - SwitchModeBuiltin: default - Explore esc: help: cancel messages: - RemoveNodeFilterFromInput: IRelativePathDoesContain - - SwitchMode: default + - SwitchModeBuiltin: default - Explore left: help: back