All posts
Swift LSP cho Claude Code
swiftclaudeai

Swift LSP cho Claude Code

Hao Nguyen K.'s avatarHao Nguyen K.
Table of Contents6 sections

Mặc định, Claude Code điều hướng codebase bằng text search — Grep, Glob, Read. Với Swift, điều này đồng nghĩa mỗi câu hỏi "processPayment định nghĩa ở đâu?" biến thành một lượt grep xuyên project: đọc hàng chục file, lọc thủ công, mất 30–60 giây và không đảm bảo đúng. Vấn đề cốt lõi: grep coi code là text, nhưng Swift không phải text — nó có structure, type và quan hệ symbol.

LSP đóng lại khoảng cách đó. Query tương tự trả về đúng file và dòng trong ~50ms, chính xác tuyệt đối. Đây không phải cải thiện tăng dần, mà là đổi hẳn category cách Claude đọc code.

Cơ chế

LSP (Language Server Protocol) tách phần phân tích ngôn ngữ khỏi client. Claude Code hỏi qua JSON-RPC, một language server chạy nền trả lời. Với Swift, server là SourceKit-LSP — Apple phát triển, đóng gói sẵn trong toolchain.

Điểm mấu chốt về hiệu năng: server index toàn project ngay lúc khởi động, không đợi bạn mở file. Khi bạn hỏi câu đầu tiên, index đã warm — goToDefinition, findReferences, hover hoạt động cho mọi symbol, kể cả file chưa mở.

Giá trị thực

Passive — self-correcting edits. Đây là phần giá trị nhất và nhiều người không nhận ra. Sau mỗi lần edit, SourceKit-LSP đẩy diagnostics: type errors, missing imports, sai số lượng tham số. Claude thấy ngay và sửa trong cùng một turn.

Ví dụ: bạn yêu cầu thêm tham số email vào createUser(). Claude sửa signature, LSP lập tức báo lỗi ở các call site, Claude tìm và fix hết — kết quả trả về đã sạch lỗi ngay lần đầu. Không LSP, vòng lặp "edit → build → paste lỗi → sửa" sẽ lặp nhiều lần; có LSP, nó gộp thành một bước.

Active — code intelligence theo yêu cầu. Bạn hỏi tự nhiên, Claude tự route sang đúng operation: goToDefinition, findReferences, hover (type + doc), documentSymbol, workspaceSymbol, goToImplementation, incomingCalls/outgoingCalls. Đặc biệt hữu ích khi refactor — đổi return type hay rename method, LSP đảm bảo tìm đúng mọi reference, không phải "grep thấy 47/52 chỗ".

Triển khai

Yêu cầu: Claude Code từ bản 2.0.74 trở lên (claude --version), và SourceKit-LSP có sẵn — kèm Xcode. Xác minh:

xcrun --find sourcekit-lsp

Bước 1 — Bật LSP tool. Đây là chỗ hầu hết mọi người vấp. Thêm vào ~/.claude/settings.json:

{
  "env": { "ENABLE_LSP_TOOL": "1" }
}

Bước 2 — Cập nhật marketplace và cài plugin:

claude plugin marketplace update claude-plugins-official
claude plugin install swift-lsp

Bước 3 — Xác minh plugin enabled:

claude plugin list

Gotcha số 1: plugin có thể installed nhưng disabled — khi đó nó không register LSP server lúc khởi động. Nếu thấy Status: disabled, chạy claude plugin enable swift-lsp. Chắc chắn hơn, set thẳng trong settings.json:

{
  "env": { "ENABLE_LSP_TOOL": "1" },
  "enabledPlugins": {
    "swift-lsp@claude-plugins-official": true
  }
}

Bước 4 — Restart Claude Code. LSP server init lúc khởi động, phải restart hẳn. Verify bằng cách hỏi "What type is [biến nào đó]?" — nếu Claude dùng hover thay vì đọc file, là ổn.

Ép Claude thực sự dùng LSP

Kể cả khi setup xong, Claude vẫn có thể mặc định quay về Grep/Read. Đây là than phiền phổ biến nhất sau setup. Fix: thêm chỉ dẫn vào CLAUDE.md (global ở ~/.claude/CLAUDE.md hoặc theo repo):

### Code Intelligence
Ưu tiên LSP hơn Grep/Glob/Read khi điu hướng code:
- goToDefinition/goToImplementation để nhy ti source
- findReferences để thy mi call site
- workspaceSymbol để tìm nơi định nghĩa
- hover để ly type mà không cn đọc file
Trước khi rename hay đổi signature, dùng findReferences tìm hết call site.
Chdùng Grep/Glob cho text search (comment, string, config).
Sau khi sa code, check diagnostics và fix type error ngay.

Debug nhanh khi không chạy

  • Binary có chưa: xcrun --find sourcekit-lsp

  • Plugin enabled chưa: claude plugin list → tìm Status: enabled

  • Log: ~/.claude/debug/latest → tìm "Total LSP servers loaded: N", N phải > 0

Kết luận

Mỗi phiên Claude Code chạy không LSP là phiên mà mỗi "tìm định nghĩa" mất 30–60s thay vì 50ms, mỗi refactor bỏ sót call site, mỗi type error lẽ ra được auto-fix lại lọt tới bước review. Setup hai phút, một dòng flag. Khác biệt không hề tinh tế — nó đúng bằng khoảng cách giữa Notepad và IDE, giờ áp cho AI assistant. Với Swift, bật nó lên và bạn cảm nhận ngay từ query đầu tiên.