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

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

Re: Fwd: completion-ui.el question: my vimpulse-show-completion-menu fun


From: Toby Cubitt
Subject: Re: Fwd: completion-ui.el question: my vimpulse-show-completion-menu function always gives me an empty menu
Date: Fri, 13 Apr 2007 10:00:52 +0200
User-agent: Thunderbird 1.5.0.10 (Windows/20070221)

Jason A. Spiro wrote:
As an Elisp coder, you're not supposed to invoke *any* completion
interface explicitly, as you've tried to do. Deciding which combination
of user-interfaces to use is the user's business, not the package
writer's. Maybe some users want to use menu completion, but others
prefer to see a list in the echo area, whilst still others just want a
tooltip to popup after a delay, etc. etc. Completion-UI offloads those
choices onto the user, which is where they should be.

OK.  I will tell vimpulse users they should set certain Completion-UI
settings themselves to get something closer to Vim completion.  But
meanwhile, I still have a question about the code I am writing myself
for testing purposes.

I now understand a bit better what you're trying to do. I guess in the special case of trying to emulate vim, my arguments are specious, since you *want* to make user-interface choices for the user. So I guess vimpulse-mode could set the completion-ui customization variables appropriately. However, the main point still stands: you shouldn't be calling any internal completion-ui functions (such as completion-menu) from your own code.


;; Begin code {{{

(require 'completion-ui)

;; Note: This code has an additional bug in addition to the problem I
;; am asking about in this mailing list message:
;; When called with a MAXNUM of nil, this func sometimes fails.  (Seems
;; to work the first time, then fail all times after, in such cases.
;; To fix, call with a normal MAXNUM.)

This might cause problems later, since completion-UI occasionally needs to call it with a nil MAXNUM. The function is then supposed to return a list of all possible completions.

BTW, I realise that setting up a temporary buffer and simulating an interactive call to hippie-expand is a simple way to get what you want, but it also seems a bit ugly to me. Hippie-expand contains a lot of code that deals with user-interface issues, and you're using completion-UI for that. Wouldn't it be better to read through the hippie-expand code, work out which internal function returns the list of completions as its return value, and call that instead? It's more work, but also less ugly, more efficient, and I suspect more robust.


(defun vimpulse-try-hippie-expand-listed-functions (prefix &optional maxnum)
;  (interactive "*MString to expand:
;nMaximum number of expansions, or nil for unlimited: ")
(setq expansions nil)
(with-temp-buffer
  (insert-string prefix)
  (hippie-expand nil)
  (unless (string-equal (current-message) "No expansion found")
    (while (and
            (not (string-equal
                  (current-message)
                  "No further expansions found"))
            (if maxnum (not (= (length expansions) maxnum))))
      ;; Hippie-expand was designed to be run interactively.  If
      ;; this-command and last-command are equal, it assumes it's
      ;; being called as a "repeated use" (additional call without
      ;; moving the point) and searches for additional expansions
      ;; with the same prefix.  So, make this-command and
      ;; last-command equal.
      (setq this-command last-command)
      (hippie-expand nil)
      (add-to-list 'expansions (buffer-string))
      (buffer-string)
    ))
  expansions))

This is almost OK. Completion-UI expects the completion-function to return a list of completion strings *without* the prefix. So you need to change "expansions" in the last line to:

  (mapcar (lambda (str) (substring str 1)) expansions)


(defun jason-problem-demo ()
(interactive)
(setq-default completion-function
'vimpulse-try-hippie-expand-listed-functions)
(setq completion-function 'vimpulse-try-hippie-expand-listed-functions)
;; is this always necessary?  Am I even ever supposed to call it?
(completion-setup-overlay 'prefix)
(completion-show-menu))
> ;; }}} End code
>
> Whenever I start typing a word then run
> M-x jason-problem-demo I get an empty menu.  Why?
>
> Am I using
> completion-show-menu wrong?  It errors on me if I don't call
> completion-setup-overlay first, so I call it first.  Should I?

This won't work, because you're *still* fighting completion-UI rather than working harmoniously with it :) What you should be doing is setting 'completion-function' to 'vimpulse-try-hippie-expand-listed-functions, and then going off to make a cup of tea, have a bite to eat, watch a movie, and then spend the weekend fishing and contemplating whether you really want to spend so much of your life at a desk hacking Emacs :) Because setting 'completion-function' is *all* you have to do!

Once 'completion-function' is set, when you type some characters and then call 'complete-word-at-point' (bound to M-TAB by default), everything should work. (At least, it did when I just tested it!) By default, you can bring up the menu using 'completion-show-menu' (bound to M-down by default). Given that you seem to want to show the menu immediately, in your case you might want to set 'completion-auto-show-menu' to non-nil, so that the menu is displayed immediately after calling 'complete-word-at-point'. (Again, setting the 'completion-auto-show-menu' customization option should normally be left to the user to customize, but in your case I can see why you might want vimpulse-mode to do the customization itself.)


Cheers,
Jason[5]

[1] http://www.emacswiki.org/cgi-bin/wiki/vimpulse.el

[2] Unfortunately hippie-expand can't complete multiple-word sequences
like dabbrev can when you press M-/ SPC M-/ SPC M-/.  Vim can do it:
just press CTRL-X CTRL-P repeatedly.  But I hope I'll eventually fix
that.

Then again, maybe I'll never have time to make that change to
hippie-expand.  So maybe I should have Completion-UI call
dabbrev-expand instead.

How exactly does this multiple-word completion work? I don't follow.


[3] e.g. CTRL-X CTRL-T for thesaurus completion, or many other[4] things.

[4] http://ianua.initd.org/vimit/vim63/html/insert.html#ins-completion

[5] P.S. You may want to mention in the completion-ui documentation at
the top of the file that
http://www.emacswiki.org/cgi-bin/wiki/CompletionUI#toc2 has examples
of how to use completion-ui with dabbrev and etags.  If I knew that
info, it would have saved me time. :-)

Ah, I kind of assumed you'd already seen them. I should probably include the examples in the documentation at the top of the file. Or better still, get round to writing some texinfo documentation for completion-UI. There are a lot of features I suspect only I know about at the moment :)


Toby




reply via email to

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