-
-
Notifications
You must be signed in to change notification settings - Fork 1
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
Feature Design #5
Comments
Someone asked to be able to snapshot all bindings and then diff them. It's a pretty reasonable bit of infrastructure to support, especially if it makes radical bindings changes more manageable for users who are subscribing to a 3rd party for bindings updates, in addition to changes in Emacs and packages. |
Declarative mass unbinding. Packages like general are already good at binding, so I'm focusing on unbinding first.
Preferred sequences report should show shadow counts and be configurable to consider different buffers and modes. Clicking on (or selecting via completion) a preferred sequence will show the shadows interface, where you can except keys from unbinding. On start up, the expanded form will be evaluated. If it detects a new shadow or a new stupid key in a map, it should maybe warn the user, but they can also just see this by loading up the interface, which they would do to investigate a problem. Optionally, to avoid being annoyed by new packages, the user could set the preferred action when new bad sequences are detected. Options like Once you build up your list of exceptions and are happy with the stupid keys configuration, you save the declaration, you expand the declaration to save the current state and record the declaration, optionally in the init file. Bindings can clobber, but this is a detectable conflict. Since the package focuses on unbinding, there is no clobbering because unbinding is both commutative, associative etc, a sum of unbindings always produces the same result. The unbindings that were done during init need to be merged with unbinding state calculated at runtime. Unbinds that would have no effect should be recorded so they can be removed when calculating a new set of unbindings. The predicates interface needs to support adding and removing predicates via completions and defining predicates via lambda forms. A few basic unbinding schemes should be provided so that users can play around with high-level ideas. At a minimum, the defaults should do a decent job a removing lots of stupid bindings and unbinding some "questionable" commands. While it's obviously subjective, the goal is to preview a world with fewer pre-configured bindings. |
Throwing this out there to potentially get some feedback and figure out my plan.
Users will, in the end, simply use a macro like so:
stupid
would mean use the configured options foruser-keys-stupid-*
to generate a mass unbinding of all "stupid" sequences. Plist options etc can be assumed in a real implementation.The macro will be capable of generating bindings. However, full expansion requires loading all of the keymaps to find all of the stupid bindings. We can't see everything that needs rebound in order to generate proper `eval-after-load' forms until all of the packages are loaded.
Cached Expansion
A cached expansion will save the state of the runtime result, which has loaded everything in order to detect all of the bad, stupid bindings, and bindings that need rebinding etc.
The user will have to update this when they load new packages. A package load hook can gently remind the user when they have loaded a feature that was not used in the last cached expansion.
Writing the Macro (like Magit)
There.. a lot of bindings the user might want to mess around with. Many exceptions could result. Copying lines from the report interfaces is faster than looking at bindings in individual buffers etc, but it's still horrible.
So a magit-like stage / unstage interface is probably going to be needed. The user should be able to see the macro and to optionally evaluate the result of individual hunks of expansion. Saving reverse operations, implemented via command pattern, is possibly an option.
Abstract commands
I don't believe abstract commands are the right road forward without first-class support from Emacs. It's somewhat of a runtime solution. If the command pattern is implemented to re-bind and reverse re-bind, we don't need abstract commands. Although, once rebinds intersect, they will necessarily clobber each other and might not work in the reverse order.
Clobbering
Yeah, this is hard. There's probably a lot of edge cases. Last write wins with
define-key
, and if the user interface is doing these things out of order, we may lose the original state of maps unless we hold a log and unsplice the unwanted events out of the log and replay back to the current state.The text was updated successfully, but these errors were encountered: