[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#16555: 24.3.50; Company and CAPF: dealing with completion values con

From: Dmitry Gutov
Subject: bug#16555: 24.3.50; Company and CAPF: dealing with completion values containing extra text
Date: Tue, 28 Jan 2014 07:37:50 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0

On 27.01.2014 04:46, Stefan Monnier wrote:
* Without the additional text property, a1 and a2 are considered equal, and
only one of them is listed in the completions buffer.

Hmm??  AFAIK even with the text property, they are considered equal, so
it's odd that it would influence whether only one or both are displayed.
AFAIK in *Completions* "duplicates" are only eliminated if their
"text+annotation" is identical.

Indeed, sorry, I made a wrong conclusion (when it tried it, the annotation function didn't work because it used the `eq' test).

But should we document that the only way to retain the information about different annotations corresponding to equal strings is to use text properties? I don't see any other way. Like mentioned, hash tables don't work:

(add-hook 'completion-at-point-functions
           (lambda ()
             (let ((bounds (bounds-of-thing-at-point 'symbol)))
               (when bounds
                  (car bounds)
                  (cdr bounds)
                  (list a1 a2 a3)
                  :annotation-function #'annota)))) nil t)

(setq tt (make-hash-table :test 'eq)
      a1 "aaa"
      a2 "aaa"
      a3 "aab")

(puthash a1 "a1" tt)
(puthash a2 "a2" tt)
(puthash a3 "a3" tt)

(defun annota (s)
  (format "(%s)"
   (gethash s tt "?")))

aa| -> aaa(?), aab(?)

`company-capf' would be affected, too, since it uses `completion-all-completions' now, and the latter, via `completion-basic-all-completions', passes the completions through `completion-hilit-commonality', which intentionally creates new strings.

And if text properties is the only way, maybe disperse with the annotation function and just document the desired property on the strings?

ELISP> (js2-time (all-completions "" obarray 'fboundp))
ELISP> (js2-time (mapcar
            (lambda (s)
              (if (> (length s) 2)
                  (propertize s 's (substring s (/ (length s) 2)))
            (all-completions "" obarray 'fboundp)))

The second measurement fluctuates between 130ms and 80ms, probably due to
GC.  Maybe this is negligible, considering that on my machine
that's a collection with 19000 elements, and most completion lists will be
considerably smaller.

While I don't want to minimize the performance problem, you also have to
take into account the fact that the whole completion operation will
actually do something with those strings, so 19K candidates will
typically suffer from performance problems elsewhere.

Well, I'm not sure: at least in this case, as you can see, fetching the candidates is an order or magnitude faster than separating their annotations. `all-completions' and `try-completion' are also faster than annotation processing, as well as `sort', but not, surprisingly, `delete-dups' (which can be replaced with `delete-consecutive-dups', however, which is also fast), and when displaying, we only need to work with a few elements of the whole completions list, so that takes more or less constant time.

But that's an extreme case: Emacs symbols, where we have the list readily at hand. As an opposite example, I have a completion backend which fetches candidates from an external Ruby process (also not the fastest of languages). Walking through all classes and returning all methods defined anywhere takes about 3.2s, the resulting list is 16K long in this case, and processing annotations takes 120ms. So in this case we're good.

`finished' can only be the status when the inserted completion doesn't
have any possible continuations in the completions table,

That description was from the point of view of "TAB-style completion".
In the case of company-complete-selection', we know that even if there
could be further continuations, the user's action indicates he doesn't
want those, so it really should be `finished'.

IOW the problem is one of how to better document the meaning of `finished'.

But wouldn't it clash with the current completion-at-point interface? I don't think we can define a CAPF function without regard to how it work there.

The reverse is also true: being able not to insert the arguments list
for a sole candidate can also be useful, and in Company user can do that at
least by repeatedly using TAB (company-complete-common) instead of

Then I guess that company-complete-common wouldn't want to pass
`finished' to the exit-function.

It won't call the exit-function at all, currently, so when going though company-capf, exit-function would only be called with `finished'. That's another discrepancy, I guess.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]