blog/content/post/2009/10/16/2009-10-16-00001240.md

221 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: candidate-transformerを用いたanythingのsourceづくり
author: kazu634
date: 2009-10-16
url: /2009/10/16/_1352/
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
---
<div class="section">
<p>
取得した候補の文字列から、「anythingの候補として表示させる部分」と「選択後にコマンドによって実行される部分」とを分断することができます。その処理を行う関数を行うのが、 candidate-transformer ということになる…らしい:
</p>
<blockquote title="2009-10-12 - 武蔵の日記" cite="http://d.hatena.ne.jp/sirocco634/20091012#1255336649">
<dl>
<dt>
candidate-transformer (オプション)
</dt>
<dd>
source から補完リストが作成された際に引数を一つとって呼び出される関数である。その引数は source から取得された候補のリストである。実際の補完に用いられる変換済み候補のリストを返さなければならない。<br /> この要素は候補のリストからアイテムを変更したり、取り除いたりするために用いることができる。<br /> この関数は「(表示文字列 . 実際の文字列)」という対のリストを返すことで、候補を修正することができる。この場合、「表示文字列」は Anything バッファーで表示されるが、「実際の文字列」は候補が選択されたときの action の引数に用いられる。このことによって、例えば候補があまりに長ければより読みやすくすることができるし、他の候補と共通の部分があり表示のために短縮した文字列に安全に置換できるようになる。<br /> 注意: 仮に「(表示文字列 . 実際の文字列)」という形式が用いられた場合、パターンマッチは表示文字列で行われ、実際の値では実施されない。
</dd>
</dl>
<p>
<cite><a href="http://d.hatena.ne.jp/sirocco634/20091012#1255336649" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/sirocco634/20091012#1255336649', '2009-10-12 &#8211; 武蔵の日記');" target="_blank">2009-10-12 &#8211; 武蔵の日記</a></cite>
</p>
</blockquote>
<p>
というわけで、実際に使ってみました。
</p>
<h4>
使用する外部スクリプト
</h4>
<p>
前回と同じようにflickrから情報を引き出すスクリプトを用いますが、ブログに投稿できるようなサイズの画像へのリンクも一緒に取得させています。
</p>
<p>
ちなみにこのスクリプトを使用する際には、flickrからapi_keyを取得し、「xxx」の部分を取得したapi_keyに変更してください。
</p>
<pre class="syntax-highlight">
<span class="synComment"># === Libraries ===</span>
<span class="synStatement">use strict</span>;
<span class="synStatement">use warnings</span>;
<span class="synStatement">use </span>Perl6::Say;
<span class="synStatement">use </span>YAML;
<span class="synStatement">use utf8</span>;
<span class="synStatement">use </span>Encode;
<span class="synStatement">use </span>WebService::Simple;
<span class="synStatement">use </span>XML::Simple;
<span class="synStatement">use </span>YAML::Syck;
<span class="synComment"># === Main part ===</span>
<span class="synStatement">my</span> <span class="synIdentifier">$flickr</span> = WebService::Simple-&#62;<span class="synStatement">new</span>(
<span class="synConstant">base_url </span>=&#62; <span class="synConstant">&#34;http://api.flickr.com/services/rest/?&#34;</span>,
<span class="synConstant">param </span>=&#62; {
<span class="synConstant">api_key </span>=&#62; <span class="synConstant">'xxx'</span>,
<span class="synConstant">method </span>=&#62; <span class="synConstant">'flickr.photos.search'</span>,
<span class="synConstant">machine_tag_mode </span>=&#62; <span class="synConstant">'any'</span>,
}
);
<span class="synStatement">my</span> <span class="synIdentifier">$response</span> = <span class="synIdentifier">$flickr</span>-&#62;get( { <span class="synConstant">user_id </span>=&#62; <span class="synConstant">'42332031@N02'</span>, } );
<span class="synComment"># (1) 取得したXMLの表示</span>
<span class="synComment"># say YAML::Syck::Dump( XMLin ($response-&#62;content));</span>
<span class="synStatement">my</span> <span class="synIdentifier">$temp</span> = XMLin(<span class="synIdentifier">$response</span>-&#62;content);
<span class="synStatement">foreach</span> <span class="synStatement">my</span> <span class="synIdentifier">$i</span> (<span class="synStatement">sort</span> <span class="synStatement">keys</span> %{<span class="synIdentifier">$temp</span>-&#62;{photos}-&#62;{photo}}) {
<span class="synStatement">my</span> <span class="synIdentifier">$title</span> = encode(<span class="synConstant">'utf8'</span>, <span class="synIdentifier">$temp</span>-&#62;{photos}-&#62;{photo}-&#62;{<span class="synIdentifier">$i</span>}-&#62;{title});
<span class="synStatement">print</span> <span class="synConstant">&#34;</span><span class="synIdentifier">$title</span><span class="synSpecial">\t</span><span class="synConstant">&#34;</span>;
say <span class="synConstant">'http://farm'</span> . <span class="synIdentifier">$temp</span>-&#62;{photos}-&#62;{photo}-&#62;{<span class="synIdentifier">$i</span>}-&#62;{farm} .
<span class="synConstant">'.static.flickr.com/'</span> . <span class="synIdentifier">$temp</span>-&#62;{photos}-&#62;{photo}-&#62;{<span class="synIdentifier">$i</span>}-&#62;{server} .
<span class="synConstant">'/'</span> . <span class="synIdentifier">$i</span> . <span class="synConstant">'_'</span> . <span class="synIdentifier">$temp</span>-&#62;{photos}-&#62;{photo}-&#62;{<span class="synIdentifier">$i</span>}-&#62;{secret} .<span class="synConstant">'.jpg'</span>;
}
</pre>
<h4>
実行結果
</h4>
<pre class="syntax-highlight">
~<span class="synStatement">/</span><span class="synConstant">bin on kazu634 </span><span class="synSpecial">[504]</span><span class="synConstant"> </span><span class="synIdentifier">$: </span><span class="synConstant">perl flickr</span><span class="synSpecial">.</span><span class="synConstant">pl </span>
<span class="synConstant">Latex Installation http:</span><span class="synStatement">/</span>/farm4.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">3519</span><span class="synStatement">/</span>3910763253_f21d0a92f4.jpg
牛タン http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2491</span><span class="synStatement">/</span>3926830661_31876f9021.jpg
夕飯 http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2652</span><span class="synStatement">/</span>3933158369_dbecc6cb8c.jpg
一ノ関の夕暮れ http://farm4.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">3516</span><span class="synStatement">/</span>3933159353_c18fbb1b1d.jpg
<span class="synConstant">324</span>-todo-flow http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2552</span><span class="synStatement">/</span>3940382629_a0ca185977.jpg
<span class="synConstant">326</span>-rsvp-flow http://farm4.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">3422</span><span class="synStatement">/</span>3940382747_7debe2c8e8.jpg
<span class="synConstant">323</span>-flow-template http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2564</span><span class="synStatement">/</span>3941161952_9c1e689cce.jpg
<span class="synConstant">325</span>-login-flow http://farm4.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">3444</span><span class="synStatement">/</span>3941162050_d5288b1b06.jpg
厳美渓の農道 http://farm4.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">3495</span><span class="synStatement">/</span>3944022597_d1010fda01.jpg
温泉 http://farm4.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">3430</span><span class="synStatement">/</span>3944023685_465f5bcf4a.jpg
フレンチ http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2558</span><span class="synStatement">/</span>3944024177_69112cd66e.jpg
一関ハーフ当日 http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2667</span><span class="synStatement">/</span>3944801484_0445c243b1.jpg
温泉 http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2553</span><span class="synStatement">/</span>3944802592_68ec2fb316.jpg
Fastfinga http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2472</span><span class="synStatement">/</span>3946789592_126226025a.jpg
Evernote http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2658</span><span class="synStatement">/</span>3950568038_b053d2bbf9.jpg
Evernote http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2590</span><span class="synStatement">/</span>3950568530_4f659bcde4.jpg
同窓会 http://farm4.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">3471</span><span class="synStatement">/</span><span class="synConstant">3955756606_8e90852</span>e93.jpg
20090929_lunch http://farm4.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">3167</span><span class="synStatement">/</span>3965082006_0b157ee2e3.jpg
ハロウィン http://farm4.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">3430</span><span class="synStatement">/</span>3976527917_9aaef1f53e.jpg
たぬき http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2558</span><span class="synStatement">/</span>3976528247_7d88f7f418.jpg
下北沢 http://farm4.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">3531</span><span class="synStatement">/</span>3977289848_4c327672af.jpg
下北沢 http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2540</span><span class="synStatement">/</span><span class="synConstant">3977290184_749e4</span>e923b.jpg
下北沢 http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2445</span><span class="synStatement">/</span>3977291276_d8d485bbd5.jpg
夕飯 http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2499</span><span class="synStatement">/</span>3977291658_ff606260a6.jpg
Stationary Hacks http://farm4.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">3282</span><span class="synStatement">/</span>3991212701_f45092560b.jpg
anythingのサンプル<span class="synConstant">2</span> http://farm4.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">3492</span><span class="synStatement">/</span>4006542967_5d62d0c82c.jpg
anythingのサンプル<span class="synConstant">1</span> http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2630</span><span class="synStatement">/</span>4007300814_5ba6ffb8f3.jpg
anything-flickr http://farm3.static.flickr.co<span class="synStatement">m/</span><span class="synConstant">2557</span><span class="synStatement">/</span>4010787675_1a0d784227.jpg
</pre>
<h4>
candidate-transformerを用いる前
</h4>
<p>
前回と同じままだと
</p>
<pre class="syntax-highlight">
<span class="synComment">;; anything-test</span>
<span class="synSpecial">(</span><span class="synStatement">defun</span> my-anything <span class="synSpecial">()</span>
<span class="synSpecial">(</span>interactive<span class="synSpecial">)</span>
<span class="synSpecial">(</span>anything
<span class="synSpecial">(</span><span class="synStatement">list</span>
tmp-c-source<span class="synSpecial">)))</span>
<span class="synSpecial">(</span><span class="synStatement">setq</span> tmp-c-source
<span class="synSpecial">'((</span>name . <span class="synConstant">&#34;Example&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span>candidates . <span class="synSpecial">(</span><span class="synStatement">lambda</span> <span class="synSpecial">()</span>
<span class="synSpecial">(</span><span class="synStatement">delete</span> <span class="synConstant">&#34;&#34;</span>
<span class="synSpecial">(</span>split-string
<span class="synSpecial">(</span>shell-command-to-string <span class="synConstant">&#34;perl ~/bin/flickr.pl&#34;</span><span class="synSpecial">)</span>
<span class="synConstant">&#34;\n&#34;</span><span class="synSpecial">))))</span>
<span class="synSpecial">(</span>action . <span class="synSpecial">((</span><span class="synConstant">&#34;Insert&#34;</span> . insert<span class="synSpecial">)))))</span>
</pre>
<p>
こんな画面が表示されます。
</p>
<p>
<center>
</center>
</p>
<p>
<a href="http://flickr.com/photos/42332031@N02/4016846972/" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://flickr.com/photos/42332031@N02/4016846972/', '');" title="Before candidate-transformer"><img src="http://farm4.static.flickr.com/3502/4016846972_54aef6f573.jpg" /></a>
</p></p>
<h4>
candidate-transformer を用いると
</h4>
<p>
ここで candidate-transformer を用いてみます。
</p>
<pre class="syntax-highlight">
<span class="synSpecial">(</span><span class="synStatement">setq</span> tmp-c-source
<span class="synSpecial">'((</span>name . <span class="synConstant">&#34;Example&#34;</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span>candidates . <span class="synSpecial">(</span><span class="synStatement">lambda</span> <span class="synSpecial">()</span>
<span class="synSpecial">(</span><span class="synStatement">delete</span> <span class="synConstant">&#34;&#34;</span>
<span class="synSpecial">(</span>split-string
<span class="synSpecial">(</span>shell-command-to-string <span class="synConstant">&#34;perl ~/bin/flickr.pl&#34;</span><span class="synSpecial">)</span>
<span class="synConstant">&#34;\n&#34;</span><span class="synSpecial">))))</span>
<span class="synComment">;; ここで (表示文字列 . 実際の文字列) の形式に変換している</span>
<span class="synSpecial">(</span>candidate-transformer . <span class="synSpecial">(</span><span class="synStatement">lambda</span> <span class="synSpecial">(</span>candidates<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">mapcar</span>
<span class="synSpecial">(</span><span class="synStatement">function</span> <span class="synSpecial">(</span><span class="synStatement">lambda</span><span class="synSpecial">(</span>arg<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">apply</span> '<span class="synStatement">cons</span> <span class="synSpecial">(</span>split-string arg <span class="synConstant">&#34;\t&#34;</span><span class="synSpecial">))))</span>
candidates<span class="synSpecial">)))</span>
<span class="synSpecial">(</span>action . <span class="synSpecial">((</span><span class="synConstant">&#34;Insert&#34;</span> . insert<span class="synSpecial">)))))</span>
</pre>
<p>
すると、このようにタイトルのみが表示されていますこの例だと「c」で絞り込んでいるので表示されている数が少ないですね。。。
</p>
<p>
<center>
</center>
</p>
<p>
<a href="http://flickr.com/photos/42332031@N02/4016092343/" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://flickr.com/photos/42332031@N02/4016092343/', '');" title="after candidate-transformer"><img src="http://farm3.static.flickr.com/2442/4016092343_fcbde60723.jpg" /></a>
</p></p>
<p>
候補を選択すると、次のようにURLが挿入されます。
</p>
<p>
<center>
</center>
</p>
<p>
<a href="http://flickr.com/photos/42332031@N02/4016860722/" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://flickr.com/photos/42332031@N02/4016860722/', '');" title="Well Done! transformer-candidate!"><img src="http://farm4.static.flickr.com/3525/4016860722_659243b672.jpg" /></a>
</p></p>
<h4>
イディオム
</h4>
<p>
外部コマンドの標準出力への出力を取り込む場合、最後の改行が問題になるから、こう書くのがイディオムみたい:
</p>
<pre class="syntax-highlight">
<span class="synSpecial">(</span><span class="synStatement">delete</span> <span class="synConstant">&#34;&#34;</span>
<span class="synSpecial">(</span>split-string
<span class="synSpecial">(</span>shell-command-to-string <span class="synConstant">&#34;perl ~/bin/flickr.pl&#34;</span><span class="synSpecial">)</span>
<span class="synConstant">&#34;\n&#34;</span><span class="synSpecial">))</span>
</pre>
</div>