--- title: candidate-transformerを用いたanythingのsourceづくり author: kazu634 date: 2009-10-16 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:4835;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}' categories: - Emacs ---
取得した候補の文字列から、「anythingの候補として表示させる部分」と「選択後にコマンドによって実行される部分」とを分断することができます。その処理を行う関数を行うのが、 candidate-transformer ということになる…らしい:
- candidate-transformer (オプション)
- source から補完リストが作成された際に引数を一つとって呼び出される関数である。その引数は source から取得された候補のリストである。実際の補完に用いられる変換済み候補のリストを返さなければならない。
この要素は候補のリストからアイテムを変更したり、取り除いたりするために用いることができる。
この関数は「(表示文字列 . 実際の文字列)」という対のリストを返すことで、候補を修正することができる。この場合、「表示文字列」は Anything バッファーで表示されるが、「実際の文字列」は候補が選択されたときの action の引数に用いられる。このことによって、例えば候補があまりに長ければより読みやすくすることができるし、他の候補と共通の部分があり表示のために短縮した文字列に安全に置換できるようになる。
注意: 仮に「(表示文字列 . 実際の文字列)」という形式が用いられた場合、パターンマッチは表示文字列で行われ、実際の値では実施されない。
というわけで、実際に使ってみました。
前回と同じようにflickrから情報を引き出すスクリプトを用いますが、ブログに投稿できるようなサイズの画像へのリンクも一緒に取得させています。
ちなみにこのスクリプトを使用する際には、flickrからapi_keyを取得し、「xxx」の部分を取得したapi_keyに変更してください。
# === Libraries === use strict; use warnings; use Perl6::Say; use YAML; use utf8; use Encode; 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}}) { my $title = encode('utf8', $temp->{photos}->{photo}->{$i}->{title}); print "$title\t"; say 'http://farm' . $temp->{photos}->{photo}->{$i}->{farm} . '.static.flickr.com/' . $temp->{photos}->{photo}->{$i}->{server} . '/' . $i . '_' . $temp->{photos}->{photo}->{$i}->{secret} .'.jpg'; }
~/bin on kazu634 [504] $: perl flickr.pl Latex Installation http://farm4.static.flickr.com/3519/3910763253_f21d0a92f4.jpg 牛タン http://farm3.static.flickr.com/2491/3926830661_31876f9021.jpg 夕飯 http://farm3.static.flickr.com/2652/3933158369_dbecc6cb8c.jpg 一ノ関の夕暮れ http://farm4.static.flickr.com/3516/3933159353_c18fbb1b1d.jpg 324-todo-flow http://farm3.static.flickr.com/2552/3940382629_a0ca185977.jpg 326-rsvp-flow http://farm4.static.flickr.com/3422/3940382747_7debe2c8e8.jpg 323-flow-template http://farm3.static.flickr.com/2564/3941161952_9c1e689cce.jpg 325-login-flow http://farm4.static.flickr.com/3444/3941162050_d5288b1b06.jpg 厳美渓の農道 http://farm4.static.flickr.com/3495/3944022597_d1010fda01.jpg 温泉 http://farm4.static.flickr.com/3430/3944023685_465f5bcf4a.jpg フレンチ http://farm3.static.flickr.com/2558/3944024177_69112cd66e.jpg 一関ハーフ当日 http://farm3.static.flickr.com/2667/3944801484_0445c243b1.jpg 温泉 http://farm3.static.flickr.com/2553/3944802592_68ec2fb316.jpg Fastfinga http://farm3.static.flickr.com/2472/3946789592_126226025a.jpg Evernote http://farm3.static.flickr.com/2658/3950568038_b053d2bbf9.jpg Evernote http://farm3.static.flickr.com/2590/3950568530_4f659bcde4.jpg 同窓会 http://farm4.static.flickr.com/3471/3955756606_8e90852e93.jpg 20090929_lunch http://farm4.static.flickr.com/3167/3965082006_0b157ee2e3.jpg ハロウィン http://farm4.static.flickr.com/3430/3976527917_9aaef1f53e.jpg たぬき http://farm3.static.flickr.com/2558/3976528247_7d88f7f418.jpg 下北沢 http://farm4.static.flickr.com/3531/3977289848_4c327672af.jpg 下北沢 http://farm3.static.flickr.com/2540/3977290184_749e4e923b.jpg 下北沢 http://farm3.static.flickr.com/2445/3977291276_d8d485bbd5.jpg 夕飯 http://farm3.static.flickr.com/2499/3977291658_ff606260a6.jpg Stationary Hacks http://farm4.static.flickr.com/3282/3991212701_f45092560b.jpg anythingのサンプル2 http://farm4.static.flickr.com/3492/4006542967_5d62d0c82c.jpg anythingのサンプル1 http://farm3.static.flickr.com/2630/4007300814_5ba6ffb8f3.jpg anything-flickr http://farm3.static.flickr.com/2557/4010787675_1a0d784227.jpg
前回と同じままだと
;; anything-test (defun my-anything () (interactive) (anything (list tmp-c-source))) (setq tmp-c-source '((name . "Example") (candidates . (lambda () (delete "" (split-string (shell-command-to-string "perl ~/bin/flickr.pl") "\n")))) (action . (("Insert" . insert)))))
こんな画面が表示されます。
ここで candidate-transformer を用いてみます。
(setq tmp-c-source '((name . "Example") (candidates . (lambda () (delete "" (split-string (shell-command-to-string "perl ~/bin/flickr.pl") "\n")))) ;; ここで (表示文字列 . 実際の文字列) の形式に変換している (candidate-transformer . (lambda (candidates) (mapcar (function (lambda(arg) (apply 'cons (split-string arg "\t")))) candidates))) (action . (("Insert" . insert)))))
すると、このようにタイトルのみが表示されています(この例だと「c」で絞り込んでいるので表示されている数が少ないですね。。。)
候補を選択すると、次のようにURLが挿入されます。
外部コマンドの標準出力への出力を取り込む場合、最後の改行が問題になるから、こう書くのがイディオムみたい:
(delete "" (split-string (shell-command-to-string "perl ~/bin/flickr.pl") "\n"))