Skip to content
Open
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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,14 +339,16 @@ Editors can pass `initializationOptions` when starting the Codebook LSP for LSP-
- `logLevel` (`"trace" | "debug" | "info" | "warn" | "error"`, default `"info"`): sets the verbosity of logs.
- `globalConfigPath` (string): overrides the auto-detected global `codebook.toml` path, useful if you sync configs from another location. On macOS and Linux, the `~/` prefix for the current user's home directory is supported.
- `checkWhileTyping` (bool, default `true`): when `false`, spelling diagnostics are only published on save instead of each keystroke. This is useful for example if performance is a problem, or the real-time diagnostics are annoying (sorry!).
- `diagnosticSeverity` (`"error" | "warning" | "information" | "hint"`, default `"information"`): sets the severity of spell check diagnostics.

Example payload:

```json
{
"logLevel": "debug",
"globalConfigPath": "~/dotfiles/codebook.toml",
"checkWhileTyping": false
"checkWhileTyping": false,
"diagnosticSeverity": "information"
}
```

Expand Down
29 changes: 28 additions & 1 deletion crates/codebook-lsp/src/init_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use serde::Deserialize;
use serde::de::Deserializer;
use serde_json::Value;
use std::path::PathBuf;
use tower_lsp::lsp_types::DiagnosticSeverity;

fn default_log_level() -> LevelFilter {
LevelFilter::Info
Expand Down Expand Up @@ -44,6 +45,24 @@ fn default_check_while_typing() -> bool {
true
}

fn default_diagnostic_severity() -> DiagnosticSeverity {
DiagnosticSeverity::INFORMATION
}

fn deserialize_diagnostic_severity<'de, D>(deserializer: D) -> Result<DiagnosticSeverity, D::Error>
where
D: Deserializer<'de>,
{
let s: Option<String> = Option::deserialize(deserializer)?;
match s.as_deref() {
Some("error") => Ok(DiagnosticSeverity::ERROR),
Some("warning") => Ok(DiagnosticSeverity::WARNING),
Some("information") => Ok(DiagnosticSeverity::INFORMATION),
Some("hint") => Ok(DiagnosticSeverity::HINT),
_ => Ok(default_diagnostic_severity()),
}
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct ClientInitializationOptions {
Expand All @@ -56,6 +75,11 @@ pub(crate) struct ClientInitializationOptions {
pub(crate) global_config_path: Option<PathBuf>,
#[serde(default = "default_check_while_typing")]
pub(crate) check_while_typing: bool,
#[serde(
default = "default_diagnostic_severity",
deserialize_with = "deserialize_diagnostic_severity"
)]
pub(crate) diagnostic_severity: DiagnosticSeverity,
}

impl Default for ClientInitializationOptions {
Expand All @@ -64,6 +88,7 @@ impl Default for ClientInitializationOptions {
log_level: default_log_level(),
global_config_path: None,
check_while_typing: true,
diagnostic_severity: default_diagnostic_severity(),
}
}
}
Expand Down Expand Up @@ -109,9 +134,11 @@ mod tests {

#[test]
fn test_json() {
let json = r#"{"logLevel": "debug", "checkWhileTyping": false}"#;
let json =
r#"{"logLevel": "debug", "checkWhileTyping": false, "diagnosticSeverity": "warning"}"#;
let options: ClientInitializationOptions = serde_json::from_str(json).unwrap();
assert_eq!(options.log_level, LevelFilter::Debug);
assert!(!options.check_while_typing);
assert_eq!(options.diagnostic_severity, DiagnosticSeverity::WARNING);
}
Comment on lines 136 to 143
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding test cases for additional scenarios: 1) testing that invalid/unknown values fall back to the default severity (e.g., "invalid_value"), 2) testing that missing the field uses the default value, and 3) testing all four severity levels (error, warning, information, hint). This would provide more comprehensive coverage of the deserialize_diagnostic_severity function.

Copilot uses AI. Check for mistakes.
}
2 changes: 1 addition & 1 deletion crates/codebook-lsp/src/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ impl Backend {
character: end_pos.col as u32,
},
},
severity: Some(DiagnosticSeverity::INFORMATION),
severity: Some(self.initialize_options.read().unwrap().diagnostic_severity),
code: None,
code_description: None,
source: Some(SOURCE_NAME.to_string()),
Expand Down