blog/content/post/1970-01-01-00000027.md

14 KiB
Raw Blame History

title author date url wordtwit_post_info categories
非同期プロセスを anything の source で活用する kazu634 1969-12-31 /1970/01/01/_34/
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:4973;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}
Emacs

Emacs内でのプロセス制御について 武蔵の日記」でも書きましたが、Emacsのプロセスには同期と非同期の二種類があります。これまでは同期プロセスを用いて候補を取得していましたが、非同期プロセスを用いて候補を取得してみます。

candidatesの説明

こんな風に書いてありました:

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

anything の source の設定値について 武蔵の日記

非同期プロセスで source を取得する際の動作

candidateで指定した関数を、パターンが入力されるたびに呼び出します。そのため呼び出す外部スクリプトは引数を受け取れるようにし、そこで絞り込む必要があります。

実行する外部スクリプト

2009-10-16 武蔵の日記」で用いた flickr に登録した画像の一覧取得スクリプトを再利用します。ただし前述の引数を受け取る処理を追加します:

#!/usr/bin/env perl
# === 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 $arg = shift || ".";
my $flickr = WebService::Simple->new(
base_url => "http://api.flickr.com/services/rest/?",
param    => {
api_key => 'f94ab2327e72d52859d7fe28520d482f',
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 {$b <=> $a} keys %{$temp->{photos}->{photo}}) {
my $title = encode('utf8', $temp->{photos}->{photo}->{$i}->{title});
my $farm = $temp->{photos}->{photo}->{$i}->{farm};
my $server = $temp->{photos}->{photo}->{$i}->{server};
my $secret = $temp->{photos}->{photo}->{$i}->{secret};
if ($title =~ /$arg/i) {
print "$title\t";
say "<a title=\"$title\" href=\"http://flickr.com/photos/42332031\@N02/$i/\"><img src=\"http://farm$farm.static.flickr.com/$server/$i\_$secret.jpg\" /></a>";
}
}

anything の source

そして次のような source を設定します。ここで注意すべきは、 candidate の部分で start-process を使用しているところです:

(defvar anything-c-source-flickr
'((name . "Flickr Photos")
(candidates . (lambda ()
(start-process "Flickr" nil
"flickr"
anything-pattern)))
(candidate-transformer . (lambda (candidates)
(mapcar
(function (lambda(arg)
(apply 'cons (split-string arg "\t"))))
candidates)))
(action . (("Insert" . (lambda (candidate)
(insert "<center>\n")
(insert
(format "%s\n" candidate))
(insert "</center>\n")))))))

ちなみに同期プロセスを使用する場合は、「2009-10-16 武蔵の日記」で紹介したようにこんな感じです:

(setq anything-c-source-flickr
'((name . "Flickr")
(candidates . (lambda ()
(delete ""
(split-string
(shell-command-to-string "flickr")
"\n"))))
(candidate-transformer . (lambda (candidates)
(mapcar
(function (lambda(arg)
(apply 'cons (split-string arg "\t"))))
candidates)))
(action . (("Insert" . insert)))))

「anything」に関連する最近のエントリ