Emacsからtiqavを使う
突然ですが、tiqavというサービスをご存知でしょうか?一言でいうとチャットでのレスポンスなどに使えるちょっとしたネタ画像を検索できるサービスで、わたしも同僚を煽るために業務上のコミュニケーションを円滑に進めるためによく使っています。
ただブラウザから使おうとすると、tiqavのサイトを開いて、検索窓にキーワードを入れて、目的の画像をマウスでクリックして……と意外と手順が多く面倒です。オモシロ画像を貼るためにせっせとマウスでURLをコピペする姿も、ウケるために必死な感じが出てしまいますしあまり人に見られたくありません。
何かもっと楽な方法は無いかと考えていたところ、いつも使っているEmacsに画像を表示する機能があったことを思い出したので、Emacsからtiqavの画像を検索して結果を選択するhelm-img-tiqav
というコマンドと、汎用的な処理を切り出したhelm-img
というライブラリを作ってみました。
ミニバッファで指定したキーワードでtiqav検索して結果をhelmバッファに表示し、選択した画像のURLをコピーすることができます。そんなに難しいことはしていないのですが、helmの候補として画像を表示するというアイディアが実は新しいのではないかと自分では思ってます。
インストール
ソースはgithubにあるので、わかる人はためしにloadして使ってみてください。
コア部分とtiqav固有の処理を分離しているのでhelm-img.elとhelm-img-tiqav.elがload-pathに存在する必要があります。
先ほどMELPAにも申請のpull-reqを投げたので、近日中にMELPA経由でインストールできるようになると思います。MELPAに載った際にはこの記事でもお知らせしますので、気になる方はこの記事をストックしておいていただくとQiitaの通知で更新を確認できてよいかもしれません。
(2015/12/31追記)
先日パッケージがMELPAに登録されましたので、package-archives
にMELPAが登録されていればM-x package-install RET helm-img-tiqav
でインストールすることができます。
インストール後はM-x helm-img-tiqav
でコマンドを実行してください。
普通の画像検索もしたい
tiqavを検索できるようになったのは良いのですが、ピンポイントで何かの画像が欲しい時にはやはりGoogle画像検索など汎用の検索エンジンも使いたくなります。そのようなケースを考慮し、今回作成したhelm-img
は入力を受け取ってURLのリストを返す関数だけ用意するだけで他の検索ソースも簡単に追加できるようになっています。実際、MicrosoftのBing Search APIを利用して画像検索を行うhelm-img-bing
コマンドもこの機構を使って簡単に実装できたので、helm-img
のリポジトリに一緒に入れておきました。
以下のようなコードで比較的簡単にhelm-img
用のsourceを定義できるので、誰かtiqavやbing以外にも面白いsourceを追加してもらえるとうれしいです。
(require 'helm-img)
;;; 指定したディレクトリにある画像をhelmバッファに表示する例
;; 入力を受け取り画像パスのリストを返す関数
(defun helm-img-dir-make-candidates (dir)
(directory-files (expand-file-name dir) t "\\.png\\|\\.PNG\\|\\.jpg\\|\\.JPG"))
;; helmのsourceを定義するマクロを呼ぶ
;; 第1引数にhogeを渡すと、helm-img-source-hogeという名前でhelmのsourceが定義される
;;
;; :candidate に引数を1つ取りURLかファイルパスのリストを返す関数を渡せば、
;; URLからの画像を取得する処理などはマクロ側で吸収してくれる。
;;
;; 単なるリストではなく '(('thumb . "サムネイルのURL") ('full . "元サイズ画像のURL)) 形式の連想リストのリストを返すと、
;; helmバッファには元画像ではなくサムネイルを表示することができる。
(helm-img-define-source "dir" :candidates 'helm-img-dir-make-candidates)
;; 定義したsourceを用いてhelmコマンドを実行する。パラメータはhelm-img-queryにバインドする。
(defun helm-img-dir (dir)
(interactive "DDirectory: ")
(let ((helm-img-query dir))
(helm
:sources helm-img-source-dir
:buffer "*helm image dir")))
(provide 'helm-img-dir)
課題
- elispに不慣れなため実装が素朴
- 画像の取得を1つずつ同期処理で行っているので件数が多いと結構遅い
- ドキュメント
この辺はまだまだ不足していると思うので年末年始にでも対応していきたいと思っています。
終わりに
helm-imgはもともと9月に札幌で開かれたEmacs寄合に参加させてもらった時に作りはじめたものでしたが、アドベントカレンダーによる締切効果もありなんとか年内に公開できる形に漕ぎつけることができました。わたしは基本怠惰な人間なので、こういう機会でも無ければなかなかパッケージを作るというところまではできなかったと思います。きっかけを作ってくださった @niku さん、LingrのEmacs部屋で相談に乗っていただいた皆さん、どうもありがとうございました。