-
Notifications
You must be signed in to change notification settings - Fork 9
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
Adds configurable keymaps for navigation movements #77
Conversation
Am I heading in the right direction with this? If so, I can continue on with setting up configurable keymaps for all actions/commands. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the configuration stuff looks great!
I did leave a couple of comments, the main thing at the moment is just that there is a bit of unnecessary repetition of logic (which can be fixed easily)
After thinking a bit further, I've realised another problem: There are certain actions in gex that are bound to multiple keys. For example, to toggle expand, you can press either space or tab. I think that this should be preserved in the configuration implementation If you could provide a list of keys, e.g. toggle_expand = [ "Tab", " " ] You could look up the relevant action thusly: if config.keymap.navigation.toggle_expand.contains(&c1) {
state.status.expand()?;
} At this point, it does feel that since there are so many actions it may be worth the overhead of spinning up a hashmap. Then the API would look something like: match config.keymap.navigation.get(keycode) {
Action::ToggleExpand => state.status.expand()?,
_ => todo!()
} I think this approach makes the most sense, but it would make the deserialisation logic more involved as you would need an intermediate type (or custom What do you think? |
I think it makes sense to be able to provide a list of keys. That way we don't have hardcoded defaults like we do now with the current approach (where the arrow keys are hard-coded in). With this approach will the user always provide a list ? Like would you have to do I'm all for spinning up a hashmap. |
I appreciate the thorough review + suggestions. Still very new to Rust so I appreciate the explanations. |
Another question: What's the difference between an action and a command ? |
This way would be the most straightforward to implement, but it's not necessary. You would just need a custom If you don't want to implement this, then the best way would be to have the user always provide a list, as then in future the "from single" implementation can be added in a way that's easily backwards compatible.
A command in gex is kind of vaguely defined as it's just an abstraction that sort've naturally occurred while I was working on it. It is a subset of an action, and one that performs some kind of operation on the repository state. This would be a sufficient distinction if it weren't for the fact that staging operations are not considered commands. (or Fetch, currently, but Fetch is in a weird place at the moment, pending refactors that I have locally) The main reason for the distinction is practical -- the commands tend to have "subcommands" whereas an action does not. In fact, currently all commands have subcommands. For this reason their implementation is separated so that I could do some work to make implementing new ones more straightforward (hence the
Great! |
Took me a while, but I figured out how to write the custom deserialize method. This PR is still incomplete (need to uncomment the text, update README.md, update other navigation movements (in the branch section)). I will hold off on completing that stuff until I can figure out how to deserialize the KeyCode from forms other than just Char + get the flow I have here reviewed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we are heading in the right direction!
…eserialization logic
08e30ee
to
7af7fad
Compare
Think v1 of this is done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is all looking great, and we're almost ready to merge.
The most important thing here is the comment I left about filling in default values, as soon as that's resolved, nothing else is really blocking and I think it's good to go!
Take a look at the strum crate, which provides some handy derivable constructs for enums. I haven't yet given a lot of thought as to how specifically you could fix the issue, but I do have a hunch that the EnumIter
derive could be helpful.
that action in their config.
@@ -171,6 +171,9 @@ impl<'de> Deserialize<'de> for Keymaps { | |||
de::value::StringDeserializer::new(action), | |||
)?; | |||
|
|||
// over-write default key-map to action | |||
navigation.retain(|_, value| value != &ac); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a less jank way to do this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine to me, only happens once anyway!
Implemented requested changes. It will be interesting to think through how to refactor this when we add keymaps for actions/commands. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All looks good. Thanks for your hard work, and for implementing my feedback! Sorry if I've been a bit slow to respond to things.
There's one point, but it's so minor that I'm happy to just merge this and fix it in another commit, so we can get this closed.
It will be interesting to think through how to refactor this when we add keymaps for actions/commands.
I have a bit of a refactor in the works for the command system anyway to make it a bit more coherent, which should be coming soon. So, it might make sense to hold off on this for now as it's likely to change
#[allow(unused_imports)] | ||
use strum::{EnumIter, IntoEnumIterator}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're only using strum in the unit test, you can move it to dev-dependencies
, and move this use
statement into the test module
Released in 0.6.4 🎉 |
Adds the ability to customize keymaps pertaining to navigation. First part of #35