- choice-program 20161230.1721(in MELPA)
- parameter based program
概要
choice-program.el は、
- 候補リストを得て
- その候補に対して何らかのアクションを行う
プログラムを実行することを支援します。
たとえば、gitでは
git branch
でブランチのリストを得て、git checkout
でそのブランチに切り替えます。
Rubyのパッケージ(gem)を扱う gem
は
gem search
で全gemのリストを得て、gem install
でそのgemをインストールします。
このようなプログラムでは
候補リストからアクションを選択できると、
とても便利ですよね!
そこでchoice-program.elが役立ちます。
リストを得るのは
同期プロセスで行われるので
多少待たされますが、
アクションは
compilation-mode
を使うため
待たされません。
インストール
パッケージシステムを初めて使う人は
以下の設定を ~/.emacs.d/init.el の
先頭に加えてください。
(package-initialize) (setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/") ("melpa" . "http://melpa.org/packages/") ("org" . "http://orgmode.org/elpa/")))
初めてchoice-programを使う方は
以下のコマンドを実行します。
M-x package-install choice-program
アップグレードする方は、
以下のコマンドでアップグレードしてください。
そのためにはpackage-utilsパッケージが必要です。
M-x package-install package-utils (初めてアップグレードする場合のみ) M-x package-utils-upgrade-by-name choice-program
使い方
候補選択は
$ ${interpreter} ${program} ${selection-args}
で行われます。
アクションは
$ #{interpreter} ${program} ${choice-switch-name} 選択した候補
で行われます。
git
ではそのまま使えます。
以下の設定で
M-x git-checkout
が定義されます
(require 'choice-program) (defvar git-checkout-instance (choice-prog nil :interpreter nil ;スクリプトではないときはnilの指定が必須 :program "git" :buffer-name "*git-checkout*" :verbose-switch-form "" ;おまじない :choice-prompt "Branch" :choice-switch-name "checkout" ;アクションを行うときの引数 :selection-args '("branch") ;候補選択のときの引数(これはリストで渡す) :documentation "Run git-checkout from git-branch") "The git-checkout object instance.") (choice-prog-create-exec-function 'git-checkout-instance 'git-checkout)
Fig1: emacsリポジトリでM-x git-checkoutを実行する(ivy を有効にした状態で)
Fig2: emacs-25を選択すると git checkout
が実行される
補完は
completing-read
を使っていますので、
helm/ido/ivy/anythingなど
お好きなインターフェースを
使ってください。
制限
selection-args
は
引数をリスト渡す必要があるため、
アクションに渡すための
加工ができません。
たとえば、
emacsの開発リポジトリにおいて
git branch
を実行すると
dynamic-modules-rc2 emacs-25 * master xwidget xwidget_mvp
と出ますが、
最初の2列を削除できません。
幸い
現在のブランチである master
を
選択することはないので
問題はありません。
gem list
のように
バージョンも表示される場合は、
ラッパースクリプトで
gem名のみを取り出す必要があります。
$ gem list - (1) 0mq (0.5.3) 0xffffff (0.1.0) 10to1-crack (0.1.3 ruby) 略
【重要】過度な抽象化は逆に理解を困難にさせる
とはいえ、正直なところ
この程度のことならば、
わざわざ複雑な
choice-program.elを
使わなくても
簡単なコマンドを
定義すればいいだけです。
choice-program.elは
eieioというオブジェクト指向
で書かれているため、
初見さんがプログラムを
理解して使いこなすまでに
時間がかかります。
この程度ならば
普通に自分でコマンドを
定義した方が楽ですし、
理解が容易です。
(defun git-checkout (branch) (interactive (list (completing-read "Branch: " (split-string (shell-command-to-string "git branch | grep -v '^\\*' | cut -c3-" ) nil t) nil t))) (compilation-start (format "git checkout %s" branch)))
上記のM-x git-checkoutは
- list
- completing-read
- split-string
- shell-command-to-string
- compilation-start
- format
と初歩的な関数のみで
構成されています。
どちらが理解しやすいのかは
火を見るよりも明らかです。
しかも
grep -v
で現在のブランチ、
cut
で余計なスペースを
取り除いています。
過度の抽象化は
かえって理解を困難にさせる
ということの見本です。
本日もお読みいただき、ありがとうございました。参考になれば嬉しいです。