gyscos / cursive

A Text User Interface library for the Rust programming language
MIT License
4.17k stars 239 forks source link

[FEATURE] Allow customization of keybindings #740

Open Builditluc opened 1 year ago

Builditluc commented 1 year ago

Is your feature request related to a problem? Please describe. I'm currently developing wiki-tui, where I want the user to be able to configure the keybindings used in the app (that includes scrolling, changing focus, etc.). Because the current keybindings are hardcoded into the individual view implementation, it is very hard (or impossible) to be able to change them and include new ones (for example scroll 10 lines down, etc.).

Describe the solution you'd like It would be nice if we could change the keybindings of individual views and if we could have access to deeper levels of some views that are currently private (for example scrolling is abstracted away and we cannot have custom scrolling actions).

Describe alternatives you've considered What I'm currently doing is copying the ScrollView and SelectView codes and then implementing custom keybindings there. But that's tedious and a pain to update. I'm also wrapping views and layers to be able to change the events coming in.

Additional context If you want, I would be happy to try implementing this feature (of course, first discussing design choices and what needs to be implemented in detail)!

gyscos commented 12 months ago

Hi, and thanks for the report!

The usual solution for shortcuts and custom input management is to handle it externally, from a wrapper view. You should be able to use an OnEventView to intercept some or all events, and process them based on some shared ruleset you can maintain and change at will.

In your case, you may be interested in on_pre_event_inner, so that you can:

Now I agree that this relies on the view you want to control to expose what you need - if something is currently private and not available, we can absolutely consider making it public!

Builditluc commented 12 months ago

handle it externally, from a wrapper view

Yeah we're using this wherever possible, but for some cases this doesn't work (mainly with the scrolling)

view you want to control to expose what you need

Exactly that is my "problem" with the ScrollView. In order to implement some vim-keybindings (and in the future, more of such custom actions) we need to be able to access the underlying scrolling ...

EDIT: Oh wow, while researching this, I discovered that the Scroller trait is public, meaning that we can get mutable access to the scroll::Core of the ScrollView. And the methods there are all public. So, my issue with the scrolling has fixed itself (if I've just read the documentation more thoroughly...).

Before continuing with this issue, I'll research a bit more to find out if the issue I'm having is already "fixed".

Anyways, thanks a lot already!

gyscos commented 1 month ago

Glad you found a solution!

Also, I agree it would be great if ScrollView exposed everything you needed, without having to go through the ScrollCore. What were you missing?