A Language Server Protocol implementation for the C3 programming language, written in C3.
- Go to Definition / Declaration — navigate to functions, macros, types, constants, enum members, and struct fields; resolves method calls, module-qualified paths (
std::io::printfn), and individual segments ofimportstatements; searches the current file, project sources, and the C3 standard library, preferring declarations in modules visible from the current file (its module tree and imports) - Find References — find all occurrences of a symbol across the project and stdlib, skipping files that cannot see the symbol's module
- Rename Symbol — rename identifiers, types, and constants across files.
- Go to Implementation — from an interface name to the types whose conformance clause lists it (
struct Foo (Printable)), and from a method to the@dynamicbodies that provide it - Call Hierarchy — incoming calls (which functions call this one, with every call site) and outgoing calls (what this function calls), for functions and macros
- Hover — type signatures and doc comments (
<* ... *>) for functions, macros, types, and struct fields - Completion — keywords, types, identifiers, compile-time builtins (
$if,@sizeof, …), and attribute names; member completion after.for struct fields, methods, and enum values. - Signature Help — parameter hints when calling functions and macros, with the active parameter highlighted
- Document Symbols — outline of modules, functions, structs, enums, macros, and constants
- Workspace Symbols — search declarations across the project and the standard library by name, each labelled with the module that declares it; queries may narrow by module or list one type's methods (see below)
- Document Highlights — highlight all occurrences of a symbol in the current file
- Semantic Tokens — enhanced syntax highlighting for identifiers, types, functions, macros, and attributes, including inside contract blocks (directives like
@requireand their arguments are colored as code, prose as comment) - Folding Ranges — code folding for braces, imports, and block comments
- Diagnostics — instant lexer errors while typing, plus errors and warnings from the C3 compiler on save (throttled, configurable)
NB! Project-wide features (references, completion, navigation) read the
sourceslist from your project'sproject.json, so make sure your project has one for the best experience.
Requires the C3 compiler (v0.8.x or later).
# Fetch the lexer/argparse dependencies (first build only)
git submodule update --init
# Build — binary is output to build/lsp
c3c build lsp
# Run tests
c3c test lsp./build/lsp [options]The server communicates over stdin/stdout using the LSP JSON-RPC protocol.
Options take their value after = (e.g. --stdlib-path=/opt/c3/lib/std).
| Flag | Description | Default |
|---|---|---|
--stdlib-path=<path> |
Path to the C3 standard library | (auto-detected, see below) |
--compiler-path=<path> |
Path to the C3 compiler binary | c3c |
--diagnostics-delay=<ms> |
Throttle delay for compiler diagnostics (ms), 0 disables throttling |
2000 |
--version, -v |
Print version and exit |
If no stdlib path is given, the server asks the configured compiler where it is
installed (c3c --version) and uses <install dir>/lib/std when it exists. A missing
or broken compiler never crashes the server — stdlib features simply stay off.
The same settings can be sent by the editor in the initialize request instead of on
the command line, via initializationOptions:
{
"stdlib-path": "/opt/c3/lib/std",
"compiler-path": "/usr/local/bin/c3c",
"diagnosticsDelay": 500
}Command-line flags take precedence over client options; auto-detection runs last.
The code is layered so that JSON never leaks into the language analysis:
src/server/— transport (Content-Lengthframing over stdio), a table-driven method dispatcher, and thin request handlers that decode params and encode responsessrc/token/— the tokenizer,TokenStream/TokenListqueries, and an mtime-based file cache so unchanged files are never re-tokenizedsrc/analysis/— one file per LSP feature (definition, hover, completion, …), all operating on token streams onlysrc/analysis/scan.c3— the single project/stdlib directory walker; features implement theFileVisitorinterface and receive each tokenized file via@dynamicdispatchsrc/json/— typed LSP structures (Position,Range,Location, …) withencodemethods
Contributions should keep c3c test lsp green — the test suite pins the exact JSON
responses for every feature.