@@ -24,8 +24,14 @@ pub enum ConfigTreeError {
24
24
/// Some rust-analyzer.toml files have changed, and/or the LSP client sent a new configuration.
25
25
pub struct ConfigChanges {
26
26
ra_toml_changes : Vec < vfs:: ChangedFile > ,
27
- xdg_config_change : Option < Arc < ConfigInput > > ,
28
- client_change : Option < Arc < ConfigInput > > ,
27
+ /// - `None` => no change
28
+ /// - `Some(None)` => the XDG_CONFIG_HOME rust-analyzer.toml file was deleted
29
+ /// - `Some(Some(...))` => the XDG_CONFIG_HOME rust-analyzer.toml file was updated
30
+ xdg_config_change : Option < Option < Arc < ConfigInput > > > ,
31
+ /// - `None` => no change
32
+ /// - `Some(None)` => the client config was removed / reset or something
33
+ /// - `Some(Some(...))` => the client config was updated
34
+ client_change : Option < Option < Arc < ConfigInput > > > ,
29
35
parent_changes : Vec < ConfigParentChange > ,
30
36
}
31
37
@@ -96,14 +102,13 @@ slotmap::new_key_type! {
96
102
97
103
struct ConfigNode {
98
104
src : ConfigSource ,
99
- // TODO: make option
100
- input : Arc < ConfigInput > ,
105
+ input : Option < Arc < ConfigInput > > ,
101
106
computed : ComputedIdx ,
102
107
}
103
108
104
109
struct ConfigTree {
105
110
tree : indextree:: Arena < ConfigNode > ,
106
- client_config : Arc < ConfigInput > ,
111
+ client_config : Option < Arc < ConfigInput > > ,
107
112
xdg_config_node_id : NodeId ,
108
113
ra_file_id_map : FxHashMap < FileId , NodeId > ,
109
114
computed : SlotMap < ComputedIdx , Option < Arc < LocalConfigData > > > ,
@@ -117,6 +122,9 @@ fn parse_toml(
117
122
) -> Option < Arc < ConfigInput > > {
118
123
let content = vfs. file_contents ( file_id) ;
119
124
let path = vfs. file_path ( file_id) ;
125
+ if content. is_empty ( ) {
126
+ return None ;
127
+ }
120
128
let content_str = match std:: str:: from_utf8 ( content) {
121
129
Err ( e) => {
122
130
tracing:: error!( "non-UTF8 TOML content for {path}: {e}" ) ;
@@ -146,18 +154,12 @@ impl ConfigTree {
146
154
let mut ra_file_id_map = FxHashMap :: default ( ) ;
147
155
let xdg_config = tree. new_node ( ConfigNode {
148
156
src : ConfigSource :: RaToml ( xdg_config_file_id) ,
149
- input : Arc :: new ( ConfigInput :: default ( ) ) ,
157
+ input : None ,
150
158
computed : computed. insert ( Option :: < Arc < LocalConfigData > > :: None ) ,
151
159
} ) ;
152
160
ra_file_id_map. insert ( xdg_config_file_id, xdg_config) ;
153
161
154
- Self {
155
- client_config : Arc :: new ( Default :: default ( ) ) ,
156
- xdg_config_node_id : xdg_config,
157
- ra_file_id_map,
158
- tree,
159
- computed,
160
- }
162
+ Self { client_config : None , xdg_config_node_id : xdg_config, ra_file_id_map, tree, computed }
161
163
}
162
164
163
165
fn read_only ( & self , file_id : FileId ) -> Result < Option < Arc < LocalConfigData > > , ConfigTreeError > {
@@ -190,12 +192,20 @@ impl ConfigTree {
190
192
{
191
193
let self_input = node. input . clone ( ) ;
192
194
let parent_computed = self . compute_inner ( parent) ?;
193
- Arc :: new ( parent_computed. clone_with_overrides ( self_input. local . clone ( ) ) )
195
+ if let Some ( input) = self_input. as_deref ( ) {
196
+ Arc :: new ( parent_computed. clone_with_overrides ( input. local . clone ( ) ) )
197
+ } else {
198
+ parent_computed
199
+ }
194
200
} else {
195
201
// We have hit a root node
196
202
let self_input = node. input . clone ( ) ;
197
- let root_local = RootLocalConfigData :: from_root_input ( self_input. local . clone ( ) ) ;
198
- Arc :: new ( root_local. 0 )
203
+ if let Some ( input) = self_input. as_deref ( ) {
204
+ let root_local = RootLocalConfigData :: from_root_input ( input. local . clone ( ) ) ;
205
+ Arc :: new ( root_local. 0 )
206
+ } else {
207
+ Arc :: new ( LocalConfigData :: default ( ) )
208
+ }
199
209
} ;
200
210
// Get a new &mut slot because self.compute(parent) also gets mut access
201
211
let slot = & mut self . computed [ idx] ;
@@ -204,7 +214,7 @@ impl ConfigTree {
204
214
}
205
215
}
206
216
207
- fn insert_toml ( & mut self , file_id : FileId , input : Arc < ConfigInput > ) -> NodeId {
217
+ fn insert_toml ( & mut self , file_id : FileId , input : Option < Arc < ConfigInput > > ) -> NodeId {
208
218
let computed = self . computed . insert ( None ) ;
209
219
let node =
210
220
self . tree . new_node ( ConfigNode { src : ConfigSource :: RaToml ( file_id) , input, computed } ) ;
@@ -215,7 +225,7 @@ impl ConfigTree {
215
225
fn update_toml (
216
226
& mut self ,
217
227
file_id : FileId ,
218
- input : Arc < ConfigInput > ,
228
+ input : Option < Arc < ConfigInput > > ,
219
229
) -> Result < ( ) , ConfigTreeError > {
220
230
let Some ( node_id) = self . ra_file_id_map . get ( & file_id) . cloned ( ) else {
221
231
return Err ( ConfigTreeError :: NonExistent ) ;
@@ -281,13 +291,11 @@ impl ConfigTree {
281
291
// turn and face the strain
282
292
match change. change_kind {
283
293
vfs:: ChangeKind :: Create => {
284
- let input = parse_toml ( change. file_id , vfs, & mut scratch_errors, errors)
285
- . unwrap_or_default ( ) ;
294
+ let input = parse_toml ( change. file_id , vfs, & mut scratch_errors, errors) ;
286
295
let _new_node = self . insert_toml ( change. file_id , input) ;
287
296
}
288
297
vfs:: ChangeKind :: Modify => {
289
- let input = parse_toml ( change. file_id , vfs, & mut scratch_errors, errors)
290
- . unwrap_or_default ( ) ;
298
+ let input = parse_toml ( change. file_id , vfs, & mut scratch_errors, errors) ;
291
299
if let Err ( e) = self . update_toml ( change. file_id , input) {
292
300
errors. push ( e) ;
293
301
}
0 commit comments