jvinhit//lab

Search posts

Type to search across journal entries.

navigate open esc close

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ệmNghĩa
Filedữ liệu trên disk
Bufferfile đang được Nvim giữ trong memory
Windowviewport nhìn vào một buffer
Tab pagemộ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
:bnextbuffer kế
:bpreviousbuffer trước
:buffer 3tới buffer số 3
:buffer mainfuzzy 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
:tabnewtab mới
:tabedit filemở file trong tab mới
gttab kế
gTtab 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:

  1. không dùng tree, dùng fuzzy finder;
  2. dùng file explorer dạng buffer như oil.nvim;
  3. dùng tree UI kiểu nvim-tree hoặc neo-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
:copenmở quickfix
:ccloseđóng quickfix
:cnextkết quả kế
:cprevkết quả trước
:cfirstkết quả đầu
:clastkết quả cuối

Location list giống quickfix nhưng gắn với window hiện tại:

LệnhÝ nghĩa
:lopenmở location list
:lnextkết quả kế
:lprevkế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ệcLệnh gốcSau này dùng plugin
Mở file:editpicker files
Xem buffer:bufferspicker buffers
Tìm text project:greplive grep
Kết quả grep:copenquickfix UI
Split dọc:vsplitkeymap
Mở thư mục cha:edit .oil.nvim
Đóng buffer:bdeletemini.bufremove

Bài tập

  1. Mở 4 file bằng :edit.
  2. Dùng :buffers, chuyển qua lại bằng :buffer.
  3. Tạo split trái/phải, mở cùng một buffer ở hai window.
  4. Mở quickfix bằng :copen, đóng bằng :cclose.
  5. 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.