ポイント下のファイル/URLをチラ見するquick-preview.elを作りました

ファイル等のいろいろな情報をチラ見したいというのは、よくあるケースだと思います。

Helm のpersistent actionは、まさにチラ見そのものですし、dired上のチラ見アプリとしては、bf-modeやpeep-diredなどがあります。

Meadow/Emacs memo: ディレクトリ表示 ― dired など
emacs-jp/bf-mode
Emacs – peep-diredを使ってみた – Qiita

こういったツールは、Emacsで完結するものばかりなんですが、チラ見に特化した外部プログラムというものも、いろいろとあります。

こういった外部プログラムをうまく使役するというのもEmacsが得意とする分野の一つであり、Emacsらしい使い方だと思っています。

外部プログラムとの連携について、深く知りたい方は松山さんが書かれた素晴らしい文書を読まれることをおすすめします。

5年も前のものですが、非常に読み応えのある文書です。

Emacsは死んだ

quick-preview.el は100行にも満たない短いコード片ですが、そういった外部プログラムとEmacsをうまく繋げて素敵なチラ見ライフを演出するツールです。

インストール

MELPAにぷるりくを出しているのですが、マージしてもらってません。 最近Steveさんもお忙しいみたいですね。。。いずれマージしてもらえるとは思いますが、マージまで待てないという方は、ファイルをダウンロードして良きにインストールしてください。

myuhe/quick-preview.el

対応している外部プログラム

今のところ、以下の三つに対応しています。

  • GNOME Sushi
  • Gloobus preview
  • Quick Look

    Windowsでも同種のツールがないかと探してみたのですが、見つけられませんでした。もし、ご存知の方いたら教えてください。

    デフォルトでは、Linuxだと GNOME Sushiに MacだとQuick Lookに設定されます。

    Mac対応と動作確認には@syohexさんに協力してもらいました。ありがとうございます!!

コマンド

提供しているコマンドは、 quick-preview-at-point の一つだけです。

quick-preview-at-point は、ポイント下にあるファイル名やURLを quick-preview-method で設定された外部プログラムによってチラ見します。

GNOME Sushiでチラ見すると以下のようになります。

image.png

web.png

QuickLookを使った時のスクリーンショットもREADMEに載せたいのですが、いかんせんMacを持っていないので、できません。

心優しいMacユーザーの方からの御提供、お待ちしています。

設定例

設定は、次のようになるかと思います。自分のところでは押しやすいキーにバインドして常用しています。

(require quick-preview)
(setq quick-preview-method 'gloobus)

;;Setting for key bindings
(global-set-key (kbd "C-c q") 'quick-preview-at-point)
(define-key dired-mode-map (kbd "Q") 'quick-preview-at-point)

Emacsらしさって外部プログラムとの連携だ

冒頭で述べたようにEmacsには実に豊富な外部プログラムとのインターフェイスが準備されています。

この短いコードの中でも、QuickLookやGloobusではコマンドラインインターフェイス、SushiではD-busインターフェイスと二つのインターフェイスが使われています。

quick-preview.el がそういった豊富な外部プログラムとの連携について知る機会となれば幸いです。

emacs_icon_512x512

Org-modeとWunderlistを連携させるorg-wunderlist.elというのを作りました

WunderListに乗りかえた

最近、タスク管理ツールのWunderListを使いはじめました。

Wunderlist | To-do リスト、リマインダー、タスク管理 – App of the Year!

以前は、いろいろと多機能な Toodledo を使っていたのですが、結局ほとんどの機能を使いきれていませんでした。

また、Toodledoは無料だとAPIの使用にいろいろと制限があったりして、不満も感じていました。

その点、WunderListはAPI使用の制限も緩く扱いやすいです。無料プランでファイルを保存できたりサブタスクも登録できるというメリットもあり、サクッと乗りかえてしまいました。

となると、やはりEmacsから触りたくなるもの。早速、Org-modeベースのクライアントを作ってみました。

org-wunderlistとは

Org-wunderlistは、Org-modeのタスクをWunderlistのタスクと関連づけて管理するためのアプリです。

Org-wunderlistでは次のような機能が提供されます。

  • WuderlistのタスクをOrg-modeに取り込み
  • Org-modeで変更したタスクをWunderlust側に反映
  • Wuderlistのタスクに添付されているファイルをダウンロード

    また、Wunderlistとの通信は、deferredにより非同期で実行されるため、軽快な動作が期待されます。

インストール

MELPAにぷるりくを出しているのですが、マージしてもらってません。いずれマージしてもらえるとは思いますが、マージまで待てないという方は、ファイルをダウンロードして良きにインストールしてください。

myuhe/org-wunderlist.el

初期設定

まず、Wunderlistにアプリを登録する必要があります。Wunderlistの登録サイトでアプリを登録してください。登録するとCliend IDとClient Secretが発行されますので、それぞれをinit.elなどの設定ファイルに以下のように書いておきます。

設定ファイルでは、その他にもWunderlistと関連づけるOrgファイル名、Wuderlistからダウンロードするファイルを格納するディレクトリ名なども設定する必要があります。

(require 'org-wunderlist)
(setq org-wlist-client-id "your-client-id"
      org-wlist-token "your-token"
      org-wlist-file  "~/.emacs.d/Wunderlist.org"
      org-wlist-dir "~/.emacs.d/org-wunderlist/")

以上で設定は終わりです。

コマンド

今のところ、以下の四つのコマンドがあります。

org-wlist-fetch

WunderlistにあるタスクをOrg-modeのタスクとして取りこみます。

org-wlist-post

ポイント上にあるタスクが変更されていた場合、変更点をWunderlist側に送信します。

org-wlist-post-all

タスクの変更が送信されてから、変更されたタスクを全てWunderlistに送信します。まだ安定しておらず今後改良していく予定です。

org-wlist-pos

Org-mode側で変更したタスクの序列をWunderlist側に反映させます。

今後の予定など

いつものごとく、安定して動作しない箇所が多々ありますので、しばらくはそういった不具合を直していこうかと思います。

Wunderlistのクライアントとしても、フォルダーをサポートしてなかったり、タグをサポートしてなかったりと、足りないところもあるのですが、今のとこ要望があれば対応したいと思っています。

その他、諸々ご意見ありましたらGitHubのIssuesにまでお願いします。

wpid-IMGP0037.jpg

小山山と神園山に登ってきた

「そうだ、山に登ろう」

、とふと思いたってしまったので、このクソ猛暑の中、山を登ってきました。

登ったのは、熊本市の近郊にある、託麻三山が二座、小山山と神園山。両座とも標高200mにも満たない低山です。

ルートは以下のとおり。

フルスクリーン表示

小山山を目指す

まずは、小山山の頂上を目指すことに。途中にはまだ紫陽花が。この間までは梅雨だったんだなあなどと思ったり。

wpid-IMGP0037.jpg

都市近郊の山ということで整備されているものだろうと高をくくっていたのですが、なんのガッツリ山でした。

wpid-IMGP0040.jpg

それでも、道がわからないということはなく、しっかり整備はされています。ただ、道標はあまりないので地図は必須。電波は全行程で通じるので、スマホでもあれば、どうにかなるか。

とかやってるうちに、山頂に到着

wpid-IMGP0046.jpg

山頂からの眺望もまずまず。

wpid-IMGP0045.jpg

早々に頂上を離れ、神園山の山頂を目指します。

神園山を目指す

神園山への道すがら、このような看板が。

wpid-IMGP0050.jpg

「とるな」と言われてもこんなに真っ暗だったら、生えてこないと思うんだけど。それとも、昔は綺麗に手入れしてたんだろうか。

神園山は、山頂近くまで車で行けることもあり、小山山に比べると登山道はさらに厳しさを増してきます。

まあ、遭難するような山ではないのでいいんですけど、虫がつらい。。。

wpid-IMGP0047.jpg

神園山の山頂に到着。電波塔があるだけの寂しい頂上。周りもなにも見えない。

wpid-IMGP0053.jpg

全行程2時間のコンパクトな登山でした。ちなみに、他の登山者とは誰一人とも遭遇しませんでした。

穴場コースとして、ちょっと体を動かしたい時とかにいいかもです。

calfw-org.elでGoogleマップが見られるようになりました

タイトルのとおりですが、見られるようになりました。

Implement map view via google map · kiwanami/emacs-calfw@b155377

使用するにはgoogle-map.elが必要となります。

Emacs packages | Julien Danjou

locationプロパティに位置情報が付加されているイベント上で、mキーを押すと対応する地図が表示されます。

ウィンドウの配置に多少手を加えていますが、以下のようになるかと思います。

-cfw-calendar-.png

拙作、org-gcal.el と組み合わせると、Googleカレンダー上の場所の情報がOrgファイルにも反映されますので、とても便利かと思います。

emacs_icon_512x512

org-gcal.elにグーグルカレンダーとOrgファイルを同期するコマンドを追加しました

一年ほど前にリリースしましたorg-gcalにグーグルカレンダーとOrg-modeのスケジュール情報を同期させるコマンドを追加しました。MELPAやel-getのレシピもありますので、お好きな方法でアップデートしてください。

myuhe/org-gcal.el

これまで、Orgファイル上で修正、または新規に作成したイベントは org-gcal-post-at-point を実行しないとGoogle側にPOSTできませんでしたが、新しく設けた org-gcal-sync を使えば、わざわざ org-gcal-post-at-point を実行せずとも、変化点を自動的に認識してGoogle側にPOSTしてくれるようになります。

同期プロセス

同期の仕組みは非常にシンプルで、およそ次のような流れで同期します。

  1. Googleのサーバにアクセスする度にイベント情報をキャッシュして永続化
  2. キャッシュしたイベント情報とOrgファイルのイベント情報を比較。
  3. キャシュしたイベント情報とOrgファイルのイベント情報が異なる場合、またはキャシュしたイベント情報の中にOrgファイルのイベント情報がそもそも見つからない場合、そのイベント情報をGoogleのサーバにPOST
  4. 再度、Googleのサーバ情報をfetch

既知の問題

このように、今のところ非常にシンプルな同期プロセスなので、いくつか制限があります。

まず、同一のイベントをGoogleカレンダーとOrgファイルの両方で編集していた場合、Orgファイルでの変更が優先されます。これについては、どちらの変更を採用するのかをたずねる対話的なインターフェイスを追加する予定です。

それと、orgファイル上で削除したイベントは、同期プロセスの中では削除されたことを認識できません。この問題については、スマートに解決する方法が見つかりそうにないので、削除用のコマンドを新たに追加する予定です。

まだ、いろいろと片づけておくべきこともありますが、これまでと比べると格段に便利になったと思います。是非お試しください。

org-multiple-keymap.el v0.2 をリリースしました

先日公開しました org-multiple-keymap.el、個人的には大変便利に使わせていただいております。

MELPA のダウンロード数などを見ましても、爆発的ヒット作とは程遠い感じですが、るびきちさんにもレビューいただき大変ありがたい限りです。

emacs org-multiple-keymap.el : org-modeで特定のカーソル位置で操作を簡単にする | MELPA Emacs Lisp Elisp パッケージ インストール 設定 使い方 スクリーンショット | るびきち「日刊Emacs」

あれから、いろいろと変更を加えましたので、ご紹介しておきます。

新しく作った要素にもキーマップが適用されるようになりました。

この問題はるびきちさんのレビューでも指摘されていた点ですが、 after-change-functions というフックポイントに更新関数をひっかけることによって 自動でキーマップが適用されるようになりました。

eieioによる構造化

中身を eieio を使って全面的に書き直しました。アクセッサーなど共通部分をスーパークラスとして、その下にtimestampなどの各要素を単位としたクラスを生成しています。 こんなに短いコードで果して eieio を使う必要があったのかというと、あまりない気もしますが見通しはとても良くなったと思います。

情報源による拡張

eieioにより構造化されたことで、機能の拡張が容易になりました。auto-completeやHelmのように情報源を定義することで独自に要素とキーマップを紐づけることができます。

使用する情報源は、 org-mukey-source-list というリストにより管理されていますので、 新しく作ったクラスを追加することで org-multiple-keymap-minor-mode が有効になる際にインスタンスが生成され、キーマップが有効となります。

例えば、 org-mukey-source-hoge というクラス定義を新たに作ったのであれば、以下のように書くと良いでしょう。Org-modeの使い方は千差万別だと思いますので、新しい情報源を定義するなり、使用する情報源を変えるなり、使いやすいようにカスタマイズしてもらえれば幸いです。

(push org-mukey-source-hoge org-mukey-source-list)

情報源の定義には、新しいクラスを定義して各スロットに必要な情報を与えることになります。以下は、timestamp sourceのクラス定義です。

(defclass org-mukey-source-timestamp (org-mukey-source)
((region :initform 'org-mukey-make-timestamp-alist)
 (keymap :initform org-mukey-timestamp-map)
 (parse-function :initform 'org-mukey-timestamp-refresh)))

各スロットは、以下のとおり。

region スロット

キーマップを適用するポイントの値からなる連想リストを返す関数を格納します。carが先頭、cdrが末尾となります。

keymap スロット

使いたいキーマップを格納します。

parse-function スロット

新たにできた要素を判定して、キーマップを適用させる関数を格納します。

新たな要素の追加

これまで、キーマップが適用される要素はtimestampとpriorityの二つだけでしたが、新たにheadingも追加しました。見出しの先頭にあるアスタリスクでキーマップが適用されます。キーマップは次のとおりです。

key command
a org-archive-subtree
b org-do-promote
d org-mukey-todo-done
f org-do-demote
n org-next-visible-heading
p org-previous-visible-heading
u outline-up-heading
nrocinu_pdf

Org-mode上のカーソルの位置でキーバインドをDWIMに変えてくれる org-multiple-keymap.elを作りました

Org-modeとキーバインド

Org-modeは、僕にとってEmacsを薦める理由の一つと言えるほど、重要なアプリです。単なるメモだけでなく、スケジュールの管理やタスクの管理もOrg-modeを使っています。

ただ、日常的に使っていても慣れることができないのが、Org-modeのキーバインドです。一般的なキーバインドだけでも これだけあります。

さらに、キーバインドを覚えにくくさせているのが、複雑なプレフィックスキーです。これはEmacsの宿命でもあるわけですがキーバインドが増えれば必然的にプレフィックスキーも長く複雑になってしまいます。

こういった問題を回避するために、以前 smartrep.el というものを作りました。

myuhe/smartrep.el

連続操作を素敵にするsmartrep.el作った – sheephead

smartrep.el は、プレフィックスキーを押す手間を劇的に軽減してくれる素敵elispだったのですが、そもそもプレフィックスキー自体いらないんじゃないか、という発想のもとで作ったのが、 org-multiple-keymap.el です。

org-multiple-keymap.elとは

Org-modeは、ヘッダーやタイムスタンプ、タグなど複数の要素から構成されていて、各要素にはそれぞれ関連性の高いコマンドが定義されています。それら要素とコマンドを短いキーバインドで結びつけるのが org-multiple-keymap.el です。

myuhe/org-multiple-keymap.el

org-multiple-keymap.el は、org-modeを構成する要素上で、特定のキーマップをセットするマイナーモードを提供します。 現在のところ、タイムスタンプ、またはプライオリティ上にカーソルがある場合、プレフィックスキーを入力せずにワンキーで任意の関数を実行することができます。

使い方は非常にシンプル。Orgファイルを開いて M-x org-multiple-keymap-minor-mode でマイナーモードを有効にするだけです。

M-x org-multiple-keymap-minor-mode を有効にすることで、以下のキーマップが有効になります。

timestamp上のキーマップ

key command
N org-timestamp-down-day
P org-timestamp-up-day
n org-timestamp-down
p org-timestamp-up
o org-open-at-point

priority上のキーマップ

key command
n org-priority-down
p org-priority-up

今後の予定

今のところ、タイムスタンプ、プライオリティにしか対応できてないので、他の要素にも随時対応していきたいと思っています。 個人的にはソースコードブロックに適用できると素敵ではないかと思っています。

他に何か面白いアイデアなどありましたら、ここのコメントかGitHubのissueで教えてください。

wpid-screenshot_2015-03-01_140040.png

dired-subtreeもシマシマにしたい

diredのサブディレクトリがひどい

dired使いなら、 一度ならずもサブディレクトリの扱いに疑問を感じた方は多いのではないでしょうか。

GNU Emacsマニュアル: Subdirectories in Dired

dired-maybe-insert-subdir などデフォルトでサブディレクトリを操作する関数もありますが、何せ表示されるのは、バッファの下の方で非常に見にくいです。階層構造がわかりにくいのもつらいし、ほとんど使ったことはありませんでした。

dired-subtreeは便利だけど

dired-subtree はdired標準のサブディレクトリにあった不満を解消してくれる素敵拡張です。

Fuco1/dired-hacks

いろいろと紹介もされていますので、詳しくはそちらを参照のこと。

emacs dired-subtree.el : 【更新】 diredがディレクトリツリーエディタに進化!dired-detailsにも対応 | MELPA Emacs Lisp Elisp パッケージ インストール 設定 使い方 スクリーンショット | るびきち「日刊Emacs」

Emacs – diredをより便利にするツール群 dired-hacks – Qiita

ところで、diredでは行の視認性を良くするために stripe-buffer を使わせてもらってます。 stripe-buffer については、以前紹介していますので、そちらを見てみてください。

DiredやOrg-modeのテーブルをシマシマにするstripe-bufferの紹介 – sheephead

この stripe-bufferdired-subtree を併用すると、なんだか悲しい感じになってしまいます。

screenshot_2015-03-01_13:44:03.png

stripe-buffer のシマシマが階層構造なぞお構いなしにシマシマにしてしまうので、階層がわかりにくくなってしまいます。

subtreeもシマシマにしてみる

せっかくなので、下の階層も階層構造に応じてシマシマにしたいですね。

というわけで、 stripe-buffer に少し手を加えてみました。

myuhe/stripe-buffer at subtree_support

作者にぷるりくも出しているので、もしかしたら、取りこんでもらえるかもしれません。

このブランチを使って、faceを良い塩梅にするとこんな感じになります。

screenshot_2015-03-01_14:00:40.png

faceの設定はこんな感じです。

(with-eval-after-load 'dired-subtree
  (set-face-attribute 'dired-subtree-depth-1-face nil :background "#B4C342")
  (set-face-attribute 'dired-subtree-depth-2-face nil :background "#F2804F")
  (set-face-attribute 'dired-subtree-depth-3-face nil :background "#9EA0E5")
  (set-face-attribute 'dired-subtree-depth-4-face nil :background "#DEB542")
  (set-face-attribute 'dired-subtree-depth-5-face nil :background "#657b83")
  (set-face-attribute 'dired-subtree-depth-6-face nil :background "#657b83"))

(with-eval-after-load 'stripe-buffer 
  (set-face-attribute 'stripe-dired-subtree-depth-1-face nil :background "#cbd57c")
  (set-face-attribute 'stripe-dired-subtree-depth-2-face nil :background "#f7b396")
  (set-face-attribute 'stripe-dired-subtree-depth-3-face nil :background "#dadbf5")
  (set-face-attribute 'stripe-dired-subtree-depth-4-face nil :background "#e9cf83")
  (set-face-attribute 'stripe-dired-subtree-depth-5-face nil :background "#657b83")
  (set-face-attribute 'stripe-dired-subtree-depth-6-face nil :background "#657b83"))

stripe-bufferdired-subtree を併用している人しかおいしくないニッチなハックでしたが、悩めるdirederのdiredバッファがカラフルなシマシマになれば幸いです。

emacs_icon_512x512

Emacs Lisp 開発者にドキュメントの書き方を丁寧に教えてくれる checkdoc-minor-mode を有効にした

Emacsでの説明文字列

Emacsでの関数や変数には説明文字列をつけることができます。Emacs Lispで何がしかの拡張を書く時はこの説明文字列をつけることが推奨されています。

さて、この説明文字列ですが、いろいろとルールがあります。

GNU Emacs Lispリファレンスマニュアル: Documentation Tips

このルールにしたがって、説明文字列が書けているかをチェックしているか、確認するためのマイナーモードが checkdoc-minor-mode です。

checkdoc-minor-mode のキーバインド

checkdoc-minor-mode を有効にすると次のようなキーバインドが有効となります。

C-M-x checkdoc-eval-defun
C-c ? SPC checkdoc-rogue-spaces
C-c ? B checkdoc-ispell-current-buffer
C-c ? C checkdoc-ispell-comments
C-c ? D checkdoc-ispell
C-c ? M checkdoc-ispell-message-text
C-c ? S checkdoc-ispell-start
C-c ? X checkdoc-ispell-defun
C-c ? ` checkdoc-continue
C-c ? b checkdoc-current-buffer
C-c ? c checkdoc-comments
C-c ? d checkdoc
C-c ? e checkdoc-eval-current-buffer
C-c ? m checkdoc-message-text
C-c ? s checkdoc-start
C-c ? x checkdoc-defun
C-c ? ~ dcheckdoc-ispell-continue

と、いろいろありますが 主に使うのが checkdoc で、これは対話的におかしいところにジャンプして修正案まで提示してくれます。aspellが使える環境であれば、 checkdoc-ispell を使うことで、スペルチェックまでしてくれます。

checkdoc-eval-current-bufferは 修正すべき箇所を別バッファにリストアップしてくれます。おかしいところがどれくらいあるか知りたい時には便利かもしれません。

面白いところでは、 C-M-xcheckdoc-eval-defun に上書きされているところでしょうか。 従来の eval-defuncheckdoc の機能を付加してくれています。

英語で書くことが前提なので、なかなか書かずに放置することが多い説明文字列ですが、多くの人に使ってもらおうと思えば、やっぱり書いておいた方がいいなぁとあらためて思いました。

emacs_icon_512x512

アーカイブを透過的に操作できるAVFSが素敵だったし、dired-avfs.elを使えば展開とかしなくて良くなると思った

AVFSって知ってますか。僕は今日知りました。以下のリンク先の説明が詳しいので、諸々割愛しますが、

Linux/AVFS – まんどいてっくうぃき

要は、tarやzipなどを仮想のファイルシステムとすることで透過的に操作できるようになるみたいです。もうこの時点でかなり便利そうです。

このAVFSを知ったのはdired-hackの中に、dired-avfs.elなるものを見つけたのがきっかけです。diredにはそもそもアーカイブ向け auto-compression-modetar-mode がありますが、いつものdiredとは雰囲気が違うのでまごつきますし、なにせ圧縮、展開時にブロックするのがいただけません。

avfsを使えばアーカイブであることを意識せずにdiredで操作できます。

使いかたはとても簡単で、dired-hackをインストールして (require 'dired-avfs) を設定ファイルに書いときます。 後は、diredを開き中身を見たいアーカイブの上で M-x dired-avfs-open とすれば、中身をいつものdiredで見ることができます。

これだけでも十分便利ですが、いちいち M-x dired-avfs-open とするのは少し面倒です。

というわけで、空気を読んでアーカイブを開いてくれるコマンドを作ってみました。

(require 'cl-lib)
(defun dired-find-dwim-alternate-file ()
  "In Dired, visit this file or directory instead of the Dired buffer. 
If this file archive, it open via avfs"
  (interactive)
  (if (cl-loop for ext in dired-avfs-archives
               thereis (string-match-p (concat "." ext "$") (dired-get-filename)))
      (dired-avfs-open)
    (dired-find-alternate-file)))

したらば、RETキーにバインド。

(define-key dired-mode-map (kbd "RET") 'dired-find-dwim-alternate-file)

これで、アーカイブの存在を忘れてしまいそうなくらい、自然に開くことができると思います。

アーカイブを開く機会が多い方はとても便利な拡張だと思います。