1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// SPDX-License-Identifier: Apache-2.0
//! Semantic code-intelligence mode (`semantic_mode` in `config.toml`).
use serde::{Deserialize, Serialize};
use super::Config;
/// How the code graph uses local semantic backends (language servers, a live
/// JetBrains IDE) on top of the always-on tree-sitter structure.
/// - `off`: structural only; no semantic backend is ever queried.
/// - `auto`: (Default) background enrichment uses only backends already
/// running — a warm language server or a live IDE — and never spawns one.
/// - `eager`: background enrichment may start the project's language servers.
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum SemanticMode {
Off,
#[default]
Auto,
Eager,
}
impl SemanticMode {
pub fn from_env() -> Option<Self> {
std::env::var("LEAN_CTX_SEMANTIC_MODE").ok().and_then(|v| {
match v.trim().to_lowercase().as_str() {
"off" => Some(Self::Off),
"auto" => Some(Self::Auto),
"eager" => Some(Self::Eager),
_ => None,
}
})
}
pub fn effective(config: &Config) -> Self {
Self::from_env().unwrap_or(config.semantic_mode)
}
/// Effective mode for `project_root` specifically (its own, trust-gated
/// `.lean-ctx.toml`), independent of the process's working directory.
///
/// `eager` lets background work start the project's language servers,
/// which execute project code (build scripts, proc macros). Whatever
/// requested it — global config, `LEAN_CTX_SEMANTIC_MODE`, or the
/// project — it applies only to a trusted workspace (`lean-ctx trust`);
/// an untrusted one runs as `auto`. Explicit tools such as `ctx_refactor`
/// are unaffected.
pub fn for_project(project_root: &str) -> Self {
let mode = Self::from_env()
.unwrap_or_else(|| Config::load_for_project_root(project_root).semantic_mode);
if mode == Self::Eager
&& !crate::core::workspace_trust::is_trusted(std::path::Path::new(project_root))
{
return Self::Auto;
}
mode
}
}