Neovimで最高のメモ環境を作る
NeovimのロゴはJason Longさんによるもので、CC BY 3.0としてライセンスされています
概要
突然ですがみなさんワーキングメモリ足りてますか? 私は足りてません。特に仕事をしてると、頻繁にワーキングメモリが枯渇します。 なので思い立ってすぐメモを残せる環境が欲しいなと常々願っていました。
そんな中、先日Raycast Noteに出会い、非常に洗練された体験だなと感銘を受けました。 キーバインド一つで立ち上がり、ササッと編集できて、またキーバインド一つで元のアプリに戻れる。クラウドで同期することができ、モバイルからも編集を続けることができる。 おそらく現存するメモアプリの中で、最高峰といっても良いのではないでしょうか。
Raycast Note最高か!と思ってしばらく使っていたのですが、やっぱりどうしても使い慣れたエディタで編集したいなーという気持ちが徐々に大きくなってきました。 今回はRaycast NoteのUXを踏襲しつつ、Neovimで編集できる最高の世界を目指していきます。
やったこと
実現するために、以下の流れで整えました。大きくは「専用ターミナル」「設定の切り分け」「トグル操作」の三つです。
Neovim専用のターミナルを用意
普段はWezTermを使用しています。ちょっとオレオレパッチを当ててビルドしたものを使うぐらいにはWezTermが好きです。 ただメモ用もWezTermにしてしまうと、開発用のターミナルと紛らわしく、アプリケーションの切り替え指定も難しいので、アプリケーションとして分けたいです。 そこでWezTermの亜種をオレオレで作ることにしました。
WezTermの亜種を作る
以下の手順で、改変したオレオレWezTermをWezNoteとして作成します。やることはほぼ複製と情報の上書きだけで、アプリとして別物に見せるのが狙いです。
# WezTerm.app を WezNote.app として複製
cp -r /Applications/WezTerm.app /Applications/WezNote.app
# Bundle Identifier を上書き
plutil -replace CFBundleIdentifier -string "local.weznote" /Applications/WezNote.app/Contents/Info.plist
# アプリ名も上書き
plutil -replace CFBundleName -string "WezNote" /Applications/WezNote.app/Contents/Info.plist
plutil -replace CFBundleDisplayName -string "WezNote" /Applications/WezNote.app/Contents/Info.plist
# アイコンも上書き → /Applications/WezNote.app/Contents/Resources/terminal.icns
# 再署名(これによりアプリケーションが改変されていても, 自分のマシンのみで有効なものとして起動できるようになります.)
codesign --force --deep --sign - /Applications/WezNote.app
![]() |
|---|
| 別アプリ(WezNote)として起動するようになった |
WezTermの設定を分ける
WezNoteも言ってしまえばWezTermなので、WezTermと同じ設定を読みに行きますが、 executable_dir を見ることで、どちらのアプリから読まれているのかを判別できます。
判別した結果、ざっくりこんな感じでWezNoteであれば色を変えています。
また環境変数を設定しているのと、デフォルトでNeovimが立ち上がるようにしています。
local executable_path = wezterm.executable_dir or ""
if executable_path:find("WezNote.app") then
config.color_scheme = 'Tomorrow Night'
config.initial_rows = 36
config.initial_cols = 120
config.set_environment_variables = {
WEZNOTE_INSTANCE = '1',
}
config.default_prog = { '/bin/zsh', '-lc', "nvim -c 'DailyScrum'" }
else
config.color_scheme = 'Tomorrow'
config.initial_rows = 96
config.initial_cols = 320
end
これにより、WezNoteがNeovim専用ターミナルとして動作するようになりました。
Neovimの設定を分ける
普段は自動保存が手に馴染まないタイプなのですが、WezNoteはなんとなく自動保存されるようにしたいなと思いました。 上記で環境変数を設定しているので、簡単に設定をWezNote用に切り分けられます。
if vim.env.WEZNOTE_INSTANCE ~= nil then
local group = vim.api.nvim_create_augroup("EnvAutoSave", { clear = true })
vim.api.nvim_create_autocmd({ "InsertLeave", "TextChanged" }, {
group = group,
pattern = "*",
callback = function()
local buf = vim.api.nvim_get_current_buf()
if vim.api.nvim_get_option_value("modified", { buf = buf })
and vim.api.nvim_get_option_value("modifiable", { buf = buf })
and vim.fn.expand("%") ~= "" then
vim.cmd("silent! update")
end
end,
desc = "Global auto save enabled by WEZNOTE_INSTANCE env var",
})
end
ショートカットキーでトグルするようにする
Raycast Noteで一番好きだったのが、呼び出しと復帰のスムーズさです。それを再現すべく、Karabiner-ElementsのComplex Modificationsで以下の設定にしました。
ctrl+, でトグルするようにしています。 WezNoteを開く前に直前のアプリを記録しておき、WezNoteで ctrl+, が押されたら記録されたアプリに戻る仕組みです。{
"description": "ctrl + , to toggle weznote",
"manipulators": [
{
"type": "basic",
"from": {
"key_code": "comma",
"modifiers": { "mandatory": ["control"], "optional": ["any"] }
},
"to": [
{
"shell_command": "front_app=$(/usr/bin/lsappinfo info -only bundleid $(/usr/bin/lsappinfo front) | cut -d '\"' -f4); if [ -n \"$front_app\" ]; then echo \"$front_app\" > /tmp/karabiner_previous_app_bundle_id; fi; /usr/bin/osascript -e 'tell application id \"local.weznote\" to activate'"
}
],
"conditions": [
{
"type": "frontmost_application_unless",
"bundle_identifiers": ["^local\\.weznote$"]
}
]
},
{
"type": "basic",
"from": {
"key_code": "comma",
"modifiers": { "mandatory": ["control"], "optional": ["any"] }
},
"to": [
{
"shell_command": "if [ -f /tmp/karabiner_previous_app_bundle_id ]; then prev_app=$(cat /tmp/karabiner_previous_app_bundle_id); if [ -n \"$prev_app\" ]; then /usr/bin/osascript -e \"tell application id \\\"$prev_app\\\" to activate\"; fi; fi"
}
],
"conditions": [
{
"type": "frontmost_application_if",
"bundle_identifiers": ["^local\\.weznote$"]
}
]
}
]
}
これにより、Raycast Noteのように必要な時に即時表示して、また即時で元のアプリに戻れるようになりました。
直前のアプリの保存先にkarabiner_cli経由で設定した変数を使おうかとも思ったのですが、特にその値をKarabiner側から使うわけでもないので、雑に /tmp 配下に書き出しています。
クラウド同期
もともとドキュメント類はObsidianに統一していたので、iCloud経由で同期し、モバイルからはObsidianで編集しています。 同期は少し遅いですが、実用上は問題になっていません。
感想
これまで自分のメモ環境にそこまで不満はありませんでしたが、Raycast NoteのUXから学ぶところがあり、より良いメモ環境を整備することができました。 やっぱり設定って楽しいなあ。
