-
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
Improve completing-read-multiple (also fixes #80) #74
Improve completing-read-multiple (also fixes #80) #74
Conversation
912e967
to
b000e57
Compare
Currently this works with recursive minibuffer, too but only by accident! |
08df694
to
bacea44
Compare
bacea44
to
6e8679e
Compare
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 clearly much better than the proof-of-concept that I hacked together previously. Thank you for working on an improvement. You can get rid of all the multiple-selection stuff from before in favor of this approach.
so the proper way would be to add another argument to selectrum-read
Yes, I agree. My previous approach already has an extra argument and a state variable for tracking whether multiple selection is enabled. Perhaps it would be best to just use that, rather than checking crm-completion-table
? (But of course we can still set crm-completion-table
, for API compliance.)
(let ((coll (cl-delete-if | ||
(lambda (i) | ||
(member i inputs)) | ||
(copy-sequence coll))) |
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.
Would cl-remove-if
do the same thing faster?
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.
The problem is when I use:
(cl-remove-if
(lambda (i)
(member i inputs))
coll)
and try to input multiple candidates the sequence gets corrupted somehow, I don't understand why this is. To test this use it with the definition above and call describe-face
. Look at the number of candidates and afterwards add one face with TAB ,
now look at the number of candidates again: they shrinked in size more than one.
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 probably because cl-remove-if
is special-cased to return the same object if there is nothing to remove. Then something downstream destructively modifies the collection.
I looked into this and found that the docstring of selectrum-read
was not really clear on whether the collection might be modified. I fixed this problem. With the latest commit, I think using the code you have right now (cl-delete-if
plus copy-sequence
) should work properly and should be the right thing to do. Let me know.
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.
I looked into this and found that the docstring of selectrum-read was not really clear on whether the collection might be modified. I fixed this problem
If the collection is a function (as in this example) the returned candidates can still later be modified by the sorting function (even if may-modify-candidates
was not provided), so if may-modify-candidates
was not provided maybe we should copy the returned values before doing the sort in post-command-hook, too?
Another thought I had is that even when may-modify-candidates
was provided it can be confusing that the candidates returned by the function above can be modified and you can't just reuse the value inside the closure. Maybe we should copy the returned candidates by default, copy-sequence
is pretty fast and I think this probably wouldn't be much of a problem and would avoid that people would need to do it manually in cases like above.
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.
The problem is that copy-sequence
is fast, but it generates a lot of garbage due to duplicating the collection, and garbage collection really kills latency. What's slow in Elisp is really not obvious at first glance.
the candidates returned by the function above can be modified and you can't just reuse the value inside the closure
If we don't copy the candidates returned from a function collection when MAY-MODIFY-CANDIDATES is nil, that's a bug.
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.
The problem is that copy-sequence is fast, but it generates a lot of garbage due to duplicating the collection, and garbage collection really kills latency. What's slow in Elisp is really not obvious at first glance.
Ah, yes thanks for pointing that out, totally forgot about gc!
If we don't copy the candidates returned from a function collection when MAY-MODIFY-CANDIDATES is nil, that's a bug.
I will open an issue for that later.
558a88f
to
004a86e
Compare
Should I replace the current description of |
62be95c
to
1148e83
Compare
d76dfde
to
daf039f
Compare
Okay I removed all the code previously used for the old approach to multiple candidate selection and updated changelog. Should all be good now. |
Thanks this is helpful! The "why 79" reference made me laugh, I had to test it to see it's true :D |
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 splendid, a great improvement. We should also update the README.
Done |
I noticed We could later decide to allow this feature for The code for |
As far as I am concerned this can be merged. Let me know if you have further considerations. |
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.
Splendid!
…ngs. This addresses radian-software#74. Using a keymap allows for better working with other packages (such as General and Use-Package) and better meets user expectations.
This PR implements an alternate replacement for
completing-read-multiple
which mimics the default interface more closely and makes it more convenient for selecting multiple candidates via completion.I requote oantolins critique of the current behaviour here for easier reference:
I have left the previous multi selection feature untouched because I'm not sure how you want to proceed with this.
To test the new version call
describe-face
then insert candidates withTAB
and press,
to proceed and add more. Finally submit input withRET
. This way it works exactly like the stock Emacs UI only that it's much better ;)This new method also has the additional benefits that history for
completing-read-multiple
looks the same as withoutselectrum-mode
and you can select history items of previous multi selections.