diff --git a/docs/en/src/default-key-bindings.md b/docs/en/src/default-key-bindings.md index 54c282d..fe2c77f 100644 --- a/docs/en/src/default-key-bindings.md +++ b/docs/en/src/default-key-bindings.md @@ -19,11 +19,11 @@ of [modes][4] and the key mappings for each mode. | . | | show hidden | | / | ctrl-f | search | | : | | action | -| ? | | global help menu | +| ? | f1 | global help menu | | G | | go to bottom | | V | ctrl-a | select/unselect all | | ctrl-d | | duplicate as | -| ctrl-i | | next visited path | +| ctrl-i | tab | next visited path | | ctrl-n | | next selection | | ctrl-o | | last visited path | | ctrl-p | | prev selection | @@ -51,102 +51,71 @@ of [modes][4] and the key mappings for each mode. ### vroot -| key | remaps | action | -| ------ | ------ | ------------ | -| . | | vroot $PWD | -| / | | vroot / | -| ctrl-r | | reset vroot | -| ctrl-u | | unset vroot | -| v | | toggle vroot | -| ~ | | vroot $HOME | +| key | remaps | action | +| ------ | ------ | ---------------- | +| . | | vroot $PWD | +| / | | vroot / | +| ctrl-r | | reset vroot | +| ctrl-u | | unset vroot | +| f1 | | global help menu | +| v | | toggle vroot | +| ~ | | vroot $HOME | -### relative_path_does_match_regex - -| key | remaps | action | -| ----- | ------ | ------ | -| enter | | submit | - -### go_to_path +### recover -| key | remaps | action | -| ----- | ------ | ------------ | -| enter | | submit | -| tab | | try complete | +| key | remaps | action | +| --- | ------ | ---------------- | +| f1 | | global help menu | -### duplicate_as +### create_file -| key | remaps | action | -| ----- | ------ | ------------ | -| enter | | submit | -| tab | | try complete | +| key | remaps | action | +| ----- | ------ | ---------------- | +| enter | | submit | +| f1 | | global help menu | +| tab | | try complete | -### debug_error +### delete -| key | remaps | action | -| ----- | ------ | ------------------- | -| enter | | open logs in editor | -| q | | quit | +| key | remaps | action | +| --- | ------ | ---------------- | +| D | | force delete | +| d | | delete | +| f1 | | global help menu | -### selection_ops +### create_directory -| key | remaps | action | -| --- | ------ | --------------- | -| c | | copy here | -| e | | edit selection | -| h | | hardlink here | -| l | | list selection | -| m | | move here | -| s | | softlink here | -| u | | clear selection | +| key | remaps | action | +| ----- | ------ | ---------------- | +| enter | | submit | +| f1 | | global help menu | +| tab | | try complete | -### sort +### create -| key | remaps | action | -| --------- | ------ | --------------------------------- | -| ! | | reverse sorters | -| C | | by created reverse | -| E | | by canonical extension reverse | -| L | | by last modified reverse | -| M | | by canonical mime essence reverse | -| N | | by node type reverse | -| R | | by relative path reverse | -| S | | by size reverse | -| backspace | | remove last sorter | -| c | | by created | -| ctrl-r | | reset sorters | -| ctrl-u | | clear sorters | -| e | | by canonical extension | -| enter | | submit | -| l | | by last modified | -| m | | by canonical mime essence | -| n | | by node type | -| r | | by relative path | -| s | | by size | +| key | remaps | action | +| --- | ------ | ---------------- | +| d | | create directory | +| f | | create file | +| f1 | | global help menu | ### go_to -| key | remaps | action | -| --- | ------ | -------------- | -| f | | follow symlink | -| g | | top | -| i | | initial $PWD | -| p | | path | -| x | | open in gui | +| key | remaps | action | +| --- | ------ | ---------------- | +| f | | follow symlink | +| f1 | | global help menu | +| g | | top | +| i | | initial $PWD | +| p | | path | +| x | | open in gui | -### edit_permissions +### relative_path_does_not_match_regex -| key | remaps | action | -| ------ | ------ | ------ | -| G | | -group | -| M | | min | -| O | | -other | -| U | | -user | -| ctrl-r | | reset | -| enter | | submit | -| g | | +group | -| m | | max | -| o | | +other | -| u | | +user | +| key | remaps | action | +| ----- | ------ | ---------------- | +| enter | | submit | +| f1 | | global help menu | ### switch_layout @@ -156,27 +125,78 @@ of [modes][4] and the key mappings for each mode. | 2 | | no help menu | | 3 | | no selection panel | | 4 | | no help or selection | +| f1 | | global help menu | -### create +### go_to_path -| key | remaps | action | -| --- | ------ | ---------------- | -| d | | create directory | -| f | | create file | +| key | remaps | action | +| ----- | ------ | ---------------- | +| enter | | submit | +| f1 | | global help menu | +| tab | | try complete | -### create_directory +### quit + +| key | remaps | action | +| ----- | ------ | ----------------------- | +| enter | | just quit | +| f | | quit printing focus | +| f1 | | global help menu | +| p | | quit printing pwd | +| r | | quit printing result | +| s | | quit printing selection | -| key | remaps | action | -| ----- | ------ | ------------ | -| enter | | submit | -| tab | | try complete | +### relative_path_does_match_regex -### create_file +| key | remaps | action | +| ----- | ------ | ---------------- | +| enter | | submit | +| f1 | | global help menu | + +### rename + +| key | remaps | action | +| ----- | ------ | ---------------- | +| enter | | submit | +| f1 | | global help menu | +| tab | | try complete | + +### debug_error + +| key | remaps | action | +| ----- | ------ | ------------------- | +| enter | | open logs in editor | +| f1 | | global help menu | +| q | | quit | + +### action -| key | remaps | action | -| ----- | ------ | ------------ | -| enter | | submit | -| tab | | try complete | +| key | remaps | action | +| ----- | ------ | -------------------- | +| ! | | shell | +| c | | create | +| e | | open in editor | +| f1 | | global help menu | +| l | | logs | +| m | | toggle mouse | +| p | | edit permissions | +| q | | quit options | +| s | | selection operations | +| v | | vroot | +| [0-9] | | go to index | + +### selection_ops + +| key | remaps | action | +| --- | ------ | ---------------- | +| c | | copy here | +| e | | edit selection | +| f1 | | global help menu | +| h | | hardlink here | +| l | | list selection | +| m | | move here | +| s | | softlink here | +| u | | clear selection | ### search @@ -191,33 +211,69 @@ of [modes][4] and the key mappings for each mode. | ctrl-z | | toggle ordering | | enter | | submit | | esc | | cancel | +| f1 | | global help menu | | left | | back | | right | | enter | | tab | | toggle selection | +### duplicate_as + +| key | remaps | action | +| ----- | ------ | ---------------- | +| enter | | submit | +| f1 | | global help menu | +| tab | | try complete | + ### number -| key | remaps | action | -| ----- | ------ | -------- | -| down | j | to down | -| enter | | to index | -| k | up | to up | -| [0-9] | | input | +| key | remaps | action | +| ----- | ------ | ---------------- | +| down | j | to down | +| enter | | to index | +| f1 | | global help menu | +| k | up | to up | +| [0-9] | | input | -### action +### sort -| key | remaps | action | -| ----- | ------ | -------------------- | -| ! | | shell | -| c | | create | -| e | | open in editor | -| l | | logs | -| m | | toggle mouse | -| p | | edit permissions | -| q | | quit options | -| s | | selection operations | -| v | | vroot | -| [0-9] | | go to index | +| key | remaps | action | +| --------- | ------ | --------------------------------- | +| ! | | reverse sorters | +| C | | by created reverse | +| E | | by canonical extension reverse | +| L | | by last modified reverse | +| M | | by canonical mime essence reverse | +| N | | by node type reverse | +| R | | by relative path reverse | +| S | | by size reverse | +| backspace | | remove last sorter | +| c | | by created | +| ctrl-r | | reset sorters | +| ctrl-u | | clear sorters | +| e | | by canonical extension | +| enter | | submit | +| f1 | | global help menu | +| l | | by last modified | +| m | | by canonical mime essence | +| n | | by node type | +| r | | by relative path | +| s | | by size | + +### edit_permissions + +| key | remaps | action | +| ------ | ------ | ---------------- | +| G | | -group | +| M | | min | +| O | | -other | +| U | | -user | +| ctrl-r | | reset | +| enter | | submit | +| f1 | | global help menu | +| g | | +group | +| m | | max | +| o | | +other | +| u | | +user | ### filter @@ -227,39 +283,5 @@ of [modes][4] and the key mappings for each mode. | backspace | | remove last filter | | ctrl-r | | reset filters | | ctrl-u | | clear filters | +| f1 | | global help menu | | r | | relative path does match regex | - -### rename - -| key | remaps | action | -| ----- | ------ | ------------ | -| enter | | submit | -| tab | | try complete | - -### relative_path_does_not_match_regex - -| key | remaps | action | -| ----- | ------ | ------ | -| enter | | submit | - -### quit - -| key | remaps | action | -| ----- | ------ | ----------------------- | -| enter | | just quit | -| f | | quit printing focus | -| p | | quit printing pwd | -| r | | quit printing result | -| s | | quit printing selection | - -### recover - -| key | remaps | action | -| --- | ------ | ------ | - -### delete - -| key | remaps | action | -| --- | ------ | ------------ | -| D | | force delete | -| d | | delete | diff --git a/docs/en/src/messages.md b/docs/en/src/messages.md index 2bb2245..d4a9305 100644 --- a/docs/en/src/messages.md +++ b/docs/en/src/messages.md @@ -320,6 +320,24 @@ Example: - Lua: `"NextVisitedPath"` - YAML: `NextVisitedPath` +#### LastVisitedDeepBranch + +Go to the previous deep level branch. + +Example: + +- Lua: `"LastVisitedDeepBranch"` +- YAML: `LastVisitedDeepBranch` + +#### NextVisitedDeepBranch + +Go to the next deep level branch. + +Example: + +- Lua: `"NextVisitedDeepBranch"` +- YAML: `NextVisitedDeepBranch` + #### FollowSymlink Follow the symlink under focus to its actual location. diff --git a/src/app.rs b/src/app.rs index 55e77a7..e8c7856 100644 --- a/src/app.rs +++ b/src/app.rs @@ -135,6 +135,10 @@ impl History { self } + fn peek(&self) -> Option<&String> { + self.paths.get(self.loc) + } + fn push(mut self, path: String) -> Self { if self.peek() != Some(&path) { self.paths = self.paths.into_iter().take(self.loc + 1).collect(); @@ -167,8 +171,51 @@ impl History { self.cleanup() } - fn peek(&self) -> Option<&String> { - self.paths.get(self.loc) + fn _is_deepest_dir(&self, path: &str) -> bool { + return self + .paths + .iter() + .filter(|p| p.ends_with('/') && p.starts_with(path) && &path != p) + .next() + .is_none(); + } + + fn _uniq_deep_dirs(&self) -> IndexSet { + self.paths + .clone() + .into_iter() + .filter(|p| p.ends_with('/') && self._is_deepest_dir(p)) + .collect::>() + } + + fn visit_next_deep_branch(self, pwd: &str) -> Self { + let uniq_deep_dirs = self._uniq_deep_dirs(); + + if let Some(path) = uniq_deep_dirs + .iter() + .skip_while(|p| p.trim_end_matches('/') != pwd) + .skip(1) + .next() + { + self.push(path.to_string()) + } else { + self + } + } + + fn visit_last_deep_branch(self, pwd: &str) -> Self { + let uniq_deep_dirs = self._uniq_deep_dirs(); + if let Some(path) = uniq_deep_dirs + .iter() + .rev() + .skip_while(|p| p.trim_end_matches('/') != pwd) + .skip(1) + .next() + { + self.push(path.to_string()) + } else { + self + } } } @@ -505,6 +552,8 @@ impl App { Back => self.back(), LastVisitedPath => self.last_visited_path(), NextVisitedPath => self.next_visited_path(), + LastVisitedDeepBranch => self.last_visited_deep_branch(), + NextVisitedDeepBranch => self.next_visited_deep_branch(), FollowSymlink => self.follow_symlink(), SetVroot(p) => self.set_vroot(&p), UnsetVroot => self.unset_vroot(), @@ -1082,6 +1131,24 @@ impl App { } } + fn last_visited_deep_branch(mut self) -> Result { + self.history = self.history.visit_last_deep_branch(&self.pwd); + if let Some(path) = self.history.peek().cloned() { + self.change_directory(path.trim_end_matches('/'), false) + } else { + Ok(self) + } + } + + fn next_visited_deep_branch(mut self) -> Result { + self.history = self.history.visit_next_deep_branch(&self.pwd); + if let Some(path) = self.history.peek().cloned() { + self.change_directory(path.trim_end_matches('/'), false) + } else { + Ok(self) + } + } + fn set_input_prompt(mut self, p: String) -> Result { self.input.prompt = p; Ok(self) diff --git a/src/init.lua b/src/init.lua index 28f0a71..c3c9846 100644 --- a/src/init.lua +++ b/src/init.lua @@ -157,11 +157,11 @@ xplr.config.general.logs.error.style = { fg = "Red" } -- * format: nullable string -- * style: [Style](https://xplr.dev/en/style) xplr.config.general.table.header.cols = { - { format = " index", style = {} }, + { format = " index", style = {} }, { format = "╭─── path", style = {} }, - { format = "perm", style = {} }, - { format = "size", style = {} }, - { format = "modified", style = {} }, + { format = "perm", style = {} }, + { format = "size", style = {} }, + { format = "modified", style = {} }, } -- Style of the table header. @@ -1123,6 +1123,18 @@ xplr.config.modes.builtin.default = { "LastVisitedPath", }, }, + [")"] = { + help = "next deep branch", + messages = { + "NextVisitedDeepBranch", + }, + }, + ["("] = { + help = "last deep branch", + messages = { + "LastVisitedDeepBranch", + }, + }, ["ctrl-r"] = { help = "refresh screen", messages = { diff --git a/src/msg/in_/external.rs b/src/msg/in_/external.rs index 22d4d35..1a136f6 100644 --- a/src/msg/in_/external.rs +++ b/src/msg/in_/external.rs @@ -277,6 +277,22 @@ pub enum ExternalMsg { /// - YAML: `NextVisitedPath` NextVisitedPath, + /// Go to the previous deep level branch. + /// + /// Example: + /// + /// - Lua: `"LastVisitedDeepBranch"` + /// - YAML: `LastVisitedDeepBranch` + LastVisitedDeepBranch, + + /// Go to the next deep level branch. + /// + /// Example: + /// + /// - Lua: `"NextVisitedDeepBranch"` + /// - YAML: `NextVisitedDeepBranch` + NextVisitedDeepBranch, + /// Follow the symlink under focus to its actual location. /// /// Example: