2

I currently have the following settings for hippie-expand in my .emacs file:

(setq hippie-expand-try-functions-list
  '(try-expand-dabbrev
    try-expand-dabbrev-all-buffers
    try-expand-dabbrev-from-kill
    try-complete-file-name-partially
    try-complete-file-name
    try-expand-all-abbrevs
    try-expand-list
    try-expand-line
    try-complete-lisp-symbol-partially
    try-complete-lisp-symbol))

However, there is one thing annoying me: The order of suggestions I get when I use the completion function. I want it to suggest the shortest completion first, not the longest one. For example when I write a text and I know I used the word I am currently writing and other variations before in the text, I want it to suggest the "lowest common denominator" of those words and not the longest of the words. Then I can simply type the next letter "giving emacs another hint" and use completion again. This can go on until I got the complete word. I like this more than switching through a long list of words. For code it is similar. I don't want the first suggestion to be the longest expression, which it can find in the buffers, but the shortest one, because the longest one might confuse, because it might be several lines long (for example s-expressions in any Lisp).

How can I reverse the order of suggestions or make it show the shortest first?

Edit

  • I now think it always suggests the least recently used completion. In text this seems OK, although I am used to having the shortest one first. However in Code, for example for some s-expressions, this is terrible, as it will insert whole blocks of code, when I only want it to complete some name of a procedure or a variable name.
Drew
  • 75,699
  • 9
  • 109
  • 225

2 Answers2

3

I'm a bit confused by your question, because hippie-expand doesn't provide results in longest-to-shortest order, and it also doesn't provide "lowest common denominator" results which aren't actual completions, so there's no way for you to achieve your aim by any kind of re-ordering process, so you're actually looking for a different kind of functionality.

To order the results at all, you'll need to generate them all up front (which hippie-expand doesn't do), so you might look at the Expansion menu approach on the Emacs Wiki for a starting point, in which I use the following to obtain a list of the completion options:

(defun my-hippie-expand-completions (&optional hippie-expand-function)
  "Return the full list of possible completions generated by `hippie-expand'.
The optional argument can be generated with `make-hippie-expand-function'."
  (let ((this-command 'my-hippie-expand-completions)
        (last-command last-command)
        (buffer-modified (buffer-modified-p))
        (hippie-expand-function (or hippie-expand-function 'hippie-expand)))
    (flet ((ding)) ; avoid the (ding) when hippie-expand exhausts its options.
      (while (progn
               (funcall hippie-expand-function nil)
               (setq last-command 'my-hippie-expand-completions)
               (not (equal he-num -1)))))
    ;; Evaluating the completions modifies the buffer, however we will finish
    ;; up in the same state that we began.
    (set-buffer-modified-p buffer-modified)
    ;; Provide the options in the order in which they are normally generated.
    (delete he-search-string (reverse he-tried-table))))
phils
  • 48,657
  • 3
  • 76
  • 115
  • Seems I am coming ore form the user's perspective on this one. What I mean is: When you call the hippie-expand function, it inserts some text. If you call it again, it inserts something else, if available. This is the next "suggestion" as I call it. The list of all suggesting in the order they appear is what I thought could somehow be reordered. If hippie-expand does not somehow create such list, how does it provide me anything at all? If it creates some iterator, that also needs to have some criteria for what comes first. Maybe that could be changed? I do not know internals of it. – Zelphir Kaltstahl Feb 17 '17 at 12:54
  • 1
    The Commentary at the top of `M-x find-library RET hippie-exp RET` gives an overview of how it works. – phils Feb 17 '17 at 13:19
  • 1
    One approach would be to replace your try-functions-list with a single custom function which builds the whole completion list (again, see the code I linked to on the Emacs Wiki which does this); sorts the list in the way you want; possibly generates new entries based on common prefix substrings; and then returns the next item in that list on each call. – phils Feb 17 '17 at 13:36
  • What @phils said. You cannot provide a set of things in a given order unless the full set is known (and then sorted). Gather all of the completions that you want to sort, then sort them, then present them to the user. – Drew Feb 17 '17 at 16:30
0

If you accidentally skip over the suggestion you want, and would like to go in reverse back to the one you skipped, try using 'undo,' ctrl-z, to go back to the one you missed.

To get to the last suggestion hold down the key combo for expand M-/ until you get "No further expansions found", then use C-z to step back through the list of suggestions.