helm拡張を書く例を示していきます.
題材は松屋ジェネレータを用いたものにします.
リポジトリ
イメージ
コード解説
依存パッケージの宣言
現在 helmは コア部分の helm-core
, その他の helm
の 2つのパッケージから構成されます. helm-core
はごくごく基本的な機能しかありません. helm
関数と各種ソース構成に関する関数マクロしか呼ばない場合は helm-core
で十分です. helmのファイル機能(helm-ff-*
)を使う, grep機能(helm-grep
)を使うという場合は helm
パッケージが必要になります.
;; Package-Requires: ((helm "1.7.7") (migemo "0"))
わからない場合は helm-core
にして, Caskでミニマルな環境を構築し, 動作検証してみるとよいでしょう. 依存パッケージの宣言が適切に行えていれば Caskは以下の内容で十分です.
(source gnu)
(source melpa)
(package-file "helm-matsuya.el")
そして cask && cask exec emacs -Q -L . -l helm-matsuya.el
とし, 動かない, バイトコンパイルで警告, エラーが出る場合は helm
に切り替えて試してみるとよいでしょう.
ライブラリのロード
helm.el
のロードは必須です. その他は必要に応じてロードしましょう.
(require 'helm)
(require 'helm-net)
(require 'cl-lib)
groupの宣言
defcustom
で定義されるカスタマイズ変数や, defface
で定義される faceがある場合は groupを宣言しましょう. :group
属性(親グループ)は helm
にしておきましょう(helm拡張の拡張となる場合はその拡張で定義されるグループを親グループとすべきです).
(defgroup helm-matsuya nil
"matsuya generator command with helm interface"
:group 'helm)
ソースの定義
別に変数に定義しておく必要はありませんが, 変数として定義しておくとあとあと便利なこともあります. 動的に生成する必要がない場合は基本的に変数として定義するのがよいでしょう. ソースの構築は以前は association listがそのまま使われていましたが, 最近は構築のための関数を使った方がよいでしょう. ここでは用途に合わせて helm-build-sync-source
を使っています. helm-build-
でドキュメントを検索するといくつかの類似する関数が見つかりますので, 気になる方は調べてみてください(多くの場合は helm-build-sync-source
と helm-build-in-buffer-source
で事足りると思います)
ソースの定義関数は第一引数が名前で, 第二引数以降がキーワード引数で, キーワード, 値, ...と設定していきます. assocication listだとタイポが実行時まで気づきませんが, これだとバイトコンパイル時には気付けるのでよいのではないかと思います.
(defvar helm-matsuya--source
(helm-build-sync-source "Menu"
:candidates #'helm-matsuya--candidates
:volatile t
:migemo t
:action (helm-make-actions
"Open Browser" #'helm-google-suggest-action
"Insert" #'insert)))
コマンドの定義
helm
関数にはいろいろキーワード引数がありますが, :sources
(使うソースのリスト), :buffer
(バッファ名)をセットすればよいでしょう. 後はドキュメントを見て必要なものを足してみてください.
;;;###autoload
(defun helm-matsuya ()
(interactive)
(helm-migemo-mode +1)
(helm :sources '(helm-matsuya--source) :buffer "*helm matsuya*"))
おわりに
helm
拡張の作り方を大雑把に説明しました.
helm
は膨大な機能があります. ドキュメントは結構書かれている方だと思いますが, そもそもどれを調べていいかわからないという状況になります. そこで私は M-x helm-descbinds
を使って, それらしいキーワードで関数, 変数を絞りこみ, 調べてみるということをしています.