@@ -35,21 +35,6 @@ pub enum Profile {
35
35
36
36
static PROFILE_DIR : & str = "src/bootstrap/defaults" ;
37
37
38
- /// A list of historical hashes of `src/etc/rust_analyzer_settings.json`.
39
- /// New entries should be appended whenever this is updated so we can detect
40
- /// outdated vs. user-modified settings files.
41
- static SETTINGS_HASHES : & [ & str ] = & [
42
- "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8" ,
43
- "56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922" ,
44
- "af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0" ,
45
- "3468fea433c25fff60be6b71e8a215a732a7b1268b6a83bf10d024344e140541" ,
46
- "47d227f424bf889b0d899b9cc992d5695e1b78c406e183cd78eafefbe5488923" ,
47
- "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a" ,
48
- "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000" ,
49
- "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d" ,
50
- ] ;
51
- static RUST_ANALYZER_SETTINGS : & str = include_str ! ( "../../../../etc/rust_analyzer_settings.json" ) ;
52
-
53
38
impl Profile {
54
39
fn include_path ( & self , src_path : & Path ) -> PathBuf {
55
40
PathBuf :: from ( format ! ( "{}/{PROFILE_DIR}/config.{}.toml" , src_path. display( ) , self ) )
@@ -533,46 +518,116 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
533
518
Ok ( ( ) )
534
519
}
535
520
536
- /// Sets up or displays `src/etc/rust_analyzer_settings.json`
537
- #[ derive( Clone , Debug , Eq , PartialEq , Hash ) ]
538
- pub struct Vscode ;
521
+ /// Handles editor-specific setup differences
522
+ #[ derive( Clone , Debug , Eq , PartialEq ) ]
523
+ enum EditorKind {
524
+ Vscode ,
525
+ Emacs ,
526
+ }
539
527
540
- impl Step for Vscode {
541
- type Output = ( ) ;
542
- const DEFAULT : bool = true ;
543
- fn should_run ( run : ShouldRun < ' _ > ) -> ShouldRun < ' _ > {
544
- run. alias ( "vscode" )
528
+ impl EditorKind {
529
+ /// A list of historical hashes of each LSP settings file
530
+ /// New entries should be appended whenever this is updated so we can detect
531
+ /// outdated vs. user-modified settings files.
532
+ fn hashes ( & self ) -> Vec < & str > {
533
+ match self {
534
+ EditorKind :: Vscode => vec ! [
535
+ "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8" ,
536
+ "56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922" ,
537
+ "af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0" ,
538
+ "3468fea433c25fff60be6b71e8a215a732a7b1268b6a83bf10d024344e140541" ,
539
+ "47d227f424bf889b0d899b9cc992d5695e1b78c406e183cd78eafefbe5488923" ,
540
+ "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a" ,
541
+ "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000" ,
542
+ "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d" ,
543
+ ] ,
544
+ EditorKind :: Emacs => vec ! [
545
+ "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0" ,
546
+ "1783df575969becc95dce9d9a9f180869a7d24545815714e05af10f4f078e5c4" ,
547
+ ] ,
548
+ }
545
549
}
546
- fn make_run ( run : RunConfig < ' _ > ) {
547
- if run. builder . config . dry_run ( ) {
548
- return ;
550
+
551
+ fn settings_path ( & self , config : & Config ) -> PathBuf {
552
+ config. src . join ( self . settings_short_path ( ) )
553
+ }
554
+
555
+ fn settings_short_path ( & self ) -> PathBuf {
556
+ match self {
557
+ EditorKind :: Vscode => PathBuf :: new ( ) . join ( ".vscode" ) . join ( "settings.json" ) ,
558
+ EditorKind :: Emacs => PathBuf :: new ( ) . join ( ".dir-locals.el" ) ,
549
559
}
550
- if let [ cmd] = & run. paths [ ..] {
551
- if cmd. assert_single_path ( ) . path . as_path ( ) . as_os_str ( ) == "vscode" {
552
- run. builder . ensure ( Vscode ) ;
553
- }
560
+ }
561
+
562
+ fn settings ( & self ) -> & str {
563
+ match self {
564
+ EditorKind :: Vscode => include_str ! ( "../../../../etc/rust_analyzer_settings.json" ) ,
565
+ EditorKind :: Emacs => include_str ! ( "../../../../etc/rust_analyzer_eglot.el" ) ,
554
566
}
555
567
}
556
- fn run ( self , builder : & Builder < ' _ > ) -> Self :: Output {
557
- let config = & builder. config ;
558
- if config. dry_run ( ) {
559
- return ;
568
+
569
+ fn backup_extension ( & self ) -> & str {
570
+ match self {
571
+ EditorKind :: Vscode => "json.bak" ,
572
+ EditorKind :: Emacs => "el.bak" ,
560
573
}
561
- while !t ! ( create_vscode_settings_maybe( config) ) { }
562
574
}
563
575
}
564
576
565
- /// Create a `.vscode/settings.json` file for rustc development, or just print it
577
+ /// Helper macro for implementing the necessary Step to support editor LSP setup
578
+ /// The first argument must match the argument set up in `flags.rs`
579
+ /// The second argument must match the name of some `EditorKind` variant
580
+ /// After using the macro, the editor needs to be registered in `builder.rs` with describe!()
581
+ macro_rules! impl_editor_support {
582
+ ( $( $editor: ident, $kind: ident) ,+ ) => { $(
583
+ #[ doc = concat!( " Sets up or displays the LSP config for " , stringify!( $editor) , "." ) ]
584
+ #[ derive( Clone , Debug , Eq , PartialEq , Hash ) ]
585
+ pub struct $kind;
586
+
587
+ impl Step for $kind {
588
+ type Output = ( ) ;
589
+ const DEFAULT : bool = true ;
590
+ fn should_run( run: ShouldRun <' _>) -> ShouldRun <' _> {
591
+ run. alias( stringify!( $editor) )
592
+ }
593
+ fn make_run( run: RunConfig <' _>) {
594
+ if run. builder. config. dry_run( ) {
595
+ return ;
596
+ }
597
+ if let [ cmd] = & run. paths[ ..] {
598
+ if cmd. assert_single_path( ) . path. as_path( ) . as_os_str( ) == stringify!( $editor) {
599
+ run. builder. ensure( $kind) ;
600
+ }
601
+ }
602
+ }
603
+ fn run( self , builder: & Builder <' _>) -> Self :: Output {
604
+ let config = & builder. config;
605
+ if config. dry_run( ) {
606
+ return ;
607
+ }
608
+ while !t!( create_editor_settings_maybe( config, EditorKind :: $kind) ) { }
609
+ }
610
+ }
611
+ ) +} ;
612
+ }
613
+
614
+ impl_editor_support ! ( vscode, Vscode ) ;
615
+ impl_editor_support ! ( emacs, Emacs ) ;
616
+
617
+ /// Create the recommended editor LSP config file for rustc development, or just print it
566
618
/// If this method should be re-called, it returns `false`.
567
- fn create_vscode_settings_maybe ( config : & Config ) -> io:: Result < bool > {
568
- let ( current_hash, historical_hashes) = SETTINGS_HASHES . split_last ( ) . unwrap ( ) ;
569
- let vscode_settings = config. src . join ( ".vscode" ) . join ( "settings.json" ) ;
570
- // If None, no settings.json exists
619
+ fn create_editor_settings_maybe ( config : & Config , editor : EditorKind ) -> io:: Result < bool > {
620
+ let hashes = editor. hashes ( ) ;
621
+ let ( current_hash, historical_hashes) = hashes. split_last ( ) . unwrap ( ) ;
622
+ let settings_path = editor. settings_path ( config) ;
623
+ let settings_short_path = editor. settings_short_path ( ) ;
624
+ let settings_filename = settings_short_path. to_str ( ) . unwrap ( ) ;
625
+ // If None, no settings file exists
571
626
// If Some(true), is a previous version of settings.json
572
627
// If Some(false), is not a previous version (i.e. user modified)
573
628
// If it's up to date we can just skip this
574
629
let mut mismatched_settings = None ;
575
- if let Ok ( current) = fs:: read_to_string ( & vscode_settings ) {
630
+ if let Ok ( current) = fs:: read_to_string ( & settings_path ) {
576
631
let mut hasher = sha2:: Sha256 :: new ( ) ;
577
632
hasher. update ( & current) ;
578
633
let hash = hex_encode ( hasher. finalize ( ) . as_slice ( ) ) ;
@@ -585,20 +640,23 @@ fn create_vscode_settings_maybe(config: &Config) -> io::Result<bool> {
585
640
}
586
641
}
587
642
println ! (
588
- "\n x.py can automatically install the recommended `.vscode/settings.json ` file for rustc development"
643
+ "\n x.py can automatically install the recommended `{settings_filename} ` file for rustc development"
589
644
) ;
645
+
590
646
match mismatched_settings {
591
647
Some ( true ) => eprintln ! (
592
- "WARNING: existing `.vscode/settings.json` is out of date, x.py will update it"
648
+ "WARNING: existing `{}` is out of date, x.py will update it" ,
649
+ settings_filename
593
650
) ,
594
651
Some ( false ) => eprintln ! (
595
- "WARNING: existing `.vscode/settings.json` has been modified by user, x.py will back it up and replace it"
652
+ "WARNING: existing `{}` has been modified by user, x.py will back it up and replace it" ,
653
+ settings_filename
596
654
) ,
597
655
_ => ( ) ,
598
656
}
599
- let should_create = match prompt_user (
600
- "Would you like to create/update settings.json ? (Press 'p' to preview values): [y/N]" ,
601
- ) ? {
657
+ let should_create = match prompt_user ( & format ! (
658
+ "Would you like to create/update `{settings_filename}` ? (Press 'p' to preview values): [y/N]"
659
+ ) ) ? {
602
660
Some ( PromptResult :: Yes ) => true ,
603
661
Some ( PromptResult :: Print ) => false ,
604
662
_ => {
@@ -607,28 +665,32 @@ fn create_vscode_settings_maybe(config: &Config) -> io::Result<bool> {
607
665
}
608
666
} ;
609
667
if should_create {
610
- let path = config . src . join ( ".vscode" ) ;
668
+ let path = settings_path . as_path ( ) . parent ( ) . unwrap ( ) ;
611
669
if !path. exists ( ) {
612
- fs:: create_dir ( & path) ?;
670
+ fs:: create_dir ( path) ?;
613
671
}
614
672
let verb = match mismatched_settings {
615
673
// exists but outdated, we can replace this
616
674
Some ( true ) => "Updated" ,
617
675
// exists but user modified, back it up
618
676
Some ( false ) => {
619
677
// exists and is not current version or outdated, so back it up
620
- let mut backup = vscode_settings. clone ( ) ;
621
- backup. set_extension ( "json.bak" ) ;
622
- eprintln ! ( "WARNING: copying `settings.json` to `settings.json.bak`" ) ;
623
- fs:: copy ( & vscode_settings, & backup) ?;
678
+ let mut backup = settings_path. clone ( ) ;
679
+ backup. set_extension ( editor. backup_extension ( ) ) ;
680
+ eprintln ! (
681
+ "WARNING: copying `{}` to `{}`" ,
682
+ settings_path. file_name( ) . unwrap( ) . to_str( ) . unwrap( ) ,
683
+ backup. file_name( ) . unwrap( ) . to_str( ) . unwrap( ) ,
684
+ ) ;
685
+ fs:: copy ( & settings_path, & backup) ?;
624
686
"Updated"
625
687
}
626
688
_ => "Created" ,
627
689
} ;
628
- fs:: write ( & vscode_settings , RUST_ANALYZER_SETTINGS ) ?;
629
- println ! ( "{verb} `.vscode/settings.json`" ) ;
690
+ fs:: write ( & settings_path , editor . settings ( ) ) ?;
691
+ println ! ( "{verb} `{}`" , settings_filename ) ;
630
692
} else {
631
- println ! ( "\n {RUST_ANALYZER_SETTINGS}" ) ;
693
+ println ! ( "\n {}" , editor . settings ( ) ) ;
632
694
}
633
695
Ok ( should_create)
634
696
}
0 commit comments