この記事は、Vim Advent Calendar 2025 13日目のエントリ記事です。
はじめに
VSCodeやJetBrains製品は、膨大な開発リソースを投じて作られた最強の武器だ。補完、デバッグ、Git統合、拡張機能——すべてが高度に洗練されている。多くの開発者にとって、これらを選ぶのは賢明な判断だと思う。
それでも、私は自分で刀を打ちたい。
ただし、誤解のないように言っておくと、名刀を打ちたいわけではない。美術館に飾られるような、完璧な一振りを目指しているわけではない。私が欲しいのは、戦場で戦うための道具だ。多少キズがあってもいい。見栄えが悪くてもいい。自分の手に馴染んで、明日の仕事で使えればそれでいい。
では、なぜ自分で作るのか。正直に言えば、効率の問題ではない。もっと根本的な、性分の問題だ。
思い返すと、私は子供の頃から構造や仕組みがどうしても気になって、分解してしまうクセがあった。おもちゃ、家電、何でも中がどうなっているか知りたくなる。そして仕組みを理解したら、自分なりに改修して「自分だけのもの」を作りたくなる。完成品を受け取るより、自分で手を入れる余地があるものに惹かれる。
開発環境も同じだ。私は元々Vimユーザーで、その後Neovimに移行した。途中でVSCode、JetBrains、Cursorに浮気したこともある。どれも素晴らしいツールだった。だが、どうしても「自分で鍛えている」という感覚がなかった。「自分のもの」という実感が湧かなかった。
具体的に言うと、こういうことだ。VSCodeを使っていたとき、settings.jsonをいじり、拡張機能を入れ替え、キーバインドを変え——気づけば「VSCodeをカスタマイズする」こと自体が目的になっていた。ならば、最初からカスタマイズ前提のツールを使えばいい。そう考えてNeovimに戻った。
理由を論理的に説明するのは難しい。効率だけで言えば、IDEを使いこなす方が早いかもしれない。それでも、自分の手で環境を組み上げ、日々磨き、少しずつ自分の形に変えていく。その過程そのものに惹かれている。これは性分だ。
こうした考え方には、実は名前がある。PDE(Personal Development Environment)——「個人開発環境」だ。自分のワークフローに最適化された、自分だけの開発環境を指す。私が10年かけてやってきたことは、まさにこのPDEの構築だった。
この記事では、2025年現在の私のPDE構成を紹介する。Rust、Go、TypeScript、Pythonでの開発、そしてKubernetesやTerraformを使ったインフラ作業を想定した構成だ。IDEが合う人にはIDEを勧める。でも、もし「自分で作ってみたい」という気持ちがあるなら、この記事が参考になれば嬉しい。
PDEとIDEの違い
IDEは万人向けに最適化されており、インストール直後から高い生産性が得られる。学習曲線は緩やか、メンテナンスはベンダー任せ。一方PDEは個人最適化の代わりに、学習コストとメンテナンスを自分で負担する。どちらが優れているかではなく、「すぐ使える便利さ」と「自分で作る楽しさ」のトレードオフだ。
もちろん、IDEにも自分の設定を入れられることは知っている。キーバインドを変更できるし、拡張機能は豊富だし、自分でプラグインを開発できる。VSCodeのsettings.jsonを何百行も書いた。それでも、私には「自分で作っている」という実感が足りなかった。論理的に説明するのは難しい。ただ、その実感の有無が、私にとっては大きかった。
では、PDEとは結局何なのか。PDEの本質は「自分の手に馴染む道具を自分で作る」こと。職人が道具を磨くように、開発者も環境を育てていく。ただし、職人の道具は飾るためではなく使うためにある。PDEも同じだ。完璧な環境を作ることが目的ではなく、日々の開発で戦えることが目的だ。効率だけを求めるなら、IDEを使った方がいい場面も多い。
私のPDE構成概要
基盤はWarp Terminal。その上でFish Shellを動かし、プロンプトにはStarshipを使っている。エディタはNeovim(NvChadベース)で、LSPとTreesitterで補完とシンタックスハイライトを実現している。
CLIツールはUnixの古典を現代版に置き換えた。lsの代わりにeza、catの代わりにbat、grepの代わりにripgrep。ディレクトリ移動はzoxide、リポジトリ管理はghq + fzf、差分表示はdeltaを使っている。
AIアシスタントは複数導入しているが、主軸はClaude Code。Neovim内ではCopilotとAvanteも使っている。
1. ターミナル:Warp
かつてはtmux + iTerm2の組み合わせを使っていた。しかし2024年、Warpに移行した。tmuxでやりたかったこと(ペイン分割、セッション管理)がWarp単体でできるし、見た目もかっこいい。使っていて特に不満もない。
正直なところ、tmuxの設定をメンテナンスするのが面倒になっていた。tmux + Bash時代は.tmux.confが600行を超えていて、何がどう動いているのか自分でも把握しきれなくなっていた。現在はWarp + Fishという構成で、tmuxの設定は丸ごと不要になった。設定ファイルが減るのは精神衛生上とても良い。
あと、Warpはモダンなターミナルらしく、補完がよく効く。コマンドを途中まで打つと候補が出てくる。tmux時代は「あのコマンドなんだっけ」とhistoryを漁ることが多かったが、その頻度が減った。
気に入っている点
- ブロックベースの出力: コマンドの出力が独立したブロックとして扱われ、コピーや再利用が容易。長いログの一部だけコピーしたいときに便利
- セッション管理の内蔵: tmuxのペイン分割・セッション管理相当の機能が標準搭載。tmuxのプレフィックスキーを覚えなくていい
- AIアシスタント: 自然言語でコマンドを生成できる。正直あまり使っていないが、たまに「あのコマンドなんだっけ」というときに便利
- 見た目: 単純にかっこいい。毎日使うものなので、見た目の満足度は意外と大事
設定のポイント
# ~/.warp/keybindings.yaml keybindings: # Vim風のペインナビゲーション - command: move_focus_to_left_pane keys: ctrl-h - command: move_focus_to_right_pane keys: ctrl-l - command: move_focus_to_pane_above keys: ctrl-k - command: move_focus_to_pane_below keys: ctrl-j
tmuxの設定をメンテナンスする必要がなくなったのは大きい。.tmux.confの600行が不要になった。
2. シェル:Fish Shell
BashやZshではなくFishを選んだ理由は明確だ。設定なしで賢い。「それならIDEを使えばいいのでは」と思うかもしれないが、シェルは基盤だ。基盤が安定しているからこそ、その上で動くエディタやツールを自由にカスタマイズできる。すべてを自分で作る必要はない。
Fish選択の決め手
- 補完がすごい: 設定なしでコマンド履歴、ファイルパス、オプションを補完
- シンタックスハイライト: コマンド入力中にエラーが分かる
- 設定の簡潔さ: ZshからFishに移行して、設定行数が600行から400行に減った
モダンCLIツール統合
Unixの古典的コマンドを現代版に置き換えている。
# ~/.config/fish/config.fish
# ls → eza (icons + git status)
if type -q eza
function ls --wraps eza
eza --icons --group-directories-first $argv
end
end
# cat → bat (syntax highlighting)
if type -q bat
function cat --wraps bat
bat --paging=never $argv
end
end
# grep → ripgrep (faster + smarter)
if type -q rg
function grep --wraps rg
rg $argv
end
end
省略形(abbr)
Fishにはabbr(abbreviation、省略形)という機能がある。入力してスペースを押すと、その場で展開される。
# ~/.config/fish/config.fish # Git省略形 abbr -a g git abbr -a ga "git add" abbr -a gc "git commit" abbr -a gco "git checkout" abbr -a gd "git diff" abbr -a gp "git push" abbr -a gl "git pull" abbr -a gs "git status" abbr -a glog "git log --oneline --graph" # Docker省略形 abbr -a d docker abbr -a dc "docker compose" abbr -a dcu "docker compose up -d" abbr -a dcd "docker compose down" abbr -a dps "docker ps" # Kubernetes省略形 abbr -a k kubectl abbr -a kgp "kubectl get pods" abbr -a kgs "kubectl get svc" abbr -a kgd "kubectl get deploy" abbr -a kd "kubectl describe" abbr -a kl "kubectl logs" abbr -a kex "kubectl exec -it"
gsと入力してスペースを押すとgit statusに展開される。私がabbrを気に入っている理由は、展開後のコマンドが履歴に残ること、そして展開後に編集できることだ。Gitコマンドを1日に数十回打つ私にとって、この小さな省力化の積み重ねは大きい。
ディレクトリ移動の革命:zoxide
cdコマンドをzoxideで置き換えた。一度訪れたディレクトリは、部分一致でジャンプできる。
# zoxideの有効化
if type -q zoxide
zoxide init fish --cmd z | source
end
# 例:~/ghq/github.com/nwiizo/projectに移動 z project # これだけでOK
ghq + fzf によるリポジトリ管理
全てのリポジトリをghqで管理し、fzfで瞬時に移動する。
function ghq_fzf_repo -d "Select repository with fzf"
set -l selected (ghq list -p | fzf \
--prompt="Repository: " \
--preview='ls -la {}')
if test -n "$selected"
cd $selected
end
end
# Ctrl+G でリポジトリ選択
bind \cg ghq_fzf_repo
direnv による環境の自動切り替え
プロジェクトごとの環境変数を.envrcで管理。ディレクトリに入ると自動で読み込まれる。
# direnvの有効化(2025年現在のベストプラクティス)
if type -q direnv
set -g direnv_fish_mode eval_on_arrow
direnv hook fish | source
end
3. プロンプト:Starship
Starshipは、Rustで書かれた高速なクロスシェルプロンプト。Git状態、言語バージョン、クラウド環境を一目で確認できる。
# ~/.config/starship.toml format = """ $directory\ $git_branch\ $git_status\ $golang\ $rust\ $python\ $kubernetes\ $cmd_duration\ $line_break\ $character""" [character] success_symbol = "[❯](bold green)" error_symbol = "[❯](bold red)" [kubernetes] symbol = "☸ " disabled = false
Kubernetes contextが常に表示されるので、本番環境で作業しているか一目で分かる。これで何度か事故を防げた。
4. エディタ:Neovim + NvChad
Vim/Neovimを使い始めて10年以上になる。途中でVSCode、JetBrains、Cursorを試したこともあるが、どれも1ヶ月以上メインに居座ったことはない。併用はしても、結局Neovimに戻ってきた。VSCodeもJetBrainsも素晴らしいエディタで、今でもそう思っている。ただ、私は自分で環境を組み立てたかった。その欲求が、他のエディタでは満たされなかった。
2025年版 Minimal UI アーキテクチャ
2025年の私のNeovim設定で最も特徴的なのは、statusline-less workflowだ。従来のstatuslineやtabuflineを廃止し、必要な情報のみをfloating windowで表示する。編集領域を最大化しつつ、必要な情報は失わない。
| コンポーネント | プラグイン | 役割 |
|---|---|---|
| ファイル情報 | incline.nvim | 右下floating statusline |
| モード表示 | modes.nvim | cursorline色でモード表示 |
| コマンドライン | noice.nvim | floating cmdline (cmdheight=0) |
| バッファ薄暗化 | vimade | 非アクティブバッファをdim |
| コードピーク | overlook.nvim | LSP定義をstackable popup表示 |
| ファイル選択 | Snacks.nvim | smart pickerでbufferline代替 |
incline.nvimは画面右下に小さなfloating windowでファイル情報を表示する。ファイルアイコン、ファイル名、未保存マーク、診断数が一目で分かる。init.luaのような汎用的なファイル名の場合は親ディレクトリも表示される(plugins/init.luaのように)。
modes.nvimはInsert/Visual/Deleteなどのモードをcursorlineの色で表現する。Insertはシアン、Visualは紫、Deleteは赤。-- INSERT --のようなテキスト表示が不要になり、視覚的に直感的。
-- options.lua での設定 vim.o.cmdheight = 0 -- コマンドライン非表示(noice.nvimが代替) vim.o.laststatus = 0 -- statusline非表示(incline.nvimが代替) vim.o.showmode = false -- モード表示非表示(modes.nvimが代替)
キーマップの発見性:which-key.nvim
2025年のNeovim設定で欠かせないのがwhich-key.nvimだ。キーを押すと、次に押せるキーの一覧がポップアップで表示される。「あのキーマップなんだったっけ」という問題が解消される。
{ "folke/which-key.nvim", opts = { preset = "helix", spec = { { "<leader>a", group = "AI" }, { "<leader>g", group = "Git" }, { "<leader>s", group = "Search" }, { "<leader>x", group = "Diagnostics" }, }, }, keys = { { "<leader>?", function() require("which-key").show() end, desc = "Buffer Keymaps" }, }, }
<leader>を押して少し待つと、aでAI、gでGit、sでSearch...とグループ分けされたキーマップが表示される。新しいプラグインを入れてもキーマップを覚える必要がない。
ナビゲーション
Snacks.nvim - 2025年のモダンユーティリティ集。
Snacks.nvimはfolke氏による新しいプラグインで、picker、lazygit統合、buffer削除などを統合している。特にsmart pickerが便利で、ファイル・バッファ・最近使用したファイルを一つのインターフェースで検索できる。
{ "folke/snacks.nvim", keys = { { "<leader><leader>", function() Snacks.picker.smart() end, desc = "Smart Picker" }, { "<leader>gg", function() Snacks.lazygit.open() end, desc = "LazyGit" }, { "<leader>sf", function() Snacks.picker.files() end, desc = "Find Files" }, { "<leader>sg", function() Snacks.picker.grep() end, desc = "Grep" }, }, }
lazygit統合ではeditPreset = "nvim-remote"を設定することで、lazygit内でファイルを開くと現在のNeovimインスタンスで開かれる。別ウィンドウが立ち上がらない。
Telescope - 検索のハブ(サブとして併用)。
{ "nvim-telescope/telescope.nvim", keys = { { "<leader>ff", "<cmd>Telescope find_files<cr>", desc = "Find Files" }, { "<leader>fg", "<cmd>Telescope live_grep<cr>", desc = "Live Grep" }, { "<C-p>", "<cmd>Telescope find_files<cr>", desc = "Find Files" }, }, }
oil.nvim - ファイルシステムをバッファとして編集。
neo-treeのようなツリー表示ではなく、ファイルシステムを通常のバッファとして扱う。ファイル名の変更は行の編集、削除は行の削除。Vimユーザーには直感的。
{ "stevearc/oil.nvim", keys = { { "-", "<cmd>Oil<cr>", desc = "Open parent directory" }, }, }
flash.nvim - 画面内の任意の位置にジャンプ。
sを押して文字を入力すると、その文字にラベルが表示される。ラベルを押すとジャンプ。hop.nvimの後継で、メンテナンスも活発。
overlook.nvim - コードピーク。
LSPの定義をfloating popupで表示する。ファイルを開かずに定義を確認できる。popupはスタック可能で、複数の定義を同時に表示できる。
{ "WilliamHsieh/overlook.nvim", keys = { { "<leader>pd", function() require("overlook").open_definition() end, desc = "Peek Definition" }, { "<leader>pc", function() require("overlook").close_all() end, desc = "Close All Popups" }, }, }
診断・デバッグ
trouble.nvim v3 - 診断情報のUI。
2024年にv3として完全書き直しされた。ツリービュー対応で、エラーの階層構造が見やすい。
{ "folke/trouble.nvim", keys = { { "<leader>xx", "<cmd>Trouble diagnostics toggle<cr>" }, { "<leader>xX", "<cmd>Trouble diagnostics toggle filter.buf=0<cr>" }, { "<leader>xs", "<cmd>Trouble symbols toggle<cr>" }, }, }
todo-comments.nvim - TODO/FIXME/NOTEのハイライト。
コード内のTODOコメントを自動検出してハイライト。Telescopeと連携してプロジェクト全体のTODOを一覧表示できる。
Git統合
gitsigns.nvim - インラインGit情報。
変更行の横にサイン(│)が表示される。hunk単位でのステージ、リセット、プレビューが可能。
{ "lewis6991/gitsigns.nvim", opts = { on_attach = function(bufnr) local gs = package.loaded.gitsigns vim.keymap.set("n", "]c", gs.next_hunk, { buffer = bufnr, desc = "Next Hunk" }) vim.keymap.set("n", "[c", gs.prev_hunk, { buffer = bufnr, desc = "Prev Hunk" }) vim.keymap.set("n", "<leader>gp", gs.preview_hunk, { buffer = bufnr, desc = "Preview Hunk" }) vim.keymap.set("n", "<leader>gb", function() gs.blame_line { full = true } end, { buffer = bufnr, desc = "Blame Line" }) end, }, }
diffview.nvim - Git diffの可視化。
Git差分をNeovim内で確認できる。ファイル履歴も見やすい。2025年版では、より多くのキーマップを設定している。
{ "sindrets/diffview.nvim", keys = { { "<leader>gd", "<cmd>DiffviewOpen<cr>", desc = "Git Diff (working tree)" }, { "<leader>gD", "<cmd>DiffviewOpen HEAD~1<cr>", desc = "Diff vs previous commit" }, { "<leader>gh", "<cmd>DiffviewFileHistory %<cr>", desc = "File History" }, { "<leader>gH", "<cmd>DiffviewFileHistory<cr>", desc = "Branch History" }, { "<leader>gm", "<cmd>DiffviewOpen main...HEAD<cr>", desc = "Diff vs main branch" }, { "<leader>gs", "<cmd>DiffviewOpen --staged<cr>", desc = "Staged changes" }, { "<leader>gq", "<cmd>DiffviewClose<cr>", desc = "Close Diffview" }, }, }
Diffview内では-でステージ/アンステージ、Sで全てステージ、Xで変更を復元。コンフリクト解決も<leader>co(ours)、<leader>ct(theirs)で直感的に操作できる。
LSP設定
Mason.nvimで言語サーバーを管理。主要な言語はすべてカバー。
ensure_installed = { -- Rust "rust-analyzer", -- Go "gopls", "gofumpt", "goimports", -- TypeScript/JavaScript "typescript-language-server", "prettier", -- Python "pyright", "black", "isort", -- Infrastructure "terraform-ls", "yaml-language-server", -- Shell "bash-language-server", "shellcheck", }
2025年のポイントとして、JSON/YAMLにはSchemaStoreを統合している。package.jsonやdocker-compose.ymlの補完がスキーマベースで効くようになる。
5. AIアシスタント統合
2024年から2025年にかけて、開発環境で最も大きく変わったのはAIの存在だ。コード補完、生成、レビュー、デバッグ——あらゆる場面でAIが介在するようになった。2025年のPDEにおいて、AIツールは最も重要な要素になっている。
私は複数のAIツールを導入しているが、主軸はClaude Codeだ。
Claude Code - 開発の中心
ターミナルで起動し、コード生成、リファクタリング、デバッグ、質問——ほとんどの作業をClaude Codeで完結させている。私の使い方の特徴は、プロジェクトごとにカスタマイズしている点だ。やっていることはシンプルで、3つのファイルを育て続けている。
project/ ├── CLAUDE.md # プロジェクト固有の指示 ├── .claude/ │ ├── commands/ # カスタムスラッシュコマンド │ │ ├── review.md │ │ └── test.md │ └── agents/ # 特化型エージェント │ └── reviewer.md
CLAUDE.md にはプロジェクトの文脈を書く。使用技術、コーディング規約、避けるべきパターンなど。これがあるとClaude Codeの回答精度が劇的に上がる。
commands にはよく使う操作をスラッシュコマンドとして定義する。/reviewでコードレビュー、/testでテスト生成など。毎回同じプロンプトを書く手間が省ける。
agents には特定タスクに特化したエージェントを定義する。レビュー専門、リファクタリング専門など、役割を分けることで精度が上がる。
重要なのは、これらを使いながら修正し続けること。「この指示だと意図と違う結果になる」と気づいたらCLAUDE.mdを更新する。コマンドの出力が物足りなければcommandを調整する。PDEと同じで、日々の開発の中で育てていく。
Neovimとの連携にはclaude-code.nvimを使っている。
{ "greggh/claude-code.nvim", keys = { { "<leader>cc", "<cmd>ClaudeCode<cr>", desc = "Claude Code" }, { "<leader>cr", "<cmd>ClaudeCodeResume<cr>", desc = "Resume Conversation" }, }, }
<leader>ccでClaude Codeのターミナルウィンドウをトグル。エディタで開いているファイルをそのままClaude Codeに渡せる。
Neovim内のAIツール
Neovim内ではCopilotとAvanteを併用している。
Copilotはインライン補完用。コードを書いている最中に候補が表示され、Tabで確定する。考えながら書くときに便利。copilot-cmpと組み合わせて、補完メニューの最上位にCopilotの提案が表示されるようにしている。
CopilotChatはAIチャット用。コードの説明、修正、テスト生成、ドキュメント生成などをチャット形式で行える。モデルはclaude-sonnet-4を使用。
{ "CopilotC-Nvim/CopilotChat.nvim", opts = { model = "claude-sonnet-4" }, keys = { { "<leader>ao", "<cmd>CopilotChatOpen<cr>", desc = "Open Chat" }, { "<leader>ae", "<cmd>CopilotChatExplain<cr>", desc = "Explain Code", mode = { "n", "v" } }, { "<leader>af", "<cmd>CopilotChatFix<cr>", desc = "Fix Code", mode = { "n", "v" } }, { "<leader>at", "<cmd>CopilotChatTests<cr>", desc = "Generate Tests", mode = { "n", "v" } }, { "<leader>ad", "<cmd>CopilotChatDocs<cr>", desc = "Generate Docs", mode = { "n", "v" } }, { "<leader>aR", "<cmd>CopilotChatReview<cr>", desc = "Review Code", mode = { "n", "v" } }, }, }
AvanteはCursorエディタのAI機能をNeovim上に再現するプラグイン。ファイル横断の変更や設計相談に使う。<leader>aaで質問すると、サイドパネルが開いてAIとの対話が始まる。
{ "yetone/avante.nvim", opts = { provider = "copilot", mode = "agentic", providers = { copilot = { model = "claude-sonnet-4" }, }, mappings = { ask = "<leader>aa", edit = "<leader>ax", }, }, }
AI統合のキーマップまとめ
| キー | プラグイン | 説明 |
|---|---|---|
<leader>aa |
Avante | AI質問 |
<leader>ao |
CopilotChat | チャットを開く |
<leader>ae |
CopilotChat | コードを説明 |
<leader>af |
CopilotChat | コードを修正 |
<leader>at |
CopilotChat | テスト生成 |
<leader>ad |
CopilotChat | ドキュメント生成 |
<leader>aR |
CopilotChat | コードレビュー |
<leader>cc |
Claude Code | Claude Code起動 |
<leader>cr |
Claude Code | 会話を再開 |
6. 言語別の設定
Rustは私のメイン言語なので、専用プラグインを導入している。rustaceanvimでrust-analyzerを強化し、crates.nvimでCargo.tomlのバージョンを管理する。Cargo.tomlを開くと、各クレートの最新バージョンがインラインで表示される。
Go、TypeScript、Pythonは特別な設定をしていない。LSP設定セクションで示したensure_installedにより、各言語サーバーが自動でセットアップされる。保存時の自動フォーマットはconform.nvimに任せている。詳細な設定はdotfilesリポジトリを参照してほしい。
7. フォーマッター統合
conform.nvimで保存時に自動フォーマット。言語ごとに適切なフォーマッターを設定。
{ "stevearc/conform.nvim", opts = { formatters_by_ft = { lua = { "stylua" }, rust = { "rustfmt" }, go = { "gofmt", "goimports", "gofumpt" }, python = { "black", "isort" }, typescript = { "prettier" }, javascript = { "prettier" }, yaml = { "prettier" }, json = { "prettier" }, markdown = { "prettier" }, }, format_on_save = { timeout_ms = 500, lsp_fallback = true }, }, }
PDEを育てるということ
PDEは完成することがない。日々の開発の中で、少しずつ手を入れ続ける。
刀から庭へ
この記事のタイトルには「刀を打つ」と書いた。実際、PDEには刀を打つ行為がある。ターミナルを選び、シェルを設定し、エディタを組み上げる。ゼロから自分の道具を作り上げていく。
ただ、刀には完成がある。名刀は打ち上がれば、あとは研ぎ澄ますだけ。床の間に飾られ、鑑賞される。しかしPDEには完成がない。プラグインは更新され、新しいツールが登場し、自分の作業スタイルも変わる。「完成した」と思った翌週には、また何かをいじっている。
最初は名刀を打つつもりだった。「理想の開発環境を作り上げる」という完成形を目指していた。だが10年経って気づいた。私が欲しかったのは名刀ではなく、戦場で使える道具だった。
戦場で使える道具とは何か。それは、完成を待たずに使い始められるものだ。使いながら調整し、壊れたら直し、足りなければ足す。常に未完成で、常に変化している。
ここで気づいた。私がやっていることは、刀を打つだけではない。打った刀を、日々手入れし続けている。使いながら研ぎ、傷がつけば直し、必要に応じて改良する。この「手入れし続ける」という感覚——何かに似ている。
そうだ、庭だ。庭も完成しない。季節ごとに姿を変え、草木は勝手に育ち、手入れを怠れば荒れる。人間が設計するが、人間の思い通りにはならない。それでも手を入れ続けることで、少しずつ自分の形になっていく。
宇野常寛さんの『庭の話』という本が、この感覚を言語化してくれた。
宇野さんは、現代のプラットフォーム(SNS)を「相互評価のゲームに特化した空間」として批判し、対抗概念として「庭」を提示する。プラットフォームが画一化された承認欲求の交換の場であるのに対し、庭は「完全にはコントロールできないもの」との共存の場だ。草木が勝手に育ち、虫が飛び交い、季節によって姿を変える。人間が設計するが、人間の思い通りにはならない。
この説明を読んだとき、私は自分のPDEのことを思い浮かべた。プラグインが勝手にアップデートされ、設定が壊れ、新しいツールが登場する。思い通りにならない。でも、手を入れ続けることで、少しずつ自分の形になっていく。
宇野さんの言う「プラットフォーム」と「庭」の対比は、そのまま開発環境にも当てはまる。IDEはプラットフォームだ。ベンダーが設計し、万人に最適化されたサービスを提供する。ユーザーはそれを消費する。便利で、効率的で、すぐに使える。しかし、自分でコントロールできる範囲は限られている。
一方、PDEは刀を打ち、庭として育てるものだ。自分で道具を作り、その道具を手入れし続ける。プラグインが競合し、設定が壊れ、アップデートで挙動が変わる。それでも、手を入れ続けることで、少しずつ自分の形になっていく。消費ではなく、制作。受け取るのではなく、育てる。
宇野さんは「消費から制作へ」という転換を説く。プラットフォームで承認を求めるのではなく、制作に没頭すること。
エンジニアとして、私たちは「正解」を求めがちだ。最適解を見つけ、効率を最大化し、その成果で報われたいと思う。だが、PDEにはそういう正解がない。「正しい設定」も「最適なプラグイン構成」も存在しない。ネットで見つけた「おすすめ設定」をコピペしても、それは自分の刀にはならない。
正解を求めて報われようとするのをやめる。他者から評価される「模範解答」を探すのではなく、自分の手に馴染む道具を、自分のために作る。PDEを構築する行為は、まさにこの「制作」だ。誰かに見せるためではなく、自分のために作る。その過程で、ツールとの対話が生まれる。
「家庭」という言葉は「家」と「庭」でできている。宇野さんは「家」の内部で承認を交換するだけでは見えないものが「庭」にはあると言う。開発環境も同じだ。IDEという「家」の中で完結するのではなく、PDEという「庭」に出ることで、ツールとの新しい関係が見えてくる。
ツールと思考の相互作用
ツールとの新しい関係とは何か。PDEを10年実践する中で、1つ気づいたことがある。
ツールは思考に影響し、思考はツールに影響される。
これは単なる比喩ではない。以前、AIエージェントとの協働について書いた記事で、私は「集中とは自分の能力ではなく環境との関係である」と述べた。
環境との関係——これはPDEにも当てはまる。具体的な例を挙げよう。Vimのモーダル編集を使い始めると、テキスト操作を「動詞+名詞」で考えるようになる。d(削除)+ w(単語)で「単語を削除」。この思考パターンは、コードを書くときの発想にも影響する。操作を小さな単位に分解し、組み合わせて目的を達成する。
逆に、自分の思考スタイルに合わないツールは、どれだけ高機能でも使いこなせない。合わないものは合わない。それだけのことだ。
重要なのは、この相互作用を意識的に活用することだ。新しいツールを導入するとき、私は「このツールは自分の思考をどう変えるか」を考える。AIエージェントを使い始めたとき、深く没入する集中から、複数タスクを並行監視する集中へと、思考のモードを切り替える必要があった。環境が変われば、思考も変わるべきなのだ。
PDEとは、単にツールをカスタマイズすることではない。自分の思考とツールの関係を最適化し続けることだ。
AIは庭の一部か、庭師か
2025年のPDEを語る上で、AIツールの位置づけは避けて通れない。
私はClaude Codeを「主軸」と書いた。しかし、これは従来のツールとは異なる存在だ。Neovimは私が設定し、私が操作する。一方Claude Codeは、私と対話し、私の意図を解釈し、時に私が思いつかなかったアプローチを提案する。
これは庭の一部なのか、それとも共に庭を育てる存在なのか。
正直に言えば、まだ答えは出ていない。ただ、1つ確かなことがある。CLAUDE.mdを更新し、カスタムコマンドを調整し、エージェントを育てる——この作業は、Neovimのプラグイン設定と同じ感覚だ。AIツールもまた、PDEの一部として「育てる」対象になっている。
同時に、Claude Codeは私のPDEを育てる側でもある。「この設定、冗長では」「こういうプラグインがある」と提案してくる。人間が庭を育て、庭が人間を育てる。その関係がAIツールとの間にも成り立っている。
私のPDE改善サイクル
では、具体的にどうやってPDEを育てているのか。私の場合、こんなサイクルを回している。
- 気づく: 「この操作、毎日10回はやってるな」
- 調べる: 既存のプラグインや設定で解決できないか
- 試す: 設定を追加して数日使ってみる
- 磨く: 使いにくければ調整、良ければ定着
このサイクルを回し続けていると、つい完璧を目指したくなる。だが、ここで立ち止まる必要がある。すべてを自作する必要はない。すべてをOSSで揃える必要もない。それをやると疲れる。Fish、Warp、Starshipを選んだのも「設定なしで賢い」からだ。力を入れるところと抜くところを分ける。適度にやっていくことが、PDEを長く続けるコツだと思う。
これもまた、刀を打ち、庭として育てることの本質だ。名刀を打つなら妥協は許されない。だが戦場で使う刀は違う。多少キズがあっても戦えればいい。庭も同じだ。すべてを自分で育てる必要はなく、買ってきた苗を植えてもいい。大事なのは、戦場で戦えること。実際の開発で使えること。完璧な道具を作ることではない。
設定ファイルの管理
dotfilesはGitで管理。どのマシンでも同じ環境を再現できる。
dotfiles/ ├── fish/ # Fish shell ├── nvim/ # Neovim ├── warp/ # Warp terminal ├── starship/ # Starship prompt └── git/ # Git config
5年後、PDEは存在するか
AIの進化を見ていると、ふと考えることがある。5年後、開発環境を「自分で構築する」という行為に意味はあるのか。
AIがコードを書き、テストを実行し、デプロイまで行う時代が来るかもしれない。そのとき、エディタの設定にこだわる意味があるのか。Neovimのキーバインドを覚える価値があるのか。
正直に言えば、分からない。5年後の開発がどうなっているか、誰にも予測できない。
ただ、こうも思う。むしろ逆かもしれない、と。従来、PDEの構築には学習コストとメンテナンスコストがかかり、それに見合う生産性向上が得られるかは不透明だった。しかしAIは、このトレードオフを限りなく等価に近づけてくれる。環境を改善すれば、その改善がAIを介して直接生産性に反映される。CLAUDE.mdを1行書き足せば、その分だけAIの出力が良くなる。PDEが「趣味」から「現実的に有効な投資」になる時代が来ているのかもしれない。
ただ、1つだけ確信していることがある。「自分で作りたい」という欲求は消えない。
ツールが変わっても、プラットフォームが変わっても、「与えられたものをそのまま使うのではなく、自分の手を入れたい」という欲求は残る。少なくとも、私はそういう人間だ。
AIがすべてを生成する時代が来ても、そのAIをどう使うか、どうカスタマイズするか、どう自分のワークフローに組み込むか——そこにPDEの精神は生き続けると思う。道具は変わっても、道具との関係を自分で設計したいという欲求は変わらない。
まとめ
ここまで私のPDE構成を紹介してきた。Warp上でFishを動かし、NeovimとClaude Codeを併用する——これらを組み合わせて、自分だけの「刀」を作り上げて「庭」を育てている。
PDEを選ぶ理由は効率では説明できない。最初の2週間は生産性が落ちるし、1ヶ月かけて元に戻る。それでも、自分で組み上げ、日々改善していく過程そのものに価値がある。消費ではなく制作、受け取るのではなく育てる。
だからといって、完璧を目指す必要はない。名刀を打つ必要はない。すべてを自作する必要もない。大事なのは、明日の開発で戦えること。そのために、今日少しだけ環境を良くする。その繰り返しがPDEだ。
もし「自分で作ってみたい」という気持ちがあるなら、試してみてほしい。合わなかったら戻ればいい。IDEという最強の武器は、いつでもそこにある。
このブログが良ければ読者になったり、nwiizoのXやGithubをフォローしてくれると嬉しいです。
この記事で紹介した設定ファイルは以下のリポジトリで公開している。