最小限のカスタマイズでvimを普段使いのメモ帳として使えるようにする


要件

概要

これまでmac標準のNotesを使ってメモを取っていたが、入力効率やファイルフォーマットの汎用性の観点から、vim + markdownの組み合わせでメモを取れるようにしたくなった。
既に様々なプラグインや補助ツールがリリースされていそうだが、やりたいこととしてはほぼ標準のコマンドの組み合わせで実現できて然るべき内容なので、本記事では「最小限のカスタマイズによる要件の達成」を目標とし、環境を構築する。

メモ帳に求められる要件

以下の要件を満たす方法をそれぞれ考える

  • メモを取りたい時に素早く起動できる
  • 各メモ冒頭の数行を一覧し、対応するメモを素早く開ける
  • メモを横断して検索できる
  • 見やすい形で人に提示できる

それぞれの要件に対する実現方法

メモを取りたい時に素早く起動できる

以下のような関数を .zshenv に登録し、 scratch というコマンドですぐメモを取り始められるようにした。


function scratch () {
    nvim --cmd 'cd ~/Scratches' ~/Scratches/`scratchf $1`
}

function scratchf () {
    echo `date +%F``echo $1 | sed 's/^\(.\)/-\1/'`.md
}

scratch コマンドを打つと、今日の日付のファイル( e.g. 2018-05-17.md )を開く、または新規作成した状態でvimが起動する。
scratch foo というように引数を渡すと、引数がファイル名末尾に付与された状態( e.g. 2018-05-17-foo.md )で上記の挙動となる。
--cmd 'cd ~/Scratches' という引数を渡しているのは、起動したvimのカレントディレクトリを設定する目的でそうしている。
なお ~/Scratches というディレクトリは、あらかじめ作成しておく。

scratchfscratch 関数から参照されており、ファイル名を生成する関数。
この関数を単体で利用するケースについては、後述する。

scratch 後に別名のメモを作成したくなった場合

上述の scratchf コマンドを利用する。
具体的にはvimのコマンドモードで :edit `scratchf foo` のようなコマンドを打てば、shellの実行結果が展開された状態で :edit が実行されるため、それを利用する。

各メモ冒頭の数行を一覧し、対応するメモを素早く開ける

普通に head コマンドを利用する。
具体的には ~/Scratches カレントディレクトリがある状態で head * とするだけで、ファイルの先頭部分が一覧できる。

==> 2018-05-16.md <==
# 備忘録

出社前に必ず靴を履くこと。
裸足で出社した場合は誰かから靴を借りる。

==> 2018-05-17.md <==
# 今日のやること

* 掃除
* 餌やり

## 忘れそうなこと

* ゴミ出し

vimからその一覧を閲覧したいときは :new | read ! head * などとすれば、新しいバッファでシェルの結果が表示される。
そこからファイルを開きたいときは、ファイル名にカーソルを合わせた状態で gf なりなんなりすれば、ファイルを開くことができる。

メモを横断して検索できる

標準のvimgrepを使う。
:vimgrep foo * | copen などど打てば、quickfixウィンドウからマッチしたポジションにジャンプできる。

見やすい形で人に提示できる

markdownをプレビューするプラグインを導入する。
今回は https://github.com/iamcco/markdown-preview.vim を利用した。
編集中にリアルタイムでプレビューが更新されたり、カーソル位置にスクロールが追従したり使い勝手は良いと感じた。

おまけ

日本語入力をスムーズにする

コードを書いているときは気にならなかったが、メモとして日本語を打っているとinsertモードを抜けた後にIMEをオフにするのが煩わしく感じた。
Karabiner-Elementsを利用し 単発の左Ctrl英数キー + Esc にマッピングするようにした。
具体的には以下のような設定となる。

{
  "title": "alone ctrl -> eisuu + esc",
  "rules": [
    {
      "description": "alone ctrl -> eisuu + esc",
      "manipulators": [
        {
          "type": "basic",
          "from": {
            "key_code": "left_control",
            "modifiers": {
              "optional": [
                "any"
              ]
            }
          },
          "to": [
            {
              "key_code": "left_control",
              "lazy": true
            }
          ],
          "to_if_alone": [
            {
              "key_code": "japanese_eisuu"
            },
            {
              "key_code": "escape"
            }
          ],
          "parameters": {
            "basic.to_if_alone_timeout_milliseconds": 200
          }
        }
      ]
    }
  ]
}

デフォルトのタイムアウトだと予期せずescが発動してしまうことが多かったので、 basic.to_if_alone_timeout_milliseconds を短めに設定した。( デフォルトは 1000 )

まとめ

プラグインを書いたり導入したり専用のソフトをインストールしたりしなくても、ちょっとした工夫の組み合わせでできることは意外と多いと感じた。
単一の目的に最適化するのもいいが、自分の場合は多少不便でも汎用的なものの組み合わせを使う習慣をつけておく方が大事だと思った。