Skip to content

Commit

Permalink
bootstrap: Consolidate editor LSP setup
Browse files Browse the repository at this point in the history
Consolidate LSP setup for different editors into one `./x setup editor`.
  • Loading branch information
mrkajetanp committed Oct 3, 2024
1 parent 9b24fae commit 456be10
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 62 deletions.
116 changes: 71 additions & 45 deletions src/bootstrap/src/core/build_steps/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,35 @@ enum EditorKind {
}

impl EditorKind {
fn prompt_user() -> io::Result<Option<EditorKind>> {
let prompt_str = "Available editors:
1. vscode
2. vim
3. emacs
4. helix
Select which editor you would like to set up [default: None]: ";

let mut input = String::new();
loop {
print!("{}", prompt_str);
io::stdout().flush()?;
input.clear();
io::stdin().read_line(&mut input)?;
match input.trim().to_lowercase().as_str() {
"1" | "vscode" => return Ok(Some(EditorKind::Vscode)),
"2" | "vim" => return Ok(Some(EditorKind::Vim)),
"3" | "emacs" => return Ok(Some(EditorKind::Emacs)),
"4" | "helix" => return Ok(Some(EditorKind::Helix)),
"" => return Ok(None),
_ => {
eprintln!("ERROR: unrecognized option '{}'", input.trim());
eprintln!("NOTE: press Ctrl+C to exit");
}
};
}
}

/// A list of historical hashes of each LSP settings file
/// New entries should be appended whenever this is updated so we can detect
/// outdated vs. user-modified settings files.
Expand Down Expand Up @@ -568,10 +597,10 @@ impl EditorKind {

fn settings_folder(&self) -> PathBuf {
match self {
EditorKind::Vscode => PathBuf::new().join(".vscode"),
EditorKind::Vim => PathBuf::new().join(".vim"),
EditorKind::Vscode => PathBuf::from(".vscode"),
EditorKind::Vim => PathBuf::from(".vim"),
EditorKind::Emacs => PathBuf::new(),
EditorKind::Helix => PathBuf::new().join(".helix"),
EditorKind::Helix => PathBuf::from(".helix"),
}
}

Expand All @@ -590,48 +619,47 @@ impl EditorKind {
}
}

/// Helper macro for implementing the necessary Step to support editor LSP setup
/// The first argument must match the argument set up in `flags.rs`
/// The second argument must match the name of some `EditorKind` variant
/// After using the macro, the editor needs to be registered in `builder.rs` with describe!()
macro_rules! impl_editor_support {
( $($editor:ident, $kind:ident),+ ) => {$(
#[doc = concat!(" Sets up or displays the LSP config for ", stringify!($editor), ".")]
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct $kind;

impl Step for $kind {
type Output = ();
const DEFAULT: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.alias(stringify!($editor))
}
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() == stringify!($editor) {
run.builder.ensure($kind);
}
}
/// Sets up or displays the LSP config for one of the supported editors
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Editor;

impl Step for Editor {
type Output = ();
const DEFAULT: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.alias("editor")
}

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() == "editor" {
run.builder.ensure(Editor);
}
fn run(self, builder: &Builder<'_>) -> Self::Output {
let config = &builder.config;
if config.dry_run() {
return;
}
}

fn run(self, builder: &Builder<'_>) -> Self::Output {
let config = &builder.config;
if config.dry_run() {
return;
}
match EditorKind::prompt_user() {
Ok(editor_kind) => {
if let Some(editor_kind) = editor_kind {
while !t!(create_editor_settings_maybe(config, editor_kind.clone())) {}
} else {
println!("Ok, skipping editor setup!");
}
while !t!(create_editor_settings_maybe(config, EditorKind::$kind)) {}
}
Err(e) => eprintln!("Could not determine the editor: {e}"),
}
)+};
}
}

impl_editor_support!(vscode, Vscode);
impl_editor_support!(vim, Vim);
impl_editor_support!(emacs, Emacs);
impl_editor_support!(helix, Helix);

/// Create the recommended editor LSP config file for rustc development, or just print it
/// If this method should be re-called, it returns `false`.
fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Result<bool> {
Expand Down Expand Up @@ -662,13 +690,11 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu
);

match mismatched_settings {
Some(true) => eprintln!(
"WARNING: existing `{}` is out of date, x.py will update it",
settings_filename
),
Some(true) => {
eprintln!("WARNING: existing `{settings_filename}` is out of date, x.py will update it")
}
Some(false) => eprintln!(
"WARNING: existing `{}` has been modified by user, x.py will back it up and replace it",
settings_filename
"WARNING: existing `{settings_filename}` has been modified by user, x.py will back it up and replace it"
),
_ => (),
}
Expand Down
10 changes: 1 addition & 9 deletions src/bootstrap/src/core/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1001,15 +1001,7 @@ impl<'a> Builder<'a> {
run::GenerateCompletions,
),
Kind::Setup => {
describe!(
setup::Profile,
setup::Hook,
setup::Link,
setup::Vscode,
setup::Emacs,
setup::Helix,
setup::Vim
)
describe!(setup::Profile, setup::Hook, setup::Link, setup::Editor)
}
Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std),
Kind::Vendor => describe!(vendor::Vendor),
Expand Down
9 changes: 3 additions & 6 deletions src/bootstrap/src/core/config/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,17 +447,14 @@ 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, editor config or toolchain link, you may use
./x.py setup hook
./x.py setup vscode
./x.py setup vim
./x.py setup emacs
./x.py setup helix
./x.py setup editor
./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|vim|emacs|helix|link")]
#[arg(value_name = "<PROFILE>|hook|editor|link")]
profile: Option<PathBuf>,
},
/// Suggest a subset of tests to run, based on modified files
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/src/utils/change_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,6 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
ChangeInfo {
change_id: 131075,
severity: ChangeSeverity::Info,
summary: "New options for ./x setup added - ./x setup [vim|emacs|helix]",
summary: "New option `./x setup editor` added, replacing `./x setup vscode` and adding support for vim, emacs and helix.",
},
];
2 changes: 1 addition & 1 deletion src/etc/completions/x.py.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2741,7 +2741,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 --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|vim|emacs|helix|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 --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [<PROFILE>|hook|editor|link] [PATHS]... [ARGS]..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
Expand Down

0 comments on commit 456be10

Please sign in to comment.