--- title: 候補を外部スクリプトから取得する author: kazu634 date: 2009-10-14 wordtwit_post_info: - 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:4833;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}' categories: - Emacs ---

candidates の説明にはこんなことが書いてあった:

candidates (candidates-in-buffer 要素を指定しなかった場合、必須)
source から候補を取得するための方法を指定する。この要素に指定できるのは、変数、引数なしの関数、あるいは実際の候補のリストである。
リストは文字列のリストでなければならず、そのため必要であれば候補を文字列に変換するのは source の責任である。
仮に候補が非同期で取得されなければならない場合(例えばコマンド終了までに時間がかかる外部コマンドで取得するような場合)には、その関数は外部コマンドを非同期で実行し、 the associated process object を戻す必要がある。
Anything はそのプロセスを管理する(そのプロセスから出力を受け取り、必要であればそのプロセスを停止する、など)。プロセスは現在のパターンにマッチする候補を返さなければならない(anything-pattern を参照すること)。
注意: 非同期の source からの結果は anything-sources 中の位置に関係なく、 anything のバッファーの最後に表示される。

2009-10-12 – 武蔵の日記

この説明を読むと、引数なしの関数を書いて、リストを返してあげれば大丈夫そう。というわけで、適当なスクリプトを書いて、それから anything の候補を生成してみた。

作成したスクリプト

自分の Flickr アカウントから、アップロードした画像のタイトル一覧を取得する Perl スクリプトです。このスクリプトを「flickr.pl」として保存してます。

# === Libraries ===
use strict;
use warnings;
use Perl6::Say;
use utf8;
use WebService::Simple;
use XML::Simple;
use YAML::Syck;
# === Main part ===
my $flickr = WebService::Simple->new(
base_url => "http://api.flickr.com/services/rest/?",
param    => {
api_key => 'xxx',
method => 'flickr.photos.search',
machine_tag_mode => 'any',
}
);
my $response = $flickr->get( { user_id => '42332031@N02', } );
# (1) 取得したXMLの表示
# say YAML::Syck::Dump( XMLin ($response->content));
my $temp = XMLin($response->content);
foreach my $i (sort keys %{$temp->{photos}->{photo}}) {
say $temp->{photos}->{photo}->{$i}->{title};
}

スクリプトの実行結果

~/bin on kazu634 [503] $: perl flickr.pl
Latex Installation
牛タン
夕飯
一ノ関の夕暮れ
324-todo-flow
326-rsvp-flow
323-flow-template
325-login-flow
厳美渓の農道
温泉
フレンチ
一関ハーフ当日
温泉
Fastfinga
Evernote
Evernote
同窓会
20090929_lunch
ハロウィン
たぬき
下北沢
下北沢
下北沢
夕飯
Stationary Hacks
anythingのサンプル2
anythingのサンプル1

Emacs側の設定

次のコマンドを使います:

shell-command-to-string
シェルコマンドの実行結果を文字列に変換する Emacs コマンド
split-string
与えられた文字列を、引数で指定した文字列で分割し、リストにする

詳細は、 M-x descrive-function してください。

(defun my-anything ()
(interactive)
(anything
(list
tmp-c-source)))
(defvar tmp-c-source
'((name . "Example")
(candidates . (lambda ()
;; 文字列を改行で区切ってリストにする
(split-string
;; perl ~/bin/flickr.plの実行結果を文字列に変換する
(shell-command-to-string "perl ~/bin/flickr.pl")
"\n")))
(action . (("Insert" . insert)))))

実行結果