1use std::collections::HashMap;
7
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10
11pub mod context_keys {
14 pub const LINE_NUMBERS: &str = "line_numbers";
15 pub const LINE_WRAP: &str = "line_wrap";
16 pub const COMPOSE_MODE: &str = "compose_mode";
17 pub const FILE_EXPLORER: &str = "file_explorer";
18 pub const MENU_BAR: &str = "menu_bar";
19 pub const FILE_EXPLORER_FOCUSED: &str = "file_explorer_focused";
20 pub const MOUSE_CAPTURE: &str = "mouse_capture";
21 pub const MOUSE_HOVER: &str = "mouse_hover";
22 pub const LSP_AVAILABLE: &str = "lsp_available";
23 pub const FILE_EXPLORER_SHOW_HIDDEN: &str = "file_explorer_show_hidden";
24 pub const FILE_EXPLORER_SHOW_GITIGNORED: &str = "file_explorer_show_gitignored";
25 pub const HAS_SELECTION: &str = "has_selection";
26 pub const FORMATTER_AVAILABLE: &str = "formatter_available";
27 pub const INLAY_HINTS: &str = "inlay_hints";
28 pub const SESSION_MODE: &str = "session_mode";
29 pub const VERTICAL_SCROLLBAR: &str = "vertical_scrollbar";
30 pub const HORIZONTAL_SCROLLBAR: &str = "horizontal_scrollbar";
31 pub const SCROLL_SYNC: &str = "scroll_sync";
32 pub const HAS_SAME_BUFFER_SPLITS: &str = "has_same_buffer_splits";
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, JsonSchema)]
37pub struct ProcessLimits {
38 #[serde(default)]
41 pub max_memory_percent: Option<u32>,
42
43 #[serde(default)]
46 pub max_cpu_percent: Option<u32>,
47
48 #[serde(default = "default_true")]
50 pub enabled: bool,
51}
52
53fn default_true() -> bool {
54 true
55}
56
57impl Default for ProcessLimits {
58 fn default() -> Self {
59 Self {
60 max_memory_percent: Some(50), max_cpu_percent: Some(90), enabled: cfg!(target_os = "linux"), }
64 }
65}
66
67impl ProcessLimits {
68 pub fn unlimited() -> Self {
70 Self {
71 max_memory_percent: None,
72 max_cpu_percent: None,
73 enabled: false,
74 }
75 }
76
77 pub fn default_cpu_limit_percent() -> u32 {
79 90
80 }
81}
82
83#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
85#[schemars(extend("x-display-field" = "/command"))]
86pub struct LspServerConfig {
87 #[serde(default)]
90 pub command: String,
91
92 #[serde(default)]
94 pub args: Vec<String>,
95
96 #[serde(default = "default_true")]
98 pub enabled: bool,
99
100 #[serde(default)]
103 pub auto_start: bool,
104
105 #[serde(default)]
107 pub process_limits: ProcessLimits,
108
109 #[serde(default)]
112 pub initialization_options: Option<serde_json::Value>,
113
114 #[serde(default)]
117 pub env: HashMap<String, String>,
118
119 #[serde(default)]
123 pub language_id_overrides: HashMap<String, String>,
124}
125
126impl LspServerConfig {
127 pub fn merge_with_defaults(self, defaults: &LspServerConfig) -> LspServerConfig {
132 LspServerConfig {
133 command: if self.command.is_empty() {
134 defaults.command.clone()
135 } else {
136 self.command
137 },
138 args: if self.args.is_empty() {
139 defaults.args.clone()
140 } else {
141 self.args
142 },
143 enabled: self.enabled,
144 auto_start: self.auto_start,
145 process_limits: self.process_limits,
146 initialization_options: self
147 .initialization_options
148 .or_else(|| defaults.initialization_options.clone()),
149 env: {
150 let mut merged = defaults.env.clone();
151 merged.extend(self.env);
152 merged
153 },
154 language_id_overrides: {
155 let mut merged = defaults.language_id_overrides.clone();
156 merged.extend(self.language_id_overrides);
157 merged
158 },
159 }
160 }
161}