エンジニアのためのメモ管理CLIツールnbの使い方
メモ管理に特化したCLIツール「nb」を紹介します。

nbとは
nbはローカルでメモやタスク管理ができるCLIです。あくまでも管理に特化したCLIです。編集は各々の愛しているテキストエディタでできます。
メモ管理難しすぎ問題
たとえば自力でメモを管理しようとすると次のような方法が考えられます。
- ファイル名を日本語タイトルにする(
プラグインの作り方.md
) - ファイル名を英語タイトルにする(
how-to-plugin.md
) - ファイル名を日時にする(
202501071032.md
)
ファイル名をタイトルにすると、後からタイトルを変えたくなった時に少々面倒です。また、そもそもメモを取り始める時点ではタイトルが決まっていないこともしばしばあります。
その対策でファイル名を日時にすると、ファイルの中身が分かりづらいです。そしてファイルを開くときにファイル名の入力が面倒です。
他にも「タグを付けたい」「検索したい」「よく開くノートをスピーディーに開けるようにしたい」などさまざまな願望が生まれることでしょう。
nbならこれら問題を解決できます。
nbのしくみとメリット
nbでは、次のいずれかをタイトルとして扱います。
- ファイルの最初のh1
- フロントマターの
title
- 上記のどちらでも無ければ本文1行目
# ここがタイトルになるここに素敵な本文を書いていく……
---title: ここがタイトルになる---ここに素敵な本文を書いていく……
今日から俺がタイトルに!?
このしくみによって後から柔軟にタイトルを付けられます。より早くメモが始められますね。
これらのタイトルはノートの一覧や検索で表示されます。

画像の例ではノートの一覧を表示しています。先頭にある[1]
のような番号が各ノートのIDです。
ファイル名とID
nbはファイル名が日時になっています。たとえば20241227173232.md
のような感じです。もちろん任意の名前を付けることもできます(例:idea.md
)。
ただファイル名が日時だと入力が面倒です。そこで、nbではノートの一つひとつにIDが割り振られます。このしくみによってあらゆる操作のタイプ数が減ります。
たとえば、普通はvim 20250107113431.md
のようにファイル名を指定して開きます。
nbを使えばnb e 11
のようにファイル名の代わりにIDを指定することで、あらかめ設定したテキストエディタで編集できます。
vim 20250107113431.md # 長い……nb e 11 # 短い!
編集後にはシェルにタイトルが表示され、中身が分かりやすいです。

各ノートとIDの対応は、ノートの一覧や検索でも表示されます(後述)。
Git管理も楽々
実態はただのテキストファイルですのでGit管理も楽です。git add
・commit
・push
などはnb側が自動でやってくれます。
インストール方法
nbはbashとGitを実行できる環境が必要です。bashは単純に実行ができればよいので、ログインシェルはZshやfishなどでも大丈夫です。
さまざまな環境でインストールできます。公式ドキュメントのInstallationを見て各OSに合った方法でインストールしましょう。
たとえばHomebrewが使える環境であれば次のコマンドでインストールします。
brew install xwmx/taps/nb
セットアップ
nb
を実行してウェルカム画面やヘルプが出れば完了です。
nb

テキストエディタの設定
nb set editor
を実行し、ノートの編集で使うテキストエディタを設定します。
nb set editor nvim
あるいは環境変数$EDITOR
を設定します。
ノートはどこに保存されるの?
デフォルトのノートの保存場所は~/.nb/home/
です。このディレクトリがGitリポジトリになっています。
ディレクトリの変更方法やリポジトリを増やす方法は後で解説します。
ノートの基本操作
基本的な操作を紹介します。
ノートの作り方
次のいずれかのコマンドで、ノートを作成してテキストエディタで開きます。
nb add# ショートカットも用意されているnb anb +

nb a
やnb +
のようなショートカットも用意されており、タイプ数が減って入力が楽です。
画像のとおり、ファイル名はデフォルトだと日時になります。ファイル名を自分で決めたい場合、次のように実行します。
nb a example.md
テキストエディタを開かずにメモしたい場合、次のように文字列を渡します。
nb a "本文だけ"nb a "# タイトルだけ"
公式ドキュメント:Adding
ノートの一覧表示
次のいずれかのコマンドで、ノートのリストを表示できます。
nb ls# 単純にnbだけでもリストが表示されるnb

ノートは最後に変更された順に並びます。ピン留め機能もあります(次の項目で解説)。
デフォルトだと15件まで表示されます。もっと表示させたい場合は--limit
、全部表示させたいなら--all
を使いましょう。
nb ls --limit 20nb ls --all
--limit
のデフォルト値を変えたい場合はnb set limit 20
のように設定できます。
公式ドキュメント:Listing & Filtering
ピン留め
リストの上位にピン留めしたいノートがあれば、次のコマンドでピン留めしましょう。
# IDが1のノートをピン留めnb pin 1
ピン留めが不要になったらunpin
を実行します。
# IDが1のノートをピン留めから外すnb unpin 1
公式ドキュメント:Pinning
ノートの編集
次のいずれかのコマンドで、ノートをテキストエディタで編集できます。
# IDが3のノートを開くnb edit 3# ショートカットも用意されているnb e 3
ファイル名でも開けます。
nb e idea.mdnb e 20241227173232.md
--content
を使えばテキストエディタを開かずに追記できます。
nb e 3 --content "追記できる"nb e 3 --c "短いオプションも用意されている"
公式ドキュメント:Editing
ノートの検索
次のようにしてノートを検索できます。
nb search "テスト"# ショートカットも用意されているnb q "テスト"
q
はクエリのq
で覚えやすいです。

AND検索・OR検索もできます。
# AND検索nb q "example" --and "demo"nb q "example" "demo"
# OR検索nb q "example" --or "sample"nb q "example|sample"
正規表現も使えるようです。内部ではgit grep
が使われていますが、rg
、ag
などにも対応しています。
公式ドキュメント:Search
ノートの削除
次のようなコマンドでノートを削除できます。
nb delete 3nb d 3nb d idea.md
公式ドキュメント:Deleting
ノートの表示
nb e 5
のようにテキストエディタで開けばノートを表示できますが、nb内でも表示用のコマンドがあります。
# nb内で開くnb show 5nb s 5# w3mで開くnb browse 5# ブラウザで開く(後述)nb browse 5 --gui
筆者はすぐに編集したくなるため、nb e
を使っています。
タスク機能
ノートの中にあるチェックボックスの一覧を表示するには、次のようなコマンドが使えます。
nb tasks 7 # タスク一覧nb tasks open 7 # 未完了のタスク一覧nb tasks closed 7 # 完了したタスク一覧# IDなしだとすべてのノートが対象nb tasksnb tasks opennb tasks closed
タスクはインデント付きで表示されます。

[8 4]
のような行頭の番号はタスク操作用のセレクタです。たとえばnb do 8 4
を実行するとそのチェックボックスにチェックが付きます。つまりテキストエディタを開かずに編集できます。
nb do 8 4

逆にチェックを外すにはnb undo 8 4
のように実行します。
nb undo 8 4
公式ドキュメント:Tasks
TODOノート
nb todo
という別の機能もあります。nb todo
はノートそのものを1つのタスクとして扱います。
nb todo add "シークレット任務" --due "2025-01-11"

ファイル名は20250107150223.todo.md
のような形式で、中身は次のようになります。
# [ ] シークレット任務
## Due
2025-01-11
TODOが完了したらnb do 6
、未完了に戻すならnb undo 6
のように実行します。
TODOノートの一覧を表示するにはnb todos
を実行します。
nb todos # TOODノートの一覧nb todos open # 未完了のTODOノート一覧nb todos closed # 完了したTODOノート一覧
筆者はtasks(チェックボックス)の方で事足りているため、TODOノートの方はまだ使いこなせていません。嘘です。この記事を書くときに初めて知りました。
サブタスク・詳細の入力などもできるようです。
公式ドキュメント:Todos
タグ機能
本文中に#タグ
のようにハッシュタグに続けて文字を書くと、タグとして認識されます。
タグは検索で便利です。
nb --tags タグ1nb q --tags タグ1 # ヒット箇所も表示

公式ドキュメント:Tagging
画像の扱い
生きていればメモと一緒に画像を管理したいときがやってきます。
nb import
で任意のファイルを管理下に加えられます。
nb import ~/Downloads/foo.pngnb import https://raw.githubusercontent.com/xwmx/nb/master/docs/images/nb.png
importしたファイルにもIDが割り振られます。
nb open
を使えばGUIのアプリケーションで開けます。
nb open 18# ファイル名でもOKnb open foo.png
ブラウザでプレビュー
先ほど少し紹介したのですが、nb browse
にオプション--gui
を加えるとブラウザでプレビューできます。
nb browse 4 --gui# オプションが前でもOKnb browse --gui 4

画像が表示できるほか、ノートのリンクを書いていればリンク化され、押せば遷移できます。
ブックマーク(Markdown化)
筆者は使っていませんが、指定したサイトをMarkdownファイル化してくれるブックマークという機能もあります。
気になる人は次のコマンドを実行してみましょう。
nb https://example.com
公式ドキュメント:Bookmarks
ファイル名の変更
ファイル名はnb move
で変更できます。
nb move bar.md buz.md# IDでも指定できるnb move 2 "new-filename" # new-filename.mdになる# ショートカットがあるnb mv bar.md buz.md# エイリアスもあるnb rename bar.md buz.md
ここでもう一度一覧を見てみる
nb ls
ではMarkdownファイル以外も表示されます。

画像・ブックマーク・TODOなどはアイコン付きで表示されます。
GitHubで管理する方法
git add
・commit
・push
などはnbが自動でやってくれます。
リモートリポジトリを設定するには次のようなコマンドを叩きます。
「別のPCでも同じリポジトリを使ってメモしたい」というときも同じコマンドが使えます。

画像の例では別のPCで同期済みのリポジトリをセットしています。
git push
は自動ですが、git pull
は自動ではありません。次のコマンドで同期させましょう。
nb sync
リポジトリやディレクトリを分ける方法
「仕事用」「プライベート用」など複数のリポジトリに分けて管理したい場合、「ノートブック」を作ってあげます。
前述の~/.nb/home/
はhome
という名前のノートブックです。
次のようにしてノートブックを追加できます。
nb notebooks add example
ノートブックの切り替え方法
新しく作ったノートブックのノートを扱うには3つの切り替え方法があります。
ディレクトリを移動することで切り替える
ノートブックのディレクトリに移動することで切り替えます。
nb add # homeのnotebookにノートが追加されるcd ~/.nb/example/nb add # exampleのnotebookにノートが追加される
prefixで都度切り替える
次のようにコマンド名・ID・ファイル名の前にnotebook名をつけてあげます。どのディレクトリにいても大丈夫です。
nb example:addnb example:e 12nb e example:12nb example:todos.md delete
useコマンドで切り替える
nb use example
を実行する方法です。どのディレクトリにいても大丈夫です。
nb add # homeのnotebookにノートが追加されるnb use examplenb add # exampleのnotebookにノートが追加される
home以外のノートブックをクローンする
home
以外のノートブックをGitHubからクローンして作成したい場合、次のように実行します。
~/.nb以外に保存したい
そもそも~/.nb
以外に保存したい場合はnb set nb_dir
で設定します。
カスタマイズ
筆者のカスタマイズ例を紹介します。
すぐに入力できるZshのキーバインド
最新の15件を表示後、コマンドラインにnb e
が入力されるキーバインドを設定しています。
function nbe() { nb ls zle reset-prompt BUFFER="nb e " zle end-of-line}
zle -N nbebindkey "^X^X" nbe
CTRL+Xを2回入力すると発動します。
ちなみにfzfを使った検索も考えたのですが、全文取得・ID取得などに時間がかかって効率的ではなかったため止めました。
上記のキーバインドで表示されなければnb q
を使って検索、というフローに落ち着いています。
よく開くノートへのエイリアス
よく開くノートはエイリアスを設定しています。
alias idea='nb e idea.md'
Neovimでのカスタマイズ
nbを導入するにあたってNeovimでカスタマイズしたところを紹介します。
bufferlineでノートタイトルを表示
bufferline.nvimで通常だとファイル名が表示されますが、nbのリポジトリであればノートタイトルを表示するように変更しました。

やっていることは単純で、「最初の行がh1ならその内容を表示」としています。
require("bufferline").setup({ options = { name_formatter = function(buf) if buf.path:match("%.nb/home/.*.md") then local file = io.open(buf.path, "r") if not file then return end local first_line = file:read("*l") file:close() local heading = first_line:match("^#%s+(.+)")
if heading then return heading end end end, },})
見出し付きwikilinkの挿入とジャンプ
[[test.md##この見出しにジャンプしたい|タイトル]]
のような見出し付きwikilinkを扱えるようにキーマップを設定しました。
詳しくは別の記事「Neovimで見出し付きwikilinkのジャンプとリンク生成」に書いています。
全文検索後にwikilinkの挿入
telescope.nvimでLive Grep後、選択したノートへのwikilinkを挿入するキーマップです。
前述の「見出し付きwikilink」の設定をした後はこのキーマップを使っていませんが一応。
設定例(クリックで開きます)
local function insert_text_at_cursor(text) local row, col = unpack(vim.api.nvim_win_get_cursor(0)) local current_line = vim.api.nvim_get_current_line() local new_line = current_line:sub(1, col) .. text .. current_line:sub(col + 1) vim.api.nvim_set_current_line(new_line) vim.api.nvim_win_set_cursor(0, { row, col + #text })end
vim.keymap.set("n", "<Leader>fw", function() require("telescope.builtin").live_grep({ file_ignore_patterns = { ".index", ".pindex", ".git" }, attach_mappings = function(prompt_bufnr, map) map("i", "<CR>", function() local picker = action_state.get_current_picker(prompt_bufnr) if picker.manager:num_results() == 0 then actions.close(prompt_bufnr) do return end end local num_selections = #picker:get_multi_selection() if not num_selections or num_selections <= 1 then actions.add_selection(prompt_bufnr) end
actions.close(prompt_bufnr)
for _, entry in ipairs(picker:get_multi_selection()) do local filename
if entry.filename then filename = entry.filename elseif not entry.bufnr then local value = entry.value if not value then return end if type(value) == "table" then value = entry.display end
local sections = vim.split(value, ":") filename = sections[1] end if filename:match("%.md$") then local file = io.open(filename, "r")
if not file then return end local first_line = file:read("*l") file:close() -- Markdownの見出し(# 見出し)のパターンにマッチするかチェック local heading = first_line:match("^#%s+(.+)")
if heading then local wikilink = "[[" .. filename .. "|" .. heading .. "]]" insert_text_at_cursor(wikilink) end end end end) return true end, })end, { desc = "grepしてwikilinkで書く(nb用)" })
Markdownを見やすくする
render-markdown.nvimを導入してMarkdownを見やすくしました。
詳しくは別の記事「render-markdown.nvimの使い方とカスタマイズ例」に書いています。
紹介しきれなかったもの
nb ls
のカラーテーマの設定、アイコンの変更、プラグインの導入など紹介しきれていない機能があります。各コマンドにも紹介していないオプションが大量にあります。
公式ドキュメントが充実していますので困ったら見てみましょう。
Web検索するとき
nb
だとググラビリティが低いため、次のように検索ワードを足すことをおすすめします。
- nb cli
- xwmx/nb
- nb memo tool
- nb note taking
以上、nbの紹介でした。
タイプ数が短くなるように工夫されていてめちゃくちゃ便利です。任意のテキストエディタで編集できるためすぐに手に馴染みました。
Zettelkastenとして扱えるところもうれしいポイントです。