コンテンツにスキップ

VimとNeovimを1日で理解するカリキュラム

まず全体像

このメモは、1日で Vim と Neovim の操作思想、設定、プラグイン、実プロジェクト運用までを一気に把握するためのカリキュラムです。

現状の ~/.config/nvim は LazyVim ベースです。 lua/config/options.lua には独自オプションがまだほぼ書かれておらず、lua/config/keymaps.lua には Lexplore を開くキーマップだけがあります。 lua/plugins/lsp.lua には goplsgd / gD / gr / K の基本 LSP キーマップがあります。

そのため、学習の軸は次の2つに分けます。

  • Vimmer: Vim のモード、移動、編集文法、検索、レジスタ、マクロを身体化する
  • Neovimmer: Lua 設定、LazyVim、LSP、Treesitter、Telescope/Snacks、format/lint、project navigation を理解する
  • Mac利用者: macOS のターミナル、クリップボード、Command キー、IME、ウィンドウ操作と衝突しない形で使う
  • cmux利用者: cmux の分割ペインや Claude Code Teams と並べて、nvim をプロジェクト編集面として使う

シーケンスで見る流れ

09:00-10:00 Vim の思想と最小操作

  • vimtutor を1周する
  • Normal / Insert / Visual / Command-line mode を説明できるようにする
  • h j k l だけでなく、w b e 0 ^ $ gg G を使う
  • i a o I A O の違いを確認する
  • u / <C-r> / . を使う

完了条件:

  • マウスなしでファイルを開き、編集し、保存し、終了できる
  • :help を開ける
  • . で直前操作を繰り返せる

10:00-12:00 Vim の編集文法

  • operator + motion を理解する
  • daw / ci" / yi( / vip / dap を練習する
  • / / ? / n / N で検索する
  • :%s/foo/bar/gc で確認付き置換する
  • register と yank/paste を確認する
  • macro を q で録画して複数行編集する

完了条件:

  • 「単語を消す」「引用符の中身を書き換える」「関数引数を選択する」を text object でできる
  • 置換と macro を使って同じ編集を複数箇所に適用できる

13:00-14:30 Neovim / LazyVim の構造を読む

  • ~/.config/nvim/init.lua から lua/config/lazy.lua への読み込みを追う
  • lua/config/options.luakeymaps.luaautocmds.lua の役割を理解する
  • lua/plugins/*.lua が lazy.nvim の plugin spec として読まれることを理解する
  • :Lazy:Mason:checkhealth を確認する

完了条件:

  • 設定をどのファイルに書くべきか説明できる
  • plugin spec の optsconfig の違いを説明できる

14:30-16:00 LSP / Treesitter / 補完を理解する

  • LSP は定義ジャンプ、参照検索、hover、rename、diagnostics を担当する
  • Treesitter は構文解析に基づく highlight、text object、fold などを担当する
  • 補完は LSP や snippet や buffer source をまとめて UI に出す層だと理解する
  • Go では gopls、Lua では lua_ls を確認する

完了条件:

  • gdgrK、rename、code action を使える
  • LSP と Treesitter の役割の違いを説明できる

16:00-17:30 プロジェクト全体を見る操作

  • nvim /Users/yuki.shishido/Develope/yoshioka0101/workspace でプロジェクトルートを開く
  • :Explore / :Lexplore で netrw を使う
  • LazyVim 標準の picker、または Snacks picker で file / grep / project を探す
  • ghq と Snacks projects の連携を確認する
  • macOS では、ターミナルアプリの Command 系ショートカットと Neovim の <D-*> キーマップの衝突を確認する
  • cmux では、左に nvim、右に Codex / Claude Code / shell を置く前提で、pane と nvim split の役割を分ける

完了条件:

  • ファイル単体ではなく workspace 全体を nvim で開ける
  • ファイル名検索、全文検索、最近開いたファイル、プロジェクト切り替えを使える
  • Mac のクリップボードと nvim の yank/paste のつながりを説明できる
  • cmux の pane 分割と nvim の window split を混同せずに使える

17:30-19:00 自分用の最小設定を言語化する

  • 自分がなぜその設定を入れるのかをコメントではなくメモに残す
  • 既定値に任せるものと、自分で明示するものを分ける
  • 設定追加後は :checkhealth と実プロジェクト編集で確認する

完了条件:

  • options.lua に入れる候補を説明できる
  • keymaps.lua に自分のプロジェクト移動用キーマップを追加できる

コード

プロジェクト全体を nvim で開く

nvim /Users/yuki.shishido/Develope/yoshioka0101/workspace

カレントディレクトリが workspace の場合:

nvim .

Macで使う前提の確認

macOS では、Neovim そのものだけでなく、ターミナル、IME、クリップボード、Command キーの扱いが体験を左右します。

# Neovim のバージョン確認
nvim --version

# clipboard provider の確認
nvim --headless "+checkhealth provider" +qa

Mac で特に確認すること:

  • ターミナルアプリが <D-b> などの Command キーを Neovim に渡すか
  • 日本語 IME のオン/オフが Normal mode の操作を邪魔しないか
  • vim.opt.clipboard = "unnamedplus" で system clipboard と連携できるか
  • pbcopy / pbpaste と Neovim の yank/paste の関係を理解する
  • Command + TabCommand + Space、ターミナルタブ切り替えなど、OS 側ショートカットと衝突しない leader key を選ぶ

Mac では <D-b> のような Command キー利用は便利ですが、ターミナルや環境によって挙動が変わります。 安定させるなら <leader> 系のキーマップを主導線にし、Command キーは補助として扱うのがよいです。

cmuxで使う前提の確認

cmux を使う場合、nvim の役割は「コードとノートを編集する主画面」です。 cmux の pane は「複数プロセスを並べる外側の分割」、nvim の split は「同じ編集セッション内でバッファを並べる内側の分割」と考えると混乱しにくいです。

基本の置き方:

cmux workspace
├── pane 1: nvim /Users/yuki.shishido/Develope/yoshioka0101/workspace
├── pane 2: codex / claude / gh issue / shell
└── pane 3: npm run zenn:preview / test / logs

cmux の Claude Code Teams 連携では、cmux claude-teams が tmux 互換 shim を作り、Claude Code から見える tmux 操作を cmux のネイティブ split へ変換します。 そのため、nvim 側で tmux 前提の操作を覚えるより、まずは次を分けて考えます。

  • cmux pane: agent、shell、preview、log を並べる
  • nvim window: 同じプロジェクト内のファイル、help、quickfix、diff を並べる
  • nvim buffer: 開いているファイルの集合
  • GitHub Issue: 学習タスクと完了条件の管理

cmux での完了条件:

  • cmux pane で nvim と agent を横に並べられる
  • agent に依頼した変更を nvim 側で git diff、picker、LSP 参照を使って確認できる
  • cmux の pane 分割を増やしすぎず、nvim 内の buffer/window と使い分けられる
  • inbox/クリップ/cmux Claude Code Teams.md の tmux shim の意味を説明できる

現状入っていない、または明示されていない設定候補

~/.config/nvim/lua/config/options.lua に明示する候補です。 LazyVim の既定値ですでに効いている可能性はあります。 ここでは「自分の意図として明文化する価値がある設定」として扱います。

-- 行番号と相対行番号
vim.opt.number = true
vim.opt.relativenumber = true

-- OS クリップボード連携
vim.opt.clipboard = "unnamedplus"

-- 分割ウィンドウの出る向き
vim.opt.splitright = true
vim.opt.splitbelow = true

-- 検索体験
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.opt.inccommand = "split"

-- 編集中の視認性
vim.opt.cursorline = true
vim.opt.signcolumn = "yes"
vim.opt.scrolloff = 8

-- undo 履歴
vim.opt.undofile = true

-- キー入力待ち時間と診断更新
vim.opt.timeoutlen = 300
vim.opt.updatetime = 250

Mac 利用で特に価値がある設定:

  • clipboard = "unnamedplus": ブラウザ、Obsidian、GitHub Issue、ChatGPT/Codex とのコピペが自然になる
  • timeoutlen = 300: <leader> 入力の待ちが長すぎず、which-key も使いやすい
  • splitright / splitbelow: Mac の横長画面や cmux pane と並べたときに分割方向が予測しやすい

プロジェクト全体を見るためのキーマップ候補

現在は Lexplore<D-b><leader>b が割り当てられています。 ファイルツリーだけでなく、検索とプロジェクト移動も覚えるなら、次のような候補があります。

vim.keymap.set("n", "<leader>e", "<cmd>Lexplore<cr>", { desc = "Open file explorer" })
vim.keymap.set("n", "<leader>fw", "<cmd>lua Snacks.picker.grep()<cr>", { desc = "Grep workspace" })
vim.keymap.set("n", "<leader>fp", "<cmd>lua Snacks.picker.projects()<cr>", { desc = "Find projects" })

Mac では <D-b> がターミナル側に取られる場合があります。 その場合でも操作できるように、主導線は <leader>e<leader>fw<leader>fp のような leader key に寄せます。

projects pickerで前回ファイルへ飛ぶ場合

Snacks の projects picker は、標準では <CR>load_session です。 そのため workspace を選んだだけでも、前回そのプロジェクトで開いていた tools/build_site.py のようなファイルが復元されることがあります。

プロジェクト全体を見たい場合の即時操作:

  • <C-e>: 選択したプロジェクトへ移動して explorer を開く
  • <C-f>: 選択したプロジェクトへ移動して file picker を開く
  • <C-g>: 選択したプロジェクトへ移動して grep を開く
  • <C-w>: 選択したプロジェクトへ cwd だけ変更する

今回の設定では、~/.config/nvim/lua/plugins/projects.luaprojects source に次を追加し、Enter でも explorer を開くようにした。

confirm = { "tcd", "picker_explorer" },

文法解説

Vim の強さは、単発ショートカットではなく「文法」です。

dawdelete around word です。 ci"change inside quotes です。 yi(yank inside parentheses です。

このように、operator、text object、motion を組み合わせると、編集対象を構造で指定できます。 Neovim の設定も同じで、闇雲に plugin を増やすのではなく、移動、選択、編集、検索、診断、整形という責務で整理します。

なぜこの書き方か

1日で理解するには、最初から巨大な設定を写経しない方がよいです。 まず Vim の編集文法を覚え、その後で Neovim の IDE 的な機能を足す方が、何を plugin に任せているのかを理解できます。

LazyVim は便利ですが、すべてを暗記する対象ではありません。 options.luakeymaps.luaplugins/*.lua のどこに何を書くかを理解すれば、自分の設定として育てられます。

別の書き方

最小主義

LazyVim にほぼ任せ、独自設定は keymaps.lua だけにする方法です。 壊れにくい一方で、何がどこで設定されているかは :Lazy や LazyVim のドキュメントを読む必要があります。

自作主義

lazy.nvim だけを使い、LSP、補完、Treesitter、format を自分で組む方法です。 理解は深まりますが、1日カリキュラムには重すぎます。 まず LazyVim で全体像を掴み、必要な部分だけ自作へ寄せるのが現実的です。

他言語比較

VS Code は設定 UI と拡張機能で機能を足します。 Neovim は Lua ファイルに設定を書き、plugin spec と keymap で振る舞いを作ります。

Go の開発で考えると、LSP は gopls による型情報ベースの補助、Treesitter は構文木ベースの補助です。 go to definitionreferences は LSP、構文 highlight や text object の拡張は Treesitter と考えると整理しやすいです。

気づき

  • Vimmer になるには、まず motion と text object を覚える必要がある
  • Neovimmer になるには、Lua 設定、plugin manager、LSP、Treesitter の責務分担を理解する必要がある
  • プロジェクト全体を見たいときは、ファイルではなくディレクトリを nvim に渡す
  • 現在の設定は LazyVim に寄っているので、設定を追加する前に「LazyVim 既定値か、自分で明示したい値か」を分ける
  • 追加したい設定は、良さと設定例を先にメモしてから options.lua に入れると破綻しにくい
  • Mac では Neovim 設定だけでなく、ターミナル、IME、Command キー、クリップボードの確認が必要
  • cmux では pane と nvim split の責務を分けると、agent と編集画面を並べても混乱しにくい

参考リンク

  • Neovim User Manual: https://neovim.io/doc/user/usr_toc.html
  • Vim User Manual: https://vimhelp.org/usr_toc.txt.html
  • ThePrimeagen Vim Fundamentals: https://theprimeagen.github.io/vim-fundamentals/intro/
  • Typecraft Neovim for Newbs: https://cms.typecraft.dev/neovim-for-newbs/
  • nvim-treesitter: https://github.com/neovim-treesitter/nvim-treesitter
  • telescope.nvim: https://github.com/nvim-telescope/telescope.nvim
  • vim-be-good: https://github.com/ThePrimeagen/vim-be-good
  • cmux Claude Code Teams: https://cmux.com/ja/docs/agent-integrations/claude-code-teams
  • ローカルcmuxクリップ: inbox/クリップ/cmux Claude Code Teams.md