Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,41 @@

A language server for [Circom](https://docs.circom.io/), built with Rust and TypeScript.

CCLS provides rich editor support for [Circom](https://docs.circom.io/) — the DSL for writing
zero-knowledge proof circuits — with an **error-recovering parser** that stays useful even on
partially-typed or invalid files.

The project is split across:

- **Rust backend** — a multi-crate workspace: `parser` (lexer + event-driven parser),
`syntax` (lossless `rowan` AST), `vfs` (virtual file system), and `lsp` (the language server).
- **VS Code extension** — TypeScript client (`circom-plus`) published to the marketplace.

## ✨ Features

### Implemented

- [x] **Go to Definition** — resolves signals, variables, parameters, templates, functions, and
components, including **cross-file** jumps through `include` statements, and jumping straight
into an included library file from its `"path.circom"` string.
- [x] **Hover** — shows the symbol kind and its declaration signature (header only for block-bodied
defs like `template`/`function`/`bus`).
- [x] **Completion** — in-scope body symbols, file top-level names, reserved keywords, and **member
completion** (`component.<signal>`) that resolves a component's template across files.
- [x] **Find References** — every occurrence of a symbol, resolved *semantically* (not text-matched),
so shadowing is respected.
- [x] **Rename** — scope-aware rename with `prepareRename` support; refuses keywords, include-path
strings, illegal names, and unresolved member-access fields.
- [x] **Error-recovering parser** — keeps working on invalid/partial circom files.
- [x] **Lazy, cached analysis** — parsing and symbol tables are memoized and invalidated only on real
edits; includes are read from disk once.
- [x] **Sandboxed includes** — `include` resolution is confined to workspace roots
(path-traversal / symlink-safe).

> See [`TODO.md`](./TODO.md) for the roadmap of features not yet implemented.

---

## 🚀 Installation

1. **Clone the repository:**
Expand Down Expand Up @@ -63,3 +98,29 @@ Optional, but recommended for snapshot testing.

---

## 🏗️ Architecture

```
circom-language-server/
├── crates/
│ ├── parser/ # `logos` lexer + event-driven parser with markers
│ ├── syntax/ # `rowan` lossless syntax tree + typed AST
│ ├── vfs/ # Virtual file system (existence, text, change log)
│ └── lsp/ # LSP server: handlers, global state, resolver, semantic index
├── editors/code/ # VS Code extension (TypeScript, `circom-plus`)
└── xtask/ # Build & install tasks (`cargo xtask install …`)
```

Key design notes:

- **Resolution core** (`resolver.rs` + `semantic.rs`) is name-based and shared by goto-definition,
hover, references, and rename — so the same symbol resolves consistently across features.
- **Source database** (`source_db.rs`) memoizes parse / file DB / symbol table per file, drained from
the VFS change log so editing file A never recomputes file B.
- Includes are loaded once from disk, cached, and confined to workspace roots.

---

## 🐛 Bugs & Feature Requests

Please open an issue on the repository: https://github.com/vuvoth/ccls/issues
36 changes: 36 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Roadmap

Features not yet implemented in CCLS. Implemented features are listed in the
[README](./README.md#-features).

## Placeholders (capability registered, returns empty)

These handlers exist but currently return `None`:

- [ ] **Document Symbol / Outline** — `textDocument/documentSymbol`. Walk the program AST and emit one
symbol per template / function / signal / variable / component with its location and kind.
See `crates/lsp/src/handler/document_symbol.rs`.
- [ ] **Formatting** — `textDocument/formatting`. Re-tokenize the document and normalize
whitespace/indentation into `TextEdit`s. See `crates/lsp/src/handler/formatting.rs`.

## Not yet implemented

- [ ] **Diagnostics** — syntax/semantic error reporting (`textDocument/publishDiagnostics`). The
parser already produces errors via `error_report()`; surface them to the client.
- [ ] **Semantic Highlighting** — `textDocument/semanticTokens`.
- [ ] **Signature Help** — `textDocument/signatureHelp`.
- [ ] **Code Actions / Quick Fixes** — `textDocument/codeAction`.
- [ ] **Folding Ranges** — `textDocument/foldingRange`.
- [ ] **Document Highlight** — `textDocument/documentHighlight`.
- [ ] **Selection Range** — `textDocument/selectionRange`.
- [ ] **Inlay Hints** — `textDocument/inlayHint`.

## Existing features — follow-ups

- [ ] **Cross-file Rename & References** — both are currently in-file only. A workspace-wide symbol
graph is needed instead of name/`def_range` matching across files (which both misses real
cross-file usages and can collide when two files define a same-named symbol at the same
line:column).
- [ ] **Doc-comment parsing** — richer hover derived from circom comments.
- [ ] **Incremental sync** — document sync is currently `Full`; switch to incremental `didChange`
ranges.
4 changes: 2 additions & 2 deletions editors/code/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ template Another() {
I recommend installing via these commands:

```bash
git clone https://github.com/vuvoth/circom-plus
cd circom-plus
git clone https://github.com/vuvoth/ccls
cd ccls
cargo xtask install --server
cargo xtask install --client
```
Expand Down
Loading