unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Dmitry Gutov <dgutov@yandex.ru>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: 16555@debbugs.gnu.org
Subject: bug#16555: 24.3.50; Company and CAPF: dealing with completion values containing extra text
Date: Mon, 27 Jan 2014 00:52:44 +0200	[thread overview]
Message-ID: <52E591BC.4090009@yandex.ru> (raw)
In-Reply-To: <jwv38kbl0w7.fsf-monnier+emacsbugs@gnu.org>

On 26.01.2014 08:23, Stefan Monnier wrote:
>> * Including extra text in completion table seems like it won't mesh well
>>    with the completion-at-point-functions interface, and specifically
>>    with the completion-at-point as the frontend. How would one write a
>>    CAPF function for clang or eclim with argument lists in mind?
>
>  From a CAPF point of view, I think it would work as follows:
> - all-completions would return the "cropped" names.
> - `annotate-function' would be used to add the arglists to *Completions*.

I played with this a bit, and looks like the proper way to make this 
work with the current completion-at-point code is to use text 
properties. I propertize the completions, and then the annotation 
function looks up the text property:

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

(setq a1 (propertize "aaa" 'a "a1")
       a2 (propertize "aaa" 'a "a2")
       a3 (propertize "aab" 'a "a3"))

(defun annota (s)
   (format "(%s)" (get-text-property 0 'a s)))

Using a hash table surprizingly didn't work, because:

* Without the additional text property, a1 and a2 are considered equal, 
and only one of them is listed in the completions buffer.
* If the hash table uses the `eq' test, lookup fails because the strings 
passed to the annotation function are not the same objects as those we 
return in the completions table.
* If the hash table uses the `equal' test, naturally it can't 
distinguish between a1 and a2 (lookup returns "a2" for both).

Is that how it's supposed to work?

And it looks to me that this approach is incompatible with the `value' 
command, if we want company-capf to support it. Using the annotation 
function, it would know how to get from value to value + annotation, but 
not the other way around.

Using `value' as described, aside from smoother transition from the 
current behavior, appealed to me because it allows to defer the string 
munging to the last possible moment, thus saving in performance on all 
strings that weren't displayed, when the candidates list is large.

But here's an extreme example, of sorts:

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

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.

On the other hand, using `annotate' cleanly separates the "meat" in 
completion candidates from the extra text, which can be used to e.g. 
visualize them differently, maybe with different faces and alignments in 
the popup. As long as we solve the issue of uniqueness.

> - `exit-function' would be used to insert the arglist after selecting
>    a candidate.

Yes, `exit-function' is the best match for `post-completion', but I 
don't see which value of STATUS should be considered as okay for 
insertion. `finished' seems to be a good candidate, but it does not seem 
to really correspond to when happens after `company-complete-selection' 
(the completion is inserted and the popup is closed). `finished' can 
only be the status when the inserted completion doesn't have any 
possible continuations in the completions table, whereas we obviously 
want to be able to do arglist insertion for these cases, too.

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 
`company-complete-selection'.





  reply	other threads:[~2014-01-26 22:52 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-26  4:11 bug#16555: 24.3.50; Company and CAPF: dealing with completion values containing extra text Dmitry Gutov
2014-01-26  6:23 ` Stefan Monnier
2014-01-26 22:52   ` Dmitry Gutov [this message]
2014-01-27  2:46     ` Stefan Monnier
2014-01-28  5:37       ` Dmitry Gutov
2014-01-28 13:24         ` Stefan Monnier
2014-01-28 16:00           ` Dmitry Gutov
2014-01-28 22:04             ` Stefan Monnier
2014-01-28 22:51               ` Dmitry Gutov
2014-01-29  1:34                 ` Stefan Monnier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=52E591BC.4090009@yandex.ru \
    --to=dgutov@yandex.ru \
    --cc=16555@debbugs.gnu.org \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).