diff --git a/README.md b/README.md index 42f3e9e..b4d7923 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- ▸[▓▓ xplr] + ▸[▓▓ xplr]

@@ -8,19 +8,19 @@ A hackable, minimal, fast TUI file explorer

- + - + - + Matrix - + @@ -30,6 +30,13 @@ A hackable, minimal, fast TUI file explorer

+

+ [Install] + [Documentation] + [Plugins] + [Community] +

+ `xplr` is a terminal UI based file explorer that aims to increase our terminal productivity by being a flexible, interactive orchestrator for the ever growing awesome command-line utilities that work with the file-system. @@ -43,50 +50,14 @@ intuitive, scriptable, keyboard controlled, real-time visual interface, also being an ideal candidate for further integration, enabling the users to achieve insane terminal productivity. -Table of content ----------------- - -- [Introduction](https://xplr.dev/en/introduction.html) -- [Quickstart](https://xplr.dev/en/quickstart.html) - - [Install](https://xplr.dev/en/install.html) - - [Post Install](https://xplr.dev/en/post-install.html) -- [Configuration](https://xplr.dev/en/configuration.html) - - [General Config](https://xplr.dev/en/general-config.html) - - [Modes](https://xplr.dev/en/modes.html) - - [Message](https://xplr.dev/en/message.html) - - [Layouts](https://xplr.dev/en/layouts.html) - - [Node Types](https://xplr.dev/en/node_types.html) - - [Style](https://xplr.dev/en/style.html) - - [Sorting](https://xplr.dev/en/sorting.html) - - [Filtering](https://xplr.dev/en/filtering.html) - - [Column Renderer](https://xplr.dev/en/column-renderer.html) -- [Default Key Bindings](https://xplr.dev/en/default-key-bindings.html) -- [Plugin](https://xplr.dev/en/plugin.html) - - [Installing Plugins](https://xplr.dev/en/installing-plugins.html) - - [Writing Plugins](https://xplr.dev/en/writing-plugins.html) - - [Awesome Plugins](https://xplr.dev/en/awesome-plugins.html) -- [Integration](https://xplr.dev/en/integration.html) - - [Awesome Integrations](https://xplr.dev/en/awesome-integrations.html) -- [TODO](https://xplr.dev/en/todo.html) -- [Alternatives](https://xplr.dev/en/alternatives.html) -- [Upgrade Guide](https://xplr.dev/en/upgrade-guide.html) -- [Community](https://xplr.dev/en/community.html) -- [Contribute](https://xplr.dev/en/contribute.html) - - -Introductions & Reviews ------------------------ +## Introductions & Reviews - [[VIDEO] XPLR: Insanely Hackable Lua File Manager ~ Brodie Robertson](https://youtu.be/MaVRtYh1IRU) +## Packaging -Packaging ---------- - - - + -Backers -------- +## Backers - + diff --git a/docs/en/src/SUMMARY.md b/docs/en/src/SUMMARY.md index 6c7372b..7683f62 100644 --- a/docs/en/src/SUMMARY.md +++ b/docs/en/src/SUMMARY.md @@ -5,6 +5,10 @@ - [Install][3] - [Post Install][4] - [Configuration][5] + - [Key Bindings][27] + - [Configure Key Bindings][28] + - [Default Key Bindings][14] + - [Debug Key Bindings][29] - [General Config][6] - [Modes][7] - [Message][8] @@ -14,7 +18,6 @@ - [Sorting][12] - [Filtering][13] - [Column Renderer][26] -- [Default Key Bindings][14] - [Plugin][15] - [Installing Plugins][16] - [Writing Plugins][17] @@ -53,3 +56,6 @@ [24]: community.md [25]: contribute.md [26]: column-renderer.md +[27]: key-bindings.md +[28]: configure-key-bindings.md +[29]: debug-key-bindings.md diff --git a/docs/en/src/configure-key-bindings.md b/docs/en/src/configure-key-bindings.md new file mode 100644 index 0000000..96d5f68 --- /dev/null +++ b/docs/en/src/configure-key-bindings.md @@ -0,0 +1,223 @@ +# Configure Key Bindings + +In xplr, each keyboard input passes through a bunch of handlers (e.g. `on_key`, +`on_number`, `default` etc.) in a given order. If any of the handlers is +configured to with an [action][16], it will intercept the key and produce +[messages][18] for xplr to handle. + +## Key Bindings + +Key bindings contains the following information: + +- [on_key][10] +- [on_alphabet][11] +- [on_number][12] +- [on_alphanumeric][32] +- [on_special_character][13] +- [on_character][33] +- [on_navigation][34] +- [default][14] + +### on_key + +Type: mapping of [Key][15] to nullable [Action][16] + +Defines what to do when an exact key is pressed. + +### on_alphabet + +Type: nullable [Action][16] + +An action to perform if the keyboard input is an alphabet and is not mapped via +the [on_key][10] field. + +### on_number + +Type: nullable [Action][16] + +An action to perform if the keyboard input is a number and is not mapped via +the [on_key][10] field. + +### on_alphanumeric + +Type: nullable [Action][16] + +An action to perform if the keyboard input is alphanumeric and is not mapped +via the [on_key][10], [on_alphabet][11] or [on_number][12] field. + +### on_special_character + +Type: nullable [Action][16] + +An action to perform if the keyboard input is a special character and is not +mapped via the [on_key][10] field. + +### on_character + +Type: nullable [Action][16] + +An action to perform if the keyboard input is a character and is not mapped +via the [on_key][10], [on_alphabet][11], [on_number][12], [on_alphanumeric][32] +or [on_special_character][13] field. + +### on_navigation + +Type: nullable [Action][16] + +An action to perform if the keyboard input is a navigation key and is not +mapped via the [on_key][10] field. + +### default + +Type: nullable [Action][16] + +Default action to perform in case if a keyboard input not mapped via any of the +`on_*` fields mentioned above. + +## Key + +A key can be one of the following: + +- 0, 1, ... 9 +- a, b, ... z +- A, B, ... Z +- f1, f2, ... f12 +- backspace +- left +- right +- up +- down +- home +- end +- page-up +- page-down +- back-tab +- delete +- insert +- enter +- tab +- esc +- ctrl-a, ctrl-b, ... ctrl-z +- ctrl-backspace, ctrl-left, ... ctrl-esc +- alt-a, alt-b, ... alt-z + +And finally, the special characters - including space (`" "`) with their `ctrl` +bindings. + +## Action + +An action contains the following information: + +- [help][1] +- [messages][17] + +### help + +Type: nullable string + +Description of what it does. If unspecified, it will be excluded from the help +menu. + +### messages + +Type: A list of [Message][18] to send. + +The list of messages to send when a key is pressed. + +## Tutorial: Adding a New Mode + +Assuming xplr is [installed][19] and [setup][20], let's +add our own mode to integrate xplr with [fzf][21]. + +We'll call it `fzxplr` mode. + +First, let's add a custom mode called `fzxplr`, and map the key `F` to an +action that will call `fzf` to search and focus on a file or enter into a +directory. + +```lua +xplr.config.modes.custom.fzxplr = { + name = "fzxplr", + key_bindings = { + on_key = { + F = { + help = "search", + messages = { + { + BashExec = [===[ + PTH=$(cat "${XPLR_PIPE_DIRECTORY_NODES_OUT:?}" | awk -F/ '{print $NF}' | fzf) + if [ -d "$PTH" ]; then + echo ChangeDirectory: "'"${PWD:?}/${PTH:?}"'" >> "${XPLR_PIPE_MSG_IN:?}" + else + echo FocusPath: "'"${PWD:?}/${PTH:?}"'" >> "${XPLR_PIPE_MSG_IN:?}" + fi + ]===] + }, + "PopMode", + }, + }, + }, + default = { + messages = { + "PopMode", + }, + }, + }, +} +``` + +As you can see, the key `F` in mode `fzxplr` (the name can be anything) +executes a script in `bash`. + +`BashExec`, `PopMode`, `SwitchModeBuiltin`, `ChangeDirectory` and `FocusPath` +are [messages][18], `$XPLR_PIPE_MSG_IN`, +`$XPLR_PIPE_DIRECTORY_NODES_OUT` are +[environment variables][22] exported by `xplr` +before executing the command. They contain the path to the +[input][23] and [output][24] pipes that +allows external tools to interact with `xplr`. + +Now that we have our new mode ready, let's add an entry point to this mode via +the `default` mode. + +```lua +xplr.config.modes.builtin.default.key_bindings.on_key["F"] = { + help = "fzf mode", + messages = { + { SwitchModeCustom = "fzxplr" }, + }, +} +``` + +Now let's try out the new `xplr`-`fzf` integration. + +[![xplr-fzf.gif][25]][26] + +--- + +Visit [Awesome Plugins][27] for more [integration][28] options. + +[1]: #help +[10]: #on_key +[11]: #on_alphabet +[12]: #on_number +[13]: #on_special_character +[14]: #default +[15]: #key +[16]: #action +[17]: #messages +[18]: message.md#message +[19]: install.md +[20]: post-install.md +[21]: https://github.com/junegunn/fzf +[22]: message.md#environment-variables +[23]: message.md#input-pipe +[24]: message.md#output-pipes +[25]: https://s3.gifyu.com/images/xplr-fzf.gif +[26]: https://gifyu.com/image/tW86 +[27]: awesome-plugins.md +[28]: awesome-plugins.md#integration +[31]: debug-key-bindings.md +[32]: #on_alphanumeric +[33]: #on_character +[34]: #on_navigation diff --git a/docs/en/src/debug-key-bindings.md b/docs/en/src/debug-key-bindings.md new file mode 100644 index 0000000..cccf864 --- /dev/null +++ b/docs/en/src/debug-key-bindings.md @@ -0,0 +1,93 @@ +# Debug Key Bindings + +If you need help debugging or understanding key bindings DYI way, you can +create a `test.lua` file with the following script, launch xplr with +`xplr --extra-config text.lua`, press `#` and play around. + +```lua +xplr.config.modes.builtin.default.key_bindings.on_key["#"] = { + help = "test", + messages = { + "PopMode", + { SwitchModeCustom = "test" }, + }, +} + +xplr.config.modes.custom.test = { + name = "test", + key_bindings = { + on_key = { + ["1"] = { + messages = { + { LogInfo = "on_key called" }, + }, + }, + a = { + messages = { + { LogInfo = "on_key called" }, + }, + }, + ["`"] = { + messages = { + { LogInfo = "on_key called" }, + }, + }, + f1 = { + messages = { + { LogInfo = "on_key called" }, + }, + }, + tab = { + messages = { + { LogInfo = "on_key called" }, + }, + }, + esc = { + messages = { + "PopMode", + }, + }, + ["ctrl-c"] = { + messages = { + "Terminate", + }, + }, + }, + on_alphabet = { + messages = { + { LogInfo = "on_alphabet called" }, + }, + }, + on_number = { + messages = { + { LogInfo = "on_number called" }, + }, + }, + -- on_alphanumeric = { + -- messages = { + -- { LogInfo = "on_alphanumeric called" }, + -- }, + -- }, + on_special_character = { + messages = { + { LogInfo = "on_special_character called" }, + }, + }, + -- on_character = { + -- messages = { + -- { LogInfo = "on_character called" }, + -- }, + -- }, + on_navigation = { + messages = { + { LogInfo = "on_navigation called" }, + }, + }, + default = { + messages = { + { LogInfo = "default called" }, + }, + }, + }, +} +``` diff --git a/docs/en/src/default-key-bindings.md b/docs/en/src/default-key-bindings.md index 2ed005c..ed1ce1b 100644 --- a/docs/en/src/default-key-bindings.md +++ b/docs/en/src/default-key-bindings.md @@ -1,8 +1,8 @@ # Default Key Bindings The default key binding is inspired by [vim][1] and slightly -overlaps with [nnn][2], but it's supposed to be -customized as per user requirements. +overlaps with [nnn][2], but it's supposed to be customized as per user +requirements. When you press `?` in [default mode][3], you can see the complete list of [modes][4] and the key mappings for each mode. @@ -47,29 +47,25 @@ of [modes][4] and the key mappings for each mode. ### filter -| key | remaps | action | -| --------- | ------ | ------------------------- | -| R | | relative does not contain | -| backspace | | remove last filter | -| ctrl-c | | terminate | -| ctrl-r | | reset filters | -| ctrl-u | | clear filters | -| enter | esc | done | -| r | | relative does contain | +| key | remaps | action | +| ------ | ------ | ------------------------- | +| R | | relative does not contain | +| ctrl-c | | terminate | +| ctrl-r | | reset filters | +| ctrl-u | | clear filters | +| enter | esc | done | +| r | | relative does contain | ### number -| key | remaps | action | -| --------- | ------ | --------------------- | -| backspace | | remove last character | -| ctrl-c | | terminate | -| ctrl-u | | remove line | -| ctrl-w | | remove last word | -| down | j | to down | -| enter | | to index | -| esc | | cancel | -| k | up | to up | -| [0-9] | | input | +| key | remaps | action | +| ------ | ------ | --------- | +| ctrl-c | | terminate | +| down | j | to down | +| enter | | to index | +| esc | | cancel | +| k | up | to up | +| [0-9] | | input | ### go to @@ -83,18 +79,15 @@ of [modes][4] and the key mappings for each mode. ### search -| key | remaps | action | -| --------- | ------ | --------------------- | -| backspace | | remove last character | -| ctrl-c | | terminate | -| ctrl-n | down | down | -| ctrl-p | up | up | -| ctrl-u | | remove line | -| ctrl-w | | remove last word | -| enter | esc | focus | -| left | | back | -| right | | enter | -| tab | | toggle selection | +| key | remaps | action | +| ------ | ------ | ---------------- | +| ctrl-c | | terminate | +| ctrl-n | down | down | +| ctrl-p | up | up | +| enter | esc | focus | +| left | | back | +| right | | enter | +| tab | | toggle selection | ### selection ops @@ -132,36 +125,27 @@ of [modes][4] and the key mappings for each mode. ### create file -| key | remaps | action | -| --------- | ------ | --------------------- | -| backspace | | remove last character | -| ctrl-c | | terminate | -| ctrl-u | | remove line | -| ctrl-w | | remove last word | -| enter | | create file | -| esc | | cancel | +| key | remaps | action | +| ------ | ------ | ----------- | +| ctrl-c | | terminate | +| enter | | create file | +| esc | | cancel | ### create directory -| key | remaps | action | -| --------- | ------ | --------------------- | -| backspace | | remove last character | -| ctrl-c | | terminate | -| ctrl-u | | remove line | -| ctrl-w | | remove last word | -| enter | | create directory | -| esc | | cancel | +| key | remaps | action | +| ------ | ------ | ---------------- | +| ctrl-c | | terminate | +| enter | | create directory | +| esc | | cancel | ### rename -| key | remaps | action | -| --------- | ------ | --------------------- | -| backspace | | remove last character | -| ctrl-c | | terminate | -| ctrl-u | | remove line | -| ctrl-w | | remove last word | -| enter | | rename | -| esc | | cancel | +| key | remaps | action | +| ------ | ------ | --------- | +| ctrl-c | | terminate | +| enter | | rename | +| esc | | cancel | ### delete @@ -195,37 +179,30 @@ of [modes][4] and the key mappings for each mode. ### filter -| key | remaps | action | -| --------- | ------ | ------------------------- | -| R | | relative does not contain | -| backspace | | remove last filter | -| ctrl-c | | terminate | -| ctrl-r | | reset filters | -| ctrl-u | | clear filters | -| enter | esc | done | -| r | | relative does contain | +| key | remaps | action | +| ------ | ------ | ------------------------- | +| R | | relative does not contain | +| ctrl-c | | terminate | +| ctrl-r | | reset filters | +| ctrl-u | | clear filters | +| enter | esc | done | +| r | | relative does contain | ### relative path does contain -| key | remaps | action | -| --------- | ------ | --------------------- | -| backspace | | remove last character | -| ctrl-c | | terminate | -| ctrl-u | | remove line | -| ctrl-w | | remove last word | -| enter | | apply filter | -| esc | | cancel | +| key | remaps | action | +| ------ | ------ | ------------ | +| ctrl-c | | terminate | +| enter | | apply filter | +| esc | | cancel | ### relative path does not contain -| key | remaps | action | -| --------- | ------ | --------------------- | -| backspace | | remove last character | -| ctrl-c | | terminate | -| ctrl-u | | remove line | -| ctrl-w | | remove last word | -| enter | | apply filter | -| esc | | cancel | +| key | remaps | action | +| ------ | ------ | ------------ | +| ctrl-c | | terminate | +| enter | | apply filter | +| esc | | cancel | ### switch layout diff --git a/docs/en/src/key-bindings.md b/docs/en/src/key-bindings.md index fc333e3..0eb1d20 100644 --- a/docs/en/src/key-bindings.md +++ b/docs/en/src/key-bindings.md @@ -1 +1,16 @@ # Key Bindings + +Key bindings define how each keyboard input will be handled while in a specific +[mode][4]. + +See the [Default key bindings][1] for example. + +To configure or work with key bindings, visit [Configure Key Bindings][2]. + +In case you need help debugging key bindings or to understand the system DYI +way, refer to the [Debug Key Bindings][3] guide. + +[1]: default-key-bindings.md +[2]: configure-key-bindings.md +[3]: debug-key-bindings.md +[4]: modes.md#mode diff --git a/docs/en/src/message.md b/docs/en/src/message.md index bcbc1f7..1ecb02e 100644 --- a/docs/en/src/message.md +++ b/docs/en/src/message.md @@ -1217,7 +1217,7 @@ xplr.config.modes.builtin.default.key_bindings.on_key.space = { ``` [1]: #full-list-of-messages -[2]: modes.md#key-bindings +[2]: key-bindings.md [3]: #lua-function-calls [4]: #input-pipe [5]: https://www.lua.org/ @@ -1234,7 +1234,7 @@ xplr.config.modes.builtin.default.key_bindings.on_key.space = { [16]: filtering.md [17]: sorting.md#sorter [18]: https://docs.rs/xplr/latest/xplr/app/struct.CallLuaArg.html#fields -[19]: modes.md#tutorial-adding-a-new-mode +[19]: configure-key-bindings.md#tutorial-adding-a-new-mode [20]: #xplr_pipe_msg_in [21]: #xplr_pipe_selection_out [22]: #xplr_pipe_global_help_menu_out diff --git a/docs/en/src/modes.md b/docs/en/src/modes.md index 03a1bdf..500e16c 100644 --- a/docs/en/src/modes.md +++ b/docs/en/src/modes.md @@ -81,7 +81,7 @@ A mode contains the following information: - [help][6] - [extra_help][7] - [key_bindings][8] -- [layout][29] +- [layout][10] ### name @@ -111,180 +111,10 @@ The key bindings available in that mode. ### layout -Type: nullable [Layout][30] +Type: nullable [Layout][11] If specified, this layout will be used to render the UI. -## Key Bindings - -Key bindings define how each keyboard input will be handled in a specific mode. - -See the [default key bindings][4] for example. - -Key bindings contains the following information: - -- [on_key][10] -- [on_alphabet][11] -- [on_number][12] -- [on_special_character][13] -- [default][14] - -### on_key - -Type: mapping of [Key][15] to nullable [Action][16] - -Defines what to do when a specific key is pressed. - -### on_alphabet - -Type: nullable [Action][16] - -An action to perform if the keyboard input is an alphabet and is not mapped via -the [on_key][10] field. - -### on_number - -Type: nullable [Action][16] - -An action to perform if the keyboard input is a number and is not mapped via -the [on_key][10] field. - -### on_special_character - -Type: nullable [Action][16] - -An action to perform if the keyboard input is a special character and is not -mapped via the [on_key][10] field. - -### default - -Type: nullable [Action][16] - -Default action to perform in case of a keyboard input not mapped via any of the -[on_key][10], [on_alphabet][11], [on_number][12] or -[on_special_character][13] field. - -## Key - -A key can be one of the following: - -- 0, 1, ... 9 -- a, b, ... z -- A, B, ... Z -- f1, f2, ... f12 -- ctrl-a, ctrl-b, ... ctrl-z -- alt-a, alt-b, ... alt-z -- backspace -- left -- right -- up -- down -- home -- end -- page-up -- page-down -- back-tab -- delete -- insert -- enter -- tab -- esc - -And finally, the special characters - including space (`" "`). - -## Action - -An action contains the following information: - -- help -- [messages][17] - -### help - -Type: nullable string - -Description of what it does. If unspecified, it will be excluded from the help -menu. - -### messages - -Type: A list of [Message][18] to send. - -The list of messages to send when a key is pressed. - -## Tutorial: Adding a New Mode - -Assuming xplr is [installed][19] and [setup][20], let's -add our own mode to integrate xplr with [fzf][21]. - -We'll call it `fzxplr` mode. - -First, let's add a custom mode called `fzxplr`, and map the key `F` to an -action that will call `fzf` to search and focus on a file or enter into a -directory. - -```lua -xplr.config.modes.custom.fzxplr = { - name = "fzxplr", - key_bindings = { - on_key = { - F = { - help = "search", - messages = { - { - BashExec = [===[ - PTH=$(cat "${XPLR_PIPE_DIRECTORY_NODES_OUT:?}" | awk -F/ '{print $NF}' | fzf) - if [ -d "$PTH" ]; then - echo ChangeDirectory: "'"${PWD:?}/${PTH:?}"'" >> "${XPLR_PIPE_MSG_IN:?}" - else - echo FocusPath: "'"${PWD:?}/${PTH:?}"'" >> "${XPLR_PIPE_MSG_IN:?}" - fi - ]===] - }, - "PopMode", - }, - }, - }, - default = { - messages = { - "PopMode", - }, - }, - }, -} -``` - -As you can see, the key `F` in mode `fzxplr` (the name can be anything) -executes a script in `bash`. - -`BashExec`, `PopMode`, `SwitchModeBuiltin`, `ChangeDirectory` and `FocusPath` -are [messages][18], `$XPLR_PIPE_MSG_IN`, -`$XPLR_PIPE_DIRECTORY_NODES_OUT` are -[environment variables][22] exported by `xplr` -before executing the command. They contain the path to the -[input][23] and [output][24] pipes that -allows external tools to interact with `xplr`. - -Now that we have our new mode ready, let's add an entry point to this mode via -the `default` mode. - -```lua -xplr.config.modes.builtin.default.key_bindings.on_key["F"] = { - help = "fzf mode", - messages = { - { SwitchModeCustom = "fzxplr" }, - }, -} -``` - -Now let's try out the new `xplr`-`fzf` integration. - -[![xplr-fzf.gif][25]][26] - ---- - -Visit [Awesome Plugins][27] for more [integration][28] options. - [1]: #builtin [2]: #custom [3]: #mode @@ -292,26 +122,7 @@ Visit [Awesome Plugins][27] for more [integration][28] options. [5]: #name [6]: #help [7]: #extra_help -[8]: #key_bindings +[8]: configure-key-bindings.md#key-bindings [9]: #key-bindings -[10]: #on_key -[11]: #on_alphabet -[12]: #on_number -[13]: #on_special_character -[14]: #default -[15]: #key -[16]: #action -[17]: #messages -[18]: message.md -[19]: install.md -[20]: post-install.md -[21]: https://github.com/junegunn/fzf -[22]: message.md#environment-variables -[23]: message.md#input-pipe -[24]: message.md#output-pipes -[25]: https://s3.gifyu.com/images/xplr-fzf.gif -[26]: https://gifyu.com/image/tW86 -[27]: awesome-plugins.md -[28]: awesome-plugins.md#integration -[29]: #layout -[30]: layouts.md#Layout +[10]: #layout +[11]: layouts.md#Layout diff --git a/docs/en/src/writing-plugins.md b/docs/en/src/writing-plugins.md index e3c86d7..d0a8c78 100644 --- a/docs/en/src/writing-plugins.md +++ b/docs/en/src/writing-plugins.md @@ -74,7 +74,7 @@ Visit [Awesome Plugins][5] for xplr plugin examples. [3]: https://neovim.io [4]: https://github.com/sayanarijit/xplr/discussions/categories/show-and-tell [5]: awesome-plugins.md -[6]: modes.md#tutorial-adding-a-new-mode +[6]: configure-key-bindings.md#tutorial-adding-a-new-mode [7]: message.md#example-using-environment-variables-and-pipes [8]: message.md#example-using-lua-function-calls [9]: layouts.md#example-defining-custom-layout diff --git a/docs/index.html b/docs/index.html index 58e59fb..c5c82ce 100644 --- a/docs/index.html +++ b/docs/index.html @@ -66,6 +66,7 @@ file explorer


+

Try or Install

Result { let kb = self.mode.key_bindings.clone(); let key_str = key.to_string(); - let default = kb.default.clone(); let msgs = kb .on_key .get(&key_str) - .to_owned() - .map(|a| Some(a.messages.clone())) - .unwrap_or_else(|| { + .map(|a| a.messages.clone()) + .or_else(|| { if key.is_alphabet() { - kb.on_alphabet.clone().map(|a| a.messages) + kb.on_alphabet.as_ref().map(|a| a.messages.clone()) } else if key.is_number() { - kb.on_number.clone().map(|a| a.messages) + kb.on_number.as_ref().map(|a| a.messages.clone()) + } else { + None + } + }) + .or_else(|| { + if key.is_alphanumeric() { + kb.on_alphanumeric.as_ref().map(|a| a.messages.clone()) } else if key.is_special_character() { - kb.on_special_character.clone().map(|a| a.messages) + kb.on_special_character.as_ref().map(|a| a.messages.clone()) + } else { + None + } + }) + .or_else(|| { + if key.is_character() { + kb.on_character.as_ref().map(|a| a.messages.clone()) + } else if key.is_navigation() { + kb.on_navigation.as_ref().map(|a| a.messages.clone()) } else { None } }) - .or_else(|| default.map(|a| a.messages)) + .or_else(|| kb.default.as_ref().map(|a| a.messages.clone())) .unwrap_or_else(|| { if self.config.general.enable_recover_mode { vec![ExternalMsg::SwitchModeBuiltin("recover".into())] diff --git a/src/config.rs b/src/config.rs index 3631515..ded5f5f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -279,9 +279,18 @@ pub struct KeyBindings { #[serde(default)] pub on_number: Option, + #[serde(default)] + pub on_alphanumeric: Option, + #[serde(default)] pub on_special_character: Option, + #[serde(default)] + pub on_character: Option, + + #[serde(default)] + pub on_navigation: Option, + #[serde(default)] pub default: Option, } diff --git a/src/init.lua b/src/init.lua index c6d5fb4..4e9d530 100644 --- a/src/init.lua +++ b/src/init.lua @@ -949,7 +949,6 @@ xplr.config.modes.builtin.default = { }, }, }, - on_alphabet = nil, on_number = { help = "input", messages = { @@ -958,8 +957,6 @@ xplr.config.modes.builtin.default = { "BufferInputFromKey", }, }, - on_special_character = nil, - default = nil, }, } @@ -1102,10 +1099,6 @@ xplr.config.modes.builtin.selection_ops = { }, }, }, - on_alphabet = nil, - on_number = nil, - on_special_character = nil, - default = nil, }, } @@ -1149,10 +1142,6 @@ xplr.config.modes.builtin.create = { }, }, }, - on_alphabet = nil, - on_number = nil, - on_special_character = nil, - default = nil, }, } @@ -1191,11 +1180,7 @@ xplr.config.modes.builtin.create_directory = { messages = { "PopMode" }, }, }, - on_alphabet = nil, - on_number = nil, - on_special_character = nil, default = { - help = nil, messages = { "UpdateInputBufferFromKey" }, }, }, @@ -1236,11 +1221,8 @@ xplr.config.modes.builtin.create_file = { messages = { "PopMode" }, }, }, - on_alphabet = nil, - on_number = nil, on_special_character = nil, default = { - help = nil, messages = { "UpdateInputBufferFromKey" }, }, }, @@ -1274,13 +1256,13 @@ xplr.config.modes.builtin.number = { messages = { "FocusPreviousByRelativeIndexFromInput", "PopMode" }, }, }, - on_alphabet = nil, + on_navigation = { + messages = { "UpdateInputBufferFromKey" }, + }, on_number = { help = "input", messages = { "UpdateInputBufferFromKey" }, }, - on_special_character = nil, - default = nil, }, } @@ -1335,10 +1317,6 @@ xplr.config.modes.builtin.go_to = { }, }, }, - on_alphabet = nil, - on_number = nil, - on_special_character = nil, - default = nil, }, } @@ -1374,9 +1352,6 @@ xplr.config.modes.builtin.rename = { messages = { "PopMode" }, }, }, - on_alphabet = nil, - on_number = nil, - on_special_character = nil, default = { help = nil, messages = { "UpdateInputBufferFromKey" }, @@ -1446,10 +1421,6 @@ xplr.config.modes.builtin.delete = { messages = { "PopMode" }, }, }, - on_alphabet = nil, - on_number = nil, - on_special_character = nil, - default = nil, }, } @@ -1537,7 +1508,6 @@ xplr.config.modes.builtin.action = { }, }, }, - on_alphabet = nil, on_number = { help = "go to index", messages = { @@ -1548,8 +1518,6 @@ xplr.config.modes.builtin.action = { "BufferInputFromKey", }, }, - on_special_character = nil, - default = nil, }, } @@ -1666,11 +1634,7 @@ xplr.config.modes.builtin.search = { messages = { "FocusPrevious" }, }, }, - on_alphabet = nil, - on_number = nil, - on_special_character = nil, default = { - help = nil, messages = { { RemoveNodeFilterFromInput = "IRelativePathDoesContain", @@ -1746,10 +1710,6 @@ xplr.config.modes.builtin.filter = { }, }, }, - on_alphabet = nil, - on_number = nil, - on_special_character = nil, - default = nil, }, } @@ -1782,9 +1742,6 @@ xplr.config.modes.builtin.relative_path_does_contain = { }, }, }, - on_alphabet = nil, - on_number = nil, - on_special_character = nil, default = { help = nil, messages = { @@ -1827,9 +1784,6 @@ xplr.config.modes.builtin.relative_path_does_not_contain = { }, }, }, - on_alphabet = nil, - on_number = nil, - on_special_character = nil, default = { help = nil, messages = { @@ -2000,32 +1954,18 @@ xplr.config.modes.builtin.sort = { ["r"] = { help = "by relative path", messages = { - { - AddNodeSorter = { - sorter = "ByIRelativePath", - reverse = false, - }, - }, + { AddNodeSorter = { sorter = "ByIRelativePath", reverse = false } }, "ExplorePwdAsync", }, }, ["s"] = { help = "by size", messages = { - { - AddNodeSorter = { - sorter = "BySize", - reverse = false, - }, - }, + { AddNodeSorter = { sorter = "BySize", reverse = false } }, "ExplorePwdAsync", }, }, }, - on_alphabet = nil, - on_number = nil, - on_special_character = nil, - default = nil, }, } @@ -2084,10 +2024,6 @@ xplr.config.modes.builtin.switch_layout = { messages = { "PopMode" }, }, }, - on_alphabet = nil, - on_number = nil, - on_special_character = nil, - default = nil, }, } diff --git a/src/input.rs b/src/input.rs index dca00f2..0fef12d 100644 --- a/src/input.rs +++ b/src/input.rs @@ -197,7 +197,7 @@ impl std::fmt::Display for Key { _ => c.to_string(), }) .unwrap_or_else(|| { - serde_yaml::to_value(self) + serde_yaml::to_value(&self) .ok() .and_then(|v| v.as_str().map(|v| v.to_string())) .unwrap_or_default() @@ -208,32 +208,27 @@ impl std::fmt::Display for Key { } impl Key { - pub fn to_input_request(self) -> Option { + pub fn to_input_request(&self) -> Option { use InputRequest::*; use Key::*; - if self.is_alphabet() || self.is_number() || self.is_special_character() - { - self.to_char().map(InsertChar) - } else { - match self { - Backspace => Some(DeletePrevChar), - Delete => Some(DeleteNextChar), - Tab => Some(InsertChar('\t')), - Space => Some(InsertChar(' ')), - Left => Some(GoToPrevChar), - CtrlLeft => Some(GoToPrevWord), - Right => Some(GoToNextChar), - CtrlRight => Some(GoToNextWord), - CtrlU => Some(DeleteLine), - CtrlW => Some(DeletePrevWord), - CtrlDelete => Some(DeleteNextWord), - CtrlA => Some(GoToStart), - CtrlE => Some(GoToEnd), - Enter => Some(Submit), - Esc => Some(Escape), - _ => None, - } + match self { + Backspace => Some(DeletePrevChar), + Delete => Some(DeleteNextChar), + Tab => Some(InsertChar('\t')), + Space => Some(InsertChar(' ')), + Left => Some(GoToPrevChar), + CtrlLeft => Some(GoToPrevWord), + Right => Some(GoToNextChar), + CtrlRight => Some(GoToNextWord), + CtrlU => Some(DeleteLine), + CtrlW => Some(DeletePrevWord), + CtrlDelete => Some(DeleteNextWord), + CtrlA => Some(GoToStart), + CtrlE => Some(GoToEnd), + Enter => Some(Submit), + Esc => Some(Escape), + key => key.to_char().map(InsertChar), } } @@ -444,11 +439,109 @@ impl Key { ) } + pub fn is_alphanumeric(&self) -> bool { + self.is_alphabet() || self.is_number() + } + pub fn is_special_character(&self) -> bool { - matches!(self, Self::Special(_)) + matches!(&self, Self::Special(_)) + } + + pub fn is_character(&self) -> bool { + self.is_alphanumeric() || self.is_special_character() + } + + pub fn is_navigation(&self) -> bool { + matches!( + &self, + Self::Backspace + | Self::Left + | Self::Right + | Self::Up + | Self::Down + | Self::Home + | Self::End + | Self::PageUp + | Self::PageDown + | Self::BackTab + | Self::Delete + | Self::Insert + | Self::Enter + | Self::Space + | Self::Tab + | Self::Esc + | Self::CtrlA + | Self::CtrlB + | Self::CtrlC + | Self::CtrlD + | Self::CtrlE + | Self::CtrlF + | Self::CtrlG + | Self::CtrlH + | Self::CtrlI + | Self::CtrlJ + | Self::CtrlK + | Self::CtrlL + | Self::CtrlM + | Self::CtrlN + | Self::CtrlO + | Self::CtrlP + | Self::CtrlQ + | Self::CtrlR + | Self::CtrlS + | Self::CtrlT + | Self::CtrlU + | Self::CtrlV + | Self::CtrlW + | Self::CtrlX + | Self::CtrlY + | Self::CtrlZ + | Self::CtrlBackspace + | Self::CtrlLeft + | Self::CtrlRight + | Self::CtrlUp + | Self::CtrlDown + | Self::CtrlHome + | Self::CtrlEnd + | Self::CtrlPageUp + | Self::CtrlPageDown + | Self::CtrlBackTab + | Self::CtrlDelete + | Self::CtrlInsert + | Self::CtrlEnter + | Self::CtrlSpace + | Self::CtrlTab + | Self::CtrlEsc + | Self::AltA + | Self::AltB + | Self::AltC + | Self::AltD + | Self::AltE + | Self::AltF + | Self::AltG + | Self::AltH + | Self::AltI + | Self::AltJ + | Self::AltK + | Self::AltL + | Self::AltM + | Self::AltN + | Self::AltO + | Self::AltP + | Self::AltQ + | Self::AltR + | Self::AltS + | Self::AltT + | Self::AltU + | Self::AltV + | Self::AltW + | Self::AltX + | Self::AltY + | Self::AltZ + ) } - pub fn to_char(self) -> Option { + pub fn to_char(&self) -> Option { match self { Self::Num0 => Some('0'), Self::Num1 => Some('1'),