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)

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

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

emacs_icon_512x512

Org-modeとToodledoを連携させるorg-toodledo.elを非同期実行に対応させました

ToodledoとOrg-modeを連携させることができるorg-toodledo.el、大変便利で愛用させてもらってます。

Emacsで書いたorg文書とToodledoを同期するorg-toodledo – 勉強日記
WeBlowg Side:org-modeとToodledoを連携してどこでもタスク管理

元々は、Org-mode界隈では有名なSacha chua さんが作っていたものをChristopher さんがforkしたものがMELPAにも登録されていました。

が、どうやらChristopherさんもメンテをしなくなってしまったようで、不具合が残ったままになっていました。

というわけで、そちらをまたforkしまして、org-toodledoをメンテしていくことにしました。MELPAにはすでに私のリポジトリに切りかえてもらいましたので、package.el等をお使いの方は、更新してもらえればいいと思います。

myuhe/org-toodledo

主な変更点は以下の4点です。

xml解析をxml-parse-regionからlibxml-parse-xml-regionに切りかえました

Emacs24.1からサポートされたlibxml2によりxml解析の関数として libxml-parse-xml-region が追加されています。この関数は処理が高速なのがウリでして、Emacs24.4から同梱されるようになったWebブラウザ eww でもその多大な恩恵を受けいます。

というわけで、org-toodledoでもその恩恵があるかもと切りかえてみることにしました。

Toodledoとの通信バックエンドをrequest.elに切りかえました

本家では、=url-http= パッケージをバックエンドに使う http-post-simple.elを使っています。

EmacsWiki: http-post-simple.el

このライブラリは、確かにシンプルで環境にも依存せず良いライブラリではあるのですが、今時使うならやっぱり request.elかなと思いましてこっちに切りかえました。

Request.el – Easy HTTP request for Emacs Lisp — Request.el 0.2.0 documentation

環境によってCurlなどに自動で切りかえてくれる便利なライブラリです。また、後述するdeferred.elとの親和性も高いため、こちらを使うことにしました。

Travis CI導入

それなりに大きなプログラムなので、Travis CIを導入してみました。とは言うもののあまりテスト書けてません。。。 まあ、おいおい。

ToodledoとOrg-modeの同期が非同期に実行できるようになりました

これがもっとも大きな変更点です。

本家では、通信周りが同期的に動作するようになっていて、同期するたびにガッツリブロックするその仕様に度々イライラしておりました。

今回の変更では、deferred.elを使ってToodledoとの通信からxmlの処理諸々が非同期に行なえるようになっています。また、deferrd.elの機能を使ってサーバとの通信を並列化したりしているので、高速化も期待できます。

deferred.el リリース – 技術日記@kiwanami
emacs-deferred/README.ja.markdown at master · kiwanami/emacs-deferred

ただ、いろいろと動作が不安定なところもあるため、非同期関連の変更については、asyncブランチで作業を行なっています。

myuhe/org-toodledo at async

dogfood eaterの皆様におかれましては、是非お召しあがりください。

今回の変更で気になっていた点は、ほぼ修正できたように思います。今後は、テストの追加やリファクタリングなどこまごまとした所に手を加えていこうかと思っています。

苦情、ご相談はGitHubのIssueにお願いします。不具合などはついでにテスト書いてプルリクもらえれば、大変ありがたいです。

wpid-IMGP7088.jpg

棚を自作した

棚を作ってみました。

wpid-IMGP7088.jpg

材料はIKEAで買った突っ張り棒と

STOLMEN 支柱 – IKEA

そのアダプター。

STOLMEN エンドフィッティング – IKEA
STOLMEN フック – IKEA

それと、余っていた板切れなど。作業時間は30分ほど。

突っ張り棒の下部にはフックをとりつけてカバンなんかをかけるようにしてます。

wpid-IMGP7090mod.jpg

 

借家住まいは、穴など開けられないので、こういう突っ張り棒は何かと便利です。

org-notify.elでスケジュールとかTODOのリマインダを通知

公私ともども、TODOやスケジュールはorg-modeを中心に管理しています。

管理していると言っても、常にorg-modeのバッファを見ているわけではなく、そもそもずっとEmacsを触っているわけではありません。

Emacsは常に起動しているものの、ブラウザを見ている時もありますし、ExcelやWordと戯れている時もあります。となれば、org-modeの中でTODO、スケジュールを管理してくれる秘書さんが必要です。

それが今回紹介するorg-notify.elです。

deadlineが近いアイテムをお知らせ

org-notify.elは、org-modeにバンドルされている拡張で、contribディレクトリに配置されています。package.elでインストールしたい場合は、org-modeの公式アーカイブを package-archives に追加して、=org-plus-contrib= をインストールしてください。

Org Emacs lisp Package Archive

org-notify では、deadlineが近づいてきたアイテムに対するリマインダをplistで定義します。以下に簡単な例を示します。

(org-notify-add 'appt
                '(:time "15m" :period "2m" :duration 100
                        :actions -notify)
                '(:time "3d" :actions -email))

ここでは、二つのリマインダが定義されています。それぞれのプロパティで、:timeはdeadlineまでの時間、:periodは次のリマインダを表示させるまでの期間、:duration はリマインダを表示させておく時間を示しています。

:action はリマインダの種類を示しています。 -notifyではnotifications.elを使ったデスクトップ通知の形でリマインダが表示されます。 -emailでは user-mail-address で設定されたメールアドレスにメールが送信されます。

:actionはデフォルトで6つ定義されています。詳しくは、org-notify-api.org を確認してください。

リマインダの定義がすめば、 (org-notify-start) を実行することで、リマインダのタイマが起動します。

独自のアクションを定義する

アクションは独自に定義することもできます。例として、前回紹介したgntp.elを使ったアクションを定義してみます。

(defun org-notify-action-growl (plist)
  "Pop up desktop notification via gntp."
  (gntp-notify 'org-notify (encode-coding-string (plist-get plist :heading) 'utf-8)
               (encode-coding-string  (org-notify-body-text plist) 'utf-8) "localhost"))

ここでsuffixがアクション名として認識されます。後は、追加するだけです。

(org-notify-add 'default '(:time    "60m"
                           :actions -growl
                           :period  "60m"))

というわけで、org-notify.elの紹介でした。独自のアクションを定義できるというのが、面白い所だと思います。 IFTTT なんかと連携させてみるのも面白いかもしれません。