Neovim 系列(一):為什麼我想離開 VSCode?

這是 Neovim 從零開始系列的第一篇。整個系列共 12 篇文章,將帶你從完全不懂 Vim,到能用 Neovim 打造一個完整的現代化開發環境。 我和 VSCode 的故事 我用 VSCode 已經好幾年了。它確實是一款優秀的編輯器——免費、生態豐富、上手容易。從 JavaScript 到 Go,從前端到後端,VSCode 幾乎都能勝任。 但隨著使用時間越長,有些小事情開始困擾我: 手不斷在鍵盤和滑鼠之間來回,選取文字、點選檔案、開關 terminal 長期使用 Claude Code 等 terminal 工具,卻得在 VSCode 和 terminal 之間頻繁切換 看著 Vim 使用者行雲流水的操作,思考自己是不是錯過了什麼 如果你也有類似的感受,那這個系列就是為你寫的。 什麼是 Modal Editing? VSCode 和大多數現代編輯器都是 modeless 的——按下 a 就是輸入 a,永遠如此。這很直覺,但也意味著所有的操作快捷鍵都得靠 Ctrl、Alt、Cmd 等修飾鍵來觸發。 Vim 採用完全不同的設計哲學:modal editing(模式編輯)。在不同的模式下,同一個按鍵有不同的功能: 模式 用途 進入方式 Normal 瀏覽、移動、操作文字 Esc Insert 輸入文字(和一般編輯器一樣) i, a, o 等 Visual 選取文字 v, V, Ctrl-V Command 執行指令 : 為什麼這樣設計?因為寫程式時,你大部分的時間都在閱讀和編輯,而非打字。Normal mode 讓你用最少的按鍵完成最多的操作——不需要任何修飾鍵。 ...

2026年2月23日 · 3 min · 481 words · Jack

Neovim 系列(二):Vim 的語言——動詞、名詞、組合技

這是 Neovim 從零開始系列的第二篇。整個系列共 12 篇文章,將帶你從完全不懂 Vim,到能用 Neovim 打造一個完整的現代化開發環境。 為什麼 Vim 像一門語言? 上一篇我們提到 Vim 的操作就像一門語言。這不是比喻——它真的是一套設計精良的文法系統。 大多數編輯器的快捷鍵是「一個組合做一件事」:Ctrl+D 選取下一個相同的詞、Ctrl+Shift+K 刪除整行。每個操作都是獨立的,你需要一個一個背。 Vim 不一樣。它的操作遵循一個簡單的文法: Operator + Motion = Action (動詞) (名詞) (動作) 學會 5 個動詞和 10 個名詞,你就有了 50 種操作。這就是 Vim 的 乘法效應。 動詞(Operators) Operator 定義了你想「做什麼」。以下是最常用的動詞: Operator 功能 記憶法 d 刪除(delete) delete c 修改(change)——刪除並進入 Insert mode change y 複製(yank) yank(Vim 用 yank 而非 copy) v 選取(visual select) visual > 向右縮排 箭頭方向 < 向左縮排 箭頭方向 = 自動排版 等號=對齊 gu 轉小寫 go uppercase 的反向 gU 轉大寫 go Uppercase 其中 d、c、y 是你每天都會用到的三個核心動詞。 ...

2026年2月24日 · 3 min · 618 words · Jack

Neovim 系列(三):移動的藝術——在程式碼中飛速穿梭

這是 Neovim 從零開始系列的第三篇。整個系列共 12 篇文章,將帶你從完全不懂 Vim,到能用 Neovim 打造一個完整的現代化開發環境。 移動是一切的基礎 上一篇我們學了 Vim 的「語言」系統。而這門語言中的「名詞」,很大一部分就是移動指令(motions)。你移動越快、越精準,整體的編輯效率就越高。 這篇會把所有重要的移動指令一次講清楚。不用急著全背下來——先看過有個印象,然後每天挑 2-3 個新的來練習。 基本移動:hjkl k ↑ h ← → l ↓ j 鍵 方向 記憶法 h 左 最左邊的鍵 j 下 j 的尾巴往下勾 k 上 k 的筆畫往上 l 右 最右邊的鍵 為什麼不用方向鍵? 方向鍵離 home row 太遠了。hjkl 就在你右手的 home row 位置,手完全不需要移動。 小技巧:剛開始可以在鍵盤上貼小貼紙提醒,一兩天就習慣了。 搭配數字 指令 功能 5j 往下 5 行 10k 往上 10 行 3l 往右 3 格 單字級移動:w / b / e 這三個可能是你除了 hjkl 之外最常用的移動: ...

2026年2月25日 · 4 min · 696 words · Jack

Neovim 系列(四):編輯效率加倍——Registers、Macros 與 Dot Command

這是 Neovim 從零開始系列的第四篇。整個系列共 12 篇文章,將帶你從完全不懂 Vim,到能用 Neovim 打造一個完整的現代化開發環境。 效率的下一個層次 前兩篇我們學了 Vim 的語言系統和移動指令。有了這些基礎,你已經能在程式碼中自由移動和編輯了。 這篇要教的三個功能——Dot Command、Registers 和 Macros——會把你的效率再推上一個層次。它們的核心概念是:重複操作的自動化。 Dot Command:最強的單一按鍵 .(dot)這個按鍵可能是 Vim 中投資報酬率最高的功能。它的作用很簡單: 重複上一次的修改操作 基本用法 // 想把所有的 var 改成 const var name = "Jack" var age = 30 var city = "Taipei" 操作步驟: 游標在第一行的 var 上 按 cw 然後輸入 const,按 Esc 移到下一行的 var 上,按 .——自動執行「把單字改成 const」 再移到下一行,按 .——同樣的操作 一個 . 就重複了整個 cw + 輸入 + Esc 的序列。 Dot Command 的威力 . 重複的是上一次「從 Normal mode 進入 Insert mode 到離開」的完整操作,或者是上一次 Normal mode 下的操作指令。 ...

2026年2月26日 · 4 min · 825 words · Jack

Neovim 系列(五):安裝 Neovim 與你的第一個 init.lua

這是 Neovim 從零開始系列的第五篇。整個系列共 12 篇文章,將帶你從完全不懂 Vim,到能用 Neovim 打造一個完整的現代化開發環境。 從練習到實戰 前四篇我們學完了 Vim 操作的核心基礎,你可能已經在 VSCode + Vim extension 中練習了一陣子。現在,是時候正式安裝 Neovim,開始打造屬於自己的編輯器了。 這篇會帶你從安裝開始,到寫出一個實用的 init.lua 配置檔。 安裝 Neovim macOS(推薦用 Homebrew) brew install neovim 安裝完成後確認版本: nvim --version 建議使用 0.10+ 以上的版本,以確保內建 LSP 和 Treesitter 等功能正常運作。 其他平台 # Ubuntu / Debian sudo apt install neovim # Arch Linux sudo pacman -S neovim # Windows(用 winget) winget install Neovim.Neovim 第一次啟動 nvim 你會看到一個歡迎畫面。按 :q 離開。恭喜,你已經成功啟動了 Neovim! 目前它看起來很陽春——沒有行號、沒有語法高亮、沒有任何自訂設定。接下來我們會一步步改善。 ...

2026年2月27日 · 7 min · 1313 words · Jack

Neovim 系列(六):Plugin 管理——用 lazy.nvim 打造你的工具箱

這是 Neovim 從零開始系列的第六篇。整個系列共 12 篇文章,將帶你從完全不懂 Vim,到能用 Neovim 打造一個完整的現代化開發環境。 為什麼需要 Plugins? 上一篇我們建立了基礎的 init.lua,但 Neovim 現在看起來還很陽春。要讓它成為一個真正好用的開發環境,我們需要 plugins 來擴充功能: 漂亮的配色主題 狀態列顯示檔案資訊 檔案瀏覽器 模糊搜尋 語法高亮 自動補全 Git 整合 這些都是 plugins 提供的。而要管理這些 plugins,我們需要一個 plugin manager。 認識 lazy.nvim lazy.nvim 是目前 Neovim 最主流的 plugin manager。它的優點: 速度極快:自動 lazy-loading,啟動時間極短 直覺的 UI:按 :Lazy 就能看到所有 plugin 的狀態 宣告式配置:用 Lua table 定義 plugin,清楚明瞭 自動管理依賴:plugin 之間的依賴關係自動處理 鎖定版本:lazy-lock.json 確保可重現的配置 重新組織配置結構 在安裝 lazy.nvim 之前,先把配置拆分成更好的結構: ~/.config/nvim/ ├── init.lua ← 入口點 ├── lua/ │ └── config/ │ ├── options.lua ← vim.opt 設定 │ ├── keymaps.lua ← 快捷鍵映射 │ └── lazy.lua ← lazy.nvim 初始化 │ └── plugins/ │ ├── colorscheme.lua ← 配色主題 │ ├── lualine.lua ← 狀態列 │ └── ... ← 其他 plugins 拆分現有設定 把上一篇 init.lua 的內容拆分: ...

2026年2月28日 · 6 min · 1077 words · Jack

Neovim 系列(七):程式碼智能——LSP 與自動補全

這是 Neovim 從零開始系列的第七篇。整個系列共 12 篇文章,將帶你從完全不懂 Vim,到能用 Neovim 打造一個完整的現代化開發環境。 什麼是 LSP? LSP(Language Server Protocol) 是微軟在 2016 年為 VSCode 設計的通訊協定,後來成為了業界標準。它的概念很簡單: Language Server:一個獨立的程式,負責分析特定語言的程式碼 Editor:透過 LSP 協定和 Language Server 溝通 ┌─────────────┐ LSP ┌──────────────────┐ │ Neovim │◄────────────►│ Language Server │ │ (Editor) │ │ (如 typescript- │ │ │ │ language-server) │ └─────────────┘ └──────────────────┘ 這樣的好處是:每個編輯器只需要實作一次 LSP client,就能支援所有語言。VSCode 的程式碼智能就是基於 LSP,而 Neovim 從 0.5 開始就內建了 LSP client。 LSP 提供的功能 功能 說明 VSCode 對應 自動補全 輸入時顯示建議 IntelliSense 跳轉到定義 查看函數/變數的定義 Go to Definition 查看引用 找到所有使用某個符號的位置 Find All References Hover 文件 游標停留時顯示型別和文件 Hover 診斷 即時顯示錯誤和警告 Problems 重新命名 全域重新命名符號 Rename Symbol 程式碼動作 快速修復、自動導入 Quick Fix 格式化 自動排版程式碼 Format Document 我們要安裝的 Plugins 要讓 LSP 和自動補全在 Neovim 中運作,需要幾個 plugin 協同工作: ...

2026年3月1日 · 5 min · 1054 words · Jack

Neovim 系列(八):語法高亮與檔案導航——Treesitter + Telescope

這是 Neovim 從零開始系列的第八篇。整個系列共 12 篇文章,將帶你從完全不懂 Vim,到能用 Neovim 打造一個完整的現代化開發環境。 本篇的目標 經過前幾篇的設定,你的 Neovim 已經有了 LSP 和自動補全。這篇要加入三個讓開發體驗再度提升的功能: Treesitter:基於語法樹的精確高亮和文字操作 Telescope:強大的模糊搜尋(取代 VSCode 的 Cmd+P) oil.nvim:檔案瀏覽器(取代 VSCode 的左側邊欄) Treesitter:真正理解你的程式碼 傳統語法高亮 vs Treesitter 傳統的語法高亮用正則表達式來匹配——它只看文字模式,不懂程式碼結構。這導致: 複雜的語法可能標錯顏色 巢狀結構容易混亂 不同語言嵌套(如 HTML 中的 JavaScript)效果差 Treesitter 完全不同——它解析程式碼為語法樹(AST),真正理解程式碼的結構。好處是: 語法高亮更精確(區分函數名、變數、型別、常數等) 支援增量解析(編輯時只重新解析修改的部分,非常快) 提供基於語法結構的文字操作(如選取整個函數) 安裝 Treesitter -- lua/plugins/treesitter.lua return { "nvim-treesitter/nvim-treesitter", build = ":TSUpdate", event = "BufReadPost", dependencies = { "nvim-treesitter/nvim-treesitter-textobjects", }, config = function() require("nvim-treesitter.configs").setup({ ensure_installed = { "lua", "vim", "vimdoc", "javascript", "typescript", "tsx", "go", "gomod", "gosum", "python", "html", "css", "json", "yaml", "toml", "markdown", "markdown_inline", "bash", "dockerfile", "gitcommit", "diff", }, auto_install = true, highlight = { enable = true, }, indent = { enable = true, }, incremental_selection = { enable = true, keymaps = { init_selection = "<C-space>", node_incremental = "<C-space>", scope_incremental = false, node_decremental = "<bs>", }, }, }) end, } 增量選取 上面設定中的 incremental_selection 是一個非常好用的功能: ...

2026年3月2日 · 5 min · 956 words · Jack

Neovim 系列(九):Git 整合工作流——在編輯器中完成所有 Git 操作

這是 Neovim 從零開始系列的第九篇。整個系列共 12 篇文章,將帶你從完全不懂 Vim,到能用 Neovim 打造一個完整的現代化開發環境。 為什麼在 Neovim 中操作 Git? VSCode 有內建的 Source Control 面板和 GitLens 擴充,讓你不用離開編輯器就能操作 Git。在 Neovim 中,我們要用幾個 plugins 達到同樣甚至更好的體驗: gitsigns.nvim:在行號旁顯示 Git 變更狀態 lazygit:功能強大的 Terminal Git UI diffview.nvim:在 Neovim 中查看 diff gitsigns.nvim:行內 Git 狀態 gitsigns 是最基本也最必要的 Git plugin。它在 sign column(行號左邊)顯示每一行的 Git 狀態: │ 綠色:新增的行 │ 藍色:修改的行 _ 紅色:刪除的行 -- lua/plugins/gitsigns.lua return { "lewis6991/gitsigns.nvim", event = "BufReadPost", config = function() require("gitsigns").setup({ signs = { add = { text = "│" }, change = { text = "│" }, delete = { text = "_" }, topdelete = { text = "‾" }, changedelete = { text = "~" }, }, on_attach = function(bufnr) local gs = package.loaded.gitsigns local opts = { buffer = bufnr } -- 導航:在 hunk(變更區塊)之間跳轉 vim.keymap.set("n", "]h", gs.next_hunk, opts) vim.keymap.set("n", "[h", gs.prev_hunk, opts) -- Stage / Unstage vim.keymap.set("n", "<leader>hs", gs.stage_hunk, opts) vim.keymap.set("n", "<leader>hr", gs.reset_hunk, opts) vim.keymap.set("v", "<leader>hs", function() gs.stage_hunk({ vim.fn.line("."), vim.fn.line("v") }) end, opts) vim.keymap.set("v", "<leader>hr", function() gs.reset_hunk({ vim.fn.line("."), vim.fn.line("v") }) end, opts) -- Stage / Reset 整個 buffer vim.keymap.set("n", "<leader>hS", gs.stage_buffer, opts) vim.keymap.set("n", "<leader>hR", gs.reset_buffer, opts) -- Undo stage vim.keymap.set("n", "<leader>hu", gs.undo_stage_hunk, opts) -- Preview hunk vim.keymap.set("n", "<leader>hp", gs.preview_hunk, opts) -- Blame vim.keymap.set("n", "<leader>hb", function() gs.blame_line({ full = true }) end, opts) vim.keymap.set("n", "<leader>tb", gs.toggle_current_line_blame, opts) -- Diff vim.keymap.set("n", "<leader>hd", gs.diffthis, opts) end, }) end, } gitsigns 快捷鍵總覽 快捷鍵 功能 說明 ]h / [h 下/上一個 hunk 在變更區塊間跳轉 <leader>hs Stage hunk 暫存當前變更區塊 <leader>hr Reset hunk 撤銷當前變更區塊 <leader>hS Stage buffer 暫存整個檔案 <leader>hR Reset buffer 撤銷整個檔案的變更 <leader>hu Undo stage 取消暫存 <leader>hp Preview hunk 預覽變更內容 <leader>hb Blame line 顯示當前行的 Git blame <leader>tb Toggle blame 切換行內 blame 顯示 <leader>hd Diff this 查看當前檔案的 diff 日常使用流程 1. 編輯程式碼(sign column 自動顯示變更標記) 2. 用 ]h / [h 在變更區塊間跳轉,檢查修改內容 3. 用 <leader>hp 預覽 hunk,確認要保留的變更 4. 用 <leader>hs stage 個別 hunk(或 <leader>hS stage 整個檔案) 5. 用 <leader>hr 撤銷不需要的變更 這種 hunk 級別的 staging 比 VSCode 的整個檔案 stage 更精細。你可以只 stage 一個檔案中的部分修改。 ...

2026年3月3日 · 4 min · 844 words · Jack

Neovim 系列(十):Terminal 與 Claude Code 整合——AI 時代的開發工作流

這是 Neovim 從零開始系列的第十篇。整個系列共 12 篇文章,將帶你從完全不懂 Vim,到能用 Neovim 打造一個完整的現代化開發環境。 Terminal 工作流的魅力 這是我當初想從 VSCode 轉到 Neovim 的核心原因之一:讓整個開發流程都在 terminal 中完成。 想像一下這樣的畫面: ┌──────────────────────────────────────┐ │ tmux session: my-project │ │ ┌────────────────┬─────────────────┐ │ │ │ │ │ │ │ │ Neovim │ Claude Code │ │ │ │ (寫程式) │ (AI 助手) │ │ │ │ │ │ │ │ ├────────────────┴─────────────────┤ │ │ │ Shell (跑測試、git 操作) │ │ │ └──────────────────────────────────┘ │ └──────────────────────────────────────┘ 所有工作在同一個 terminal 視窗中完成。不切換應用程式、不碰滑鼠、不離開鍵盤。 ...

2026年3月4日 · 5 min · 997 words · Jack