@@ -782,7 +782,6 @@ pub struct Config {
782
782
/// | Windows | `{FOLDERID_RoamingAppData}` | C:\Users\Alice\AppData\Roaming |
783
783
user_config_path : VfsPath ,
784
784
785
- /// FIXME @alibektas : Change this to sth better.
786
785
/// Config node whose values apply to **every** Rust project.
787
786
user_config : Option < ( GlobalLocalConfigInput , ConfigErrors ) > ,
788
787
@@ -798,6 +797,13 @@ pub struct Config {
798
797
/// Clone of the value that is stored inside a `GlobalState`.
799
798
source_root_parent_map : Arc < FxHashMap < SourceRootId , SourceRootId > > ,
800
799
800
+ /// Use case : It is an error to have an empty value for `check_command`.
801
+ /// Since it is a `global` command at the moment, its final value can only be determined by
802
+ /// traversing through `global` configs and the `client` config. However the non-null value constraint
803
+ /// is config level agnostic, so this requires an independent error storage
804
+ /// FIXME : bad name I know...
805
+ other_errors : ConfigErrors ,
806
+
801
807
detached_files : Vec < AbsPathBuf > ,
802
808
}
803
809
@@ -827,6 +833,7 @@ impl Config {
827
833
/// The return tuple's bool component signals whether the `GlobalState` should call its `update_configuration()` method.
828
834
fn apply_change_with_sink ( & self , change : ConfigChange ) -> ( Config , bool ) {
829
835
let mut config = self . clone ( ) ;
836
+ config. other_errors = ConfigErrors :: default ( ) ;
830
837
831
838
let mut should_update = false ;
832
839
@@ -855,6 +862,7 @@ impl Config {
855
862
856
863
if let Some ( mut json) = change. client_config_change {
857
864
tracing:: info!( "updating config from JSON: {:#}" , json) ;
865
+
858
866
if !( json. is_null ( ) || json. as_object ( ) . map_or ( false , |it| it. is_empty ( ) ) ) {
859
867
let mut json_errors = vec ! [ ] ;
860
868
let detached_files = get_field :: < Vec < Utf8PathBuf > > (
@@ -870,6 +878,38 @@ impl Config {
870
878
871
879
patch_old_style:: patch_json_for_outdated_configs ( & mut json) ;
872
880
881
+ // IMPORTANT : This holds as long as ` completion_snippets_custom` is declared `client`.
882
+ config. snippets . clear ( ) ;
883
+
884
+ let snips = self . completion_snippets_custom ( ) . to_owned ( ) ;
885
+
886
+ for ( name, def) in snips. iter ( ) {
887
+ if def. prefix . is_empty ( ) && def. postfix . is_empty ( ) {
888
+ continue ;
889
+ }
890
+ let scope = match def. scope {
891
+ SnippetScopeDef :: Expr => SnippetScope :: Expr ,
892
+ SnippetScopeDef :: Type => SnippetScope :: Type ,
893
+ SnippetScopeDef :: Item => SnippetScope :: Item ,
894
+ } ;
895
+ #[ allow( clippy:: single_match) ]
896
+ match Snippet :: new (
897
+ & def. prefix ,
898
+ & def. postfix ,
899
+ & def. body ,
900
+ def. description . as_ref ( ) . unwrap_or ( name) ,
901
+ & def. requires ,
902
+ scope,
903
+ ) {
904
+ Some ( snippet) => config. snippets . push ( snippet) ,
905
+ None => json_errors. push ( (
906
+ name. to_owned ( ) ,
907
+ <serde_json:: Error as serde:: de:: Error >:: custom ( format ! (
908
+ "snippet {name} is invalid or triggers are missing" ,
909
+ ) ) ,
910
+ ) ) ,
911
+ }
912
+ }
873
913
config. client_config = (
874
914
FullConfigInput :: from_json ( json, & mut json_errors) ,
875
915
ConfigErrors (
@@ -909,8 +949,15 @@ impl Config {
909
949
) ) ;
910
950
should_update = true ;
911
951
}
912
- // FIXME
913
- Err ( _) => ( ) ,
952
+ Err ( e) => {
953
+ config. root_ratoml = Some ( (
954
+ GlobalLocalConfigInput :: from_toml ( toml:: map:: Map :: default ( ) , & mut vec ! [ ] ) ,
955
+ ConfigErrors ( vec ! [ ConfigErrorInner :: ParseError {
956
+ reason: e. message( ) . to_owned( ) ,
957
+ }
958
+ . into( ) ] ) ,
959
+ ) ) ;
960
+ }
914
961
}
915
962
}
916
963
@@ -945,8 +992,18 @@ impl Config {
945
992
) ,
946
993
) ;
947
994
}
948
- // FIXME
949
- Err ( _) => ( ) ,
995
+ Err ( e) => {
996
+ config. root_ratoml = Some ( (
997
+ GlobalLocalConfigInput :: from_toml (
998
+ toml:: map:: Map :: default ( ) ,
999
+ & mut vec ! [ ] ,
1000
+ ) ,
1001
+ ConfigErrors ( vec ! [ ConfigErrorInner :: ParseError {
1002
+ reason: e. message( ) . to_owned( ) ,
1003
+ }
1004
+ . into( ) ] ) ,
1005
+ ) ) ;
1006
+ }
950
1007
}
951
1008
}
952
1009
}
@@ -956,48 +1013,13 @@ impl Config {
956
1013
config. source_root_parent_map = source_root_map;
957
1014
}
958
1015
959
- // IMPORTANT : This holds as long as ` completion_snippets_custom` is declared `client`.
960
- config. snippets . clear ( ) ;
961
-
962
- let snips = self . completion_snippets_custom ( ) . to_owned ( ) ;
963
-
964
- for ( name, def) in snips. iter ( ) {
965
- if def. prefix . is_empty ( ) && def. postfix . is_empty ( ) {
966
- continue ;
967
- }
968
- let scope = match def. scope {
969
- SnippetScopeDef :: Expr => SnippetScope :: Expr ,
970
- SnippetScopeDef :: Type => SnippetScope :: Type ,
971
- SnippetScopeDef :: Item => SnippetScope :: Item ,
972
- } ;
973
- #[ allow( clippy:: single_match) ]
974
- match Snippet :: new (
975
- & def. prefix ,
976
- & def. postfix ,
977
- & def. body ,
978
- def. description . as_ref ( ) . unwrap_or ( name) ,
979
- & def. requires ,
980
- scope,
981
- ) {
982
- Some ( snippet) => config. snippets . push ( snippet) ,
983
- // FIXME
984
- // None => error_sink.0.push(ConfigErrorInner::Json {
985
- // config_key: "".to_owned(),
986
- // error: <serde_json::Error as serde::de::Error>::custom(format!(
987
- // "snippet {name} is invalid or triggers are missing",
988
- // )),
989
- // }),
990
- None => ( ) ,
991
- }
1016
+ if config. check_command ( ) . is_empty ( ) {
1017
+ config. other_errors . 0 . push ( Arc :: new ( ConfigErrorInner :: Json {
1018
+ config_key : "/check/command" . to_owned ( ) ,
1019
+ error : serde_json:: Error :: custom ( "expected a non-empty string" ) ,
1020
+ } ) ) ;
992
1021
}
993
1022
994
- // FIXME: bring this back
995
- // if config.check_command().is_empty() {
996
- // error_sink.0.push(ConfigErrorInner::Json {
997
- // config_key: "/check/command".to_owned(),
998
- // error: serde_json::Error::custom("expected a non-empty string"),
999
- // });
1000
- // }
1001
1023
( config, should_update)
1002
1024
}
1003
1025
@@ -1015,6 +1037,7 @@ impl Config {
1015
1037
. chain ( config. root_ratoml . as_ref ( ) . into_iter ( ) . flat_map ( |it| it. 1 . 0 . iter ( ) ) )
1016
1038
. chain ( config. user_config . as_ref ( ) . into_iter ( ) . flat_map ( |it| it. 1 . 0 . iter ( ) ) )
1017
1039
. chain ( config. ratoml_files . values ( ) . flat_map ( |it| it. 1 . 0 . iter ( ) ) )
1040
+ . chain ( config. other_errors . 0 . iter ( ) )
1018
1041
. cloned ( )
1019
1042
. collect ( ) ,
1020
1043
) ;
@@ -1262,9 +1285,10 @@ pub struct ClientCommandsConfig {
1262
1285
pub enum ConfigErrorInner {
1263
1286
Json { config_key : String , error : serde_json:: Error } ,
1264
1287
Toml { config_key : String , error : toml:: de:: Error } ,
1288
+ ParseError { reason : String } ,
1265
1289
}
1266
1290
1267
- #[ derive( Clone , Debug ) ]
1291
+ #[ derive( Clone , Debug , Default ) ]
1268
1292
pub struct ConfigErrors ( Vec < Arc < ConfigErrorInner > > ) ;
1269
1293
1270
1294
impl ConfigErrors {
@@ -1286,6 +1310,7 @@ impl fmt::Display for ConfigErrors {
1286
1310
f ( & ": " ) ?;
1287
1311
f ( e)
1288
1312
}
1313
+ ConfigErrorInner :: ParseError { reason } => f ( reason) ,
1289
1314
} ) ;
1290
1315
write ! ( f, "invalid config value{}:\n {}" , if self . 0 . len( ) == 1 { "" } else { "s" } , errors)
1291
1316
}
@@ -1339,6 +1364,7 @@ impl Config {
1339
1364
root_ratoml : None ,
1340
1365
root_ratoml_path,
1341
1366
detached_files : Default :: default ( ) ,
1367
+ other_errors : Default :: default ( ) ,
1342
1368
}
1343
1369
}
1344
1370
@@ -2580,6 +2606,7 @@ macro_rules! _impl_for_config_data {
2580
2606
}
2581
2607
}
2582
2608
2609
+
2583
2610
& self . default_config. global. $field
2584
2611
}
2585
2612
) *
@@ -3309,7 +3336,7 @@ fn validate_toml_table(
3309
3336
ptr. push_str ( k) ;
3310
3337
3311
3338
match v {
3312
- // This is a table config, any entry in it is therefor valid
3339
+ // This is a table config, any entry in it is therefore valid
3313
3340
toml:: Value :: Table ( _) if verify ( ptr) => ( ) ,
3314
3341
toml:: Value :: Table ( table) => validate_toml_table ( known_ptrs, table, ptr, error_sink) ,
3315
3342
_ if !verify ( ptr) => error_sink
0 commit comments