Android版のEmacsを使ってみて、org-capture が使いづらいというのはすぐに気がつきました。私はorg-capture コマンドを C-c r に割り当てていますが、Ctrlを押さなければならない時点でタッチパネルからでは使いづらいです。その後もテンプレートを選ぶのにキー入力が必要ですし、最後の C-c C-c や C-c C-k もタッチでは打ちづらいです。org-capture は「キーボードで素早くノートを取る」ことに最適化されていますが、これがタッチでは逆に障害となっています。
なので、まずはテンプレートの選択はGUIメニューで行うようにします。
テンプレート選択メニュー
そして入力が終わった後の C-c C-c や C-c C-w 、 C-c C-k と書いてある部分を押せるようにします。
ヘッダーラインにキャプチャ終了アクションが表示されている
作成したコードは次の通りです。
(defun my-org-mks (table _title &optional prompt specials)
(unless prompt (setq prompt "Select: " ))
(x-popup-menu t
(list
prompt
(cons ""
(nconc
(cl-loop for item in table
when (cddr item) collect (cons (cadr item) item))
(cl-loop for item in specials
collect (cons (cadr item) (car item))))))))
(defun my-org-mks-around (old-fun &rest args)
(if (use-dialog-box-p)
(apply #'my-org-mks args)
(apply old-fun args)))
(advice-add 'org-mks :around 'my-org-mks-around)
(defun my-org-capture-make-clickable (str keymap)
"STRの中にあるfaceがhelp-key-bindingである部分をボタンにして押せるようにします。"
(setq str (copy-sequence str))
(let ((pos 0))
(while pos
(let ((face (get-text-property pos 'font-lock-face str))
(next (next-property-change pos str)))
(when (eq face 'help-key-binding)
(let* ((end (or next (length str)))
(key-str (substring str pos end))
(command (lookup-key keymap (kbd key-str))))
(when command
(let ((km (make-sparse-keymap)))
(define-key km [down-mouse-1] command)
(define-key km [header-line down-mouse-1] command)
(put-text-property pos end 'keymap km str)
(put-text-property pos end 'pointer 'hand str)))))
(setq pos next))))
str)
(defun my-org-capture-init ()
(defvar org-capture-mode-map )
(setq header-line-format
(my-org-capture-make-clickable
(substitute-command-keys "\\< org-capture-mode-map > Finish:\\[ org-capture-finalize ] Refile:\\[ org-capture-refile ] Abort:\\[ org-capture-kill ]" )
org-capture-mode-map)))
(add-hook 'org-capture-mode-hook 'my-org-capture-init)
テンプレート選択のGUIメニュー化はorg-mks 関数にadviceを仕込むことで実現しました。そこではy-or-n-p 等がやっているように、use-dialog-box-p を使ってマウス・タッチ操作からのコマンド起動かを判断して、必要ならGUIでメニューを表示します。 my-org-mks はx-popup-menu を使ってテンプレート選択メニューを表示するorg-mks の代替物です。私はあまり複雑なテンプレートの指定をしていないので、これでorg-mks の全てのユースケースをカバーしているかは分かりません。org-mks はざっと調べた限りorg-capture とorg-insert-structure-template でしか使われていないみたいです。
終了アクションをタッチでできるようにするために header-line 上の C-c C-c などと書かれている部分をボタン化することにしました。 window-tool-bar を使って上に○×ボタンを表示するのも面白いかなと思ったのですが、面倒なのでこの方法にしました。 my-org-capture-make-clickable 関数は、文字列(header-line-format )中の特殊なface(help-key-binding )が指定されている部分に、keymapテキストプロパティを追加してdown-mouse-1イベントに反応するようにします。kbd を使っている部分がキー設定によっては正しく動かない可能性はありますが(キー割り当てが M-x org-capture-finalize のように表示されている場合など)、デフォルトの状態なら問題は無いでしょう。
org-capture コマンドはすでにメニューバーにも追加していましたが、ツールバーにも追加しておきます。
メニューバーに「+」ボタンを追加したところ
そのあたりのコードは以前の記事に追記しておきました。
Emacsのツールバーをカスタマイズする | Misohena Blog
これでスマートフォンからの入力がさらに便利になりました。
org-capture は前々から少し疑問を感じていた仕組みではありました。私は特定のファイルに新規エントリーを追加するという単純な目的にしか使っていません。それならもっと単純なやり方がある気がします。テンプレートを選んだら、即特定のファイルを開いて新規エントリーを挿入し、ポイントを適切な位置に移動すれば十分です。キャンセルしたければundoすれば良いのですから。なので今回の改良ではノートのキャプチャを行う仕組み自体を書き直そうかとも思いました。
しかしorg-capture にはノートを取った後に何事もなかったかのように元の状態に戻るという特徴があります。思いついた時にノートを取って、またすぐに元の作業に戻る。それがorg-capture の良いところなのかもしれないなと思い、今回はorg-capture を活かす改良で留めてみました。また不満を感じたら全体を書き直すかもしれません。