Skip to content

Configuration ​

clice reads configuration from clice.toml in the workspace root, or from .clice/config.toml if the former does not exist. Configuration can also be passed via LSP initializationOptions (JSON format); values from initializationOptions override the config file, and defaults fill in whatever remains unset after the merge.

Configuration is read once at server startup. Changing it — either file — requires restarting the server; there is no hot reload.

A JSON schema of the whole configuration is published at clice-config.schema.json; editors that validate TOML or JSON against a schema can point at it.

Relative paths and patterns in the file resolve against the directory of the configuration file itself; values passed through initializationOptions resolve against the workspace root.

Several Folders ​

Each workspace folder the editor opens is a project of its own, with its own clice.toml, compilation databases and cache directory, as long as it holds a clice.toml or a compile_commands.json (in the folder itself or one of its immediate subdirectories, where discovery looks). A folder with neither that sits inside another open folder is part of that folder's project instead; and inside a folder, a directory holding its own clice.toml or database serves, as a project of its own, the files the folder's project does not build. A file opened outside every folder belongs to the nearest directory above it holding a clice.toml or a compile_commands.json (directly or in its build/ directory), which is then served as if it were open, unless a served project loads that database already. A file is compiled by the project whose database lists it; a header without an entry of its own borrows a host from a project whose sources include it, preferring the project whose folder holds it. Workspace symbol search spans every project, and navigation — references, definitions and declarations, call and type hierarchies, implementations — reaches into the projects that declare the symbol in the same file. A file open in the editor answers only through the project serving it, so its unsaved edits are what every query sees.

initializationOptions apply to every project, and a cache directory serves one project: a directory outside the project records the project that first used it, and another project, in this server or a later clice index run alike, falls back to the one its clice.toml names, then to .clice in its folder, and runs without a cache when those are taken too. An absolute cache_dir in initializationOptions therefore goes to the first folder only. The worker counts are the largest any folder asks for at startup. Listing or switching configurations acts on the project of the file the request names — in VS Code, the active editor's — else on the first folder.

Variable Substitution ​

The following variable is supported in string values:

VariableDescription
${workspace}The workspace directory provided by the client

Workspace ​

Top-level options, written before any section.

OptionTypeDefault
default_configurationstring""

The build configuration to fall back on when neither --configuration nor a persisted selection names one: a tag declared on rules. When rules carry tags and this names none of them, the first declared tag is used and a warning is logged.

[project] ​

OptionTypeDefault
cache_dirstring""

Directory for the unified on-disk cache (PCH, PCM and index artifacts). Empty defaults to ${workspace}/.clice, which keeps itself out of version control and backups via generated .gitignore and CACHEDIR.TAG markers (a .clice/config.toml stays visible to Git; backup tools honoring CACHEDIR.TAG skip the whole directory); an explicitly configured directory is never marked. The resolved path is printed at startup.

OptionTypeDefault
logging_dirstring""

Directory for log files; empty derives ${cache_dir}/logs. Each server session logs into its own timestamped subdirectory.

OptionTypeDefault
enable_indexingbooltrue

Build the background index that serves cross-TU features (find references, workspace symbols, ...).

OptionTypeDefault
readonlystring"off"

Read-only serving for open files: "off" targets a full AST for every open file — builds are pulled by the first request that needs them, with the index answering in the meantime; "on" never builds a PCH — reads serve from the index alone (a cold file jumps the indexing queue), while completion and signature help still compile on demand without a preamble; "auto" starts every file as "on", switches it to "off" at the first edit intent (edit, completion, signature help, context switch), and falls back to "off" for a file the index cannot serve. Feature routing always answers from the best source currently available.

OptionTypeDefault
idle_timeout_msuint323000

Idle delay in milliseconds before background indexing starts.

OptionTypeDefault
test_hooksboolfalse

Enable the clice/internal test hooks used by the test harness.

OptionTypeDefault
stateful_worker_countuint322

Number of stateful workers — they hold ASTs in memory and serve queries (hover, semantic tokens, ...); 0 is invalid and falls back to the default.

OptionTypeDefault
stateless_worker_countuint32—

Number of stateless workers started — they handle ephemeral tasks (PCH/PCM builds, completion, signature help, background indexing) — and the most that background indexing keeps busy at once; defaults to half the machine's physical cores, at least 2. 0 is invalid and falls back to that default.

OptionTypeDefault
min_stateless_worker_countuint321

Lower bound for dynamic stateless-worker scaling; 0 is invalid and falls back to the default.

OptionTypeDefault
max_stateless_worker_countuint32—

Upper bound for dynamic stateless-worker scaling, which only interactive work that finds every worker busy reaches; 0 means the machine's physical cores, which is also the default.

[tracker] ​

clice looks at files on disk in the background to notice changes made outside the editor (a git checkout, a regenerated compile_commands.json, an agent or a code generator writing files), so the server picks them up without a restart. A workspace file is also looked at before every request that depends on it; headers the toolchain installed are looked at every few minutes, whenever their environment is updated, and at every save. Setting workspace_poll_seconds to 0 turns the background polling off.

OptionTypeDefault
workspace_poll_secondsuint3230

Longest interval in seconds between two background looks at a workspace file: the interval doubles at every look that finds the file unchanged, up to this. 0 disables background polling, compilation databases included.

[hover] ​

The [hover] section controls how hover cards render.

OptionTypeDefault
parse_comment_as_markdownbooltrue

Render the hover card as markdown; false produces plain text for clients that cannot display it.

OptionTypeDefault
show_akabooltrue

Show the desugared form of a type, e.g. vector<int>::size_type (aka unsigned long).

[inlay_hints] ​

The [inlay_hints] section controls which inlay hint categories the server produces. A client-side refresh then requests hints with the updated values; no recompile is involved.

OptionTypeDefault
enabledbooltrue

Master switch: false disables all inlay hints.

OptionTypeDefault
parametersbooltrue

Parameter name hints at call sites, e.g. draw(width: 800, height: 600), including & markers for arguments passed by mutable reference.

OptionTypeDefault
deduced_typesbooltrue

Deduced type hints for auto variables, structured bindings and deduced return types.

OptionTypeDefault
designatorsbooltrue

Field designator hints in aggregate initialization, e.g. .x= and .y= in Point{1, 2}.

OptionTypeDefault
block_endboolfalse

// name hints after the closing brace of long blocks (functions, types, namespaces, control flow).

OptionTypeDefault
default_argumentsboolfalse

Show the default arguments a call omitted, abbreviated when long.

OptionTypeDefault
type_name_limituint3232

Byte budget for rendered hint text: over-long deduced types fall back to a sugared spelling or are dropped, over-long default arguments are abbreviated. 0 means no limit.

[code_completion] ​

The [code_completion] section controls completion item assembly.

OptionTypeDefault
enable_keyword_snippetboolfalse

Complete statements such as if and for as snippets with placeholders for their parts; otherwise only the keyword is inserted. Ignored for clients without snippet support.

OptionTypeDefault
enable_function_arguments_snippetboolfalse

Insert function arguments as a snippet when completing a call. For functions this applies to individually listed overloads, so it requires bundle_overloads = false; function-like macros have no overload sets and always take the snippet. Ignored for clients without snippet support.

OptionTypeDefault
enable_template_arguments_snippetboolfalse

Insert template arguments as a snippet when completing a class, alias or variable template. Ignored for clients without snippet support.

OptionTypeDefault
insert_paren_in_function_callboolfalse

Insert parentheses when completing a function call, unless the name is already followed by one; with snippet support the cursor lands between them.

OptionTypeDefault
bundle_overloadsbooltrue

Collapse an overload set into a single completion item.

OptionTypeDefault
limituint320

Maximum number of completion items (not yet implemented).

[[rules]] ​

A rule names files by pattern and says where they take their compile commands from and how those commands are edited. Every rule matching a file applies, in declaration order: an earlier rule's databases rank first among the file's candidates, the first matching rule with a default_command supplies the command of a file without an entry, append and remove accumulate with a later remove cancelling an earlier append, and index = false on any matching rule keeps the file out of the index. A rule carrying a configuration tag applies only while that configuration is active; the distinct tags form the configuration menu.

OptionTypeDefault
patternsarray of string[]

Glob patterns selecting the files this rule applies to. A relative pattern is anchored at this configuration file's directory (.. segments allowed), or at the workspace root for a rule passed through initializationOptions; an absolute pattern or one starting with ** matches the file's absolute path. * matches within a path segment, ? a single character, ** any number of segments, {a,b} alternatives, [0-9] a character range, [!...] a negated range. Omitted means every file.

OptionTypeDefault
configurationstring""

Build configuration tag. A tagged rule applies only while that configuration is active; an untagged rule always applies. The distinct tags form the configuration menu; --configuration, the persisted selection and default_configuration pick the active one, in that order.

OptionTypeDefault
compile_commandsarray of string[]

Compilation databases, in priority order: a compile_commands.json or a directory containing one, relative to this configuration file (to the workspace root for a rule passed through initializationOptions). All of them load, and every entry applies to its own file whatever the patterns say; the patterns and the order decide which entry a file present in several databases gets by default. A rule without patterns names the workspace's databases. When no rule declares a source, every compile_commands.json in the workspace root and its immediate subdirectories loads, and so do the ones in the directories above a file when it is opened.

OptionTypeDefault
default_commandstring or array of string""

The compile command for matching files without a database entry, without the source file: a string tokenized like a shell command line, or an argv array. It runs from the directory of the configuration file it was read from (the workspace root for a rule passed through initializationOptions), and the matching source files on disk join the background index (unless the rule turns index off) — enumerated at startup and again on every workspace poll, so a file created later compiles when opened and joins the index within a poll period. Omitted means none.

OptionTypeDefault
appendarray of string[]

Compilation flags appended for matching files, e.g. ["-std=c++20", "-DNDEBUG"].

OptionTypeDefault
removearray of string[]

Compilation flags removed for matching files, e.g. ["-Wall"].

OptionTypeDefault
indexbooltrue

Whether matching translation units join the background index. false keeps them out; they still compile when opened and still host the headers they include. Any matching rule saying false wins.

OptionTypeDefault
lintbooltrue

Whether clice lint checks matching files. false keeps them out: their findings are dropped and a translation unit they head is not parsed, unless --index needs it for the index. Files outside the workspace are never checked. Any matching rule saying false wins.

OptionTypeDefault
formatbooltrue

Whether clice format formats matching files. false keeps them out. Files outside the workspace are never formatted. Any matching rule saying false wins.

Example ​

toml
[[rules]]
compile_commands = ["build"]
append = ["-std=c++23"]

[[rules]]
patterns = ["test/**"]
append = ["-DTEST_MODE"]

Two build directories as switchable configurations, and a project without a compilation database:

toml
default_configuration = "debug"

[[rules]]
configuration = "debug"
compile_commands = ["build/debug"]

[[rules]]
configuration = "release"
compile_commands = ["build/release"]
toml
[[rules]]
patterns = ["src/**", "include/**"]
default_command = "arm-none-eabi-gcc -std=c23 -mcpu=cortex-m4 -Iinclude"

Switching Configurations ​

The configuration tags on rules form a menu, and one tag is active per project; untagged rules always apply. The active one is, in priority order, the --configuration <tag> argument (accepted by clice serve, clice index, clice lint and clice inspect), the persisted selection, or default_configuration. A selection is made from the editor — in VS Code the status bar shows the active configuration and clicking it opens the menu, other clients call clice/switchConfiguration — and is stored in state.json under cache_dir, never in clice.toml; it takes effect when the server is started again, which the VS Code extension does on its own. Each configuration keeps its own index under cache_dir, so switching back and forth never reindexes what a configuration already indexed. The tags are also how the batch commands choose an index: clice index --configuration release builds the release index, and clice index --stats reports the index of the configuration it resolves the same way.