Skip to content

필사 모드: LSP & Tree-sitter 생태계 2026 — ast-grep / Biome / Helix / Zed / Neovim Treesitter / 언어별 LSP 심층 가이드

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

프롤로그 — 코드 도구의 양대 표준

2010년대의 에디터 전쟁은 단순했다. **"어떤 앱을 쓰느냐"** 가 거의 모든 것을 결정했다. VS Code인가, JetBrains인가, Vim인가, Emacs인가. 각자 자기만의 자동완성·정의 이동·리팩토링·문법 강조를 따로 구현했고, 새 언어가 나오면 **에디터 x 언어** 만큼의 작업이 매번 필요했다.

2026년의 그림은 완전히 다르다. 에디터·IDE의 진짜 무게중심은 **두 개의 프로토콜·라이브러리**로 옮겨갔다.

| 표준 | 무엇을 표준화했나 | 누가 만들었나 |

| --- | --- | --- |

| **LSP** (Language Server Protocol) | 코드 "지능" — 자동완성·정의 이동·리네임·진단·포맷 | Microsoft (2016) |

| **Tree-sitter** | 코드 "구조" — 증분 파서·문법 강조·구조 인식 | Max Brunsfeld (GitHub, 2018~) |

지난 10년의 함의는 분명하다. **에디터를 만드는 것보다, 표준에 붙는 것이 압도적으로 싸다.** 그래서 Helix와 Zed처럼 새로 등장한 에디터들은 처음부터 LSP + Tree-sitter를 **빌트인**으로 짠다. Neovim은 0.5부터 LSP 클라이언트를 코어에 내장했고, VS Code는 처음부터 LSP의 레퍼런스 클라이언트였다.

그리고 이 두 표준 위에 새로운 생태계가 폭발적으로 자라고 있다 — **ast-grep**(Tree-sitter 기반 구조 검색·리라이트), **BiomeJS**(Rust로 다시 짠 JS 툴체인), **Marksman**(Markdown LSP), **Semgrep / CodeQL**(보안·정책 검색), **Comby**(언어 중립 리라이트). 이 글은 그 전부를 한 권으로 정리한다.

1장 · LSP — Microsoft 표준의 자리

1.1 왜 LSP가 필요했나

2015년 이전: 새 언어를 지원하려면 에디터마다 따로 플러그인을 짜야 했다.

| 에디터 | 언어 | 결과 |

| --- | --- | --- |

| VS Code | TypeScript | 플러그인 A |

| Vim | TypeScript | 플러그인 B (재구현) |

| Emacs | TypeScript | 플러그인 C (재구현) |

| Atom | TypeScript | 플러그인 D (재구현) |

언어가 M개, 에디터가 N개면 M x N개의 플러그인이 필요했다. 게다가 각 플러그인이 "정의 이동"이나 "리네임" 같은 기능을 다시 구현해야 했고, 품질은 천차만별이었다.

**Microsoft의 통찰**: 코드 분석 로직을 **별도 프로세스(언어 서버)** 로 분리하고, 에디터와 서버가 **표준 JSON-RPC 메시지**로 대화하게 하면, M + N으로 줄어든다.

1.2 LSP 핵심 메시지

| 메시지 | 무엇을 묻나 |

| --- | --- |

| `textDocument/completion` | 커서 위치의 자동완성 후보 |

| `textDocument/definition` | 심볼의 정의 위치 |

| `textDocument/references` | 심볼을 참조하는 모든 위치 |

| `textDocument/hover` | 커서 위 심볼의 타입·문서 |

| `textDocument/rename` | 심볼 이름 일괄 변경 |

| `textDocument/formatting` | 코드 포맷 |

| `textDocument/codeAction` | 빠른 수정·리팩토링 제안 |

| `textDocument/publishDiagnostics` | 서버 -> 클라이언트 (에러·경고) |

전송 계층은 기본적으로 stdin/stdout JSON-RPC 2.0이다. TCP·소켓도 가능하지만 stdio가 표준이다.

1.3 LSP의 한 줄 그림

┌──────────────┐ ┌─────────────────────┐

│ 에디터 │ JSON │ 언어 서버 (LSP) │

│ (클라이언트) │◀────────▶│ rust-analyzer 등 │

│ VS Code, │ RPC │ (별도 프로세스) │

│ Helix, Zed, │ │ │

│ Neovim ... │ │ - 파싱 │

└──────────────┘ │ - 타입 추론 │

│ - 인덱싱 │

└─────────────────────┘

에디터 쪽은 **얇아진다**. 언어 서버 쪽은 **두꺼워진다**. 그리고 한 번 잘 짠 서버는 모든 에디터에서 쓸 수 있다.

1.4 2026년 LSP의 위상

- **모든 진지한 에디터가 LSP 클라이언트를 내장.** VS Code, JetBrains, Helix, Zed, Neovim, Emacs (eglot), Sublime.

- **모든 활발한 언어가 자기 LSP 서버를 가짐.** rust-analyzer, gopls, pyright, typescript-language-server, clangd 등.

- **벤더 락인이 사라진 영역.** 더 이상 "VS Code에서만 잘 되는 언어 지원"이라는 말이 어색하다.

2장 · Tree-sitter — Max Brunsfeld의 증분 파서

2.1 정규식 강조의 한계

2010년대 중반까지, 거의 모든 에디터의 문법 강조는 **정규식**이었다. TextMate 문법 (.tmLanguage) 같은 형식이 사실상 표준이었다.

문제:

- **거짓말한다.** 정규식은 진짜 파서가 아니라서, 중첩된 문자열·복잡한 보간·매크로에서 무너진다.

- **느리다.** 큰 파일에서 매 키 입력마다 다시 매칭한다.

- **에러에 약하다.** 코드가 잠시 깨졌을 때 강조가 통째로 망가진다.

2.2 Tree-sitter의 답

**Max Brunsfeld**(Atom 출신, GitHub)가 만든 Tree-sitter는 다음을 동시에 푼다.

1. **증분(incremental)**. 키 입력 한 번에 트리 전체를 다시 파싱하지 않고, 바뀐 부분만 재파싱한다.

2. **에러 복구.** 코드가 일시적으로 깨져도 가능한 만큼 파싱하고 나머지는 에러 노드로 둔다.

3. **일반화된 LR**(GLR) 알고리즘. 모호한 문법도 처리.

4. **언어 중립.** 문법은 DSL(JS 비슷한 문법 정의)로 쓰고, 파서는 C로 생성된다.

5. **빠르다.** 진짜 파서면서도 강조 용도로 충분히 빠르다.

2.3 어디에 쓰는가

- **문법 강조**: 진짜 AST 기반이라 정확하다.

- **코드 폴딩**: 함수·블록을 구조 기반으로 접는다.

- **구조 선택**: "함수 전체 선택", "표현식 단위 확장 선택" 같은 동작.

- **검색·리라이트**: 텍스트가 아니라 AST 노드로 쿼리한다 (ast-grep, Comby).

- **하이라이트 외 인덱싱**: 함수·클래스·임포트 목록 추출.

2.4 누가 쓰나

| 도구 | Tree-sitter 사용처 |

| --- | --- |

| **Neovim** | nvim-treesitter 플러그인 — 강조·폴딩·구조 텍스트 객체 |

| **Helix** | 빌트인. 강조·들여쓰기·구조 모션 전부 TS 기반 |

| **Zed** | 빌트인. 강조·아웃라인·구조 검색 |

| **GitHub** | 코드 검색·강조·심볼 추출 |

| **ast-grep** | 구조 검색·리라이트 엔진 |

| **Difftastic** | 구조 인식 diff |

2.5 grammar의 분포

`tree-sitter-rust`, `tree-sitter-python`, `tree-sitter-typescript` ... 거의 모든 인기 언어가 별도 npm/crates 패키지로 grammar를 제공한다. 새 언어를 지원하려면 grammar만 새로 짜면 되고, 강조 쿼리(.scm)는 짧다.

3장 · ast-grep (sg) — 구조적 검색/리라이트

3.1 grep의 한계, ast-grep의 답

`grep`은 텍스트 매칭이다. **"console.log를 호출하는 모든 곳"** 을 찾으면, 주석·문자열·doc 안의 console.log도 같이 잡힌다. 게다가 **"console.log의 첫 인자가 객체인 곳만"** 같은 질문은 정규식으로는 사실상 불가능하다.

ast-grep(`sg`)는 다르다. **Tree-sitter로 파싱한 AST 위에서** 패턴을 매칭한다. 패턴 언어는 그 언어 자체의 코드처럼 보이고, `$VAR`로 메타변수를 둔다.

3.2 누가 만들었나, 무엇이 새로운가

- **Herrington Darkholme** 가 Rust로 작성.

- 2024년에 외부 투자(시드 라운드)를 받으며, "ast-grep 회사"로 본격 확장 — 엔터프라이즈 코드 마이그레이션·정책 검색이 타깃.

- Rust + Tree-sitter 조합이라 **빠르고**, 모든 Tree-sitter 지원 언어에서 동작.

3.3 패턴 예시

console.log를 어떤 인자로든 호출한 모든 곳

sg --pattern 'console.log($A)' --lang typescript

첫 인자가 객체 리터럴인 호출만

sg --pattern 'console.log({ $$$ })' --lang typescript

리라이트: console.log(x) -> logger.debug(x)

sg --pattern 'console.log($A)' --rewrite 'logger.debug($A)' --lang typescript --update-all

`$A`는 임의의 표현식 하나, `$$$`는 임의의 노드 목록을 잡는 메타변수다.

3.4 sgconfig.yml — 코드베이스 정책

ast-grep은 **YAML 룰셋**으로 팀 정책을 저장할 수 있다. CI에서 룰셋을 돌리면 "이 패턴을 쓰지 마라" 같은 정책이 자동 검사된다.

id: no-direct-fetch

language: typescript

rule:

pattern: fetch($URL)

message: "fetch 대신 apiClient.get을 쓰세요"

severity: warning

3.5 어디에 적합한가

- **대규모 리팩토링.** "이 API 호출 패턴을 새 SDK로 일괄 마이그레이션." 손으로 하면 일주일, ast-grep으로는 몇 분.

- **코드베이스 정책.** "이 모듈에서 console.log 금지", "useEffect 안에 fetch 금지" 같은 규칙.

- **거대한 코드베이스 탐색.** "이 패턴을 쓰는 모든 곳" 같은 질문에 grep보다 훨씬 정확.

4장 · BiomeJS — ESLint + Prettier 대체

4.1 JS 툴체인의 누적된 문제

2010년대 중반 이후 JS 개발자가 반드시 쓰던 두 도구:

- **ESLint** — 코드 품질 린트 (JS로 작성)

- **Prettier** — 코드 포맷터 (JS로 작성)

둘 다 훌륭하지만:

- **느리다.** 거대한 모노레포에서 Lint 30초, 포맷 10초가 일상.

- **설정이 복잡하다.** ESLint config가 plugin·preset·rule의 미로.

- **둘이 따로 돈다.** ESLint --fix와 Prettier가 충돌해서 추가 플러그인이 필요.

- **타입 정보 없이 동작.** AST 수준 검사라 한계가 있다.

4.2 Biome의 접근

**Biome**(원래 Rome 프로젝트에서 분리·재출범)은 다음을 묶었다.

- **Rust로 작성** — 같은 코드에 대해 ESLint+Prettier 대비 수십~수백 배 빠르다.

- **단일 바이너리** — Lint + 포맷 + 임포트 정리 + 코드 액션이 한 도구.

- **거의 제로 설정** — 좋은 기본값. `biome.json` 한 파일.

- **LSP 서버 내장** — 에디터 통합이 자체 제공.

4.3 한 줄로 보는 차이

전통적

eslint . --fix && prettier --write .

Biome

biome check . --apply

4.4 한계

- **TypeScript 전용 룰은 ESLint가 여전히 더 풍부**(2026년 기준 빠르게 줄어드는 중).

- **커스텀 룰**: ESLint가 더 성숙. Biome도 v2부터 플러그인 시스템 확장.

- **Vue·Svelte 같은 비표준 문법**: 지원 중이지만 ESLint 만큼 깊지 않을 때가 있다.

그래도 **신규 JS/TS 프로젝트의 기본값**은 빠르게 Biome로 이동하고 있다.

5장 · Marksman — Markdown LSP

5.1 Markdown도 LSP가 필요한가

처음엔 의외다. 마크다운은 그냥 텍스트인데? 하지만 마크다운을 본격적으로 쓰는 위키·노트·블로그·문서 사이트에서는 다음이 필요하다.

- 문서 간 링크의 **정의 이동** (`[foo](./other.md)` 가서 열기).

- 헤딩·앵커·이미지의 **자동완성**.

- 깨진 링크의 **진단**.

- 백링크 추적.

- 이름 변경 시 모든 참조 일괄 수정.

이게 LSP의 정확한 사용처다.

5.2 Marksman의 자리

**Marksman**(F# 작성)은 마크다운 전용 LSP 서버다. Helix·Zed·Neovim·VS Code 모두에서 동작한다.

- `[[wiki-link]]` 와 `[text](path.md)` 양쪽을 지원.

- 헤딩 자동완성: `[#`까지 치면 가능한 헤딩 목록.

- 깨진 링크 표시.

- 헤딩 리네임이 모든 참조에 전파.

- 워크스페이스 심볼: 모든 헤딩이 검색 가능.

5.3 비슷한 도구

- **zk-lsp** — Zettelkasten 스타일 노트.

- **Obsidian** — 자체 인덱서지만, 외부 에디터에서 같은 vault를 다룰 때 Marksman이 표준이다.

6장 · Helix 에디터 — built-in LSP + Tree-sitter

6.1 Helix의 디자인 결정

**Helix**는 Rust로 짠 모달 에디터다. Vim/Kakoune의 후예이지만 결정적인 차이가 있다.

- **빌트인 LSP 클라이언트.** 플러그인 없음. `languages.toml`에 서버를 등록하면 끝.

- **빌트인 Tree-sitter.** 강조·들여쓰기·구조 모션·텍스트 객체 전부 TS 기반.

- **selection-first 편집 모델.** Vim의 verb-object를 뒤집어 object-verb로. 선택이 항상 먼저 보인다.

- **플러그인 시스템이 거의 없음**(설계 의도). 코어가 두꺼워서 거의 필요 없게 만든다.

6.2 왜 매력적인가

| 항목 | Vim/Neovim | Helix |

| --- | --- | --- |

| LSP 통합 | 플러그인 (nvim-lspconfig) | 빌트인 |

| Tree-sitter | 플러그인 (nvim-treesitter) | 빌트인 |

| 설정 | 수십~수백 줄 | 거의 제로 |

| 첫 사용 경험 | 가팔라짐 | 즉시 작동 |

| 확장성 | 무제한 (Lua) | 제한적 |

"한 시간 안에 IDE급 환경"이 Helix의 약속이다. 트레이드오프는 분명하다 — 깊은 커스터마이즈는 Neovim이 여전히 왕이다.

6.3 `languages.toml` 예시

[[language]]

name = "rust"

language-servers = ["rust-analyzer"]

auto-format = true

[[language]]

name = "python"

language-servers = ["basedpyright"]

이게 거의 전부다.

7장 · Zed 에디터 — Tree-sitter + LSP + 실시간 협업

7.1 Zed의 출신과 야망

**Zed**는 Atom·Electron 시절의 공동저자(Nathan Sobo 등)가 다시 만든 에디터다. 핵심은 **Rust로 처음부터 다시 짠 네이티브 에디터** + **공동 편집(collab)** + **AI 통합**.

- **GPU 가속 렌더링.** 에디터로서 매우 빠르다.

- **빌트인 Tree-sitter / LSP.** Helix와 같은 철학.

- **실시간 공동 편집.** Google Docs 같은 멀티 커서·음성 통화·화면 공유까지 일체화.

- **AI 통합.** 챗·인라인 어시스트·에이전트 통합이 빌트인.

- **확장 시스템.** WebAssembly 기반.

7.2 누구에게 맞나

- **VS Code의 무거움**(Electron, RAM 사용량, 시작 속도)에 지친 사람.

- **공동 편집을 제품 수준으로** 자주 쓰는 페어 프로그래밍 팀.

- **AI 기능을 에디터 코어에서** 쓰고 싶은 사람.

7.3 트레이드오프

- 확장 생태계가 VS Code만큼 깊지 않다.

- 거대 모노레포의 일부 워크플로우(특정 디버거·테스트 러너)는 아직 VS Code 쪽이 더 풍부.

8장 · Neovim 통합 — nvim-treesitter / lsp-zero / nvim-lspconfig

8.1 Neovim의 자리

Neovim은 Vim에서 포크되어 **빌트인 LSP 클라이언트**(0.5+)와 **Lua 런타임**, **Tree-sitter 지원**(0.8+)을 코어에 넣었다. 결과적으로 **무한 커스터마이즈**가 가능한 에디터로 남았다.

대표 플러그인:

| 플러그인 | 역할 |

| --- | --- |

| **nvim-treesitter** | Tree-sitter 통합 — 강조·들여쓰기·텍스트 객체 |

| **nvim-lspconfig** | 잘 알려진 LSP 서버 설정 모음 |

| **lsp-zero** | nvim-lspconfig + mason + cmp의 사전 통합 — "한 줄로 LSP 켜기" |

| **mason.nvim** | LSP 서버·포맷터·린터·디버거 설치 관리자 |

| **nvim-cmp** | 자동완성 UI 엔진 |

| **none-ls / null-ls** | LSP가 아닌 도구(eslint, prettier, ...)를 LSP처럼 노출 |

| **telescope.nvim** | 퍼지 파인더 (파일·심볼·LSP 결과) |

8.2 lsp-zero의 가치

Neovim의 LSP 셋업은 강력하지만 처음엔 가파르다. 1) lspconfig로 서버 등록, 2) mason으로 설치, 3) cmp로 자동완성 연결, 4) 키맵 설정. **lsp-zero**는 이 네 단계를 합리적인 기본값으로 한 번에 한다.

local lsp_zero = require('lsp-zero')

lsp_zero.on_attach(function(client, bufnr)

lsp_zero.default_keymaps({buffer = bufnr})

end)

require('mason').setup({})

require('mason-lspconfig').setup({

ensure_installed = { 'rust_analyzer', 'gopls', 'basedpyright', 'tsserver' },

handlers = { lsp_zero.default_setup },

})

8.3 nvim-treesitter

require('nvim-treesitter.configs').setup({

ensure_installed = { 'rust', 'go', 'python', 'typescript', 'tsx', 'lua' },

highlight = { enable = true },

indent = { enable = true },

})

이걸 켜는 순간 정규식 강조와는 비교가 안 되는 정확성이 들어온다.

9장 · 언어별 LSP 카탈로그

9.1 Rust — rust-analyzer

- Rust 공식 권장 LSP.

- 매크로 확장·트레잇 추론·라이프타임 단서까지 인라인 표시.

- 메모리·CPU를 적지 않게 먹지만 그만한 값을 한다.

9.2 Go — gopls

- Go 팀이 직접 유지. 사실상 표준.

- gofmt·goimports와 통합된 빠른 포맷.

- generics 도입 이후 안정화가 빨랐다.

9.3 Python — pyright / basedpyright / jedi / pylyzer

| 서버 | 특징 |

| --- | --- |

| **pyright** | Microsoft가 만든 빠른 타입 체커 기반 LSP |

| **basedpyright** | pyright 포크. 오픈소스 친화·기본 엄격성 강화 |

| **jedi-language-server** | jedi 기반. 타입 어노테이션 부족한 코드에 강함 |

| **pylyzer** | Rust로 작성된 빠른 정적 분석기 + LSP. 초기 단계지만 약속 큼 |

2026년 기준: 새 코드베이스에 권장은 **basedpyright**. 레거시 untyped 코드에는 jedi.

9.4 TypeScript / JavaScript

- **typescript-language-server** (오랜 표준). tsserver를 LSP로 래핑.

- **vtsls** — VS Code의 TS 확장에 더 가깝게 동작하는 신흥 래퍼. 2026년에는 많은 Neovim/Helix 사용자가 vtsls로 이동.

- 포맷·린트는 BiomeJS가 빠르게 잡아먹는 중.

9.5 C/C++ — clangd

- LLVM 진영의 표준. `compile_commands.json`만 잘 만들면 거대한 코드베이스에서도 동작.

- 인덱싱이 느릴 수 있지만 한 번 인덱스가 만들어지면 응답이 빠르다.

9.6 Java — jdtls

- Eclipse JDT를 LSP로 노출. Java 생태계의 사실상 표준 LSP.

- 메모리 사용이 크다. Maven/Gradle 통합 깊음.

9.7 그 외

| 언어 | LSP |

| --- | --- |

| Ruby | **Solargraph** (전통), **ruby-lsp** (신흥, Shopify) |

| Elixir | **elixir-ls**, **next-ls** |

| Haskell | **hls** (haskell-language-server) |

| Nim | **nimlsp** |

| OCaml | **ocaml-lsp** |

| Lua | **sumneko-lua** / **lua-language-server** (Neovim 설정에 필수) |

| Zig | **zls** |

| Kotlin | **kotlin-language-server** |

| Swift | **sourcekit-lsp** |

| Erlang | **erlang_ls** |

| Bash | **bash-language-server** |

| YAML | **yaml-language-server** (Red Hat) |

| JSON | **vscode-json-languageserver** |

| Terraform | **terraform-ls** |

| Markdown | **Marksman** |

9.8 한 가지 패턴

- **언어 팀이 직접 만든 LSP** (gopls, rust-analyzer, ruby-lsp, hls, ocaml-lsp)는 거의 항상 가장 깊고 정확하다.

- **사설 회사가 만든 LSP** (pyright, sourcekit-lsp)도 종종 표준이 된다.

- **언어가 정적 타입을 가지면** LSP 품질이 비약적으로 좋아진다 — 타입 정보가 곧 LSP의 재료다.

10장 · 구조적 검색 — Comby / Semgrep / CodeQL

ast-grep과 가까운 동네에 있는 세 도구. 각자 약간 다른 자리를 차지한다.

10.1 Comby

- 언어 중립 구조 매칭 도구. 자체 미니 파서로 "괄호·중괄호·따옴표 같은 균형 잡힌 구조"를 인식.

- 새 언어 지원이 아주 저렴 — 진짜 grammar가 아니라 "언어의 토큰 모양"만 등록하면 된다.

- 작고 빠른 일회성 리라이트에 강하다.

comby 'foo(:[x])' 'bar(:[x])' file.py

10.2 Semgrep

- 보안 중심으로 출발. 지금은 일반 정책 검색 엔진.

- 패턴은 **그 언어의 코드 자체**처럼 보임. `$X.execute($Y)` 같은 메타변수.

- 룰셋이 거대 (수천 개의 보안 룰). CI에 꽂아 두는 표준 도구.

- 회사 차원의 코드 정책 — "이 API 호출 금지", "이 인자 패턴 확인" — 에 최적.

10.3 CodeQL

- GitHub(Microsoft) 소유. "코드를 데이터베이스로 보고 SQL-like 쿼리".

- 패턴 매칭이 아니라 **데이터 흐름 분석**까지 한다.

- 매우 강력하지만 학습 곡선이 가팔라서 보통 보안팀이 사용.

- GitHub Code Scanning의 기본 엔진.

10.4 셋 비교

| 도구 | 패러다임 | 강점 | 진입장벽 |

| --- | --- | --- | --- |

| **ast-grep** | Tree-sitter AST 매칭·리라이트 | 빠르고 직관적, 모든 TS 언어 | 낮음 |

| **Comby** | 균형 구조 매칭·리라이트 | 새 언어 지원 저렴, 일회성 강함 | 낮음 |

| **Semgrep** | AST 패턴 + 정책 룰셋 | 거대 보안 룰셋·CI 친화 | 중간 |

| **CodeQL** | 데이터 흐름 쿼리 언어 | 가장 강력한 분석, taint tracking | 높음 |

선택 가이드:

- 한 번 잘 짜고 팀이 계속 검사 -> **Semgrep**.

- 즉석 대규모 리팩토링 -> **ast-grep**.

- 가볍게 한두 곳 -> **Comby** 또는 ast-grep.

- 깊은 보안 분석 -> **CodeQL**.

11장 · Tabnine vs 언어별 자동완성

11.1 두 갈래

자동완성은 두 가지가 섞여 있다.

| 종류 | 출처 | 예 |

| --- | --- | --- |

| **언어 기반** | LSP 서버. 타입·심볼 인덱스 | pyright, rust-analyzer |

| **확률 기반** | LLM·로컬 모델 | Tabnine, Copilot, Codeium, Cursor Tab |

11.2 Tabnine의 자리

- 초창기 GPT-2 기반 로컬 자동완성으로 알려졌다.

- 2026년에는 엔터프라이즈 자가호스팅·코드 학습 격리에 집중. "회사 사내 코드만 학습한 모델"을 제공.

- Copilot이 너무 강해진 시장에서 "프라이버시·온프레미스" 포지션을 잡았다.

11.3 LSP 완성과 LLM 완성은 같이 가야 한다

- LSP 완성은 **정확한 타입·심볼**을 안다. 환각이 없다.

- LLM 완성은 **긴 컨텍스트·패턴 일반화**가 강하다. 모르는 이름도 추측.

- 좋은 에디터(Cursor, Zed, VS Code+Copilot, Neovim+lsp+ai 플러그인)는 **두 흐름을 동시에** 보여주고, 사용자가 고를 수 있게 한다.

자동완성 = LSP + LLM의 하이브리드가 2026년의 표준이다.

12장 · 한국·일본 현장

12.1 한국 — 토스의 LSP·내부 도구 활용

토스는 사내 도구·플랫폼팀 글에서 자주 LSP·Tree-sitter 기반 도구를 언급한다.

- 거대 모노레포에서 **타입 인식 grep**(ast-grep) 으로 API 마이그레이션·deprecation 검색.

- **vtsls + Biome** 조합으로 프론트엔드 자동완성·포맷을 빠르게.

- 자체 디자인 시스템·내부 SDK를 위한 ESLint/Biome 룰을 사내에서 유지.

- 보안팀은 Semgrep 룰셋을 코드베이스 정책으로 운영.

요점은 **에디터 자유**다. 누구는 IntelliJ, 누구는 Cursor, 누구는 Neovim을 쓰지만, LSP·Tree-sitter·Biome·ast-grep 같은 표준 위에 있으면 팀의 룰셋이 모두에게 동일하게 적용된다.

12.2 일본 — メルカリ의 Tree-sitter 활용

メルカリ(Mercari)는 사내 기술 블로그에서 Tree-sitter 기반 도구로 다음을 자주 언급한다.

- **코드 검색·심볼 인덱스** — 거대 모노레포에서 정확한 함수·심볼 추출.

- **GitHub Actions에서 ast-grep / Semgrep 룰셋** 으로 사내 코드 정책 검사.

- **Go + gopls·Rust + rust-analyzer**가 사내 표준 LSP 조합. 결제·검색 등 백엔드의 기본.

- 모바일 쪽에서는 **kotlin-language-server / sourcekit-lsp** 가 빌드 인프라와 묶여 사용된다.

일본의 다른 회사들 — DeNA·CyberAgent·SmartHR·LINE — 도 비슷한 그림이다. LSP·Tree-sitter는 2026년의 "당연한 인프라"로 자리잡았다.

13장 · 누가 무엇을 골라야 하나

13.1 시나리오별 추천

**"VS Code를 그대로 쓰고 싶다"**

- VS Code + 언어별 공식 LSP 확장 (rust-analyzer, gopls, basedpyright, ...).

- 자동완성: Copilot 또는 Cursor 포크.

- 린트/포맷: Biome (JS/TS), 언어별 표준 (rustfmt, gofmt, ruff).

**"VS Code가 무겁다, 빠른 네이티브 에디터로"**

- Zed. 빌트인 LSP·TS·협업·AI. 가장 부담 없는 이주.

- Helix. 더 가볍고 더 키보드 중심. 모달 에디터에 익숙하다면.

**"무한 커스터마이즈와 키보드 워크플로"**

- Neovim + lsp-zero + nvim-treesitter + telescope + nvim-cmp.

- 첫 셋업은 가파르지만, 한 번 자리 잡으면 가장 강한 워크플로.

**"거대 모노레포 리팩토링·정책"**

- 코드 검색·리라이트: ast-grep.

- 보안·정책: Semgrep.

- 깊은 분석: CodeQL.

- 일회성 가벼운 리라이트: Comby.

**"마크다운 위주 작업(노트·문서·블로그)"**

- 에디터는 무엇이든, LSP로 Marksman.

- Obsidian 사용자는 외부 에디터 + Marksman 조합도 좋은 선택.

13.2 모든 경우의 공통점

| 항목 | 권장 |

| --- | --- |

| 자동완성 | LSP(언어 기반) + LLM(확률 기반) 둘 다 |

| 강조 | Tree-sitter |

| 포맷 | 언어 공식 포맷터 (rustfmt, gofmt, ruff format, biome) |

| 린트 | 언어별 표준 + Semgrep으로 회사 정책 |

| 검색 | 정확도가 필요하면 ast-grep |

14장 · 함정과 안티패턴

14.1 흔한 함정

- **LSP 서버를 너무 많이 켠다.** Neovim에서 같은 파일에 LSP 두 개(예: tsserver + vtsls)가 동시에 붙으면 진단이 중복되고 메모리가 새어 나간다. 한 언어당 하나로 줄여라.

- **거대 모노레포에서 인덱싱 비용을 무시.** 첫 인덱스가 10분 걸리는 건 흔하다. CI 캐싱·서버 재시작 시점을 신경 써야 한다.

- **포맷터 충돌.** Prettier·Biome·ESLint --fix·언어 공식 포맷터를 동시에 켜면 저장할 때마다 코드가 진동한다. 단 하나의 "포맷 권위"만 둬라.

- **Tree-sitter grammar 버전 불일치.** 에디터마다 grammar 버전이 다르면 같은 파일이 다르게 강조된다. 큰 문제는 아니지만 헷갈린다.

14.2 안티패턴

- **정규식으로 리팩토링.** 다섯 군데 이상이면 거의 항상 ast-grep / Comby / Semgrep이 빠르고 안전하다.

- **수동 임포트 정리.** LSP의 `organize imports` 또는 Biome로 자동화.

- **LSP 없이 거대 코드베이스 탐색.** 정의 이동·참조 검색이 없으면 잃는 시간이 어마어마하다.

- **로컬에만 LSP, CI에는 없음.** Lint·타입 체크·정책 검사는 CI에도 같이 있어야 한다.

15장 · 정리 — 표준 위에 사는 법

2026년의 코드 도구 생태계는 **두 개의 표준** 위에 서 있다.

- **LSP** — 코드 지능.

- **Tree-sitter** — 코드 구조.

이 두 표준 덕분에:

- 에디터를 바꾸는 비용이 폭락했다.

- 새 언어를 지원하는 비용이 폭락했다.

- 회사 정책을 코드로 표현하는 비용이 폭락했다.

그 위에 자라난 생태계 — **ast-grep, Biome, Marksman, Helix, Zed, Neovim의 lsp-zero/treesitter 체인, 그리고 언어별로 잘 만들어진 LSP들** — 는 모두 이 두 축의 직접적인 후예다.

**선택할 때 기억할 것 하나**: 도구가 LSP·Tree-sitter 같은 표준 위에 있다면, 잘못된 선택이 거의 없다. 언제든 옮길 수 있고, 팀 룰셋이 이주를 따라간다.

참고 / References

- LSP 공식 사양 — https://microsoft.github.io/language-server-protocol/

- Tree-sitter — https://tree-sitter.github.io/tree-sitter/

- ast-grep (sg) — https://ast-grep.github.io/

- BiomeJS — https://biomejs.dev/

- Marksman — https://github.com/artempyanykh/marksman

- Helix editor — https://helix-editor.com/

- Zed editor — https://zed.dev/

- Neovim — https://neovim.io/

- nvim-treesitter — https://github.com/nvim-treesitter/nvim-treesitter

- nvim-lspconfig — https://github.com/neovim/nvim-lspconfig

- lsp-zero.nvim — https://github.com/VonHeikemen/lsp-zero.nvim

- mason.nvim — https://github.com/williamboman/mason.nvim

- rust-analyzer — https://rust-analyzer.github.io/

- gopls — https://pkg.go.dev/golang.org/x/tools/gopls

- pyright — https://github.com/microsoft/pyright

- basedpyright — https://github.com/DetachHead/basedpyright

- jedi-language-server — https://github.com/pappasam/jedi-language-server

- pylyzer — https://github.com/mtshiba/pylyzer

- typescript-language-server — https://github.com/typescript-language-server/typescript-language-server

- vtsls — https://github.com/yioneko/vtsls

- clangd — https://clangd.llvm.org/

- jdtls — https://github.com/eclipse-jdtls/eclipse.jdt.ls

- Solargraph — https://solargraph.org/

- ruby-lsp — https://github.com/Shopify/ruby-lsp

- elixir-ls — https://github.com/elixir-lsp/elixir-ls

- haskell-language-server — https://github.com/haskell/haskell-language-server

- nimlsp — https://github.com/PMunch/nimlsp

- ocaml-lsp — https://github.com/ocaml/ocaml-lsp

- sumneko/lua-language-server — https://github.com/LuaLS/lua-language-server

- zls — https://github.com/zigtools/zls

- Comby — https://comby.dev/

- Semgrep — https://semgrep.dev/

- CodeQL — https://codeql.github.com/

- GitLens (VS Code) — https://github.com/gitkraken/vscode-gitlens

- Difftastic — https://github.com/Wilfred/difftastic

- Tabnine — https://www.tabnine.com/

- 토스 기술 블로그 — https://toss.tech/

- メルカリ Engineering Blog — https://engineering.mercari.com/

현재 단락 (1/346)

2010년대의 에디터 전쟁은 단순했다. **"어떤 앱을 쓰느냐"** 가 거의 모든 것을 결정했다. VS Code인가, JetBrains인가, Vim인가, Emacs인가. 각자 자기...

작성 글자: 0원문 글자: 14,665작성 단락: 0/346