Neovim 中的浮動 TUI 工具 (Floating TUI Tools)¶
Terminology rule (zh-TW pages)
技術名詞首次出現以「中文 (English original)」格式呈現,例:依賴注入
(dependency injection)。不自創翻譯——若無公認譯名直接保留英文
(如 embedding、tokenizer)。代碼、API 名、CLI flag、套件名、檔名一律不翻。
提供 TUI 工具的浮動終端視窗 (floating terminal windows),由 Snacks.terminal 驅動(隨 LazyVim 一起捆綁)。
運作方式¶
所有 TUI 的快捷鍵 (keymaps) 都放在 lua/plugins/floating-tui.lua。每個工具都是單一個 Snacks.terminal.toggle(cmd, opts) 呼叫——不需要自訂的 Lua 模組 (module)。Snacks 會處理:
- 浮動視窗的生命週期 (lifecycle)(建立、顯示、隱藏、調整大小)
- 終端 session 持久化 (persistence)(用
q隱藏、用相同快捷鍵重新開啟) - 連按兩次 Esc 離開終端的 insert mode
- 程式結束時自動清理
這也是 <leader>gg(透過 Snacks.lazygit() 啟動 LazyGit)背後的相同機制。
預設快捷鍵¶
| 快捷鍵 | 工具 | 類別 |
|---|---|---|
<leader>gg |
LazyGit | Git(LazyVim 內建) |
<leader>zg |
gh dash | Git / GitHub |
<leader>zs |
sqlit | 資料庫 |
<leader>fy |
yazi | 檔案管理員 |
<leader>zb |
btop | 系統監控 |
<leader>zd |
lazydocker | 容器 |
<leader>zi |
ipython | REPL |
在浮動 TUI 視窗內:
- 連按兩次 Esc — 離開終端 insert mode(回到 normal mode)
- q(normal mode) — 隱藏視窗,程式持續執行
- 再次按下相同快捷鍵 — 重新開啟已隱藏的視窗
關於 <leader>zg 背後託管的 gh-dash / diffnav / lazygit 設定,請見 Git Diff 工作流程。
新增一個 TUI¶
在 lua/plugins/floating-tui.lua 的 keys 表格中加一筆:
{
"<leader>zX",
function()
Snacks.terminal.toggle("mytool", {
win = { title = " mytool " },
})
end,
desc = "MyTool",
},
常見選項¶
Snacks.terminal.toggle(cmd, {
cwd = vim.uv.cwd(), -- 工作目錄
cwd = LazyVim.root.git(), -- 或使用 git 根目錄
env = { FOO = "bar" }, -- 環境變數
auto_close = false, -- 程式結束後保留視窗(適用於短生命週期工具)
win = {
title = " tool name ", -- 浮動視窗標題
width = 0.9, -- 0-1 = 比例,>1 = 欄數
height = 0.9,
border = "rounded", -- "rounded", "double", "single", "none"
position = "float", -- "float"(cmd 預設), "bottom", "left", "right"
},
})
多字命令¶
要傳入帶參數的命令時,使用 table:
Snacks.terminal.toggle({ "gh", "dash" }, { ... })
Snacks.terminal.toggle({ "psql", "postgres://localhost/mydb" }, { ... })
會快速離開的工具¶
某些工具(如 sqlit)可能會結束並顯示 [Process exited 0]。設定 auto_close = false 可保留視窗顯示,方便檢查輸出。關閉後下次切換 (toggle) 會建立新的實例 (instance)。
具有類 Vim 鍵綁定的工具¶
把 Esc 用於內部按鍵的工具(例如 sqlit 的 vim mode)能與 Snacks 的 double-Esc 計時器良好搭配——單次 Esc 會送到 TUI,在 200ms 內再按一次 Esc 才會離開終端 insert mode。
使用 q 退出的工具¶
預設情況下,Snacks 會把 normal mode 中的 q 對映到隱藏浮動視窗(程式持續執行)。然而某些 TUI 工具(如 sqlit)會把 q 當成自己的 quit 命令,這會結束程式。
衝突點: 若你按 Double-Esc 回到 Neovim 的 normal mode 並按下 q,Snacks 會隱藏視窗——但若你還在終端 insert mode 時按 q,TUI 會收到該按鍵並可能直接結束程式。
解法: 把 Snacks 的隱藏鍵 (hide key) 重新對映到 <C-q>,這樣 q 永遠不會被 Snacks 攔截:
Snacks.terminal.toggle("sqlit", {
win = {
title = " sqlit ",
keys = {
q = false, -- 停用預設的 q-to-hide
hide = { "<C-q>", "hide", mode = "n" }, -- 改用 Ctrl-q 來隱藏
},
},
auto_close = false,
})
這類工具的工作流程:
- 連按兩次 Esc — 離開終端 insert mode
- Ctrl-q(normal mode) — 隱藏視窗,程式持續執行
- 相同快捷鍵(例如
<leader>zs) — 重新開啟已隱藏的視窗
這個模式適用於任何 q 帶有特殊意義的 TUI 工具(例如資料庫 client、互動式檢視器)。
何時改用專用外掛 (Dedicated Plugin)¶
對大多數 TUI 工具來說,Snacks.terminal.toggle 已經足夠。在以下情況才考慮專用外掛:
- 深度 Neovim 整合 — 例如
Snacks.lazygit()會自動設定 colorscheme 主題與 nvim-remote 編輯 - 檔案選擇 callback — 例如 yazi.nvim 可在 Neovim buffer 中開啟所選檔案
- 輸出解析 / RPC — 需要把結構化資料 (structured data) 送回 Neovim 的工具
| 工具 | 通用 (Snacks) | 專用外掛 |
|---|---|---|
| lazygit | OK | Snacks.lazygit()(內建,推薦) |
| yazi | 瀏覽用 OK | 若需要 file-open callbacks 則用 yazi.nvim |
| gh dash | OK | 若每天使用則用 gh-dash.nvim |
| btop, htop, k9s 等 | 推薦 | N/A |