auto-completeで特定の単語で補完を消す方法

元ネタ: id:kitokitoki:20090819

要するに<?phpとうったときにphpinfoとかが候補として出るとRETで改行できない(候補があるため)という問題。解決策は以下の3通り。

RETのキーバインドを外す

RETはそもそも補完のアクションを実行するコマンドのために割り当ててある(現状yasnippetでしか使ってない)。単純に補完するだけならTABで十分なのでRETのキーバインドを外すという方法はありだと思う。

(define-key ac-complete-mode-map "\r" nil)

オムニ補完の機構で強制的に消す

ベータ版の実験的機能のオムニ補完の機構を使って強制的に消すのもありです。仕様はほぼこれで確定なのでバージョンアップ時に動かなくなることはないと思います。

方法はオムニ補完のトリガに補完を消したい単語を指定し、その時に使用されるsourcesはnilにしておきます。

(add-hook 'php-mode-hook (lambda () (push '("<\\?php") ac-omni-completion-sources)))

ちなみに最新のauto-completeじゃないと正しく動作しません。次のURLからインストールしてください。

http://cx4a.org/pub/auto-complete.el

candidate-filterを使う

これは正攻法ではないのですが、一応可能なので。最新のauto-completeにはac-candidate-filter-functionという変数があって、それに任意の関数を設定することでユーザー独自の候補絞り込みが可能になります。これを利用して<?phpの直後にいる場合はnilを返すようにしてやれば解決できます。将来的にcandidate-filterの仕様が変わる可能性があるので無茶なことはしないほうがいいです。

(defun ac-php-candidate-filter (candidates)
  (unless (looking-back "<\\?php")
    candidates))

(add-hook 'php-mode-hook
          (lambda ()
            (make-local-variable 'ac-candidate-filter-function)
            (setq ac-candidate-filter-function 'ac-php-candidate-filter)))