yaotti's diary

QiitaやKobito、Qiita:Teamを作っています。Software is Eating the World

anything関数を好きな言語で実装できるanything-with-everything.el (Emacs Advent Calendar 2010 8日目)

Emacs Advent Calendar jp: 2010の8日目の記事です.
7日目はid:moozさん(そうだ Info 読もう - mooz deceives you)でした.明日はid:rubikitchさんです.


この記事では,anythingをより身近に使えるようになるanything-with-everything.elというのを書いたので,その紹介をします.
yaotti/anything-with-everything.el · GitHub
インターフェースを少し変更


を受けて,関数名を文字列ではなくシンボルで渡すように変更しました.

(defun-anything-function-with-script
    anything-emacswiki-changes  ; "anything-emacswiki-changes"ではない
    "get-emacswiki-changes.pl")

これは何?

(そもそもanything.elって何?/Emacsユーザーだけど入れてない,という人はanything導入のeverything 〜3分で使えるanything.el〜 - (rubikitch loves (Emacs Ruby CUI Books))を読んでとりあえず導入して色々試してみましょう.anything-find-fileの代わりにanything-filelist+を使おう - (rubikitch loves (Emacs Ruby CUI Books))などは衝撃的だと思います.)

anything-with-everything.elというのは,anything関数をelisp以外で実装することを可能にするelispです.
anythingインターフェースはとても快適なので様々な面で使いたくなるのですが,ちょっと複雑なことをしようとするとelispがそこまで書けない/よくわからないのであきらめる,ということが多いと思います.
Web APIを叩いてパースしてあれこれやる,なんてことをしようと思うと大変そうです.使い慣れた言語ならすぐに書けるのに…
そこでanything-with-everything.elを利用すれば,好きな言語でanything関数の処理を書いてelispを1行足すだけで自分のanything関数を作ることができます.

どう使うの?

まずanything関数の処理を行うscriptを書きます.そのスクリプト(以下ではhoge.pl)が備えるべきインターフェースは

  • $ hoge.pl --init=list でanythingの"選択候補"群を出力する
    • 1行に1つずつ,改行区切りで標準出力に印字する
  • $ hoge.pl --action=open CANDIDATE で処理を行う
    • CANDIDATEというのは上の"選択候補"のことです
    • 改行無しで渡ってきます

の2つです.
これだけだと何だかよくわからないので,例を.

サンプル

以下はEmacsWikiの最近更新されたURLを一覧表示し,選択するとブラウザで開くというサンプルです.

このスクリプトを~/.emacs.d/anything/scripts/以下に置き*1,以下のelispを評価します.

(require 'anything-with-everything)
(defun-anything-function-with-script anything-emacswiki-changes "get-emacswiki-changes.pl")

すると,anything-emacswiki-changesという関数が定義されるので,M-x anything-emacswiki-changesとすれば実行できます.

応用例

複数ソースを利用したいときには以下のようにします.
以下のスクリプト

を同じように~/.emacs.d/anything/scripts/へ保存し,(依存するモジュールが多いので普段perlを使わない人は動かないと思います)

(require 'anything-with-everything)
(defun-anything-function-with-script anything-hb-entries "get-hb-entries.pl"
  (("list" . "Hot Entries") ("my_entries" . "My Entries")))

を評価すると,「はてなブックマークの人気エントリ」「自分のブックマーク」の2つから候補を選択することができます.
先程のelispと違う最後のリストは,それぞれ(--initオプションの値 . ソースの名前)を表しています.
アクションは先程と同じように script --action=open CANDIDATEと実行されることを想定しています*2

まとめ

これは unite.vim の source をお好きなスクリプト言語で書ける unite-script - はこべにっき#を見て,anythingでも同じようにやりたい!と思って書いたものです.id:hakobe932++
スクリプトがやることは「候補を改行区切りで出力する」「その中の1つを引数に取って実行する」の2つなのでelispの知識がなくても簡単に実行/検証することができます.
これを使って面白い/便利なanything関数を作ってみてください.何かあればtwitterの@yaottiまで.


Emacs Advent Calendar 2010の明日9日目は,anything.elで有名なid:rubikitchさんです.

*1:このディレクトリは(setq awe:scripts-root-dir "/path/to/another/location")などとすれば変更できます

*2:今は複数のアクションを実行できないですが(間に合わなかった…)できるようにするつもりです