エンジニアのためのメモ管理CLIツールnbの使い方

メモ管理に特化したCLIツール「nb」を紹介します。

nb ls

nbとは

nbはローカルでメモやタスク管理ができるCLIです。あくまでも管理に特化したCLIです。編集は各々の愛しているテキストエディタでできます。

メモ管理難しすぎ問題

たとえば自力でメモを管理しようとすると次のような方法が考えられます。

  • ファイル名を日本語タイトルにする(プラグインの作り方.md
  • ファイル名を英語タイトルにする(how-to-plugin.md
  • ファイル名を日時にする(202501071032.md

ファイル名をタイトルにすると、後からタイトルを変えたくなった時に少々面倒です。また、そもそもメモを取り始める時点ではタイトルが決まっていないこともしばしばあります。
その対策でファイル名を日時にすると、ファイルの中身が分かりづらいです。そしてファイルを開くときにファイル名の入力が面倒です。

他にも「タグを付けたい」「検索したい」「よく開くノートをスピーディーに開けるようにしたい」などさまざまな願望が生まれることでしょう。

nbならこれら問題を解決できます。

nbのしくみとメリット

nbでは、次のいずれかをタイトルとして扱います。

  • ファイルの最初のh1
  • フロントマターのtitle
  • 上記のどちらでも無ければ本文1行目
ファイルの最初のh1がタイトルの例
# ここがタイトルになる
ここに素敵な本文を書いていく……
フロントマターでタイトルを指定する例
---
title: ここがタイトルになる
---
ここに素敵な本文を書いていく……
本文1行目がタイトルの例
今日から俺がタイトルに!?

このしくみによって後から柔軟にタイトルを付けられます。より早くメモが始められますね。

これらのタイトルはノートの一覧や検索で表示されます。

nb lsの例

画像の例ではノートの一覧を表示しています。先頭にある[1]のような番号が各ノートのIDです。

ファイル名とID

nbはファイル名が日時になっています。たとえば20241227173232.mdのような感じです。もちろん任意の名前を付けることもできます(例:idea.md)。
ただファイル名が日時だと入力が面倒です。そこで、nbではノートの一つひとつにIDが割り振られます。このしくみによってあらゆる操作のタイプ数が減ります

たとえば、普通はvim 20250107113431.mdのようにファイル名を指定して開きます。
nbを使えばnb e 11のようにファイル名の代わりにIDを指定することで、あらかめ設定したテキストエディタで編集できます。

Terminal window
vim 20250107113431.md # 長い……
nb e 11 # 短い!

編集後にはシェルにタイトルが表示され、中身が分かりやすいです。

alt

各ノートとIDの対応は、ノートの一覧や検索でも表示されます(後述)。

Git管理も楽々

実態はただのテキストファイルですのでGit管理も楽です。git addcommitpushなどはnb側が自動でやってくれます。

インストール方法

nbはbashとGitを実行できる環境が必要です。bashは単純に実行ができればよいので、ログインシェルはZshやfishなどでも大丈夫です。

さまざまな環境でインストールできます。公式ドキュメントのInstallationを見て各OSに合った方法でインストールしましょう。
たとえばHomebrewが使える環境であれば次のコマンドでインストールします。

Terminal window
brew install xwmx/taps/nb

セットアップ

nbを実行してウェルカム画面やヘルプが出れば完了です。

Terminal window
nb
ウェルカム画面

テキストエディタの設定

nb set editorを実行し、ノートの編集で使うテキストエディタを設定します。

Terminal window
nb set editor nvim

あるいは環境変数$EDITORを設定します。

ノートはどこに保存されるの?

デフォルトのノートの保存場所は~/.nb/home/です。このディレクトリがGitリポジトリになっています。
ディレクトリの変更方法やリポジトリを増やす方法は後で解説します。

ノートの基本操作

基本的な操作を紹介します。

ノートの作り方

次のいずれかのコマンドで、ノートを作成してテキストエディタで開きます。

Terminal window
nb add
# ショートカットも用意されている
nb a
nb +
ノートの追加

nb anb +のようなショートカットも用意されており、タイプ数が減って入力が楽です。

画像のとおり、ファイル名はデフォルトだと日時になります。ファイル名を自分で決めたい場合、次のように実行します。

Terminal window
nb a example.md

テキストエディタを開かずにメモしたい場合、次のように文字列を渡します。

Terminal window
nb a "本文だけ"
nb a "# タイトルだけ"

公式ドキュメント:Adding

ノートの一覧表示

次のいずれかのコマンドで、ノートのリストを表示できます。

Terminal window
nb ls
# 単純にnbだけでもリストが表示される
nb
nb ls

ノートは最後に変更された順に並びます。ピン留め機能もあります(次の項目で解説)。

デフォルトだと15件まで表示されます。もっと表示させたい場合は--limit、全部表示させたいなら--allを使いましょう。

Terminal window
nb ls --limit 20
nb ls --all

--limitのデフォルト値を変えたい場合はnb set limit 20のように設定できます。

公式ドキュメント:Listing & Filtering

ピン留め

リストの上位にピン留めしたいノートがあれば、次のコマンドでピン留めしましょう。

Terminal window
# IDが1のノートをピン留め
nb pin 1

ピン留めが不要になったらunpinを実行します。

Terminal window
# IDが1のノートをピン留めから外す
nb unpin 1

公式ドキュメント:Pinning

ノートの編集

次のいずれかのコマンドで、ノートをテキストエディタで編集できます。

Terminal window
# IDが3のノートを開く
nb edit 3
# ショートカットも用意されている
nb e 3

ファイル名でも開けます。

Terminal window
nb e idea.md
nb e 20241227173232.md

--contentを使えばテキストエディタを開かずに追記できます。

Terminal window
nb e 3 --content "追記できる"
nb e 3 --c "短いオプションも用意されている"

公式ドキュメント:Editing

ノートの検索

次のようにしてノートを検索できます。

Terminal window
nb search "テスト"
# ショートカットも用意されている
nb q "テスト"

qはクエリのqで覚えやすいです。

nb q

AND検索・OR検索もできます。

Terminal window
# AND検索
nb q "example" --and "demo"
nb q "example" "demo"
# OR検索
nb q "example" --or "sample"
nb q "example|sample"

正規表現も使えるようです。内部ではgit grepが使われていますが、rgagなどにも対応しています。

公式ドキュメント:Search

ノートの削除

次のようなコマンドでノートを削除できます。

Terminal window
nb delete 3
nb d 3
nb d idea.md

公式ドキュメント:Deleting

ノートの表示

nb e 5のようにテキストエディタで開けばノートを表示できますが、nb内でも表示用のコマンドがあります。

Terminal window
# nb内で開く
nb show 5
nb s 5
# w3mで開く
nb browse 5
# ブラウザで開く(後述)
nb browse 5 --gui

筆者はすぐに編集したくなるため、nb eを使っています。

タスク機能

ノートの中にあるチェックボックスの一覧を表示するには、次のようなコマンドが使えます。

Terminal window
nb tasks 7 # タスク一覧
nb tasks open 7 # 未完了のタスク一覧
nb tasks closed 7 # 完了したタスク一覧
# IDなしだとすべてのノートが対象
nb tasks
nb tasks open
nb tasks closed

タスクはインデント付きで表示されます。

nb tasks

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

Terminal window
nb do 8 4
nb do

逆にチェックを外すにはnb undo 8 4のように実行します。

Terminal window
nb undo 8 4

公式ドキュメント:Tasks

TODOノート

nb todoという別の機能もあります。nb todoはノートそのものを1つのタスクとして扱います。

Terminal window
nb todo add "シークレット任務" --due "2025-01-11"
nb todo add

ファイル名は20250107150223.todo.mdのような形式で、中身は次のようになります。

20250107150223.todo.md
# [ ] シークレット任務
## Due
2025-01-11

TODOが完了したらnb do 6、未完了に戻すならnb undo 6のように実行します。

TODOノートの一覧を表示するにはnb todosを実行します。

Terminal window
nb todos # TOODノートの一覧
nb todos open # 未完了のTODOノート一覧
nb todos closed # 完了したTODOノート一覧

筆者はtasks(チェックボックス)の方で事足りているため、TODOノートの方はまだ使いこなせていません。嘘です。この記事を書くときに初めて知りました。

サブタスク・詳細の入力などもできるようです。

公式ドキュメント:Todos

タグ機能

本文中に#タグのようにハッシュタグに続けて文字を書くと、タグとして認識されます。

タグは検索で便利です。

Terminal window
nb --tags タグ1
nb q --tags タグ1 # ヒット箇所も表示
タグ機能

公式ドキュメント:Tagging

画像の扱い

生きていればメモと一緒に画像を管理したいときがやってきます。

nb importで任意のファイルを管理下に加えられます。

Terminal window
nb import ~/Downloads/foo.png
nb import https://raw.githubusercontent.com/xwmx/nb/master/docs/images/nb.png

importしたファイルにもIDが割り振られます。

nb openを使えばGUIのアプリケーションで開けます。

Terminal window
nb open 18
# ファイル名でもOK
nb open foo.png

ブラウザでプレビュー

先ほど少し紹介したのですが、nb browseにオプション--guiを加えるとブラウザでプレビューできます。

Terminal window
nb browse 4 --gui
# オプションが前でもOK
nb browse --gui 4
nb browse

画像が表示できるほか、ノートのリンクを書いていればリンク化され、押せば遷移できます。

ブックマーク(Markdown化)

筆者は使っていませんが、指定したサイトをMarkdownファイル化してくれるブックマークという機能もあります。
気になる人は次のコマンドを実行してみましょう。

Terminal window
nb https://example.com

公式ドキュメント:Bookmarks

ファイル名の変更

ファイル名はnb moveで変更できます。

Terminal window
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ファイル以外も表示されます。

nb lsでいろんなファイルが表示されている

画像・ブックマーク・TODOなどはアイコン付きで表示されます。

GitHubで管理する方法

git addcommitpushなどはnbが自動でやってくれます。

リモートリポジトリを設定するには次のようなコマンドを叩きます。

Terminal window
nb remote set [email protected]:example/example.git

「別のPCでも同じリポジトリを使ってメモしたい」というときも同じコマンドが使えます。

リポジトリリポジトリの設定

画像の例では別のPCで同期済みのリポジトリをセットしています。

git pushは自動ですが、git pullは自動ではありません。次のコマンドで同期させましょう。

Terminal window
nb sync

リポジトリやディレクトリを分ける方法

「仕事用」「プライベート用」など複数のリポジトリに分けて管理したい場合、「ノートブック」を作ってあげます。
前述の~/.nb/home/homeという名前のノートブックです。
次のようにしてノートブックを追加できます。

Terminal window
nb notebooks add example

ノートブックの切り替え方法

新しく作ったノートブックのノートを扱うには3つの切り替え方法があります。

ディレクトリを移動することで切り替える

ノートブックのディレクトリに移動することで切り替えます。

Terminal window
nb add # homeのnotebookにノートが追加される
cd ~/.nb/example/
nb add # exampleのnotebookにノートが追加される

prefixで都度切り替える

次のようにコマンド名・ID・ファイル名の前にnotebook名をつけてあげます。どのディレクトリにいても大丈夫です。

Terminal window
nb example:add
nb example:e 12
nb e example:12
nb example:todos.md delete

useコマンドで切り替える

nb use exampleを実行する方法です。どのディレクトリにいても大丈夫です。

Terminal window
nb add # homeのnotebookにノートが追加される
nb use example
nb add # exampleのnotebookにノートが追加される

home以外のノートブックをクローンする

home以外のノートブックをGitHubからクローンして作成したい場合、次のように実行します。

Terminal window
nb notebooks add example [email protected]:example/example.git main

~/.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 nbe
bindkey "^X^X" nbe

CTRL+Xを2回入力すると発動します。

ちなみにfzfを使った検索も考えたのですが、全文取得・ID取得などに時間がかかって効率的ではなかったため止めました。
上記のキーバインドで表示されなければnb qを使って検索、というフローに落ち着いています。

よく開くノートへのエイリアス

よく開くノートはエイリアスを設定しています。

alias idea='nb e idea.md'

Neovimでのカスタマイズ

nbを導入するにあたってNeovimでカスタマイズしたところを紹介します。

bufferlineでノートタイトルを表示

bufferline.nvimで通常だとファイル名が表示されますが、nbのリポジトリであればノートタイトルを表示するように変更しました。

ノートタイトルをbufferlineで表示している

やっていることは単純で、「最初の行が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として扱えるところもうれしいポイントです。