Skip to content

Commit

Permalink
Added project-specific Zed IDE settings
Browse files Browse the repository at this point in the history
  • Loading branch information
ChaiTRex committed Jul 17, 2024
1 parent 24d2ac0 commit 6e7ac23
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Session.vim
.idea
*.iml
.vscode
.zed
.project
.favorites.json
.settings/
Expand Down
129 changes: 118 additions & 11 deletions src/bootstrap/src/core/build_steps/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ pub enum Profile {

static PROFILE_DIR: &str = "src/bootstrap/defaults";

/// A list of historical hashes of `src/etc/rust_analyzer_settings.json`.
/// New entries should be appended whenever this is updated so we can detect
/// A list of historical SHA-256 hashes of `src/etc/vscode_settings.json`. New
/// entries should be appended whenever this is updated so we can detect
/// outdated vs. user-modified settings files.
static SETTINGS_HASHES: &[&str] = &[
static VSCODE_SETTINGS_HASHES: &[&str] = &[
"ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8",
"56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922",
"af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0",
Expand All @@ -46,7 +46,14 @@ static SETTINGS_HASHES: &[&str] = &[
"b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a",
"828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000",
];
static RUST_ANALYZER_SETTINGS: &str = include_str!("../../../../etc/rust_analyzer_settings.json");
static VSCODE_SETTINGS: &str = include_str!("../../../../etc/vscode_settings.json");

/// A list of historical SHA-256 hashes of `src/etc/zed_settings.json`. New
/// entries should be appended whenever this is updated so we can detect
/// outdated vs. user-modified settings files.
static ZED_SETTINGS_HASHES: &[&str] =
&["08bb47a0a93947284102eece102cb2e21a91ff952bf21798df92590e31240d98"];
static ZED_SETTINGS: &str = include_str!("../../../../etc/zed_settings.json");

impl Profile {
fn include_path(&self, src_path: &Path) -> PathBuf {
Expand Down Expand Up @@ -527,11 +534,11 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
Ok(())
}

/// Sets up or displays `src/etc/rust_analyzer_settings.json`
/// Sets up or displays `src/etc/vscode_settings.json`
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Vscode;
pub struct VsCode;

impl Step for Vscode {
impl Step for VsCode {
type Output = ();
const DEFAULT: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
Expand All @@ -543,7 +550,7 @@ impl Step for Vscode {
}
if let [cmd] = &run.paths[..] {
if cmd.assert_single_path().path.as_path().as_os_str() == "vscode" {
run.builder.ensure(Vscode);
run.builder.ensure(VsCode);
}
}
}
Expand All @@ -559,7 +566,7 @@ impl Step for Vscode {
/// Create a `.vscode/settings.json` file for rustc development, or just print it
/// If this method should be re-called, it returns `false`.
fn create_vscode_settings_maybe(config: &Config) -> io::Result<bool> {
let (current_hash, historical_hashes) = SETTINGS_HASHES.split_last().unwrap();
let (current_hash, historical_hashes) = VSCODE_SETTINGS_HASHES.split_last().unwrap();
let vscode_settings = config.src.join(".vscode").join("settings.json");
// If None, no settings.json exists
// If Some(true), is a previous version of settings.json
Expand Down Expand Up @@ -619,10 +626,110 @@ fn create_vscode_settings_maybe(config: &Config) -> io::Result<bool> {
}
_ => "Created",
};
fs::write(&vscode_settings, RUST_ANALYZER_SETTINGS)?;
fs::write(&vscode_settings, VSCODE_SETTINGS)?;
println!("{verb} `.vscode/settings.json`");
} else {
println!("\n{RUST_ANALYZER_SETTINGS}");
println!("\n{VSCODE_SETTINGS}");
}
Ok(should_create)
}

/// Sets up or displays `src/etc/zed_settings.json`
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Zed;

impl Step for Zed {
type Output = ();
const DEFAULT: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.alias("zed")
}
fn make_run(run: RunConfig<'_>) {
if run.builder.config.dry_run() {
return;
}
if let [cmd] = &run.paths[..] {
if cmd.assert_single_path().path.as_path().as_os_str() == "zed" {
run.builder.ensure(Zed);
}
}
}
fn run(self, builder: &Builder<'_>) -> Self::Output {
let config = &builder.config;
if config.dry_run() {
return;
}
while !t!(create_zed_settings_maybe(config)) {}
}
}

/// Create a `.zed/settings.json` file for rustc development, or just print it
/// If this method should be re-called, it returns `false`.
fn create_zed_settings_maybe(config: &Config) -> io::Result<bool> {
let (current_hash, historical_hashes) = ZED_SETTINGS_HASHES.split_last().unwrap();
let zed_settings = config.src.join(".zed").join("settings.json");
// If None, no settings.json exists
// If Some(true), is a previous version of settings.json
// If Some(false), is not a previous version (i.e. user modified)
// If it's up to date we can just skip this
let mut mismatched_settings = None;
if let Ok(current) = fs::read_to_string(&zed_settings) {
let mut hasher = sha2::Sha256::new();
hasher.update(&current);
let hash = hex_encode(hasher.finalize().as_slice());
if hash == *current_hash {
return Ok(true);
} else if historical_hashes.contains(&hash.as_str()) {
mismatched_settings = Some(true);
} else {
mismatched_settings = Some(false);
}
}
println!(
"\nx.py can automatically install the recommended `.zed/settings.json` file for rustc development"
);
match mismatched_settings {
Some(true) => eprintln!(
"WARNING: existing `.zed/settings.json` is out of date, x.py will update it"
),
Some(false) => eprintln!(
"WARNING: existing `.zed/settings.json` has been modified by user, x.py will back it up and replace it"
),
_ => (),
}
let should_create = match prompt_user(
"Would you like to create/update settings.json? (Press 'p' to preview values): [y/N]",
)? {
Some(PromptResult::Yes) => true,
Some(PromptResult::Print) => false,
_ => {
println!("Ok, skipping settings!");
return Ok(true);
}
};
if should_create {
let path = config.src.join(".zed");
if !path.exists() {
fs::create_dir(&path)?;
}
let verb = match mismatched_settings {
// exists but outdated, we can replace this
Some(true) => "Updated",
// exists but user modified, back it up
Some(false) => {
// exists and is not current version or outdated, so back it up
let mut backup = zed_settings.clone();
backup.set_extension("json.bak");
eprintln!("WARNING: copying `settings.json` to `settings.json.bak`");
fs::copy(&zed_settings, &backup)?;
"Updated"
}
_ => "Created",
};
fs::write(&zed_settings, ZED_SETTINGS)?;
println!("{verb} `.zed/settings.json`");
} else {
println!("\n{ZED_SETTINGS}");
}
Ok(should_create)
}
2 changes: 1 addition & 1 deletion src/bootstrap/src/core/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,7 @@ impl<'a> Builder<'a> {
run::GenerateWindowsSys,
run::GenerateCompletions,
),
Kind::Setup => describe!(setup::Profile, setup::Hook, setup::Link, setup::Vscode),
Kind::Setup => describe!(setup::Profile, setup::Hook, setup::Link, setup::VsCode, setup::Zed),
Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std),
Kind::Vendor => describe!(vendor::Vendor),
// special-cased in Build::build()
Expand Down
5 changes: 3 additions & 2 deletions src/bootstrap/src/core/config/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,14 +443,15 @@ Arguments:
The profile is optional and you will be prompted interactively if it is not given.
The following profiles are available:
{}
To only set up the git hook, VS Code config or toolchain link, you may use
To only set up the git hook, VS Code config, Zed config, or toolchain link, you may use
./x.py setup hook
./x.py setup vscode
./x.py setup zed
./x.py setup link", Profile::all_for_help(" ").trim_end()))]
Setup {
/// Either the profile for `config.toml` or another setup action.
/// May be omitted to set up interactively
#[arg(value_name = "<PROFILE>|hook|vscode|link")]
#[arg(value_name = "<PROFILE>|hook|vscode|zed|link")]
profile: Option<PathBuf>,
},
/// Suggest a subset of tests to run, based on modified files
Expand Down
2 changes: 1 addition & 1 deletion src/etc/completions/x.py.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1642,7 +1642,7 @@ _x.py() {
return 0
;;
x.py__setup)
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]..."
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]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
Expand Down
File renamed without changes.
48 changes: 48 additions & 0 deletions src/etc/zed_settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
// The following commented-out VS Code settings are not supported by Zed yet.
// "git.detectSubmodulesLimit": 20
"lsp": {
"rust-analyzer": {
"initialization_options": {
"check": {
"invocationLocation": "root",
"invocationStrategy": "once",
"overrideCommand": ["python3", "x.py", "check", "--json-output"]
},
"linkedProjects": [
"Cargo.toml",
"src/tools/x/Cargo.toml",
"src/bootstrap/Cargo.toml",
"src/tools/rust-analyzer/Cargo.toml",
"compiler/rustc_codegen_cranelift/Cargo.toml",
"compiler/rustc_codegen_gcc/Cargo.toml"
],
"rustfmt": {
"overrideCommand": [
"${workspaceFolder}/build/host/rustfmt/bin/rustfmt",
"--edition=2021"
]
},
"procMacro": {
"server": "${workspaceFolder}/build/host/stage0/libexec/rust-analyzer-proc-macro-srv",
"enable": true
},
"cargo": {
"buildScripts": {
"enable": true,
"invocationLocation": "root",
"invocationStrategy": "once",
"overrideCommand": ["python3", "x.py", "check", "--json-output"]
},
"sysrootSrc": "./library",
"extraEnv": {
"RUSTC_BOOTSTRAP": "1"
}
},
"rustc": {
"source": "./Cargo.toml"
}
}
}
}
}

0 comments on commit 6e7ac23

Please sign in to comment.