Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get_mode_info based on keybinds #319

Closed
wants to merge 22 commits into from

Conversation

horasal
Copy link
Contributor

@horasal horasal commented Apr 22, 2021

This pr changes the default static get_mode_info to dynamically strings generated from keybinds.

Now get_mode_info accepts Keybind and will search Key for each Action. key is handled by the following rules:

  • order: Left/Right arrow > up/down arrow > pgup/pgdn > other. e.g. if both "→" and "L" exists for the same action, only "→" will be shown.
  • if a action has multiple arms (e.g. Resize has 4 arms Left/Right/Up/Down), all arms will be shown
  • if any arm has more than one character(e.g. PGDN, Ctrl-L, etc.), arms will be joined with "/"

@horasal horasal changed the title get_mode_info according to keybinds get_mode_info based on keybinds Apr 22, 2021
Copy link
Member

@TheLostLambda TheLostLambda left a comment

Choose a reason for hiding this comment

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

This is excellent to have! Another thing that's been on my todo list!

I've left a couple of comments for consideration and might like to get some second opinions about the Display implementation, but things are looking great so far 😄

The status bar plugin might also need the mode removed where it does this:
Screenshot from 2021-04-23 03-51-04

The <p>ane thing won't really work once that key is remapped. Try shrinking your terminal to see it switch to this mode :)

zellij-tile/src/data.rs Outdated Show resolved Hide resolved
src/common/input/handler.rs Outdated Show resolved Hide resolved
src/common/input/handler.rs Outdated Show resolved Hide resolved
@horasal horasal marked this pull request as draft April 23, 2021 08:05
@horasal horasal marked this pull request as ready for review April 23, 2021 10:24
@horasal
Copy link
Contributor Author

horasal commented Apr 23, 2021

  • Now Action is a part of zellij-tile
  • get_mode_info is moved to status-bar plugin
  • Mode Update will pass a Key / Action map instead of Strings. (in a vec, because of json's limitation)

@horasal horasal mentioned this pull request Apr 23, 2021
12 tasks
@horasal
Copy link
Contributor Author

horasal commented Apr 24, 2021

I'm also working on status bar improvement, but it may take a while horasal@18ff3a7

@TheLostLambda
Copy link
Member

Hey @horasal ! Thanks for doing all of this! Is this ready for a review or are you looking to finish your status-bar improvements first?

@horasal
Copy link
Contributor Author

horasal commented Apr 26, 2021

@TheLostLambda
This is ready for a review :) !

Status-bar improvements needs many extra works so I decide to file another pr for that

Copy link
Member

@TheLostLambda TheLostLambda left a comment

Choose a reason for hiding this comment

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

Overall looking great! I would personally simplify the const fn into a HashMap stored in State and would merge the actions module into the data module, but aside from that, this looks ready to merge!

If you want to sort out the merge conflicts and address those two points, I'm happy to press the button for you!

use std::collections::HashMap;

// const fn now does not support PartialEq/Eq, we have to implement our own compare fn
const fn compare_key(l: &Key, r: &Key) -> bool {
Copy link
Member

Choose a reason for hiding this comment

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

These are really cool (and I also realize I told you to try using these when this code was still in Zellij 😅 ), but if you'd like, the State struct here is secretly stored in a lazy_static! already! You could go back to your shorter first solution and pop the HashMap in there and implement either Default or populate it during the call to load().

Sorry again to do the 180 on you here, but that would probably clean things back up a little!

Copy link
Contributor Author

@horasal horasal Apr 29, 2021

Choose a reason for hiding this comment

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

I tried to put key_order in State. However, it's necessary to pass Hashmap everywhere and it's really annoying. I prefer a lazy_static in mode_info.rs or just use current const. How do you think about it? or is there any better way to pass Hashmap around?

Copy link
Member

Choose a reason for hiding this comment

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

I'll give this a more thorough review today, but I think this vastly simplifies these two const fns into one! (Let me know if this actually is not doing the right thing 😅)

const fn get_key_order(key: &Key) -> Option<i32> {
    match key {
        Key::Left | Key::Right => Some(0),
        Key::Up | Key::Down => Some(1),
        Key::PageUp | Key::PageDown => Some(2),
        Key::Char(_) => Some(3),
        _ => None,
    }
}

Match doesn't actually need Eq to function in this basic manner :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

you're right. this looks awesome!

@@ -1,3 +1,4 @@
pub mod actions;
Copy link
Member

Choose a reason for hiding this comment

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

I'd personally merge this file in with the data module, but if you disagree, I'm happy to chat about it!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Merged into data 9c0767a

}
}

impl Display for Key {
Copy link
Member

Choose a reason for hiding this comment

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

Looks great!

@@ -71,8 +105,7 @@ impl Default for InputMode {
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct ModeInfo {
pub mode: InputMode,
// FIXME: This should probably return Keys and Actions, then sort out strings plugin-side
pub keybinds: Vec<(String, String)>, // <shortcut> => <shortcut description>
pub keybinds: Vec<(Key, Vec<Action>)>,
Copy link
Member

Choose a reason for hiding this comment

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

This looks awesome! You said the HashMap had some issues with JSON, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, Json can not serialize HashMap<Key, ..> because Key will be serialized as a map but a map can not be a key in json.

@horasal
Copy link
Contributor Author

horasal commented Apr 29, 2021

rebased
The conflict is a bit complicate. I carefully fixed them to make sure not break anything but this pr should be carefully reviewed.

Copy link
Member

@TheLostLambda TheLostLambda left a comment

Choose a reason for hiding this comment

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

This is coming along well! I think there is a bit of behavior that we need to fix though. Currently, the first part of the status bar will always show the defaults and never custom keybinds (as far as I can tell).

image
Also, this mode:
image
Still needs removing I think!

Sorry this is taking so long, it's a quite complex change, but certainly an important one!

use std::collections::HashMap;

// const fn now does not support PartialEq/Eq, we have to implement our own compare fn
const fn compare_key(l: &Key, r: &Key) -> bool {
Copy link
Member

Choose a reason for hiding this comment

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

I'll give this a more thorough review today, but I think this vastly simplifies these two const fns into one! (Let me know if this actually is not doing the right thing 😅)

const fn get_key_order(key: &Key) -> Option<i32> {
    match key {
        Key::Left | Key::Right => Some(0),
        Key::Up | Key::Down => Some(1),
        Key::PageUp | Key::PageDown => Some(2),
        Key::Char(_) => Some(3),
        _ => None,
    }
}

Match doesn't actually need Eq to function in this basic manner :)

@horasal
Copy link
Contributor Author

horasal commented Apr 30, 2021

This is coming along well! I think there is a bit of behavior that we need to fix though. Currently, the first part of the status bar will always show the defaults and never custom keybinds (as far as I can tell).

image
Also, this mode:
image
Still needs removing I think!

Sorry this is taking so long, it's a quite complex change, but certainly an important one!

I totally agree with you. I'm working on this in another branch. but there are many things to be done, e.g.

  • Normal Mode do not contain keybinds so nothing will be shown on startup
  • Keybind does not contain key for current mode
  • decide how to handle keybinds with different prefix (e.g. Ctrl-G for lock but Alt-P for Pane mode)

I will file another PR once I make some progress!

EDIT: or do you think this improvement should also be done in this pr?

@TheLostLambda
Copy link
Member

Thanks for all of your continued hard work on this!

I think it might be a little confusing if we had a half-functional rebinding UI like this in main, so I'd personally like to combine this PR with the status-bar fixes, but I know that might make for a big diff.

Let me know if you'd be up for that!

@horasal
Copy link
Contributor Author

horasal commented Apr 30, 2021

  • make first line generated from keybinds
  • make second line generated from keybinds
  • adjust prefix based on keybinds

@horasal
Copy link
Contributor Author

horasal commented May 1, 2021

@TheLostLambda
Now everything is done & ready for a review!

status bar now correctly show new keybinds:


Copy link
Member

@TheLostLambda TheLostLambda left a comment

Choose a reason for hiding this comment

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

This is great! I really like the new status bar behavior! It does seem like we've lost a little bit of spacing though if you'd like to add that back in. It may be hard to see without the proper fonts installed.

Current main:
image

This PR:
image

The spacing before Ctrl and around each item of the first line seems to have gone missing.

Additionally, were there some complications with including the [] keybindings in the tip?

Thanks again for all of your hard work! This is incredible stuff!

@horasal
Copy link
Contributor Author

horasal commented May 2, 2021

fix style, add [] navigate.

Now

  • if navigate key only one char, do not show "/"
  • works well even when some keybind is missing
  • add some spaces


@horasal
Copy link
Contributor Author

horasal commented May 2, 2021

rebased

@horasal
Copy link
Contributor Author

horasal commented May 2, 2021

@TheLostLambda
do you know why is the tests failing?
it seems work well on my local pc

@TheLostLambda
Copy link
Member

@horasal Not sure about the tests! I've rerun them a couple of times and it seems to fail on different resizing tests... I'll poke @imsnif to see if he has any idea (it looks like the resizing snapshots recently changed somehow in main.

@imsnif
Copy link
Member

imsnif commented May 2, 2021

I'll poke @imsnif to see if he has any idea (it looks like the resizing snapshots recently changed somehow in main.

Unfortunately our tests are a little flaky at times, especially on the CI :( It's on my TODO. I re-ran them and they pass now.

@horasal
Copy link
Contributor Author

horasal commented May 3, 2021

@TheLostLambda
I think all works are done and ready to be merged.
However, the conflicts are too complicated because 98d9eac introduced color theme, but that patch seems start from half of this pr (only contain the very first version of dynamic keybind).

I'm wondering if anyone (maybe @denismaxim0v can provide some hints?) can resolve these conflicts.

p.s. I'm pretty sure that we can just change the color of ShortCutTextElement::to_styled_text to achieve this but I haven't got enough time to follow color theme commits.

impl ShortCutTextElement {
    fn to_styled_text(&self, style: CtrlKeyMode) -> ANSIGenericString<str> { // all colors are defined in this function
        match (style, self) {
            (CtrlKeyMode::Unselected, ShortCutTextElement::Prefix) => {
                Style::new().fg(GRAY).on(BRIGHT_GRAY) // just change things here
            }

@imsnif
Copy link
Member

imsnif commented May 4, 2021

@TheLostLambda
I think all works are done and ready to be merged.
However, the conflicts are too complicated because 98d9eac introduced color theme, but that patch seems start from half of this pr (only contain the very first version of dynamic keybind).

I'm wondering if anyone (maybe @denismaxim0v can provide some hints?) can resolve these conflicts.

p.s. I'm pretty sure that we can just change the color of ShortCutTextElement::to_styled_text to achieve this but I haven't got enough time to follow color theme commits.

impl ShortCutTextElement {
    fn to_styled_text(&self, style: CtrlKeyMode) -> ANSIGenericString<str> { // all colors are defined in this function
        match (style, self) {
            (CtrlKeyMode::Unselected, ShortCutTextElement::Prefix) => {
                Style::new().fg(GRAY).on(BRIGHT_GRAY) // just change things here
            }

Hey @horasal - I'm afraid I now had to change things even further in regards to color themes and the api of the plugins!
I have a lot on my plate now, but I can try to give input to help you resolve the conflicts. Is there anything specific that is causing you trouble?
(btw, in such a case I personally like to forgo the merge and just reapply my changes with the new world order - I find it's quicker! But however is convenient for you, of course)
This code-base is moving quite fast these days! It can be frustrating, I know - but maybe also adventurous? :D

@a-kenji
Copy link
Contributor

a-kenji commented Jul 10, 2022

Closing in favor of #1242, thanks @horasal for starting this work!

@a-kenji a-kenji closed this Jul 10, 2022
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