Skip to content

Commit 1231eec

Browse files
1 parent 27a6871 commit 1231eec

64 files changed

Lines changed: 2514 additions & 1054 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Source/ApplicationState/ApplicationState.rs

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
// File: Mountain/Source/ApplicationState/ApplicationState.rs
22
// Role: Defines the main `ApplicationState` struct, which is the central,
3+
34
// shared, thread-safe state container for the entire Mountain
45
// application. Responsibilities:
56
// - Hold all runtime state for services like configuration, extensions,
7+
68
// documents, and UI.
79
// - Provide thread-safe access to this state via `Arc<Mutex<...>>`.
810
// - Be managed by Tauri and accessible to all command handlers and
@@ -11,6 +13,7 @@
1113
//! # ApplicationState Struct
1214
//!
1315
//! Defines the main `ApplicationState` struct, which is the central, shared,
16+
1417
//! thread-safe state container for the entire Mountain application. It is
1518
//! managed by Tauri and is accessible to all command handlers and Environment
1619
//! providers.
@@ -62,39 +65,66 @@ use crate::Environment::CommandProvider::CommandHandler;
6265
pub struct ApplicationState {
6366
// --- WorkSpace State ---
6467
pub WorkSpaceFolders:Arc<StandardMutex<Vec<WorkSpaceFolderStateDTO>>>,
68+
6569
pub WorkSpaceConfigurationPath:Arc<StandardMutex<Option<PathBuf>>>,
70+
6671
pub IsTrusted:Arc<AtomicBool>,
72+
6773
pub WindowState:Arc<StandardMutex<WindowStateDTO>>,
74+
6875
pub ActiveDocumentURI:Arc<StandardMutex<Option<String>>>,
6976

7077
// --- Configuration & Storage ---
7178
pub Configuration:Arc<StandardMutex<MergedConfigurationStateDTO>>,
79+
7280
pub GlobalMemento:Arc<StandardMutex<HashMap<String, serde_json::Value>>>,
81+
7382
pub GlobalMementoPath:PathBuf,
83+
7484
pub WorkSpaceMemento:Arc<StandardMutex<HashMap<String, serde_json::Value>>>,
85+
7586
pub WorkSpaceMementoPath:Arc<StandardMutex<Option<PathBuf>>>,
7687

7788
// --- Extension & Provider Management ---
7889
pub CommandRegistry:Arc<StandardMutex<HashMap<String, CommandHandler<Wry>>>>,
90+
7991
pub LanguageProviders:Arc<StandardMutex<HashMap<u32, ProviderRegistrationDTO>>>,
92+
8093
pub NextProviderHandle:Arc<AtomicU32>,
94+
8195
pub ScannedExtensions:Arc<StandardMutex<HashMap<String, ExtensionDescriptionStateDTO>>>,
96+
8297
pub EnabledProposedAPIs:Arc<StandardMutex<HashMap<String, Vec<String>>>>,
98+
8399
pub ExtensionScanPaths:Arc<StandardMutex<Vec<PathBuf>>>,
84100

85101
// --- Feature-specific State ---
86102
pub DiagnosticsMap:Arc<StandardMutex<HashMap<String, HashMap<String, Vec<MarkerDataDTO>>>>>,
103+
87104
pub OpenDocuments:Arc<StandardMutex<HashMap<String, DocumentStateDTO>>>,
105+
88106
pub OutputChannels:Arc<StandardMutex<HashMap<String, OutputChannelStateDTO>>>,
107+
89108
pub ActiveTerminals:Arc<StandardMutex<HashMap<u64, Arc<StandardMutex<TerminalStateDTO>>>>>,
109+
90110
pub NextTerminalIdentifier:Arc<AtomicU64>,
111+
91112
pub ActiveWebViews:Arc<StandardMutex<HashMap<String, WebViewStateDTO>>>,
113+
92114
pub ActiveCustomDocuments:Arc<StandardMutex<HashMap<String, CustomDocumentStateDTO>>>,
115+
93116
pub ActiveStatusBarItems:Arc<StandardMutex<HashMap<String, StatusBarEntryDTO>>>,
117+
94118
pub ActiveTreeViews:Arc<StandardMutex<HashMap<String, TreeViewStateDTO>>>,
119+
95120
pub SourceControlManagementProviders:Arc<StandardMutex<HashMap<u32, SourceControlManagementProviderDTO>>>,
96-
pub SourceControlManagementGroups:Arc<StandardMutex<HashMap<u32, HashMap<String, SourceControlManagementGroupDTO>>>>,
97-
pub SourceControlManagementResources:Arc<StandardMutex<HashMap<u32, HashMap<String, Vec<SourceControlManagementResourceDTO>>>>>,
121+
122+
pub SourceControlManagementGroups:
123+
Arc<StandardMutex<HashMap<u32, HashMap<String, SourceControlManagementGroupDTO>>>>,
124+
125+
pub SourceControlManagementResources:
126+
Arc<StandardMutex<HashMap<u32, HashMap<String, Vec<SourceControlManagementResourceDTO>>>>>,
127+
98128
pub NextSourceControlManagementProviderHandle:Arc<AtomicU32>,
99129

100130
// --- IPC & User Interface State ---
@@ -107,13 +137,16 @@ fn map_lock_error<T>(e:PoisonError<T>) -> CommonError { CommonError::StateLockPo
107137
impl Default for ApplicationState {
108138
fn default() -> Self {
109139
info!("[ApplicationState] Initializing default application state...");
140+
110141
let ApplicationNameForPaths = env!("CARGO_PKG_NAME");
142+
111143
let ApplicationDataDirectoryPath =
112144
dirs::config_dir().map(|p| p.join(ApplicationNameForPaths)).unwrap_or_else(|| {
113145
warn!(
114146
"[ApplicationState] Could not get config dir. Using relative path '.{}-appdata'.",
115147
ApplicationNameForPaths
116148
);
149+
117150
PathBuf::from(format!(".{}-appdata", ApplicationNameForPaths))
118151
});
119152

@@ -129,39 +162,70 @@ impl Default for ApplicationState {
129162
}
130163

131164
let GlobalMementoFilePath = Internal::ResolveMementoStorageFilePath(&ApplicationDataDirectoryPath, true, "");
165+
132166
let InitialGlobalMementoMap = Internal::LoadInitialMementoFromDisk(&GlobalMementoFilePath);
133167

134168
info!("[ApplicationState] Default state initialization complete.");
169+
135170
Self {
136171
WorkSpaceFolders:Arc::new(StandardMutex::new(Vec::new())),
172+
137173
WorkSpaceConfigurationPath:Arc::new(StandardMutex::new(None)),
174+
138175
IsTrusted:Arc::new(AtomicBool::new(false)),
176+
139177
WindowState:Arc::new(StandardMutex::new(Default::default())),
178+
140179
ActiveDocumentURI:Arc::new(StandardMutex::new(None)),
180+
141181
Configuration:Arc::new(StandardMutex::new(MergedConfigurationStateDTO::default())),
182+
142183
GlobalMemento:Arc::new(StandardMutex::new(InitialGlobalMementoMap)),
184+
143185
GlobalMementoPath:GlobalMementoFilePath,
186+
144187
WorkSpaceMemento:Arc::new(StandardMutex::new(HashMap::new())),
188+
145189
WorkSpaceMementoPath:Arc::new(StandardMutex::new(None)),
190+
146191
CommandRegistry:Arc::new(StandardMutex::new(HashMap::new())),
192+
147193
LanguageProviders:Arc::new(StandardMutex::new(HashMap::new())),
194+
148195
NextProviderHandle:Arc::new(AtomicU32::new(1)),
196+
149197
ScannedExtensions:Arc::new(StandardMutex::new(HashMap::new())),
198+
150199
EnabledProposedAPIs:Arc::new(StandardMutex::new(HashMap::new())),
200+
151201
ExtensionScanPaths:Arc::new(StandardMutex::new(Vec::new())),
202+
152203
DiagnosticsMap:Arc::new(StandardMutex::new(HashMap::new())),
204+
153205
OpenDocuments:Arc::new(StandardMutex::new(HashMap::new())),
206+
154207
OutputChannels:Arc::new(StandardMutex::new(HashMap::new())),
208+
155209
ActiveTerminals:Arc::new(StandardMutex::new(HashMap::new())),
210+
156211
NextTerminalIdentifier:Arc::new(AtomicU64::new(1)),
212+
157213
ActiveWebViews:Arc::new(StandardMutex::new(HashMap::new())),
214+
158215
ActiveCustomDocuments:Arc::new(StandardMutex::new(HashMap::new())),
216+
159217
ActiveStatusBarItems:Arc::new(StandardMutex::new(HashMap::new())),
218+
160219
ActiveTreeViews:Arc::new(StandardMutex::new(HashMap::new())),
220+
161221
SourceControlManagementProviders:Arc::new(StandardMutex::new(HashMap::new())),
222+
162223
SourceControlManagementGroups:Arc::new(StandardMutex::new(HashMap::new())),
224+
163225
SourceControlManagementResources:Arc::new(StandardMutex::new(HashMap::new())),
226+
164227
NextSourceControlManagementProviderHandle:Arc::new(AtomicU32::new(1)),
228+
165229
PendingUserInterfaceRequests:Arc::new(StandardMutex::new(HashMap::new())),
166230
}
167231
}
@@ -172,16 +236,21 @@ impl ApplicationState {
172236
/// workspace.
173237
pub fn GetWorkSpaceIdentifier(&self) -> Result<String, CommonError> {
174238
let ConfigurationPathGuard = self.WorkSpaceConfigurationPath.lock().map_err(map_lock_error)?;
239+
175240
if let Some(ConfigurationPath) = ConfigurationPathGuard.as_ref() {
176241
return Ok(ConfigurationPath.file_name().unwrap_or_default().to_string_lossy().into_owned());
177242
}
243+
178244
drop(ConfigurationPathGuard);
179245

180246
let FoldersGuard = self.WorkSpaceFolders.lock().map_err(map_lock_error)?;
247+
181248
if let Some(FirstFolder) = FoldersGuard.first() {
182249
let PathString = FirstFolder.URI.path();
250+
183251
// Create a more stable hash for the identifier.
184252
let Hash = format!("{:x}", md5::compute(PathString));
253+
185254
return Ok(format!(
186255
"{}-{}",
187256
FirstFolder.Name.replace(|c:char| !c.is_alphanumeric(), "_"),
@@ -199,36 +268,47 @@ impl ApplicationState {
199268
/// Returns the next available unique identifier for a terminal instance.
200269
pub fn GetNextTerminalIdentifier(&self) -> u64 { self.NextTerminalIdentifier.fetch_add(1, AtomicOrdering::Relaxed) }
201270

202-
/// Returns the next available unique identifier for an SourceControlManagement provider
203-
/// instance.
204-
pub fn GetNextSourceControlManagementProviderHandle(&self) -> u32 { self.NextSourceControlManagementProviderHandle.fetch_add(1, AtomicOrdering::Relaxed) }
271+
/// Returns the next available unique identifier for an
272+
/// SourceControlManagement provider instance.
273+
pub fn GetNextSourceControlManagementProviderHandle(&self) -> u32 {
274+
self.NextSourceControlManagementProviderHandle
275+
.fetch_add(1, AtomicOrdering::Relaxed)
276+
}
205277

206278
/// Updates the path to the workspace memento file and reloads its content
207279
/// from disk.
208280
pub fn UpdateWorkSpaceMementoPathAndReload(&self, ApplicationDataDirectory:&Path) -> Result<(), String> {
209281
let WorkSpaceIdentifier = self.GetWorkSpaceIdentifier().map_err(|e| e.to_string())?;
282+
210283
let mut PathGuard = self.WorkSpaceMementoPath.lock().map_err(|e| e.to_string())?;
211284

212285
if WorkSpaceIdentifier == "NO_WORKSPACE" {
213286
if PathGuard.is_some() {
214287
*PathGuard = None;
288+
215289
self.WorkSpaceMemento.lock().map_err(|e| e.to_string())?.clear();
216290
}
291+
217292
return Ok(());
218293
}
219294

220295
let NewMementoPath =
221296
Internal::ResolveMementoStorageFilePath(ApplicationDataDirectory, false, &WorkSpaceIdentifier);
297+
222298
if PathGuard.as_ref() != Some(&NewMementoPath) {
223299
if let Some(Parent) = NewMementoPath.parent() {
224300
if !Parent.exists() {
225301
std::fs::create_dir_all(Parent).map_err(|e| e.to_string())?;
226302
}
227303
}
304+
228305
*PathGuard = Some(NewMementoPath.clone());
306+
229307
let NewMementoContent = Internal::LoadInitialMementoFromDisk(&NewMementoPath);
308+
230309
*self.WorkSpaceMemento.lock().map_err(|e| e.to_string())? = NewMementoContent;
231310
}
311+
232312
Ok(())
233313
}
234314
}

Source/ApplicationState/DTO/DocumentStateDTO.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,25 @@ pub struct DocumentStateDTO {
1717
/// The unique resource identifier for this document.
1818
#[serde(with = "URLSerializationHelper")]
1919
pub URI:Url,
20+
2021
/// The VS Code language identifier (e.g., "rust", "typescript").
2122
pub LanguageIdentifier:String,
23+
2224
/// The version number, incremented on each change from the client.
2325
pub Version:i64,
26+
2427
/// The content of the document, split into lines.
2528
pub Lines:Vec<String>,
29+
2630
/// The detected end-of-line sequence (e.g., `\n` or `\r\n`).
2731
pub EOL:String,
32+
2833
/// A flag indicating if the in-memory version has unsaved changes.
2934
pub IsDirty:bool,
35+
3036
/// The detected file encoding (e.g., "utf8").
3137
pub Encoding:String,
38+
3239
/// An internal version number, used for tracking changes within the host.
3340
pub VersionIdentifier:i64,
3441
}
@@ -37,17 +44,26 @@ impl DocumentStateDTO {
3744
/// Creates a new `DocumentStateDTO` from its initial content.
3845
pub fn Create(URI:Url, LanguageIdentifier:Option<String>, Content:String) -> Self {
3946
let (Lines, EOL) = AnalyzeTextLinesAndEOL(&Content);
47+
4048
let LanguageID = LanguageIdentifier.unwrap_or_else(|| "plaintext".to_string());
49+
4150
let Encoding = "utf8".to_string();
4251

4352
Self {
4453
URI,
54+
4555
LanguageIdentifier:LanguageID,
56+
4657
Version:1,
58+
4759
Lines,
60+
4861
EOL,
62+
4963
IsDirty:false,
64+
5065
Encoding,
66+
5167
VersionIdentifier:1,
5268
}
5369
}
@@ -67,17 +83,25 @@ impl DocumentStateDTO {
6783

6884
let _RPCChanges:Vec<RPCModelContentChangeDTO> = match serde_json::from_value(ChangesValue.clone()) {
6985
Ok(changes) => changes,
86+
7087
Err(_) => {
7188
if let Some(FullText) = ChangesValue.as_str() {
7289
let (NewLines, NewEOL) = AnalyzeTextLinesAndEOL(FullText);
90+
7391
self.Lines = NewLines;
92+
7493
self.EOL = NewEOL;
94+
7595
self.Version = NewVersion;
96+
7697
// Increment internal version
7798
self.VersionIdentifier += 1;
99+
78100
self.IsDirty = true;
101+
79102
return Ok(());
80103
}
104+
81105
return Err(format!("Invalid RPCModelContentChangeDTO for {}", self.URI));
82106
},
83107
};
@@ -88,9 +112,12 @@ impl DocumentStateDTO {
88112
);
89113

90114
self.Version = NewVersion;
115+
91116
// Increment internal version
92117
self.VersionIdentifier += 1;
118+
93119
self.IsDirty = true;
120+
94121
Ok(())
95122
}
96123
}

Source/ApplicationState/DTO/ExtensionDescriptionStateDTO.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize};
99
use serde_json::Value;
1010

1111
/// Represents the deserialized content of an extension's `package.json` file,
12+
1213
/// augmented with location information and other metadata.
1314
///
1415
/// This is stored in `ApplicationState` to provide the extension host with the
@@ -19,29 +20,37 @@ pub struct ExtensionDescriptionStateDTO {
1920
// --- Core Metadata ---
2021
// DTO: { value: string, uuid?: string }
2122
pub Identifier:Value,
23+
2224
pub Name:String,
25+
2326
pub Version:String,
27+
2428
pub Publisher:String,
29+
2530
// DTO: { vscode: string }
2631
pub Engines:Value,
2732

2833
// --- Entry Points ---
2934
#[serde(skip_serializing_if = "Option::is_none")]
3035
pub Main:Option<String>,
36+
3137
#[serde(skip_serializing_if = "Option::is_none")]
3238
pub Browser:Option<String>,
3339

3440
// --- Type & Flags ---
3541
#[serde(rename = "Type", skip_serializing_if = "Option::is_none")]
3642
pub ModuleType:Option<String>,
43+
3744
#[serde(default)]
3845
pub IsBuiltin:bool,
46+
3947
#[serde(default)]
4048
pub IsUnderDevelopment:bool,
4149

4250
// --- Location & Activation ---
4351
// Serialized UriComponents DTO
4452
pub ExtensionLocation:Value,
53+
4554
#[serde(skip_serializing_if = "Option::is_none")]
4655
pub ActivationEvents:Option<Vec<String>>,
4756

0 commit comments

Comments
 (0)