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
Respect completion boundaries in completion-in-region #89
Conversation
That is an important point and I agree with your conclusions. Your solution is probably the right way to adapt to these observations.
I think this bug is super annoying. I have looked into how file name completion is handled in I'm can not think of any downsides setting these in combination with |
I think a cleaner fix is to detect the completion category in metadata, and if it's |
That is a good idea but I think using the meta data would probably affect more use cases, we probably don't want to affect or block the exit function for all file completions (there might be use cases we haven't thought of). |
Thinking about it the cleanest way would probably be to use status |
I agree, that's the best we can do for now. I'll add a note in the comment to explain this workaround, and hope someone read it could find the real solution. |
I have another thought. When completing the filename, the user would want to type some characters, hit tab, type more, hit tab again, until the whole path is inserted. This actually is how things work with the default completion UI. Right now, when completing the filename, we can only choose file/directories in one level. Why not use |
I think in general this is would be a great feature. I wrote my own completion function added to |
This is also what I'm worried about. My opinion is we can do this as long as |
I'm not sure I understand that. Also if I understand correctly this is only the default completion table but what about custom completion tables which return category |
You understood correctly. About custom completion tables, I'm just assuming people won't create their own ones for filename completion. Maybe a better option is to implement a |
There are also custom built-in ones like
Yes I think that should work. We could pass a function to |
I implemented it using
If we are going to handle these things, we need to extend |
Cool, that you were able to reuse
There are some discussions about making the metadata available for regular |
I just tested it and it works great! I noticed another thing:
With the new behaviour I think using the finished status really makes sense, awesome work! |
(when result
(let* ((bound (car (completion-boundaries
input collection predicate "")))
(start (pcase category
('file start)
(_ (+ start bound)))))
(delete-region start end)
(insert (substring-no-properties result))))
(when exit-func
(funcall exit-func result exit-status)) Are there cases where the exit function should run even if there is no completion result? Another idea I had is that we could push the mark (inactively) before inserting the completion so it would be easy to pop back to the initial input after the completion got inserted. But this may violate expectations in some cases so I'm not sure but it could be convenient I guess. |
I think no. I'll signal an error when the result is nil or an empty string, like the default behavior. Edit: In the default UI, the bell does ring when there's no completions, but suprisingly the "No match" message is sent by
I don't quite understand "pop back to the initial input". is this the same as undo? |
This is done by
Sorry that was poorly phrased. I meant you could jump back to the point where you started completion via |
Thanks! This is utilized now.
I found this is actually the default behavior, but I didn't find a |
Maybe this was by accident I can't see this behaviour in |
Yes. I found it's caused by |
@raxod502 This PR is ready. It does 2 things:
|
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.
Thanks!
Simple test:
M-x shell
cd /some/path
completion-in-region
/some/path
will be deleted.@clemera offerd a lot of help and suggestions in #84 (Thanks!). I'd like to explain some of my decisions, and discuss on those I'm not sure about.
@clemera suggested using
choose-completion-string
. It actually doesn't fix the bug. I looked into it, it usescompletion-boundaries
onminibuffer-completion-table
andminibuffer-completion-predicate
, but even I let bind those variables, it doesn't work. So I fixed it by directly usingcompletion-boundaries
.Also, based on the code of
simple.el
, seemschoose-completion-string
is used when choose a candidate in the*Completion*
buffer.We mentioned
base-size
. I found the relevant docstrings: seecompletion-base-size
andcompletion-base-position
. From the docstrings, they are used only for the*Completion*
buffer (should be some face related things), plus handling it doesn't fix the bug. So I didn't use it.@clemera suggested using
completion--done
to do the things after completion (e.g. callingexit-function
). I didn't use it, but I don't oppose it. From the code, seems it deals with some message relevant things, which I don't understand well for now.@clemera suggested always using the
exact
status inexit-function
, since it "leads to less problems". When completing the path inshell-mode
, with this patch, sometimes a space is inserted after completion, and sometimes doesn't. And with the default UI, it never inserts the space. I don't oppose this change, but I feel the reason is insufficient.When hacking this, my feeling is it seems Emacs strongly assumes the
*Completion*
buffer is the only UI to use, so relevant code is everywhere and in every abstraction level, which contradicts the pluggablecompletion-in-region-function
design. Due to this reason, I would like to avoid using these built-in functions inselectrum-completion-in-region
.