jvinhit//lab

Search posts

Type to search across journal entries.

navigate open esc close

Neovim · Part 8 — Search, Navigation và Refactor

Thay Command Palette của VSCode bằng picker, live grep, quickfix, LSP references, symbols, rename và workflow refactor an toàn.

Nếu modal editing là tốc độ trong một file, thì search/navigation là tốc độ trong cả project.

VSCode có Cmd+P, sidebar search, symbol search. Neovim có:

  • fuzzy finder;
  • live grep bằng ripgrep;
  • quickfix/location list;
  • LSP references/symbols;
  • :grep, :vimgrep, :cdo, :argdo.

Chọn picker

Hai lựa chọn phổ biến:

  • Telescope: lâu đời, nhiều extension, dễ học.
  • Snacks picker: mới hơn, tích hợp trong bộ QoL của Folke.

Series này dùng Telescope vì dễ giải thích và tài liệu dồi dào. Khi đã vững, bạn có thể đổi picker mà không đổi mental model.


Setup Telescope

Tạo lua/plugins/search.lua:

return {
  {
    "nvim-telescope/telescope.nvim",
    dependencies = {
      "nvim-lua/plenary.nvim",
      {
        "nvim-telescope/telescope-fzf-native.nvim",
        build = "make",
        cond = function()
          return vim.fn.executable("make") == 1
        end,
      },
    },
    cmd = "Telescope",
    keys = {
      { "<leader>ff", "<cmd>Telescope find_files<CR>", desc = "Find files" },
      { "<leader>fg", "<cmd>Telescope live_grep<CR>", desc = "Live grep" },
      { "<leader>fb", "<cmd>Telescope buffers<CR>", desc = "Find buffers" },
      { "<leader>fh", "<cmd>Telescope help_tags<CR>", desc = "Help tags" },
      { "<leader>fs", "<cmd>Telescope lsp_document_symbols<CR>", desc = "Document symbols" },
      { "<leader>fr", "<cmd>Telescope lsp_references<CR>", desc = "References" },
    },
    config = function()
      local telescope = require("telescope")
      telescope.setup({
        defaults = {
          mappings = {
            i = {
              ["<C-j>"] = "move_selection_next",
              ["<C-k>"] = "move_selection_previous",
            },
          },
        },
      })
      pcall(telescope.load_extension, "fzf")
    end,
  },
}

Cài ripgrepfd để picker nhanh:

brew install ripgrep fd
# hoặc apt/dnf/pacman tùy hệ điều hành

Mapping từ VSCode

VSCodeNvim
Cmd+P / Ctrl+P<leader>ff
Search toàn project<leader>fg
Open symbol in file<leader>fs hoặc gO
Find referencesgrr hoặc <leader>fr
Rename symbolgrn
Code actiongra
Problems paneldiagnostics location list

Bạn không cần sidebar file tree nếu find_fileslive_grep đã thành phản xạ.


Quickfix là superpower

Live grep đẹp, nhưng quickfix mới là công cụ refactor mạnh.

Grep bằng lệnh gốc:

:grep TODO src
:copen

Đi qua kết quả:

:cnext
:cprev

Thay đổi hàng loạt:

:cdo s/oldName/newName/g | update

Cẩn thận: :cdo chạy trên mọi entry trong quickfix. Trước khi dùng, hãy kiểm tra danh sách và đảm bảo Git sạch hoặc diff dễ review.


Search trong file

LệnhÝ nghĩa
/textsearch forward
?textsearch backward
nkết quả kế
Nkết quả trước
*search word dưới cursor
#search word dưới cursor ngược lại
:%s/a/b/greplace toàn file
:%s/a/b/gcreplace toàn file có confirm

Khi replace, thêm c để confirm:

:%s/useState/useSignal/gc

Refactor an toàn bằng LSP

ViệcLệnh
Rename symbolgrn
Code actiongra
Referencesgrr
Implementationgri
Type definitiongrt trên Nvim mới
Document symbolsgO

Refactor workflow:

  1. chạy test trước nếu có;
  2. dùng LSP rename thay vì search/replace khi đổi symbol;
  3. dùng live grep kiểm tra tên cũ;
  4. chạy formatter/linter;
  5. xem Git diff.

Search/replace tốt cho text. Rename symbol tốt cho code.


Project navigation không cần sidebar

Một workflow nhanh:

  1. <leader>ff mở file.
  2. <leader>fg tìm text.
  3. grr xem references.
  4. gO xem symbol trong file.
  5. :copen xử lý danh sách kết quả.
  6. <C-o> quay lại vị trí cũ, <C-i> tiến tới vị trí sau.

Jump list rất đáng học:

KeyÝ nghĩa
<C-o>jump back
<C-i>jump forward
:jumpsxem jump list
mAđặt mark A
'Aquay lại mark A

Bài tập

  1. Cài Telescope.
  2. Dùng <leader>ff mở 5 file khác nhau.
  3. Dùng <leader>fg tìm một function đang được dùng nhiều nơi.
  4. Đẩy kết quả grep vào quickfix, mở :copen.
  5. Dùng LSP rename một biến local, rồi live grep tên cũ.
Gợi ý

Nếu bạn đang ở repo frontend, tìm useEffect, fetch, hoặc tên component. Đừng refactor symbol public lớn ngay. Luyện với biến local trước.


Điều cốt lõi

Search pro trong Neovim là sự kết hợp giữa picker để tìm nhanh, quickfix để xử lý danh sách, và LSP để refactor đúng ngữ nghĩa. Ba lớp này thay gần hết Command Palette/Search panel của VSCode.