VisualStudioCodeの勢いがすごい昨今、周りでもVim派とVisualStudioCode派とそれぞれの言語用のIDE派の人たちが大部分を占めている。 Emacsユーザーに出会う機会も少ないし、まして熱心にEmacsを使っている人はもっと少ないように感じる。 もはやEmacsはマイナーなエディターになってしまったのか。 悲しい限りではあるが、私にとってはまだまだ他のエディターと比べて使いやすくカスタマイズしやすい最高のエディターだ。 ただ最高のエディターとは書いたが不満はたくさんある。 これらの不満を自分のペースで解決していきやすいところがEmacsの良いところだ。
今回はEmacsの補完機能をカスタマイズする。今回はcompany-modeを取り上げる。 company-modeのWiki1に従って簡単な補完を実装する。
fooと入力すると
- foobar
- foobaz
- foobarbaz
を提案して来るようになる。
(setq company-idle-delay 0)
(setq company-minimum-prefix-length 1)
(setq company-selection-wrap-around t)
(require 'cl-lib)
(require 'company)
(defun company-simple-backend (command &optional arg &rest ignored)
(interactive (list 'interactive))
(print command)
(print arg)
(print ignored)
(cl-case command
(interactive (company-begin-backend 'company-simple-backend))
(prefix (when (looking-back "foo\\\\>")
(match-string 0)))
(candidates (when (equal arg "foo")
(list "foobar" "foobaz" "foobarbaz")))
(meta (format "This value is named %s" arg))))
(add-to-list 'company-backends 'company-simple-backend)
もう少し複雑な処理をしたい場合の例を示す。
(require 'cl-lib)
(defvar company-advanced-keywords
'(("foo" "overload 1") ("foo" "overload 2") ("bar" "method 1")))
(defun company-advanced–make-candidate (candidate)
(let ((text (car candidate))
(meta (cadr candidate)))
(propertize text 'meta meta)))
(defun company-advanced–candidates (prefix)
(let (res)
(dolist (item company-advanced-keywords)
(when (string-prefix-p prefix (car item))
(push (company-advanced–make-candidate item) res)))
res))
(defun company-advanced–meta (candidate)
(format "This will use %s of %s"
(get-text-property 0 'meta candidate)
(substring-no-properties candidate)))
(defun company-advanced–anotation (candidate)
(format " (%s)" (get-text-property 0 'meta candidate)))
(defun company-advanced (command &optional arg &rest ignored)
(interactive (list 'interactive))
(cl-case command
(interactive (company-begin-backend 'company-advanced))
(prefix (company-grab-symbol-cons "\\\\.\\\\|->" 2))
(candidates (company-advanced–candidates arg))
(annotation (company-advanced–anotation arg))
(meta (company-advanced–meta arg))))
(add-to-list 'company-backends 'company-advanced)