Emacsのテンプレート用パッケージTempelの設定

テンプレート挿入・展開に便利なパッケージTempel がある.

github.com

公式を参考に,設定はこんな感じ.テンプレート展開の部分キーワードを入力して M-+ でテンプレートが展開するので便利である. また「ここにテンプレートを展開したい」と思ったところで M-* でテンプレートを選択して展開することもできる.

;; テンプレート展開をトリガーするためのプレフィックス
;; テンプレート挿入モードに入るためのキー,という認識
;; デフォルトはnil,つまり地のソースコードとテンプレート挿入の境界がない
;; (setq tempel-trigger-prefix "<") 

(global-set-key (kbd "M-+") 'tempel-complete) ;; テンプレートキーワード途中までの入力内容で補完し,挿入
(global-set-key (kbd "M-*") 'tempel-insert) ;; 何も書かれていないところにテンプレート挿入

;; completion-at-point にテンプレート展開を追加
(defun tempel-setup-capf ()
  (setq-local completion-at-point-functions
              (cons #'tempel-expand  ;; exact match; キーワードに厳密にマッチしたときに発動
                    completion-at-point-functions)))

;; テンプレート展開を適用するメジャーモードを指定
(add-hook 'prog-mode-hook 'tempel-setup-capf) ;; プログラミング系全般
(add-hook 'text-mode-hook 'tempel-setup-capf)

;; eglotを使う場合はeglot-completion-at-pointの優先度が上がるので、それを阻止
;; (add-hook 'eglot-managed-mode-hook 'tempel-setup-capf)

;; フィールド移動のキーバインドを追加
(with-eval-after-load "tempel"
  (define-key tempel-map (kbd "<tab>") #'tempel-next)
  (define-key tempel-map (kbd "C-i") #'tempel-next)
  (define-key tempel-map (kbd "<backtab>") #'tempel-previous)
  (define-key tempel-map (kbd "C-S-i") #'tempel-previous))

tempel自体はテンプレート展開の枠組みを提供しているだけなので,テンプレートは自分で用意しなければならない. そこでまずtempel-collectionを入れておくと良い.Pythonなどはこれで間に合う.

github.com

さらに足りないものは自分でテンプレートを書いて追加していけばよい.例えばC言語の場合は以下のようなテンプレートを書いておくのも良いだろう.記述のルールはTempelの公式リポジトリに書いてあり,簡単である. オリジナルのテンプレートファイルの置き場所は ~/.emacs.d/templates となっている. (2024/06/29)

c-mode
(io "#include <stdio.h>" n)
(lib "#include <stdlib.h>" n)
(str "#include <string.h>" n)
(math "#include <math.h>" n)
(main "int main(int argc, const char *argv[]) {"n> q n> "return 0;" n "}")
(for "for (" (p "i") "; " p "; " p ") {"n> q n "}" >)
(switch "switch (" p ") {"n> "case " (p "1") ":" n> q n> "break;\n" "\t\tdefault:"n >n "break;"> n "}" >)
(while "while (" p ") {"n> q n "}" >)
(struct "struct " p " {" n> q n "};")