|
|
@ -966,7 +966,7 @@ pub enum ExternalMsg {
|
|
|
|
|
|
|
|
|
|
|
|
/// Focus on the `n`th node relative to the current focus where `n` is a given value.
|
|
|
|
/// 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),
|
|
|
|
FocusNextByRelativeIndex(usize),
|
|
|
|
|
|
|
|
|
|
|
|
/// Focus on the `n`th node relative to the current focus where `n` is read from
|
|
|
|
/// 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.
|
|
|
|
/// 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),
|
|
|
|
FocusPreviousByRelativeIndex(usize),
|
|
|
|
|
|
|
|
|
|
|
|
/// Focus on the `-n`th node relative to the current focus where `n` is read from
|
|
|
|
/// 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.
|
|
|
|
/// Focus on the given path.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `FocusPath: /tmp`
|
|
|
|
/// **Example:** `FocusPath: /tmp`
|
|
|
|
FocusPath(String),
|
|
|
|
FocusPath(String),
|
|
|
|
|
|
|
|
|
|
|
|
/// Focus on the path read from input buffer.
|
|
|
|
/// 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.
|
|
|
|
/// Focus on the absolute `n`th node where `n` is a given value.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `FocusByIndex: 2`
|
|
|
|
/// **Example:** `FocusByIndex: 2`
|
|
|
|
FocusByIndex(usize),
|
|
|
|
FocusByIndex(usize),
|
|
|
|
|
|
|
|
|
|
|
|
/// Focus on the absolute `n`th node where `n` is read from the input buffer.
|
|
|
|
/// 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.
|
|
|
|
/// Focus on the file by name from the present working directory.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `FocusByFileName: README.md`
|
|
|
|
/// **Example:** `FocusByFileName: README.md`
|
|
|
|
FocusByFileName(String),
|
|
|
|
FocusByFileName(String),
|
|
|
|
|
|
|
|
|
|
|
|
/// Change the present working directory ($PWD)
|
|
|
|
/// Change the present working directory ($PWD)
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `ChangeDirectory: /tmp`
|
|
|
|
/// **Example:** `ChangeDirectory: /tmp`
|
|
|
|
ChangeDirectory(String),
|
|
|
|
ChangeDirectory(String),
|
|
|
|
|
|
|
|
|
|
|
|
/// Enter into the currently focused path if it's a directory.
|
|
|
|
/// 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.
|
|
|
|
/// Append/buffer the given string into the input buffer.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `BufferInput: foo`
|
|
|
|
/// **Example:** `BufferInput: foo`
|
|
|
|
BufferInput(String),
|
|
|
|
BufferInput(String),
|
|
|
|
|
|
|
|
|
|
|
|
/// Append/buffer the characted read from a keyboard input into the
|
|
|
|
/// 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)
|
|
|
|
/// When the input buffer is not-null (even if empty string)
|
|
|
|
/// it will show in the UI.
|
|
|
|
/// it will show in the UI.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `SetInputBuffer: foo`
|
|
|
|
/// **Example:** `SetInputBuffer: foo`
|
|
|
|
SetInputBuffer(String),
|
|
|
|
SetInputBuffer(String),
|
|
|
|
|
|
|
|
|
|
|
|
/// Remove input buffer's last character.
|
|
|
|
/// Remove input buffer's last character.
|
|
|
@ -1060,34 +1060,49 @@ pub enum ExternalMsg {
|
|
|
|
/// Switch input mode.
|
|
|
|
/// Switch input mode.
|
|
|
|
/// This will reset the input buffer and call `Refresh` automatically.
|
|
|
|
/// 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),
|
|
|
|
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.
|
|
|
|
/// Call a shell command with the given arguments.
|
|
|
|
/// Note that the arguments will be shell-escaped.
|
|
|
|
/// Note that the arguments will be shell-escaped.
|
|
|
|
/// So to read the variables, the `-c` option of the shell
|
|
|
|
/// So to read the variables, the `-c` option of the shell
|
|
|
|
/// can be used.
|
|
|
|
/// can be used.
|
|
|
|
/// You may need to pass `Refresh` or `Explore` depening on the expectation.
|
|
|
|
/// 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),
|
|
|
|
Call(Command),
|
|
|
|
|
|
|
|
|
|
|
|
/// Like `Call` but without the flicker. The stdin, stdout
|
|
|
|
/// Like `Call` but without the flicker. The stdin, stdout
|
|
|
|
/// stderr will be piped to null. So it's non-interactive.
|
|
|
|
/// 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),
|
|
|
|
CallSilently(Command),
|
|
|
|
|
|
|
|
|
|
|
|
/// An alias to `Call: {command: bash, args: ["-c", "${command}"], silent: false}`
|
|
|
|
/// An alias to `Call: {command: bash, args: ["-c", "${command}"], silent: false}`
|
|
|
|
/// where ${command} is the given value.
|
|
|
|
/// where ${command} is the given value.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `BashExec: "read -p test"`
|
|
|
|
/// **Example:** `BashExec: "read -p test"`
|
|
|
|
BashExec(String),
|
|
|
|
BashExec(String),
|
|
|
|
|
|
|
|
|
|
|
|
/// Like `BashExec` but without the flicker. The stdin, stdout
|
|
|
|
/// Like `BashExec` but without the flicker. The stdin, stdout
|
|
|
|
/// stderr will be piped to null. So it's non-interactive.
|
|
|
|
/// stderr will be piped to null. So it's non-interactive.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `BashExecSilently: "tput bell"`
|
|
|
|
/// **Example:** `BashExecSilently: "tput bell"`
|
|
|
|
BashExecSilently(String),
|
|
|
|
BashExecSilently(String),
|
|
|
|
|
|
|
|
|
|
|
|
/// Select the focused node.
|
|
|
|
/// Select the focused node.
|
|
|
@ -1098,7 +1113,7 @@ pub enum ExternalMsg {
|
|
|
|
|
|
|
|
|
|
|
|
/// Select the given path.
|
|
|
|
/// Select the given path.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `SelectPath: "/tmp"`
|
|
|
|
/// **Example:** `SelectPath: "/tmp"`
|
|
|
|
SelectPath(String),
|
|
|
|
SelectPath(String),
|
|
|
|
|
|
|
|
|
|
|
|
/// Unselect the focused node.
|
|
|
|
/// Unselect the focused node.
|
|
|
@ -1109,7 +1124,7 @@ pub enum ExternalMsg {
|
|
|
|
|
|
|
|
|
|
|
|
/// UnSelect the given path.
|
|
|
|
/// UnSelect the given path.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `UnSelectPath: "/tmp"`
|
|
|
|
/// **Example:** `UnSelectPath: "/tmp"`
|
|
|
|
UnSelectPath(String),
|
|
|
|
UnSelectPath(String),
|
|
|
|
|
|
|
|
|
|
|
|
/// Toggle selection on the focused node.
|
|
|
|
/// Toggle selection on the focused node.
|
|
|
@ -1120,7 +1135,7 @@ pub enum ExternalMsg {
|
|
|
|
|
|
|
|
|
|
|
|
/// Toggle selection by file path.
|
|
|
|
/// Toggle selection by file path.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `ToggleSelectionByPath: "/tmp"`
|
|
|
|
/// **Example:** `ToggleSelectionByPath: "/tmp"`
|
|
|
|
ToggleSelectionByPath(String),
|
|
|
|
ToggleSelectionByPath(String),
|
|
|
|
|
|
|
|
|
|
|
|
/// Clear the selection.
|
|
|
|
/// Clear the selection.
|
|
|
@ -1128,27 +1143,27 @@ pub enum ExternalMsg {
|
|
|
|
|
|
|
|
|
|
|
|
/// Add a filter to exclude nodes while exploring directories.
|
|
|
|
/// Add a filter to exclude nodes while exploring directories.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `AddNodeFilter: {filter: RelativePathDoesStartWith, input: foo}`
|
|
|
|
/// **Example:** `AddNodeFilter: {filter: RelativePathDoesStartWith, input: foo}`
|
|
|
|
AddNodeFilter(NodeFilterApplicable),
|
|
|
|
AddNodeFilter(NodeFilterApplicable),
|
|
|
|
|
|
|
|
|
|
|
|
/// Remove an existing filter.
|
|
|
|
/// Remove an existing filter.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `RemoveNodeFilter: {filter: RelativePathDoesStartWith, input: foo}`
|
|
|
|
/// **Example:** `RemoveNodeFilter: {filter: RelativePathDoesStartWith, input: foo}`
|
|
|
|
RemoveNodeFilter(NodeFilterApplicable),
|
|
|
|
RemoveNodeFilter(NodeFilterApplicable),
|
|
|
|
|
|
|
|
|
|
|
|
/// Remove a filter if it exists, else, add a it.
|
|
|
|
/// Remove a filter if it exists, else, add a it.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `ToggleNodeFilter: {filter: RelativePathDoesStartWith, input: foo}`
|
|
|
|
/// **Example:** `ToggleNodeFilter: {filter: RelativePathDoesStartWith, input: foo}`
|
|
|
|
ToggleNodeFilter(NodeFilterApplicable),
|
|
|
|
ToggleNodeFilter(NodeFilterApplicable),
|
|
|
|
|
|
|
|
|
|
|
|
/// Add a node filter reading the input from the buffer.
|
|
|
|
/// Add a node filter reading the input from the buffer.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `AddNodeFilterFromInput: RelativePathDoesStartWith`
|
|
|
|
/// **Example:** `AddNodeFilterFromInput: RelativePathDoesStartWith`
|
|
|
|
AddNodeFilterFromInput(NodeFilter),
|
|
|
|
AddNodeFilterFromInput(NodeFilter),
|
|
|
|
|
|
|
|
|
|
|
|
/// Remove a node filter reading the input from the buffer.
|
|
|
|
/// Remove a node filter reading the input from the buffer.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `RemoveNodeFilterFromInput: RelativePathDoesStartWith`
|
|
|
|
/// **Example:** `RemoveNodeFilterFromInput: RelativePathDoesStartWith`
|
|
|
|
RemoveNodeFilterFromInput(NodeFilter),
|
|
|
|
RemoveNodeFilterFromInput(NodeFilter),
|
|
|
|
|
|
|
|
|
|
|
|
/// Remove the last node filter.
|
|
|
|
/// Remove the last node filter.
|
|
|
@ -1162,22 +1177,22 @@ pub enum ExternalMsg {
|
|
|
|
|
|
|
|
|
|
|
|
/// Add a sorter to sort nodes while exploring directories.
|
|
|
|
/// Add a sorter to sort nodes while exploring directories.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `AddNodeSorter: {sorter: ByRelativePath, reverse: false}`
|
|
|
|
/// **Example:** `AddNodeSorter: {sorter: ByRelativePath, reverse: false}`
|
|
|
|
AddNodeSorter(NodeSorterApplicable),
|
|
|
|
AddNodeSorter(NodeSorterApplicable),
|
|
|
|
|
|
|
|
|
|
|
|
/// Remove an existing sorter.
|
|
|
|
/// Remove an existing sorter.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `RemoveNodeSorter: ByRelativePath`
|
|
|
|
/// **Example:** `RemoveNodeSorter: ByRelativePath`
|
|
|
|
RemoveNodeSorter(NodeSorter),
|
|
|
|
RemoveNodeSorter(NodeSorter),
|
|
|
|
|
|
|
|
|
|
|
|
/// Reverse a node sorter.
|
|
|
|
/// Reverse a node sorter.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `ReverseNodeSorter: ByRelativePath`
|
|
|
|
/// **Example:** `ReverseNodeSorter: ByRelativePath`
|
|
|
|
ReverseNodeSorter(NodeSorter),
|
|
|
|
ReverseNodeSorter(NodeSorter),
|
|
|
|
|
|
|
|
|
|
|
|
/// Remove a sorter if it exists, else, add a it.
|
|
|
|
/// Remove a sorter if it exists, else, add a it.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `ToggleSorterSorter: {sorter: ByRelativePath, reverse: false}`
|
|
|
|
/// **Example:** `ToggleSorterSorter: {sorter: ByRelativePath, reverse: false}`
|
|
|
|
ToggleNodeSorter(NodeSorterApplicable),
|
|
|
|
ToggleNodeSorter(NodeSorterApplicable),
|
|
|
|
|
|
|
|
|
|
|
|
/// Reverse the node sorters.
|
|
|
|
/// Reverse the node sorters.
|
|
|
@ -1194,17 +1209,17 @@ pub enum ExternalMsg {
|
|
|
|
|
|
|
|
|
|
|
|
/// Log information message.
|
|
|
|
/// Log information message.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `LogInfo: launching satellite`
|
|
|
|
/// **Example:** `LogInfo: launching satellite`
|
|
|
|
LogInfo(String),
|
|
|
|
LogInfo(String),
|
|
|
|
|
|
|
|
|
|
|
|
/// Log a success message.
|
|
|
|
/// Log a success message.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `LogSuccess: satellite reached destination`.
|
|
|
|
/// **Example:** `LogSuccess: satellite reached destination`.
|
|
|
|
LogSuccess(String),
|
|
|
|
LogSuccess(String),
|
|
|
|
|
|
|
|
|
|
|
|
/// Log an error message.
|
|
|
|
/// Log an error message.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Example: `LogError: satellite crashed`
|
|
|
|
/// **Example:** `LogError: satellite crashed`
|
|
|
|
LogError(String),
|
|
|
|
LogError(String),
|
|
|
|
|
|
|
|
|
|
|
|
/// Quit with returncode zero (success).
|
|
|
|
/// Quit with returncode zero (success).
|
|
|
@ -1560,6 +1575,8 @@ impl App {
|
|
|
|
ExternalMsg::RemoveInputBufferLastWord => self.remove_input_buffer_last_word(),
|
|
|
|
ExternalMsg::RemoveInputBufferLastWord => self.remove_input_buffer_last_word(),
|
|
|
|
ExternalMsg::ResetInputBuffer => self.reset_input_buffer(),
|
|
|
|
ExternalMsg::ResetInputBuffer => self.reset_input_buffer(),
|
|
|
|
ExternalMsg::SwitchMode(mode) => self.switch_mode(&mode),
|
|
|
|
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::Call(cmd) => self.call(cmd),
|
|
|
|
ExternalMsg::CallSilently(cmd) => self.call_silently(cmd),
|
|
|
|
ExternalMsg::CallSilently(cmd) => self.call_silently(cmd),
|
|
|
|
ExternalMsg::BashExec(cmd) => self.bash_exec(cmd),
|
|
|
|
ExternalMsg::BashExec(cmd) => self.bash_exec(cmd),
|
|
|
@ -1900,8 +1917,36 @@ impl App {
|
|
|
|
.to_owned()
|
|
|
|
.to_owned()
|
|
|
|
.sanitized(self.config().general().read_only().unwrap_or_default());
|
|
|
|
.sanitized(self.config().general().read_only().unwrap_or_default());
|
|
|
|
self.msg_out.push_back(MsgOut::Refresh);
|
|
|
|
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<Self> {
|
|
|
|
|
|
|
|
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<Self> {
|
|
|
|
|
|
|
|
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<Self> {
|
|
|
|
fn call(mut self, command: Command) -> Result<Self> {
|
|
|
|