본문 바로가기
C.W.K.
Stream
Lesson 02 of 04 · published

Treesitter와 Telescope — 구조 + 찾기

~15 min · neovim, treesitter, telescope

Level 0갇힌 자
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

Treesitter — 코드를 패턴이 아니라 트리로

Vim의 옛 syntax 표시는 regex 기반이야. 토큰 종류를 패턴으로 맞춰서 색을 칠하는 거지. 돌아가긴 하는데 코드를 이해하지는 못해. Treesitter는 코드를 진짜 Abstract Syntax Tree (AST) 로 파싱해서 그걸 색 표시와 들여쓰기와 구조 단위 text object에 써. 더 빠르고, 더 정확하고, regex로는 꿈도 못 꿀 것들을 열어줘.

Treesitter가 실제로 주는 것

  • 더 나은 색 표시 — 문자열 안의 보간, JSX 중첩, Markdown 코드 블록까지 제대로 칠해줘.
  • 똑똑한 들여쓰기 — 맥락이 중요한 언어에서 (Python, Lua, JSX).
  • 점점 넓혀가는 선택Ctrl-Space를 누를 때마다 선택이 AST 노드 한 단계씩 넓어져. 단어에서 표현식으로, 문장으로, 함수로. Visual 선택에서는 거의 마법이야.
  • 구조 단위 text object — 짝 plugin인 nvim-treesitter-textobjects를 얹으면 af (함수 통째로), if (함수 안쪽), ac (클래스 통째로), ic (클래스 안쪽) 를 쓸 수 있어. operator와 붙이면 daf는 함수를 통째로 지우고 cif는 함수 본문을 갈아끼워.
  • syntax로 접기 — regex로 대충 흉내 낸 게 아니라 코드를 이해하는 진짜 fold야.

Telescope — 뭐든 찾아주는 fuzzy finder

telescope.nvim이 fuzzy finder야. 파일, buffer, grep 결과, LSP 심볼, 최근 파일, 도움말 태그, git 브랜치, 명령 기록까지 — "고를 수 있는 목록"이 있는 건 뭐든 Telescope 화면으로 띄울 수 있어. 쓰는 방식은 전부 같아. 화면이 뜨고, 치면 걸러지고, Enter로 고르는 거야.

매일 쓰게 될 것들

  • find_files — 파일 fuzzy 찾아 열기. Cmd-P 자리야.
  • live_grep — 프로젝트 전체에서 파일 내용 검색. Cmd-Shift-F 자리고.
  • buffers — 열린 buffer 사이 이동.
  • oldfiles — 최근 연 파일 (Neovim을 껐다 켜도 남아).
  • lsp_document_symbols — 지금 파일의 개요 (함수, 클래스).
  • lsp_workspace_symbols — 프로젝트 전체에서 심볼 검색.
  • diagnostics — LSP 에러와 경고, 걸러서 보기.
  • help_tags — Neovim 도움말을 fuzzy로 검색.
Telescope 하나가 메뉴 셋을 대신해. 명령 팔레트, 파일 열기 대화창, 전체 검색 패널이 키 하나짜리 패턴으로 합쳐져. <leader>ff, <leader>fg, <leader>fb가 손에 붙고 나면 어떤 프로젝트에서 뭘 열든 키 두 번에 몇 글자면 끝이야.

Code

Treesitter — 풀 셋업·lua
{
  "nvim-treesitter/nvim-treesitter",
  build = ":TSUpdate",
  event = { "BufReadPost", "BufNewFile" },
  dependencies = {
    "nvim-treesitter/nvim-treesitter-textobjects",
  },
  config = function()
    require("nvim-treesitter.configs").setup({
      ensure_installed = {
        "lua", "python", "javascript", "typescript", "tsx",
        "html", "css", "json", "yaml", "toml", "bash",
        "markdown", "markdown_inline", "vim", "vimdoc", "regex",
      },
      auto_install = true,
      highlight = { enable = true },
      indent = { enable = true },
      incremental_selection = {
        enable = true,
        keymaps = {
          init_selection    = "<C-space>",
          node_incremental  = "<C-space>",
          scope_incremental = "<C-s>",
          node_decremental  = "<BS>",
        },
      },
      textobjects = {
        select = {
          enable = true,
          lookahead = true,
          keymaps = {
            ["af"] = "@function.outer",
            ["if"] = "@function.inner",
            ["ac"] = "@class.outer",
            ["ic"] = "@class.inner",
            ["aa"] = "@parameter.outer",
            ["ia"] = "@parameter.inner",
          },
        },
        move = {
          enable = true,
          set_jumps = true,
          goto_next_start = {
            ["]f"] = "@function.outer",
            ["]c"] = "@class.outer",
          },
          goto_previous_start = {
            ["[f"] = "@function.outer",
            ["[c"] = "@class.outer",
          },
        },
      },
    })
  end,
}
Telescope — 일상 사용 키맵 풀 셋업·lua
{
  "nvim-telescope/telescope.nvim",
  cmd = "Telescope",
  dependencies = {
    "nvim-lua/plenary.nvim",
    { "nvim-telescope/telescope-fzf-native.nvim", build = "make" },
  },
  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 = "Buffers" },
    { "<leader>fh", "<cmd>Telescope help_tags<CR>",   desc = "Help" },
    { "<leader>fr", "<cmd>Telescope oldfiles<CR>",    desc = "Recent files" },
    { "<leader>fd", "<cmd>Telescope diagnostics<CR>", desc = "Diagnostics" },
    { "<leader>fs", "<cmd>Telescope lsp_document_symbols<CR>", desc = "Symbols (file)" },
    { "<leader>fS", "<cmd>Telescope lsp_workspace_symbols<CR>", desc = "Symbols (project)" },
    { "<leader>/",  "<cmd>Telescope current_buffer_fuzzy_find<CR>", desc = "Search buffer" },
  },
  opts = {
    defaults = {
      file_ignore_patterns = { "node_modules", ".git/" },
      layout_strategy = "flex",
    },
  },
  config = function(_, opts)
    require("telescope").setup(opts)
    pcall(require("telescope").load_extension, "fzf")
  end,
}
Treesitter text object 작동·vim
daf       " a 함수 삭제 (시그니처 포함 통째로)
dif       " 함수 안 삭제 (본문만)
vac       " a 클래스 visual select
yif       " 함수 본문 yank
]f        " 다음 함수 시작으로
[f        " 이전 함수 시작으로
]c        " 다음 클래스 시작으로
[c        " 이전 클래스 시작으로

External links

Exercise

위 treesitter와 telescope 블록을 깔고 진짜 코드베이스를 열어. (1) <leader>ff에 파일명 몇 글자를 쳐서 열어보기. (2) <leader>fg에 한 파일에만 있는 문자열을 쳐서 바로 뛰어보기. (3) 함수 안에서 Ctrl-Space를 반복해 누르며 선택이 AST 노드를 따라 자라는 걸 보기. (4) daf로 함수를 통째로 지워보기. 하나하나가 "이거 없이 그동안 어떻게 했지" 싶어야 정상이야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.