@@ -34,10 +34,10 @@ pub enum Profile {
3434
3535static PROFILE_DIR : & str = "src/bootstrap/defaults" ;
3636
37- /// A list of historical hashes of `src/etc/rust_analyzer_settings .json`.
38- /// New entries should be appended whenever this is updated so we can detect
37+ /// A list of historical SHA-256 hashes of `src/etc/vscode_settings .json`. New
38+ /// entries should be appended whenever this is updated so we can detect
3939/// outdated vs. user-modified settings files.
40- static SETTINGS_HASHES : & [ & str ] = & [
40+ static VSCODE_SETTINGS_HASHES : & [ & str ] = & [
4141 "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8" ,
4242 "56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922" ,
4343 "af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0" ,
@@ -46,7 +46,14 @@ static SETTINGS_HASHES: &[&str] = &[
4646 "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a" ,
4747 "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000" ,
4848] ;
49- static RUST_ANALYZER_SETTINGS : & str = include_str ! ( "../../../../etc/rust_analyzer_settings.json" ) ;
49+ static VSCODE_SETTINGS : & str = include_str ! ( "../../../../etc/vscode_settings.json" ) ;
50+
51+ /// A list of historical SHA-256 hashes of `src/etc/zed_settings.json`. New
52+ /// entries should be appended whenever this is updated so we can detect
53+ /// outdated vs. user-modified settings files.
54+ static ZED_SETTINGS_HASHES : & [ & str ] =
55+ & [ "08bb47a0a93947284102eece102cb2e21a91ff952bf21798df92590e31240d98" ] ;
56+ static ZED_SETTINGS : & str = include_str ! ( "../../../../etc/zed_settings.json" ) ;
5057
5158impl Profile {
5259 fn include_path ( & self , src_path : & Path ) -> PathBuf {
@@ -527,11 +534,11 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
527534 Ok ( ( ) )
528535}
529536
530- /// Sets up or displays `src/etc/rust_analyzer_settings .json`
537+ /// Sets up or displays `src/etc/vscode_settings .json`
531538#[ derive( Clone , Debug , Eq , PartialEq , Hash ) ]
532- pub struct Vscode ;
539+ pub struct VsCode ;
533540
534- impl Step for Vscode {
541+ impl Step for VsCode {
535542 type Output = ( ) ;
536543 const DEFAULT : bool = true ;
537544 fn should_run ( run : ShouldRun < ' _ > ) -> ShouldRun < ' _ > {
@@ -543,7 +550,7 @@ impl Step for Vscode {
543550 }
544551 if let [ cmd] = & run. paths [ ..] {
545552 if cmd. assert_single_path ( ) . path . as_path ( ) . as_os_str ( ) == "vscode" {
546- run. builder . ensure ( Vscode ) ;
553+ run. builder . ensure ( VsCode ) ;
547554 }
548555 }
549556 }
@@ -559,7 +566,7 @@ impl Step for Vscode {
559566/// Create a `.vscode/settings.json` file for rustc development, or just print it
560567/// If this method should be re-called, it returns `false`.
561568fn create_vscode_settings_maybe ( config : & Config ) -> io:: Result < bool > {
562- let ( current_hash, historical_hashes) = SETTINGS_HASHES . split_last ( ) . unwrap ( ) ;
569+ let ( current_hash, historical_hashes) = VSCODE_SETTINGS_HASHES . split_last ( ) . unwrap ( ) ;
563570 let vscode_settings = config. src . join ( ".vscode" ) . join ( "settings.json" ) ;
564571 // If None, no settings.json exists
565572 // If Some(true), is a previous version of settings.json
@@ -619,10 +626,110 @@ fn create_vscode_settings_maybe(config: &Config) -> io::Result<bool> {
619626 }
620627 _ => "Created" ,
621628 } ;
622- fs:: write ( & vscode_settings, RUST_ANALYZER_SETTINGS ) ?;
629+ fs:: write ( & vscode_settings, VSCODE_SETTINGS ) ?;
623630 println ! ( "{verb} `.vscode/settings.json`" ) ;
624631 } else {
625- println ! ( "\n {RUST_ANALYZER_SETTINGS}" ) ;
632+ println ! ( "\n {VSCODE_SETTINGS}" ) ;
633+ }
634+ Ok ( should_create)
635+ }
636+
637+ /// Sets up or displays `src/etc/zed_settings.json`
638+ #[ derive( Clone , Debug , Eq , PartialEq , Hash ) ]
639+ pub struct Zed ;
640+
641+ impl Step for Zed {
642+ type Output = ( ) ;
643+ const DEFAULT : bool = true ;
644+ fn should_run ( run : ShouldRun < ' _ > ) -> ShouldRun < ' _ > {
645+ run. alias ( "zed" )
646+ }
647+ fn make_run ( run : RunConfig < ' _ > ) {
648+ if run. builder . config . dry_run ( ) {
649+ return ;
650+ }
651+ if let [ cmd] = & run. paths [ ..] {
652+ if cmd. assert_single_path ( ) . path . as_path ( ) . as_os_str ( ) == "zed" {
653+ run. builder . ensure ( Zed ) ;
654+ }
655+ }
656+ }
657+ fn run ( self , builder : & Builder < ' _ > ) -> Self :: Output {
658+ let config = & builder. config ;
659+ if config. dry_run ( ) {
660+ return ;
661+ }
662+ while !t ! ( create_zed_settings_maybe( config) ) { }
663+ }
664+ }
665+
666+ /// Create a `.zed/settings.json` file for rustc development, or just print it
667+ /// If this method should be re-called, it returns `false`.
668+ fn create_zed_settings_maybe ( config : & Config ) -> io:: Result < bool > {
669+ let ( current_hash, historical_hashes) = ZED_SETTINGS_HASHES . split_last ( ) . unwrap ( ) ;
670+ let zed_settings = config. src . join ( ".zed" ) . join ( "settings.json" ) ;
671+ // If None, no settings.json exists
672+ // If Some(true), is a previous version of settings.json
673+ // If Some(false), is not a previous version (i.e. user modified)
674+ // If it's up to date we can just skip this
675+ let mut mismatched_settings = None ;
676+ if let Ok ( current) = fs:: read_to_string ( & zed_settings) {
677+ let mut hasher = sha2:: Sha256 :: new ( ) ;
678+ hasher. update ( & current) ;
679+ let hash = hex_encode ( hasher. finalize ( ) . as_slice ( ) ) ;
680+ if hash == * current_hash {
681+ return Ok ( true ) ;
682+ } else if historical_hashes. contains ( & hash. as_str ( ) ) {
683+ mismatched_settings = Some ( true ) ;
684+ } else {
685+ mismatched_settings = Some ( false ) ;
686+ }
687+ }
688+ println ! (
689+ "\n x.py can automatically install the recommended `.zed/settings.json` file for rustc development"
690+ ) ;
691+ match mismatched_settings {
692+ Some ( true ) => eprintln ! (
693+ "WARNING: existing `.zed/settings.json` is out of date, x.py will update it"
694+ ) ,
695+ Some ( false ) => eprintln ! (
696+ "WARNING: existing `.zed/settings.json` has been modified by user, x.py will back it up and replace it"
697+ ) ,
698+ _ => ( ) ,
699+ }
700+ let should_create = match prompt_user (
701+ "Would you like to create/update settings.json? (Press 'p' to preview values): [y/N]" ,
702+ ) ? {
703+ Some ( PromptResult :: Yes ) => true ,
704+ Some ( PromptResult :: Print ) => false ,
705+ _ => {
706+ println ! ( "Ok, skipping settings!" ) ;
707+ return Ok ( true ) ;
708+ }
709+ } ;
710+ if should_create {
711+ let path = config. src . join ( ".zed" ) ;
712+ if !path. exists ( ) {
713+ fs:: create_dir ( & path) ?;
714+ }
715+ let verb = match mismatched_settings {
716+ // exists but outdated, we can replace this
717+ Some ( true ) => "Updated" ,
718+ // exists but user modified, back it up
719+ Some ( false ) => {
720+ // exists and is not current version or outdated, so back it up
721+ let mut backup = zed_settings. clone ( ) ;
722+ backup. set_extension ( "json.bak" ) ;
723+ eprintln ! ( "WARNING: copying `settings.json` to `settings.json.bak`" ) ;
724+ fs:: copy ( & zed_settings, & backup) ?;
725+ "Updated"
726+ }
727+ _ => "Created" ,
728+ } ;
729+ fs:: write ( & zed_settings, ZED_SETTINGS ) ?;
730+ println ! ( "{verb} `.zed/settings.json`" ) ;
731+ } else {
732+ println ! ( "\n {ZED_SETTINGS}" ) ;
626733 }
627734 Ok ( should_create)
628735}
0 commit comments