Skip to content

Conversation

@trevarj
Copy link
Contributor

@trevarj trevarj commented May 24, 2021

Actions can now be overridden with custom keys

Implementation and usage are fairly straight forward if you look at the config.yaml

I won't really be using this, so I tried to make it very simple. Maybe if someone who uses custom key maps has other ideas, then I will add to this. For example, binding a command to a key combo, or adding more combos (ctrl_shift_x), etc...

Closes #328

Actions can now be overridden with custom keys
@trevarj trevarj mentioned this pull request May 24, 2021
Copy link
Contributor Author

@trevarj trevarj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of the diff in crates/libtiny_tui/src/input_area/mod.rs is just moving code around


#[derive(Debug, Copy, Clone, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub(crate) enum KeyAction {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A KeyAction is dropped in any where a hardcoded Key combo was (except in a few areas where it makes no sense, like up arrow for scrolling back in history.

[8] => Key::Backspace,
[127] => Key::Backspace,
[1] => Key::Ctrl('a'),
[2] => Key::Ctrl('b'),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added more supported keys. Did not verify them all, but a few I did verify with showkey -a.
If more keys/combos are useful I can add them too

@eoli3n
Copy link

eoli3n commented May 25, 2021

Note to myself

Sandbox
https://gist.github.com/eoli3n/93111f23dbb1233f2f00f460663f99e2

Install

pacman -S rust vim --noconfirm
su - user
git clone https://github.com/trevarj/tiny.git
cd tiny
git checkout custom-keymap
cargo install --path crates/tiny

Generate config file template

~/.cargo/bin/tiny

Add to the end of config file

key_map:
  ### Defaults ###
  ctrl_c: exit
  ctrl_x: run_editor

  alt_&: 
      tab_goto: 1
  alt_é: 
      tab_goto: 2
  alt_": 
      tab_goto: 3
  alt_': 
      tab_goto: 4
  alt_(: 
      tab_goto: 5
  alt_-: 
      tab_goto: 6
  alt_è: 
      tab_goto: 7
  alt__: 
      tab_goto: 8
  alt_ç: 
      tab_goto: 9
  alt_à: 
      tab_goto: 0
  alt_right:  tab_next
  alt_left:   tab_prev

  shift_up:   messages_scroll_up
  shift_down: messages_scroll_down
  #ctrl_u:     input_delete_to_start
  ctrl_d:     exit
  pgup:       messages_page_up
  pgdown:     messages_page_down
  home:       input_move_curs_start
  end:        input_move_curs_end

  left:       input_move_curs_left
  right:      input_move_curs_right
  ctrl_a:     input_move_curs_start
  ctrl_e:     input_move_curs_end
  ctrl_left:  input_move_word_left
  ctrl_right: input_move_word_right
  ctrl_k:     input_delete_to_end
  ctrl_w:     input_delete_prev_word
  backspace:  input_delete_prev_char
  del:        input_delete_next_char
  tab:        input_auto_complete

I use AZERTY keyboard.
All keymaps are not working because of the following error

Can't parse TUI config: Message("invalid value: string \"é\", expected single keys: backspace, del, end, esc, home, pgdown, pgup, tab, up, down, left right, [a-z], [0-9]modifiers with arrow key or single characters:  alt, shift, ctrl", 
Some(Pos { marker: Marker { index: 3023, line: 150, col: 2 }, path: "key_map" }))

@eoli3n
Copy link

eoli3n commented May 25, 2021

input_delete_to_start function doesn't exist, would you create it please ?
It's default ctrl+u in terminal

edit: WIP on #300

Added 'disabled' action to disable key
@eoli3n
Copy link

eoli3n commented May 26, 2021

Everything is working well with my AZERTY keyboard and my mapping.
Good work, thanks for this @trevarj !

Copy link
Owner

@osa1 osa1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @trevarj !

One concern here is, as far as I can see, we allow keys that we don't support. For example, C-h cannot be supported but we allow ctrl_h. As a user I would absolutely hate it if I would have to manually debug unsupported keys by making changes in my config, /reload, try again...

Maybe we could add a function in term_input to return a list of all supported keys, and then have a validation step after parsing to check that the keys user specified are supported.

We should also have a documentation somewhere (perhaps a GitHub wiki page) for the actions, and what they do.

@trevarj
Copy link
Contributor Author

trevarj commented May 30, 2021

We should also have a documentation somewhere (perhaps a GitHub wiki page) for the actions, and what they do.

@osa1 Let's enable the wiki and I can write some docs on this and also migrate some stuff from the README over to it for more organization

Maybe we could add a function in term_input to return a list of all supported keys

Pushing a commit to address this

@eoli3n eoli3n mentioned this pull request May 30, 2021
Copy link
Owner

@osa1 osa1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @trevarj , this is really great. This is requested so many times, it will be great to finally have it. Left a few inline comments.

@trevarj
Copy link
Contributor Author

trevarj commented Jun 21, 2021

@osa1 thanks for the review. I addressed all the above comments except for the "Disable" key action

  • Fully removed size_hints
  • used given #fn_name identifier for macro generated is_valid_key check
  • moved term_input specific logic to non macro-generated function
  • removed extra whitespace

.map(|r| &r.value.0)
.collect::<HashSet<_>>()
.into_iter();
let fn_name = format_ident!("{}_is_valid_key", fn_name);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't know about this macro, nice 👍

@osa1
Copy link
Owner

osa1 commented Jul 2, 2021

I created a Wiki page to list supported key actions and key sequences: https://github.com/osa1/tiny/wiki/Configuring-key-bindings

- Added prev/next entry KeyAction (previously Up and Down arrow)
- Added KeyAction::Cancel as a default binding for the Key::Esc
- Added KeyAction::Input(char), so individual character keys can be
  remapped
pub(crate) fn keypressed(&mut self, key: Key) -> WidgetRet {
match key {
Key::Ctrl('c') => {
pub(crate) fn keypressed(&mut self, key_action: Option<KeyAction>) -> WidgetRet {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function does not handle None case (returns KeyIgnored), I think if we make the argument KeyAction instead of Option<KeyAction> it becomes clear to the caller that this does not handle when a key is not mapped to an action.

If we do that then we decide what to do when a key is not mapped in the code where we try to map the key to an action. It's much nicer, I don't need to follow the value in the code base to find out where the None case is handled and how.

Could you implement that? Should be a few lines of change in TUI::keypressed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

If no KeyAction is found in the current keymap we check to see if the
key is a regular character or alt+char to map it to the respective
actions
@osa1 osa1 merged commit f860b49 into osa1:master Jul 2, 2021
@osa1
Copy link
Owner

osa1 commented Jul 2, 2021

Thanks @trevarj !

@trevarj trevarj deleted the custom-keymap branch July 2, 2021 12:53
osa1 added a commit that referenced this pull request Jul 2, 2021
@097115
Copy link

097115 commented Jul 4, 2021

@trevarj

Great work, thanks! But we can't map the functional keys (F1...F12...) right now, am I correct?

@trevarj
Copy link
Contributor Author

trevarj commented Jul 4, 2021

@097115 right, those keys aren't captured correctly by Tiny and aren't supported yet. I can look into it and see what it would take to add them.

@097115
Copy link

097115 commented Jul 4, 2021

@trevarj Would be great, thanks once again!

@097115
Copy link

097115 commented Jul 4, 2021

@trevarj

Sorry to disturb you, but a bit of issue: ShiftLeft and ShiftRight keys aren't defined in crates/term_input/src/lib.rs, probably something like this should be added at line 105:

[27, 91, 49, 59, 50, 68] => Key::ShiftLeft
[27, 91, 49, 59, 50, 67] => Key::ShiftRight

@trevarj
Copy link
Contributor Author

trevarj commented Jul 4, 2021

@097115 thanks. I will add these

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants