-
Notifications
You must be signed in to change notification settings - Fork 33
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
Alternative multiple candidate select UI? #489
Comments
We could think about combing both approaches, we had a selection feature in the early days see the #74 for more discussion about the current UI. |
Right now the candidates are simply removed from the list, maybe it would be better to leave them there but show them selected? |
Hm, I don't think there would be a benefit, could you describe more what you don't like about the current UI? Maybe you are just annoyed about the scrolling of the prompt as the candidates are so long? |
Yes, the candidates are too long. Given a vertical ui long candidates are common. People are developing applications which produce long candidates as in this case with bibtex. |
The prompt gets scrolled for me in this case. |
Maybe it is a problem when you want to inspect your selections visually or am I missing something? |
I took a quick look at #74 (thanks), but it seemed like @oantolin's critiques of the earlier UI (which I never saw) were more implementation than basic concept?
It's more than "annoyed"; it seems initially completely impractical for this use case :-) Let me elaborate on the use case. When writing book or article manuscript, I need to be able to very quickly and easily, so as to avoid interrupting the writing process, select and insert citations. Sometimes citations have one key, often more. With the I can instantly see what I have selected, and so what citation will be inserted at point. Not so with selectrum. I can only see one selection at a time, and I have to switch UI context to be able to scroll. Perhaps different selection UIs are optimized for different use cases? @clemera (who posted this after I started replying)
Yes. Say I have 2000 references in my bibtex file(s). I need to be able to select the exact three that I need to insert as a citation at point, and those may be pretty similar to others I don't want (same author, say). Being able to see all I have selected at once allows me to confirm I have the right ones. Does that explain better? |
I see, another improvement in this use case would be to select multiple items without resetting the input between as discussed in #395 (I forgot about that one and I also needed some explanation there, I just have no such use case 😆) so you can pick the similar items right away without repeating previous inputs. |
The previous UI worked similar to what you are suggesting, the critique by @oantolin back then was also about the UI itself, there are use cases for both it would be nice to allow both in tandem is some way. |
Is that really true in Helm? Does it move selected candidates closer together or something? I thought that if you had 2000 references in your bibtex file and you wanted to cite references 21, 803 and 1831 you could not see in Helm at a glance which were selected, you'd have to scroll like a madman to see which one are selected. Am I wrong? EDIT: Well, I guess if all the chosen references have some text in common, you could type that into Helm to bring the selected ones closer to each other. |
Oh, good question @oantolin. No, it doesn't. In that workflow, I'm assuming I'd narrow to some manageable subset.
Yes, this. The most common case is I'm citing a person's work, for example, so I narrow on the references of that person. |
What about moving the selected items to the top such that they are always visible if not scrolled out of sight? |
First thought is that would be an improvement on the helm version. |
I think that for this particular situation, I'd like the standard completing-read-multiple interface but with each selected candidate displayed as just the bibtex key. The only issue right now is that the text in the minibuffer prompt is too long, no? |
@oantolin Currently the input resets after inserting a candidate with ´TAB` so the previous search matches are gone, if you want to select multiple similar candidates (contained in you current set of matches) you need to input the same text again, for this use case selection would be more convenient. |
I had wondered about that. Is that possible? That could be an elegant solution, particularly if coupled with @minad's on moving to the top of the list. And if there was some way that I could see which key was associated with which candidate somehow. |
I also thought about that proposal by @oantolin. I don't think it is possible. The candidates are long, there is no way to communicate a short form to the completion system. You could invent an extension but if that can be avoided it would be better. |
@clemera makes a good point, that if the candidates you want to select do have some text in common, marking several candidates is more convenient than have to type the text again for each one. I also don't think my suggestion of using the crm interface but dislaying just the bibtex key in the minibuffer is very practical: I hadn't noticed the bibtex keys aren't displayed with the candidates so using them to summarize the chosen entry isn't a very good idea idea, since you'd still need a way for the user to visually confirm those keys correspond to the entries they meant to select. One similar thing that could be done is to put a function in the minibuffer's |
Perhaps instead of shortening the chosen candidates they could be displayed one per line (by displaying the crm-separator as |
Yes, but this seems less convenient than having multiple candidates listed at top which can be selected/deselected with a keypress. |
True. |
I missed this earlier, but just to clear, yes; that would be a start. Edit: not sure if this is what you're thinking, @clemera, but it seems like it might be not so hard conceptually to bring these together. Like, at a basic level (I know there are details and nuances):
|
Just curious: how do you deal with this in |
icomplete-vertical has no special behavior for Note that removal of chosen candidates in Selectrum, while probably a good idea, feels a little "wrong" since you are allowed to select the same candidate many times in |
One detail: I saw grouping come up here recently (see #458). How would this interact with that? Would, for example, selected candidates be a group? Could have some advantages, like allowing a selection to be visible even if the user modified the filtering to otherwise hide a candidate? |
@bdarcus |
I was leaving that deliberately vague because unsure. But I'm fine with your preference.
Yes.
I'm not following on this.
So in my UI, how would I select two candidates to run the default action?
What would be the indication they were selected? The two candidates highlighted, at the top of the list, perhaps in a group? And if I was using some other commands, where it was easier to use the TAB approach, I would:
If that's what you mean, that sounds good. Edit: and de-select would be do shift + TAB again? |
In file completions you can move and kill path levels using standard sexp commands I was suggesting allowing the same for crm so you could easily move through your "selections" and kill items to "unselect".
You press SHIFT + TAB and the item gets inserted like with TAB but additionally the current input gets inserted so you can proceed from where you left off.
They would be remove from the list and added to the prompt like with TAB (in addition to that the input would get inserted as mentioned above.
To "deselect" you would I'm suggesting not showing visual selections but incorporating the advantages of a selection UI into the current UI. |
So then how would this address my concerns with the long completions in that UI? Yes, I don't have to restart the completions, but as discussed above, that's only one part of the problem.
And what are those advantages for my use case? |
I thought that you can quickly select similar items which match the same string and inspect/edit your selected candidates (one by one) but it seems that wasn't your main interest, I just tried to projecting what is missing and find a way to add that, I'm sorry if it doesn't match your view on it or if it doesn't solve your pain points, what do you feel is missing? Is it that you can't easily see all selections at once? What is the advantage of seeing all the selections at once? |
If we have sexp commands for candidate navigation within the prompt you can navigate to the start of a candidate using |
I appreciate your openness to continued discussion :-) Let me wait a bit to answer your questions, and in the interim see if @minad has any thoughts that can bridge the gap. EDIT: I'll also add an example from my own data of what the actual candidate strings look like (with your help on reddit, I use a different string for the display using the display property, which has a little less data, but is formatted for full-width display): "✎ climate change,geo211,geography future 2019-02-19 Wallace-Wells, David The Uninhabitable Earth: Life After Warming book wallace-wells_2019" |
EDIT: I just reread your comment above and noticed you already mentioned seeing a single item a time doesn't work out nicely for you. Here is another idea which is similar to what @minad was suggesting by showing items at the top of the list: We could show a stack of the inserted candidates above the prompt (between the input line and the mode-line) that would grow up when you add another candidate. You could maybe also navigate into that collected stack and pop items back (not sure how this would feel in practice but maybe this would work out). |
So that "stack" would be just below the "doom:scratch" line here? So conceptually like the grouping idea I was asking about, but I guess there are technical reasons this might work better? EDIT: And so, as you select candidates (and I can do shift + TAB to do that?), the UX is they move up, from the candidate list to that stack? That sounds helpful to me in addressing the core issue; maybe even really cool! |
Yup, that would be the idea.
Yes, you could also just press TAB (in that case we could delete the input and add the candidate to the stack) when you press SHIFT + TAB the candidate would also move to the stack but your input would stay so you can keep adding items from the current result set. |
Sounds good to me. Only other question I have (which you were contemplating above) is how to make the deselect process as simple and elegant as the select process. EDIT: And, of course, I'd be eager to test it to see how smoothly it all worked. Might be so simple as one keypress to migrate to the stack, select item to deselect, and then same shift + TAB to deselect, which removes it? Given the different context, would there be any point in a different key combination? BTW, here's the documentation section for describing how this works in https://github.com/bdarcus/helm-bibtex#apply-actions-to-multiple-entries |
Maybe removing the last added candidate could be done with DEL which is usually a no-op at the empty prompt. To deselect other candidates than the last one you could navigate to them using |
There is one problem with history and pasting strings into the crm prompt those should both continue to work, mabye some kind of hybrid solution would be best? What about a command which shows the items currently in the prompt temporarily instead of the static visualization we talked about? |
In theory, that seems to make sense. I know how the prompt approach works now, but how would this alternative in relation? How do you think to allow the hybrid, without having them conflict? I was just wondering what would happen, for example, if one selected some candidates using the direct approach, and then did TAB for the prompt.
Are you thinking it would be redundant or waste real estate to disclose statically when using the prompt? And how would that visualization compare to what we earlier discussed? Where would they be disclosed? The same idea, just that one could toggle? |
I hadn't thought above the concerns I mentioned (navigating history/pasting) before. There is also the case that you use an unknown Maybe a third approach could be to select the candidates like you do currently and on exit get a buffer where you can inspect and change the submitted selections before finally submitting them? I think this all needs some experimentation, we can discuss more details when we have an implementation to play with. |
I was thinking about this yesterday too, as I had to add code to my package to use a different Ideally I could tell
Sounds good. |
I thought I'd just add another note here on a pain point with the current UI, that I think would be solved with the direction this was going. I needed to add an initial-value argument to some of my commands to pre-narrow the candidate list. This works well when selecting one candidate, but does not when selecting multiple, since the initial value only applies to the first. Also, I just linked here from another issue to do with history for these long candidates, which is another pain point. |
See emacs-citar/citar#160 for an alternative idea for an improved CRM ui, which can be implemented cheaply on top of I thought maybe it is better to give up on crm and use something else based directly on (defun simple-crm (prompt candidates)
(let ((selected-list)
(selected-hash (make-hash-table :test #'equal))
(items candidates))
(while
(let ((item
(completing-read
(format "%s (%s/%s): " prompt
(hash-table-count selected-hash)
(length candidates))
(lambda (str pred action)
(if (eq action 'metadata)
`(metadata (display-sort-function . ,#'identity)
(cycle-sort-function . ,#'identity)
(group-function
. ,(lambda (cand transform)
(cond
(transform cand)
((get-text-property 0 'simple-crm-selected cand) "Selected")
(t "Not selected")))))
(complete-with-action action items str pred)))
nil
t
nil
nil
"")))
(unless (equal item "")
(cond
((gethash item selected-hash)
(remhash item selected-hash)
(setq selected-list (delete item selected-list)))
(t
(puthash item t selected-hash)
(setq selected-list (nconc selected-list
(list (propertize item 'face 'region
'simple-crm-selected t))))))
(setq items
(append selected-list
(seq-remove (lambda (x)
(gethash x selected-hash))
candidates)))
t)))
selected-list))
(simple-crm "Select multiple" '("first" "second" "third" "fourth")) Fortunately there is also no need to implement a custom completion table. I wonder if such a functionality deserves to be provided by some package. |
Your (By the way, I somehow I thought RET in Selectrum and Vertico also always selected the first candidate or the selected candidate if you move the selection, but it seems I was wrong. What does it do? Select the default if non-nil and otherwise select the first candidate? And here you set the default to be the empty string?) |
Yes, that was my response too! Since this comment, the thread on the linked issue got kind of long and complicated (though I think interesting!), but I think to summarize: This should work well for my package, and so I am working on adding it here: But there are a few minor issues, that probably won't matter in my case. OTOH, generalizing it for inclusion in Consult (which @minad had been seriously thinking of doing), and/or Vertico/Selectrum, will require more thought, and work, which may not be worth it in the face of other priorities, etc. This comment gives a good overview of the open questions for him: emacs-citar/citar#160 (comment) I don't think he's closing the door on the idea though. |
In the case of Vertico, RET returns the currently selected candidate ( ;; select either the prompt or the first candidate
(if (or vertico--default-missing ;; prompt is empty and default is not an element of all completions
(= 0 vertico--total)
(and (= (car bounds) (length content)) ;; input is a valid completion
(test-completion content minibuffer-completion-table
minibuffer-completion-predicate)))
-1 0) When the prompt is selected, the prompt string is submitted by RET. In case the prompt string is empty, |
@oantolin What do you think about |
Solved by |
I'm working on this package, which is sort of a port of
helm-bibtex
tocompleting-read
, aimed at selectrum (and icomplete-vertical).My core completion function uses
completing-read
, but I think I need to change it to usecompleting-read-multiple
, as the backend functions all take multiple keys as parameter.But I don't think selectrum's current UI for this will work, as the completion strings are very long.
Notice what happens in this screenshot at the top:
Now, compare to
helm-bibtex
, where one doesctrl-space
to mark the candidates.Is there any reason this wouldn't be a more general and consistent approach?
If not, is there any workaround you can suggest?
cc oantolin/embark#166 emacs-citar/citar#17
The text was updated successfully, but these errors were encountered: