Subject: Re: bug#8492: 23.3; Time to use a different binding for completion?

From: Lennart Borgman <[email-masked]>
Date: Tue, 19 Apr 2011 15:01:14 +0200

On Tue, Apr 19, 2011 at 2:46 PM, Stefan Monnier
<[email-masked]> wrote:
>>>>> Is it therefore time to admit defeat and find an alternative binding for
>>>>> completion functions, even if it’s an extra binding rather than simply a
>>>>> different one?
>>>> TAB can do completion if you (setq tab-always-indent 'complete).
>>> Thanks for the tip, I'll try that.
>> The idea is nice, but there is perhaps a problem with the current
>> implementation: There are many ways to complete in Emacs.
>
> It's not the ultimate solution, no.  I'm not sure what "other choices"
> you're thinking of, but I know that for some major modes, mixing
> completion and indentation via (setq tab-always-indent 'complete) is not
> really an option (e.g. Python where TAB cycles through various
> indentation levels).

This is what I have in tabkey2.el in nXhtml (though it might be broken
at the moment):

(defcustom tabkey2-completion-functions
  '(
    ("Emacs default completion" completion-at-point
completion-at-point-functions)
    ;; Front ends (should take care of the rest, ie temporary things,
    ;; snippets etc...)
    ("Company Mode completion" company-complete company-mode)
    ;; Temporary things
    ("Spell check word" flyspell-correct-word-before-point nil)
    ;; Snippets
    ("Yasnippet" yas/expand (yas/expandable-at-point))
    ;; Main mode related, often used
    ("Semantic Smart Completion" senator-complete-symbol senator-minor-mode)
    ("Programmable completion" pcomplete (and (boundp
'pcomplete-parse-arguments-function)

pcomplete-parse-arguments-function))
    ("nXML completion" nxml-complete (derived-mode-p 'nxml-mode))
    ("Complete Emacs symbol" lisp-complete-symbol (and (derived-mode-p
'emacs-lisp-mode)
                                                       (not (fboundp
'completion-at-point))))
    ("Widget complete" widget-complete nil)
    ("Comint Dynamic Complete" comint-dynamic-complete nil)
    ("PHP completion" php-complete-function php-mode)
    ("Tags completion" complete-tag nil)
    ;; General word completion
    ("Predictive word" complete-word-at-point predictive-mode)
    ("Predictive abbreviations" pabbrev-expand-maybe)
    ("Dynamic word expansion" dabbrev-expand t (setq
dabbrev--last-abbrev-location nil))
    ("Ispell complete word" ispell-complete-word t)
    ;; The catch all
    ("Anything" anything (commandp 'anything))
    )
  "List of completion functions.
The first 'active' entry in this list is normally used during the
'Tab completion state' by `tabkey2-complete'.  An entry in the
list should have either of this forms

  \(TITLE COMPLETION-FUNCTION ACTIVE-FORM RESET-FORM)

TITLE to show in menus etc.

COMPLETION-FUNCTION is the completion function symbol.

The entry is considered active if the symbol COMPLETION-FUNCTION
is bound to a command and

  - This function has a key binding at point and ACTIVE-FORM is
  equal to nil.

or

  - The elisp expression ACTIVE-FORM evaluates to non-nil.  If it
  is a single symbol then its variable value is used, otherwise
  the elisp form is evaled.

RESET-FORM is used to reset the completion function before
calling it.

When choosing with `tabkey2-cycle-completion-functions'
only the currently active entry in this list are shown."
  :type '(repeat (list string (choice (command :tag "Currently known command")
                                      (symbol  :tag "Command not known yet"))
                       (choice (const :tag "Active only if it has a
key binding at point" nil)
                               (sexp :tag "Elisp, if evals to non-nil
then active"))
                       (sexp :tag "Elisp, reset completion function")))
  :group 'tabkey2)