-
-
Notifications
You must be signed in to change notification settings - Fork 59
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
Inability to consider current context as matching multiple target types #92
Comments
I've wanted this too for a while! The case that bug me the most is functions, variables or macros with the same name as a package. For example, I've tried several times to run describe-symbol on The fairly recent change from separate target finders and classifiers to functions that return a pair of a calssification symbol and a string target was made with an eye toward this. There are some choices about how to present this functionality. I think that to start somewhere I might just gather all the targets found in the current context, and enable all their keymaps simultaneously. If this proves too frustrating with actions shadowing other actions, I guess I could prompt for which target you mean before enabling a keymaps. Something like that, probably some experimentation is needed to find a good balance. (On a related note, for embark-become I recently switched from enabling the first key map containing the current command to enabling all such key maps.) |
What about nesting the keymaps somehow using a reserved prefix key, e.g.,
I don't know if this works but one could even cycle through the keymaps using long prefix key sequences :) Maybe Emacs refuses to handle cyclic prefix keymaps? |
@oantolin Cool! For my fingers memory I think that I need not clash between keymaps, so enabling them all seems the right option. I might try to code it up, if so I'll submit a PR. |
I wrote a quick sketch in the multiple-targets branch 73a4c62. Please test, @jyp. It at least solves my problem of wanting to run Now, shadowing doesn't mean the simple enable-all-keymaps approach has to be abandoned, it might be possible to just rearrange the target finders in an order where the shadowing is OK. If not, maybe @minad's idea works. |
I would also prefer the merge actually. But I think there are multiple cases where the best key is used for multiple different twings. And then you probably don't want to make the single target keymaps worse in order to avoid shadowing? Maybe combine the merging and add the cycle option via a prefix key. Maybe only bind the alternative bindings in the nested maps. a action Or just create the alternative keymaps by rotating the different keymaps and then merge. |
Or how about: we enable all keymaps, read a key sequence, if it specifies a unique command run it, otherwise prompt using completing-read. The candidates when prompting would be |
I think the cycling you suggest @minad would leave you flying blind. How do you know how many times to press x? Ah, nevermind, your answer is: which-key. |
What you suggest is also good. Maybe better. Downside is only that you introduce some kind of intermediate logic instead of just using the keymaps. But it is probably good for usability. I tried to make a proposal purely with keymaps. |
Yes I thought about which-key. I think this will look like cycling through keymaps. And you can always go back since it is a cycle. I think the idea is kind of cute, but maybe not very usable. Nevertheless, I wonder how Embark can be used without some kind of indicator for the actions. If you merge keymaps it is already pretty much like flying blind to me since you have to know which keymaps have been activated. But probably in many cases you know what will happen for the specific target. |
I just noticed another problem: what if the command you use as an action is not bound in any keymaps (I know, I know, I'm the only crazy person that cares about that case 😛)? You'd need to specify somehow which of the targets it should act on. |
Now, I am confused. You already specify the action you want to execute. So it will just do what it is supposed to do? I mean the question here is what happens if a target matches multiple target types. Maybe I misunderstood? (Edit: I am not very familiar with the Embark actions in arbitrary contexts, since I have been focused mainly on the completion context now.) |
By the way, here are two examples I often use that are not bound in any keymap:
|
The target finders return pairs of type and target, there is no restriction that all targets are equal and just the types differ. To use my |
Ok I understand, for arbitrary commands you have to select if you either want to act on the file or symbol. Then I think it is better to always go with the completing-read solution for consistency instead of doing some prefix keymap trickery. |
I did only a couple of test, but as far as I can see it's exactly what I wanted! 👍 |
Good to hear @jyp! It needs some work, including design work, before I can merge it, but knowing it's a step in the right direction, I'll work on it some more. Also, I'm sure it's buggy in its current state, I just banged out the first thing I thought of as quickly as I could. |
Alright. Perhaps you already know about it, and it's not clear if its related to the changes in the branch, but I'm getting an error due to the definition at line 705:
Indeed, |
I decided to see what I could do about this. After cleaning up the code from everything that I did not need, I ended up with just a page of code plus the configuration. So it may not make sense to combine minibuffer actions with general context-based actions. |
@jyp I did also propose originally to split up the Embark package. The cutting point that you made here is certainly a possibility and I had considered that too (minibuffer actions vs other contexts). I wonder what you are missing from Embark functionality now in the other contexts? It seems you added a few more targets? Is it possible to cut out the other contexts from Embark and only use Embark for minibuffer actions and completions, then binding dap and embark to the same key, but Embark only to the minibuffer map? If that is the case the packages could cooperate cleanly in a non overlapping fashion. But I don't think it is possible since you may want to reuse certain Embark keymaps in minibuffer and other contexts? In that case such a split could not be made. However it still may make sense to have a dap package for people who don't want minibuffer actions or want to combine it with another completion system which already brings actions. But it wouldn't fit with the spirit of having small orthogonal independent packages. |
I like it, @jyp! Nice and simple. I think I need something more general for Embark, but if If I understand your code correctly:
I do like your strategy of partially applying the action to the target in the composed keymap. Much nicer than my strategy of searching for the right target once the action is known. |
Those share like 95% of the code. You need to (1) get the target, (2) figure out which actions to offer for it, (3) prompt the user for an action, (4) run the action on the target. The only part that differs from minibuffer targets and non-minibuffer targets is step (1).Since non-minibuffer targets are varied it makes sense to have a configurable list of target finders for the non-minibuffer case. Once you have that, you can just add the minibuffer target finder to that list and you've also covered minibuffer actions! |
Okay, then the dap package by @jyp is mainly useful if you do not need minibuffer actions or already have them due to ivy/helm. Otherwise Embark covers everything or is there some other selling point of the dap package that I missed?
Since you mentioned the calling convention - I do believe that the Embark calling convention you are using is the right method to reuse interactive commands! I somehow implicitly assumed that dap also uses this technique.
You don't have these multi actions merged yet, right? I agree that it would be good to have this with some prompt to select the action has been discussed above. It is not good if keymaps are not allowed from shadowing each other. Shadowing should be minimized, but this cannot be avoided always in particular if you want to use the best keys in different keymaps.
I am using this feature now that I learned that it exists 😄 |
Correct.
I see. I must say I did not understand this bit at all and this is why I did it the way I did. It would still possible to take the apply-partially approach, and read the argument interactively (using
I did not do any disambiguation. I configured my targets in such a way that there is either a clear target to prioritize, or use different keys for targets which may overlap. Perhaps I can do this because I never need to "become" something else.
Since I am never using it from the minibuffer, using M-x has not much (any?) use.
That would be a bug in set-transient-keymap
|
Functionality is shared, but in reality after I got rid of things that I did not need and simplified the code there is not much in common except the configuration.
Beside simplifying the code (which can help if you want to configure/reuse parts), as far as I know the differences are:
|
Before I forget, another thing that I added (easy when using set-transient-keymap) is that you can configure an action to be repeatable. For example, you can move a column in an org-mode table by several positions in a single run. |
I think maybe I didn't explain the |
That is nice! Old versions of Embark used EDIT: No, it's not tricky to get right, I think. What I should have said is that I didn't figure out how to correctly implement Embark's calling convention with |
As you know, I argued before in favor of |
When not acting in the minibuffer all target finders are executed. The action indicator will then indicate that multiple targets exist. By pressing the `embark-act` key again, the user can cycle to the next target.
When not acting in the minibuffer all target finders are executed. The action indicator will then indicate that multiple targets exist. By pressing the `embark-act` key again, the user can cycle to the next target.
When not acting in the minibuffer all target finders are executed. The action indicator will then indicate that multiple targets exist. By pressing the `embark-act` key again, the user can cycle to the next target. The alternative approach discussed in oantolin#92 was to merge the keymaps. This approach has disadvantages: Multiple targets are active at the same time and depending on the selected action, the target is selected. This complicates the current `embark--act` implementation, which is untouched by this PR. Furthermore keybindings are shadowed, which makes the individual keymaps a lot less useful. This shadowing will lead to confusion and it will not be obvious to the user which target is actually being used. The current approach is also easy to implement, it fits well within the existing codebase. This is a good indication to go this route.
When not acting in the minibuffer all target finders are executed. The action indicator will then indicate that multiple targets exist. By pressing the `embark-act` key again, the user can cycle to the next target. The alternative approach discussed in oantolin#92 was to merge the keymaps. This approach has disadvantages: Multiple targets are active at the same time and depending on the selected action, the target is selected. This complicates the current `embark--act` implementation, which is untouched by this PR. Furthermore keybindings are shadowed, which makes the individual keymaps a lot less useful. This shadowing will lead to confusion and it will not be obvious to the user which target is actually being used. The current approach is also easy to implement, it fits well within the existing codebase. This is a good indication to go this route.
When not acting in the minibuffer all target finders are executed. The action indicator will then indicate that multiple targets exist. By pressing the `embark-act` key again, the user can cycle to the next target. The alternative approach discussed in oantolin#92 was to merge the keymaps. This approach has disadvantages: Multiple targets are active at the same time and depending on the selected action, the target is selected. This complicates the current `embark--act` implementation, which is untouched by this PR. Furthermore keybindings are shadowed, which makes the individual keymaps a lot less useful. This shadowing will lead to confusion and it will not be obvious to the user which target is actually being used. The current approach is also easy to implement, it fits well within the existing codebase. This is a good indication to go this route.
When not acting in the minibuffer all target finders are executed. The action indicator will then indicate that multiple targets exist. By pressing the `embark-act` key again, the user can cycle to the next target. The alternative approach discussed in oantolin#92 was to merge the keymaps. This approach has disadvantages: Multiple targets are active at the same time and depending on the selected action, the target is selected. This complicates the current `embark--act` implementation, which is untouched by this PR. Furthermore keybindings are shadowed, which makes the individual keymaps a lot less useful. This shadowing will lead to confusion and it will not be obvious to the user which target is actually being used. The current approach is also easy to implement, it fits well within the existing codebase. This is a good indication to go this route.
When not acting in the minibuffer all target finders are executed. The action indicator will then indicate that multiple targets exist. By pressing the `embark-act` key again, the user can cycle to the next target. The alternative approach discussed in oantolin#92 was to merge the keymaps. This approach has disadvantages: Multiple targets are active at the same time and depending on the selected action, the target is selected. This complicates the current `embark--act` implementation, which is untouched by this PR. Furthermore keybindings are shadowed, which makes the individual keymaps a lot less useful. This shadowing will lead to confusion and it will not be obvious to the user which target is actually being used. The current approach is also easy to implement, it fits well within the existing codebase. This is a good indication to go this route.
When not acting in the minibuffer all target finders are executed. The action indicator will then indicate that multiple targets exist. By pressing the `embark-act` key again, the user can cycle to the next target. The alternative approach discussed in oantolin#92 was to merge the keymaps. This approach has disadvantages: Multiple targets are active at the same time and depending on the selected action, the target is selected. This complicates the current `embark--act` implementation, which is untouched by this PR. Furthermore keybindings are shadowed, which makes the individual keymaps a lot less useful. This shadowing will lead to confusion and it will not be obvious to the user which target is actually being used. The current approach is also easy to implement, it fits well within the existing codebase. This is a good indication to go this route.
When not acting in the minibuffer all target finders are executed. The action indicator will then indicate that multiple targets exist. By pressing the `embark-act` key again, the user can cycle to the next target. The alternative approach discussed in oantolin#92 was to merge the keymaps. This approach has disadvantages: Multiple targets are active at the same time and depending on the selected action, the target is selected. This complicates the current `embark--act` implementation, which is untouched by this PR. Furthermore keybindings are shadowed, which makes the individual keymaps a lot less useful. This shadowing will lead to confusion and it will not be obvious to the user which target is actually being used. The current approach is also easy to implement, it fits well within the existing codebase. This is a good indication to go this route.
When not acting in the minibuffer all target finders are executed. The action indicator will then indicate that multiple targets exist. By pressing the `embark-act` key again, the user can cycle to the next target. The alternative approach discussed in oantolin#92 was to merge the keymaps. This approach has disadvantages: Multiple targets are active at the same time and depending on the selected action, the target is selected. This complicates the current `embark--act` implementation, which is untouched by this PR. Furthermore keybindings are shadowed, which makes the individual keymaps a lot less useful. This shadowing will lead to confusion and it will not be obvious to the user which target is actually being used. The current approach is also easy to implement, it fits well within the existing codebase. This is a good indication to go this route.
When not acting in the minibuffer all target finders are executed. The action indicator will then indicate that multiple targets exist. By pressing the `embark-act` key again, the user can cycle to the next target. The alternative approach discussed in oantolin#92 was to merge the keymaps. This approach has disadvantages: Multiple targets are active at the same time and depending on the selected action, the target is selected. This complicates the current `embark--act` implementation, which is untouched by this PR. Furthermore keybindings are shadowed, which makes the individual keymaps a lot less useful. This shadowing will lead to confusion and it will not be obvious to the user which target is actually being used. The current approach is also easy to implement, it fits well within the existing codebase. This is a good indication to go this route.
When not acting in the minibuffer all target finders are executed. The action indicator will then indicate that multiple targets exist. By pressing the `embark-act` key again, the user can cycle to the next target. The alternative approach discussed in oantolin#92 was to merge the keymaps. This approach has disadvantages: Multiple targets are active at the same time and depending on the selected action, the target is selected. This complicates the current `embark--act` implementation, which is untouched by this PR. Furthermore keybindings are shadowed, which makes the individual keymaps a lot less useful. This shadowing will lead to confusion and it will not be obvious to the user which target is actually being used. The current approach is also easy to implement, it fits well within the existing codebase. This is a good indication to go this route.
Implement multiple targets at point (Fix #92)
I would be able to use Embark as a general context-dependent way to execute actions. This may mean that several things may be relevant in the current context (and thus several keymaps may apply). Currently, only the first matching target is taken into account.
Why do I want to do this? For example, there may be simultaneously 1. a flymake error at point to deal with and 2. a symbol whose definition can be looked up. Another use-case would be to handle all xref-identifiers uniformly (do
xref-find-definition
on the identifier at point), which currently with the elisp symbol definition (which is only valid in elisp contexts, but offers a wider set of actions).Do you think that the scope of Embark can be widened to support this sort of use-case? Perhaps there is another package which is more suitable for this?
The text was updated successfully, but these errors were encountered: