gnu-emacs-sources
[Top][All Lists]
Advanced

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

Re: completion-ui.el -- new release


From: Maciej Katafiasz
Subject: Re: completion-ui.el -- new release
Date: Mon, 23 Apr 2007 12:51:04 +0000 (UTC)
User-agent: pan 0.120 (Plate of Shrimp)

Den Wed, 14 Feb 2007 20:08:18 +0000 skrev Toby Cubitt:

> ;;; completion-ui.el --- in-buffer completion user interface
> 
> ;; This package provides a user-interface for in-buffer text
> ;; completion. It doesn't find completions itself. Instead, a completion
> ;; package can simply set the `completion-function' variable to a function
> ;; that takes two arguments, a string PREFIX and an integer MAXNUM, and
> ;; returns a list of at most MAXNUM completion candidates for
> ;; PREFIX. Completion-UI does the rest.

I can whole-heartedly agree with the above idea, but I can see some
problems with the implementation. First, the package is fairly confusing
from the user's perspective, especially with all methods being enabled by
default and no clear decision on which one will actually get used. There
should be a single customisation to say that, instead of each method
having an on/off toggle. They are mutually exclusive after all.

Second, I've had very bad luck trying to use it, my quick hack of a
function[0] revealed a couple of bugs: 

1) it doesn't actually work :), when trying to commit it doesn't dismiss
the popup and the result is a garbled mess with a completion candidate
still haging around. The non-workingness might be related to:

2) it doesn't have any concept of separation between what's presented as
the completion, and what's actually inserted when the user commits. Why it
is useful to distinguish is immediately demonstrated by the following
ASCII-artish completion popup:

ba __________________
  |int     bar       |
  |float   baz       |
  |FooBar *ballooney | => `ballooney' gets inserted
  `------------------'

Incidentally, this is exactly what my completion function returns, for
reasons that will become apparent in a moment. And that breaks
completion-ui.el horribly.

3) I had even worse of luck trying to get the tooltip display method to
work than with dynamic completion. For some reason as soon as the tooltip
is presented, the garbled mess mentioned above is inserted at point, so now
I have to aggressively orange garbled messes presented (one of them
being the tooltip) and no clear way of getting out ;)

4) I don't like the way you do your keymaps at all, and I happen to know
you can do _much_ better than that, again for reasons that will become
apparent in a moment. Creating maps based on some hardcoded set of
"printable" characters gets a huge :( from me.

Now to the apparent reasons. I happen to be working, like, right now this
very moment, on an IDE-ish style completion pop-up, based on Semantic
Bovinator and CEDET[1] in general. This is WIP, so not released yet, but
it's already working to a fairly large extent. You can see a screenie and
current code snapshot at:

http://mathrick.org/files/emacs-intellisense.png
http://mathrick.org/files/semantic-hover-completion.el

The core part and idea of my package is that the popup does NOT get in the
way you type your code, ever. In particular, it means it does not get in
the way of your usually defined keybindings, other than those specifically
assigned a meaning in an appropriate custom. (At this point I should
mention you should really try it out, talking about it just doesn't show
how awesomely it works. And it's not just bragging, it simply does
everything[2] I wanted it to do when I set out to write it.) Oh, and it
also provides you with keyboard-navigable completion tooltip. You can
press up/down and have it move between candidates, but just press
left/right and not only does it disappear, since those are meaningless
when it comes to selecting completions, but also moves point as if the
popup was never there in the first place.

Now how it does what it does: it's very careful to always be the last one
to install the keymap, and generally makes sure the keymap is installed at
the latest possible moment, in order to both avoid interferring with
others and others interferring with us by changing key(map)s whilst we're
not looking. It defines only a couple of navigational keys that allow
selection and committing of candidates, and everything else causes it to
drop into the magic function `semantic-hover-completion-dismiss-or-filter'
that does one of the following:

- If the key would normally trigger self-insert-command, let it insert,
but also use the character to narrow down the selection list

- Otherwise it means we should dismiss the pop-up *and* spill the event
over to the command that would be normally bound, had we not been there to
intercept the keypress

It does the above by the magic of default keybindings and judicious
lookups / replays of events.

Now I would be very glad to have the tooltip-related code split out and
reusable by anyone, and I wanted to add another display method anyway,
namely buffer-inline pseudo-tooltip rendered with character overlays,
which I intend to steal from uim.el. But in order for completion-ui.el
being that common display library, it needs to be improved considerably.
I'd like you to take a look at semantic-hover-completion.el, and steal
the code when I'm done, as I believe it does a better job of being good
UI than completion-ui.el rigth now.

Cheers,
Maciej

[0] (defun my-cmpl (prefix maxnum)
      (let ((cands (car (semantic-hover-completion-make-candidates)))
            (len (length prefix)))
        (delete nil
                (mapcar (lambda (elt)
                      (and
                       (>= (incf maxnum -1) 0)
                       (semantic-format-tag-prototype elt)))
                        cands))))

Notice it disregards the supplied PREFIX, since Semantic is generally able
to figure it out on its own. And that's exactly why it breaks, too, since
the returned strings don't have PREFIX, even though the actual completions
that should be inserted do.

[1] http://cedet.sf.net
[2] Of course it's a bit hacky right now, particularly wrt. state
    management and installing keymaps, but it works and there's nothing
    that couldn't be cleaned up. And there's one bug that makes me want to
    kill emacs and its entire family to the third generation, you can read
    all about it in the comment in `semantic-hover-completion-unfilter',
    but as soon as I get it down, that's it, the code attains perfection
    and reaches Nirvana. Or something.





reply via email to

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