abo-abo / swiper

Ivy - a generic completion frontend for Emacs, Swiper - isearch with an overview, and more. Oh, man!
https://oremacs.com/swiper/
2.3k stars 338 forks source link

More in-buffer completion woes #1410

Open basil-conto opened 6 years ago

basil-conto commented 6 years ago

I've bisected the following behaviour to 3bd5f3b7d191c9622e17e89755a133419457365e, which pertains to #1361 :

  1. make plain
  2. (message-make C-M-i
    • Expected: "No matches" in echo area, buffer unchanged
    • Actual: message-make is deleted and in-buffer completion is started for the following candidates
      • message-forward-rmail-make-body
      • message-forward-make-body
abo-abo commented 6 years ago

Thanks, I can reproduce this as well. But I don't see a good fix.

Looking at completion-at-point-functions, it's (elisp-completion-at-point t).

This function passes the obarray to ivy-completion-in-region as collection. Nothing better to do with that than to call completion-all-completions.

Which gives us:

comps
;; =>
;; (#("message-forward-rmail-make-body"
;;    0 26 (font-lock-face
;;          completions-common-part)
;;    26 27 (font-lock-face
;;           completions-first-difference))
;;   #("message-forward-make-body"
;;     0 20 (font-lock-face
;;           completions-common-part)
;;     20 21 (font-lock-face
;;            completions-first-difference)))

I don't really want Ivy to check if the collection is an obarray and write code to treat that case if completion-all-completions is already available. Maybe report a bug against completion-all-completions if you think it should not return that result?

Here's the gist of the issue:

(completion-all-completions
 "message-make"
 obarray
 'fboundp
 (length "message-make"))
;; =>
;; (#("message-forward-rmail-make-body"
;;    0 26 (font-lock-face
;;          completions-common-part)
;;    26 27 (font-lock-face
;;           completions-first-difference))
;;   #("message-forward-make-body"
;;     0 20 (font-lock-face
;;           completions-common-part)
;;     20 21 (font-lock-face
;;            completions-first-difference)) . 0)

Thinking about it, we could use this instead:

(all-completions "message-make" obarray 'fboundp)
;; => nil

But then we can't rely on completion-all-completions to make ivy-completion-common-length work.

On the other hand, all-completions treats the input as the prefix. So ivy-completion-common-length could be replaced with (- end start).

I'll have to think about this some more. Suggestions welcome.

abo-abo commented 6 years ago

OK, I've looked into all-completions replacement. It simplifies things a lot, also fixing your case.

But we lose the functionality tested by ivy-partial-2: when doing eval-expression, 's-c-t-st should expand to shell-command-to-string. This functionality isn't very valuable to me, but some users will probably be upset by this no longer working.