blog/content/post/2009/10/14/2009-10-14-00001239.md

166 lines
7.7 KiB
Markdown

---
title: 候補を外部スクリプトから取得する
author: kazu634
date: 2009-10-14
url: /2009/10/14/_1351/
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
---
<div class="section">
<p>
candidates の説明にはこんなことが書いてあった:
</p>
<blockquote title="2009-10-12 - 武蔵の日記" cite="http://d.hatena.ne.jp/sirocco634/20091012#1255336649">
<dl>
<dt>
candidates (candidates-in-buffer 要素を指定しなかった場合、必須)
</dt>
<dd>
source から候補を取得するための方法を指定する。この要素に指定できるのは、変数、引数なしの関数、あるいは実際の候補のリストである。<br />リストは文字列のリストでなければならず、そのため必要であれば候補を文字列に変換するのは source の責任である。<br />仮に候補が非同期で取得されなければならない場合(例えばコマンド終了までに時間がかかる外部コマンドで取得するような場合)には、その関数は外部コマンドを非同期で実行し、 the associated process object を戻す必要がある。<br />Anything はそのプロセスを管理する(そのプロセスから出力を受け取り、必要であればそのプロセスを停止する、など)。プロセスは現在のパターンにマッチする候補を返さなければならない(anything-pattern を参照すること)。<br />注意: 非同期の source からの結果は anything-sources 中の位置に関係なく、 anything のバッファーの最後に表示される。
</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>
この説明を読むと、引数なしの関数を書いて、リストを返してあげれば大丈夫そう。というわけで、適当なスクリプトを書いて、それから anything の候補を生成してみた。
</p>
<h4>
作成したスクリプト
</h4>
<p>
自分の Flickr アカウントから、アップロードした画像のタイトル一覧を取得する Perl スクリプトです。このスクリプトを「flickr.pl」として保存してます。
</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 utf8</span>;
<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}}) {
say <span class="synIdentifier">$temp</span>-&#62;{photos}-&#62;{photo}-&#62;{<span class="synIdentifier">$i</span>}-&#62;{title};
}
</pre>
<h4>
スクリプトの実行結果
</h4>
<pre class="syntax-highlight">
~/bin on kazu634 <span class="synStatement">[</span><span class="synConstant">503</span><span class="synStatement">]</span> $: perl flickr.pl
Latex Installation
牛タン
夕飯
一ノ関の夕暮れ
<span class="synConstant">324</span>-todo-flow
<span class="synConstant">326</span>-rsvp-flow
<span class="synConstant">323</span>-flow-template
<span class="synConstant">325</span>-login-flow
厳美渓の農道
温泉
フレンチ
一関ハーフ当日
温泉
Fastfinga
Evernote
Evernote
同窓会
20090929_lunch
ハロウィン
たぬき
下北沢
下北沢
下北沢
夕飯
Stationary Hacks
anythingのサンプル<span class="synConstant">2</span>
anythingのサンプル<span class="synConstant">1</span>
</pre>
<h4>
Emacs側の設定
</h4>
<p>
次のコマンドを使います:
</p>
<dl>
<dt>
shell-command-to-string
</dt>
<dd>
シェルコマンドの実行結果を文字列に変換する Emacs コマンド
</dd>
<dt>
split-string
</dt>
<dd>
与えられた文字列を、引数で指定した文字列で分割し、リストにする
</dd>
</dl>
<p>
詳細は、 M-x descrive-function してください。
</p>
<pre class="syntax-highlight">
<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">defvar</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="synComment">;; 文字列を改行で区切ってリストにする</span>
<span class="synSpecial">(</span>split-string
<span class="synComment">;; perl ~/bin/flickr.plの実行結果を文字列に変換する</span>
<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>
<h4>
実行結果
</h4>
<p>
<center>
</center>
</p>
<p>
<a href="http://flickr.com/photos/42332031@N02/4010787675/" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://flickr.com/photos/42332031@N02/4010787675/', '');" title="anything-flickr"><img src="http://farm3.static.flickr.com/2557/4010787675_1a0d784227.jpg" /></a>
</p></p>
</div>