Neovim · Part 4 — Files, Buffers, Windows và Tabs
Không lạc trong project lớn: hiểu file, buffer, window, tab, quickfix, arglist và workflow mở/sửa nhiều file trong Neovim.
Một cú sốc khi chuyển từ VSCode sang Neovim: bạn không còn sidebar/tab UI quen thuộc. Nhưng Neovim có model riêng, rất mạnh nếu hiểu đúng.
Ba khái niệm:
| Khái niệm | Nghĩa |
|---|---|
| File | dữ liệu trên disk |
| Buffer | file đang được Nvim giữ trong memory |
| Window | viewport nhìn vào một buffer |
| Tab page | một layout gồm nhiều window |
Sai lầm phổ biến: nghĩ tab của Nvim giống tab file của VSCode. Không phải. Buffer là file tab, còn tab page là workspace layout.
Buffer
Mở file:
:edit src/main.ts
Danh sách buffer:
:buffers
Chuyển buffer:
| Lệnh | Ý nghĩa |
|---|---|
:bnext | buffer kế |
:bprevious | buffer trước |
:buffer 3 | tới buffer số 3 |
:buffer main | fuzzy nhẹ theo tên |
:bdelete | đóng buffer |
Keymap nên có:
vim.keymap.set("n", "<leader>bn", "<cmd>bnext<CR>", { desc = "Next buffer" })
vim.keymap.set("n", "<leader>bp", "<cmd>bprevious<CR>", { desc = "Previous buffer" })
vim.keymap.set("n", "<leader>bd", "<cmd>bdelete<CR>", { desc = "Delete buffer" })
Sau này picker sẽ thay nhiều lệnh buffer, nhưng hiểu lệnh gốc giúp bạn debug tốt hơn.
Window split
Window là vùng nhìn. Một buffer có thể xuất hiện trong nhiều window cùng lúc.
| Lệnh | Ý nghĩa |
| --------- | ------------- | ----------- |
| :split | split ngang |
| :vsplit | split dọc |
| <C-w>h | qua trái |
| <C-w>j | xuống |
| <C-w>k | lên |
| <C-w>l | qua phải |
| <C-w>= | cân bằng size |
| <C-w>_ | cao tối đa |
| <C-w> | | rộng tối đa |
| <C-w>q | đóng window |
Map di chuyển window bằng Ctrl:
vim.keymap.set("n", "<C-h>", "<C-w>h", { desc = "Left window" })
vim.keymap.set("n", "<C-j>", "<C-w>j", { desc = "Lower window" })
vim.keymap.set("n", "<C-k>", "<C-w>k", { desc = "Upper window" })
vim.keymap.set("n", "<C-l>", "<C-w>l", { desc = "Right window" })
Workflow thường dùng:
- trái: file đang sửa;
- phải: definition/test/docs;
- dưới: terminal hoặc quickfix.
Tab page
Tab page là layout. Dùng khi bạn muốn giữ nhiều bố cục:
- tab 1: code feature;
- tab 2: test/log;
- tab 3: docs/config.
| Lệnh | Ý nghĩa |
|---|---|
:tabnew | tab mới |
:tabedit file | mở file trong tab mới |
gt | tab kế |
gT | tab trước |
:tabclose | đóng tab |
Đừng mở 20 tab cho 20 file. Hãy dùng buffers + picker.
File explorer theo kiểu Nvim
Bạn có ba hướng:
- không dùng tree, dùng fuzzy finder;
- dùng file explorer dạng buffer như
oil.nvim; - dùng tree UI kiểu
nvim-treehoặcneo-tree.
Khuyến nghị cho người chuyển từ VSCode: bắt đầu với fuzzy finder + oil.nvim.
Vì sao oil.nvim hợp Vim? Nó biến thư mục thành buffer. Rename, move, delete giống sửa text rồi save.
Ví dụ spec sau này:
{
"stevearc/oil.nvim",
opts = {
default_file_explorer = true,
view_options = { show_hidden = true },
},
keys = {
{ "-", "<cmd>Oil<CR>", desc = "Open parent directory" },
},
}
Quickfix và location list
Quickfix là danh sách kết quả toàn cục: grep, compile errors, diagnostics, references.
| Lệnh | Ý nghĩa |
|---|---|
:copen | mở quickfix |
:cclose | đóng quickfix |
:cnext | kết quả kế |
:cprev | kết quả trước |
:cfirst | kết quả đầu |
:clast | kết quả cuối |
Location list giống quickfix nhưng gắn với window hiện tại:
| Lệnh | Ý nghĩa |
|---|---|
:lopen | mở location list |
:lnext | kết quả kế |
:lprev | kết quả trước |
Neovim 0.11+ có nhiều mapping mặc định kiểu unimpaired cho quickfix/location list, như ]q, [q, ]l, [l. Bạn nên thử trước khi tự map quá nhiều.
Arglist
Arglist là danh sách file cho một phiên edit có chủ đích:
:args src/**/*.ts
:argdo %s/oldName/newName/ge | update
Đây là công cụ mạnh cho refactor hàng loạt. Nhưng dùng cẩn thận: luôn kiểm tra Git diff sau khi chạy.
Cheatsheet điều hướng project
| Việc | Lệnh gốc | Sau này dùng plugin |
|---|---|---|
| Mở file | :edit | picker files |
| Xem buffer | :buffers | picker buffers |
| Tìm text project | :grep | live grep |
| Kết quả grep | :copen | quickfix UI |
| Split dọc | :vsplit | keymap |
| Mở thư mục cha | :edit . | oil.nvim |
| Đóng buffer | :bdelete | mini.bufremove |
Bài tập
- Mở 4 file bằng
:edit. - Dùng
:buffers, chuyển qua lại bằng:buffer. - Tạo split trái/phải, mở cùng một buffer ở hai window.
- Mở quickfix bằng
:copen, đóng bằng:cclose. - Tạo tab mới cho một layout khác, rồi quay lại bằng
gT.
Lời giải gợi ý
:edit package.json
:edit src/content.config.ts
:edit src/lib/series.ts
:buffers
:buffer series
:vsplit
<C-w>l
:edit README.md
:tabnew
:edit astro.config.mjs
gTĐiều cốt lõi
Trong Neovim, buffer là file đang mở, window là góc nhìn, tab là layout. Khi model này rõ, bạn sẽ không còn cần tab bar kiểu VSCode để biết mình đang ở đâu.