私の org-mode の使い方 2020

3 min read読了の目安(約2900字

はじめに

org-mode は emacs の中でもかなり特殊なモードではないでしょうか。TODO管理ができたり、タイマーがあったり、テーブル操作もできる(知らなかったらぜひ使ってほしい)し、HTML 出力や markdown 出力なんかも対応しています。標準対応ではないですが、ポモドーロ機能を追加するパッケージなんかもありました。(そしてすぐ飽きてしまった)

この記事では、私が六年くらいカスタマイズして使っている機能について紹介したいと思います。

1日1セクション

かつて私は open-junk-file.el をインストールして、毎日1個のメモファイルを作成していました。しかし、毎日1個のメモファイルを作ったときは検索をするときに一手間必要になりますし、昨日のメモを今日のメモにコピーしたい、という場合に2つのファイルをまたいで操作しなければいけません。そのことが気になってから、毎日1個のファイルを作るのではなくて、1年に1個のファイルを作って、そこにすべてを書き込むようにしました。

トップレベルのセクションには必ず日付をつけるようにしています。2020年の私のファイルで全てのセクションを折りたたむと下のようになっています。

当日書いたメモ以外を見ることはほとんどありませんので普段は org-narrow-subtree (C-x n s)コマンドを実行して関心のないツリーを隠しています。隠しているツリーを再び開示したい場合は widen を実行します。

セクションの日付と曜日ははじめは手打ちしていましたが、今は下のようなコマンドを定義してショートカットを割り当てて実行しています。(もっと手軽な方法があるかもしれません)

    (defun insert-current-date (&optional diff)
      "現在年月日をカレントバッファに出力します。引数Nを与えるとN日前を出力します。"
      (interactive "P")
        (insert
         (shell-command-to-string
          (format
           "echo -n $(LC_ALL=ja_JP date -v-%dd +'%%Y/%%m/%%d (%%a)')"
           (or diff 0)))))

リンクを使い倒す

org-mode では org-insert-link (C-c C-l) コマンドがあります。このコマンドは org でのハイパーリンクを挿入するというものです。単に外部サイトに飛ばすだけならば、URLをそのまま書き込むだけでも十分なのですが、ローカルファイルへのパスを与えると、そのファイルを即座に開くことができます。私はソースコードを読み込むときにこの機能をよく使っています。実際のサンプルを乗せる事はできませんが、架空のコードに対するメモをとるとしたら、下のようになります。

コード調査のセクションに黄色でハイライトされた文字があります。これが org-insert-link で挿入したリンクです。ここにカーソルを当て C-c C-o を入力すると、直ちにそのファイルを開くことができます。さらに文字をチルダで囲むインラインコードや、C-c C-, で挿入するコードブロックなども使っています。

テキストでコードを読み解いた痕跡を残すというのは非常に難しいのですがorg-mode ではこのように、実際のコードへのリンクを残しながら記録を取れます。これは、誰かに情報共有するときにも有用です。「このファイルのこの関数にジャンプして…次はここで…」というのを即座に説明できます。(もちろん、ファイルの置き場所が変わってしまったり、ファイル自体の内容が変わってしまうと行数を維持する意味はなくなります)

さて、このように org-mode のリンクを残すことは有益なのですが、実際にローカルファイルへのリンクを作るときには下のようにファイルの長いパス、そして行数をつけたければ :: で接続した行数を org ファイルに書き込まなければいけません。

    [[/Users/eggc/project/app/model/transaction.rb::34][ここ]] で呼び出す。

これを手打ちするのはとても大変なので現在開いているファイル、行数の org-link をクリップボードに挿入するという自作の関数を使っています。

    (defun to-clipboard (x)
      "与えられた文字列をクリップボードにコピーします"
      (when x
        (with-temp-buffer
          (insert x)
          (clipboard-kill-region (point-min) (point-max)))
        (message x)))

    (defun file-full-path ()
      "今開いているファイルの絶対パス::行数を返します"
      (if (equal major-mode 'dired-mode)
          default-directory
        (concat (buffer-file-name) "::" (number-to-string (line-number-at-pos)))))

    (defun file-full-path-org-link-to-clipboard ()
      "今開いているファイルの org link をクリップボードにコピーします"
      (interactive)
      (to-clipboard (concat "[[" (file-full-path) "][" (file-name-nondirectory buffer-file-name) "]]")))

終わりに

私の org-mode カスタマイズについて少しだけ説明しました。その他の操作方法や TODO 管理機能などはあえて説明するまでもなく、いろいろな記事があるので省略しました。最近は markdown が主流で、技術ブロクに投稿するときにはいちいち markdown に変換しなければならないのが辛いところです。けれど org-mode には決まった使い方というのがなく、サポートしている機能も広大なので markdown に負けずに流行っていったらいいなと思います。