minad / cape

🦸cape.el - Completion At Point Extensions
GNU General Public License v3.0
584 stars 20 forks source link

cape-file-directory-must-exist and completing files in default-directory #56

Closed jdtsmith closed 1 year ago

jdtsmith commented 1 year ago

cape-file must have this variable disabled to complete files in the default-directory. Is that by design? It might be preferable if must-exist only applied to actual written out directories, so that completing some-f[Tab] where some-file exists in default-directory works. BTW, I've found cape-file is much more robust than the comint file completion table.

minad commented 1 year ago

Is that by design?

Yes, otherwise file completion may set in too often. If you trigger cape-file explicitly and manually cape-file-directory-must-exist is bound to nil. But the option is there to be disabled if you don't like it. You can also disable it buffer-locally if you prefer the more aggressive completion in certain modes.

BTW, I've found cape-file is much more robust than the comint file completion table.

I don't recall what exactly is wrong with the comint-completion-at-point function, but I had some reason to write the separate cape-file. You mentioned the Comint Capf when we first discussed alternative backends in https://github.com/minad/corfu/issues/9#issuecomment-881970276. But note that the completion table is the same. It is only the Capf logic itself which is different, but this matters for usability and Capf composition.

jdtsmith commented 1 year ago

Thanks, I'll disable as needed.

If you trigger cape-file explicitly...

Hmm, M-x cape-file doesn't seem to work here, and I see it is called twice in a row, the first time nested via interactive=t, returning a table, the second time not nested, returning nil. You'll never guess the reason: corfu--post-command and its infamous use of the CAPF itself to see if exit should occur! Since the predicate aka CAPF doesn't have a closure over cape-file-directory-must-exist, this 2nd time it is called it returns nil and exits completion.

jdtsmith commented 1 year ago

BTW, I haven't yet gotten on board with "different keys for different completion flavors". I wonder if it would be interesting if we could make the distinction between auto completion and M-Tab completion in this way. I'm sure there's a simple approach, and this could be generally useful (a corfu-mostly-auto if you will).

minad commented 1 year ago

I wonder if it would be interesting if we could make the distinction between auto completion and M-Tab completion in this way. I'm sure there's a simple approach, and this could be generally useful (a corfu-mostly-auto if you will).

I also thought about this but I am not sure we need it. There are these three scenarios:

  1. Auto completion, uses completion-at-point-functions
  2. Manual completion M-TAB, uses completion-at-point/completion-at-point-functions
  3. Manually invoking the backend directly (interactive argument of company backends or cape-capfs)

You are talking about distinguishing 1 and 2. I actually like that thes are treated in exactly the same way, since this makes auto completion seamless. This feature is actually unique in Corfu. In Company you won't manage to get a setup where completion-at-point and auto completion interact that harmonically.

Afaik Company also doesn't have the ability to distinguish 1 and 2. Adding this would require some extension to keep the frontend/backend abstractions intact. But technically it should be already possible. One could check this-command inside the Capf. If it is completion-at-point we have case 2, otherwise we have 1.

jdtsmith commented 1 year ago

I actually like that thes are treated in exactly the same way, since this makes auto completion seamless

I was just having the same thought. It is indeed a real point of real distinction, one I point out to people often. Plus you can say: if it doesn't work in normal emacs completion, it won't work in corfu.