Skip to content

Commit 6e7ac23

Browse files
committed
Added project-specific Zed IDE settings
1 parent 24d2ac0 commit 6e7ac23

File tree

7 files changed

+172
-15
lines changed

7 files changed

+172
-15
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Session.vim
1818
.idea
1919
*.iml
2020
.vscode
21+
.zed
2122
.project
2223
.favorites.json
2324
.settings/

src/bootstrap/src/core/build_steps/setup.rs

+118-11
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ pub enum Profile {
3434

3535
static 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

5158
impl 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`.
561568
fn 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+
"\nx.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
}

src/bootstrap/src/core/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -960,7 +960,7 @@ impl<'a> Builder<'a> {
960960
run::GenerateWindowsSys,
961961
run::GenerateCompletions,
962962
),
963-
Kind::Setup => describe!(setup::Profile, setup::Hook, setup::Link, setup::Vscode),
963+
Kind::Setup => describe!(setup::Profile, setup::Hook, setup::Link, setup::VsCode, setup::Zed),
964964
Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std),
965965
Kind::Vendor => describe!(vendor::Vendor),
966966
// special-cased in Build::build()

src/bootstrap/src/core/config/flags.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -443,14 +443,15 @@ Arguments:
443443
The profile is optional and you will be prompted interactively if it is not given.
444444
The following profiles are available:
445445
{}
446-
To only set up the git hook, VS Code config or toolchain link, you may use
446+
To only set up the git hook, VS Code config, Zed config, or toolchain link, you may use
447447
./x.py setup hook
448448
./x.py setup vscode
449+
./x.py setup zed
449450
./x.py setup link", Profile::all_for_help(" ").trim_end()))]
450451
Setup {
451452
/// Either the profile for `config.toml` or another setup action.
452453
/// May be omitted to set up interactively
453-
#[arg(value_name = "<PROFILE>|hook|vscode|link")]
454+
#[arg(value_name = "<PROFILE>|hook|vscode|zed|link")]
454455
profile: Option<PathBuf>,
455456
},
456457
/// Suggest a subset of tests to run, based on modified files

src/etc/completions/x.py.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -1642,7 +1642,7 @@ _x.py() {
16421642
return 0
16431643
;;
16441644
x.py__setup)
1645-
opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [<PROFILE>|hook|vscode|link] [PATHS]... [ARGS]..."
1645+
opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [<PROFILE>|hook|vscode|zed|link] [PATHS]... [ARGS]..."
16461646
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
16471647
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
16481648
return 0
File renamed without changes.

src/etc/zed_settings.json

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
// The following commented-out VS Code settings are not supported by Zed yet.
3+
// "git.detectSubmodulesLimit": 20
4+
"lsp": {
5+
"rust-analyzer": {
6+
"initialization_options": {
7+
"check": {
8+
"invocationLocation": "root",
9+
"invocationStrategy": "once",
10+
"overrideCommand": ["python3", "x.py", "check", "--json-output"]
11+
},
12+
"linkedProjects": [
13+
"Cargo.toml",
14+
"src/tools/x/Cargo.toml",
15+
"src/bootstrap/Cargo.toml",
16+
"src/tools/rust-analyzer/Cargo.toml",
17+
"compiler/rustc_codegen_cranelift/Cargo.toml",
18+
"compiler/rustc_codegen_gcc/Cargo.toml"
19+
],
20+
"rustfmt": {
21+
"overrideCommand": [
22+
"${workspaceFolder}/build/host/rustfmt/bin/rustfmt",
23+
"--edition=2021"
24+
]
25+
},
26+
"procMacro": {
27+
"server": "${workspaceFolder}/build/host/stage0/libexec/rust-analyzer-proc-macro-srv",
28+
"enable": true
29+
},
30+
"cargo": {
31+
"buildScripts": {
32+
"enable": true,
33+
"invocationLocation": "root",
34+
"invocationStrategy": "once",
35+
"overrideCommand": ["python3", "x.py", "check", "--json-output"]
36+
},
37+
"sysrootSrc": "./library",
38+
"extraEnv": {
39+
"RUSTC_BOOTSTRAP": "1"
40+
}
41+
},
42+
"rustc": {
43+
"source": "./Cargo.toml"
44+
}
45+
}
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)