@@ -18,7 +18,6 @@ use ide_db::{
1818 imports:: insert_use:: { ImportGranularity , InsertUseConfig , PrefixKind } ,
1919 SnippetCap ,
2020} ;
21- use indexmap:: IndexMap ;
2221use itertools:: Itertools ;
2322use lsp_types:: { ClientCapabilities , MarkupKind } ;
2423use paths:: { Utf8Path , Utf8PathBuf } ;
@@ -382,8 +381,7 @@ config_data! {
382381 /// Enables completions of private items and fields that are defined in the current workspace even if they are not visible at the current position.
383382 completion_privateEditable_enable: bool = false ,
384383 /// Custom completion snippets.
385- // NOTE: we use IndexMap for deterministic serialization ordering
386- completion_snippets_custom: IndexMap <String , SnippetDef > = serde_json:: from_str( r#"{
384+ completion_snippets_custom: FxHashMap <String , SnippetDef > = serde_json:: from_str( r#"{
387385 "Arc::new": {
388386 "postfix": "arc",
389387 "body": "Arc::new(${receiver})",
@@ -1243,7 +1241,19 @@ impl Config {
12431241 }
12441242
12451243 pub fn json_schema ( ) -> serde_json:: Value {
1246- FullConfigInput :: json_schema ( )
1244+ let mut s = FullConfigInput :: json_schema ( ) ;
1245+
1246+ fn sort_objects_by_field ( json : & mut serde_json:: Value ) {
1247+ if let serde_json:: Value :: Object ( object) = json {
1248+ let old = std:: mem:: take ( object) ;
1249+ old. into_iter ( ) . sorted_by ( |( k, _) , ( k2, _) | k. cmp ( k2) ) . for_each ( |( k, mut v) | {
1250+ sort_objects_by_field ( & mut v) ;
1251+ object. insert ( k, v) ;
1252+ } ) ;
1253+ }
1254+ }
1255+ sort_objects_by_field ( & mut s) ;
1256+ s
12471257 }
12481258
12491259 pub fn root_path ( & self ) -> & AbsPathBuf {
@@ -2640,9 +2650,8 @@ macro_rules! _config_data {
26402650
26412651 /// All fields `Option<T>`, `None` representing fields not set in a particular JSON/TOML blob.
26422652 #[ allow( non_snake_case) ]
2643- #[ derive( Clone , Serialize , Default ) ]
2653+ #[ derive( Clone , Default ) ]
26442654 struct $input { $(
2645- #[ serde( skip_serializing_if = "Option::is_none" ) ]
26462655 $field: Option <$ty>,
26472656 ) * }
26482657
@@ -2725,7 +2734,7 @@ struct DefaultConfigData {
27252734/// All of the config levels, all fields `Option<T>`, to describe fields that are actually set by
27262735/// some rust-analyzer.toml file or JSON blob. An empty rust-analyzer.toml corresponds to
27272736/// all fields being None.
2728- #[ derive( Debug , Clone , Default , Serialize ) ]
2737+ #[ derive( Debug , Clone , Default ) ]
27292738struct FullConfigInput {
27302739 global : GlobalConfigInput ,
27312740 local : LocalConfigInput ,
@@ -2770,7 +2779,7 @@ impl FullConfigInput {
27702779/// All of the config levels, all fields `Option<T>`, to describe fields that are actually set by
27712780/// some rust-analyzer.toml file or JSON blob. An empty rust-analyzer.toml corresponds to
27722781/// all fields being None.
2773- #[ derive( Debug , Clone , Default , Serialize ) ]
2782+ #[ derive( Debug , Clone , Default ) ]
27742783struct GlobalLocalConfigInput {
27752784 global : GlobalConfigInput ,
27762785 local : LocalConfigInput ,
@@ -2932,7 +2941,7 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
29322941 "FxHashMap<Box<str>, Box<[Box<str>]>>" => set ! {
29332942 "type" : "object" ,
29342943 } ,
2935- "IndexMap <String, SnippetDef>" => set ! {
2944+ "FxHashMap <String, SnippetDef>" => set ! {
29362945 "type" : "object" ,
29372946 } ,
29382947 "FxHashMap<String, String>" => set ! {
@@ -3347,6 +3356,7 @@ mod tests {
33473356 #[ test]
33483357 fn generate_package_json_config ( ) {
33493358 let s = Config :: json_schema ( ) ;
3359+
33503360 let schema = format ! ( "{s:#}" ) ;
33513361 let mut schema = schema
33523362 . trim_start_matches ( '[' )
0 commit comments