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