From 100d3f9c0649d42fd0741468e288c6188c4c06e0 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Thu, 22 Aug 2024 19:03:00 +0200 Subject: [PATCH 01/13] Make cargo_ workspace again --- crates/rust-analyzer/src/cli/scip.rs | 2 +- crates/rust-analyzer/src/config.rs | 275 +++++++++--------- crates/rust-analyzer/src/global_state.rs | 10 + .../src/handlers/notification.rs | 30 +- crates/rust-analyzer/src/handlers/request.rs | 6 +- crates/rust-analyzer/src/main_loop.rs | 6 +- crates/rust-analyzer/src/reload.rs | 16 +- crates/rust-analyzer/src/target_spec.rs | 2 +- 8 files changed, 190 insertions(+), 157 deletions(-) diff --git a/crates/rust-analyzer/src/cli/scip.rs b/crates/rust-analyzer/src/cli/scip.rs index a8a02712fe..01bde39579 100644 --- a/crates/rust-analyzer/src/cli/scip.rs +++ b/crates/rust-analyzer/src/cli/scip.rs @@ -51,7 +51,7 @@ impl flags::Scip { // FIXME @alibektas : What happens to errors without logging? error!(?error_sink, "Config Error(s)"); } - let cargo_config = config.cargo(); + let cargo_config = config.cargo(None); let (db, vfs, _) = load_workspace_at( root.as_path().as_ref(), &cargo_config, diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 2889af844b..9a8075043e 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -76,87 +76,6 @@ config_data! { /// How many worker threads to handle priming caches. The default `0` means to pick automatically. cachePriming_numThreads: NumThreads = NumThreads::Physical, - /// Pass `--all-targets` to cargo invocation. - cargo_allTargets: bool = true, - /// Automatically refresh project info via `cargo metadata` on - /// `Cargo.toml` or `.cargo/config.toml` changes. - pub(crate) cargo_autoreload: bool = true, - /// Run build scripts (`build.rs`) for more precise code analysis. - cargo_buildScripts_enable: bool = true, - /// Specifies the invocation strategy to use when running the build scripts command. - /// If `per_workspace` is set, the command will be executed for each Rust workspace with the - /// workspace as the working directory. - /// If `once` is set, the command will be executed once with the opened project as the - /// working directory. - /// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#` - /// is set. - cargo_buildScripts_invocationStrategy: InvocationStrategy = InvocationStrategy::PerWorkspace, - /// Override the command rust-analyzer uses to run build scripts and - /// build procedural macros. The command is required to output json - /// and should therefore include `--message-format=json` or a similar - /// option. - /// - /// If there are multiple linked projects/workspaces, this command is invoked for - /// each of them, with the working directory being the workspace root - /// (i.e., the folder containing the `Cargo.toml`). This can be overwritten - /// by changing `#rust-analyzer.cargo.buildScripts.invocationStrategy#`. - /// - /// By default, a cargo invocation will be constructed for the configured - /// targets and features, with the following base command line: - /// - /// ```bash - /// cargo check --quiet --workspace --message-format=json --all-targets --keep-going - /// ``` - /// . - cargo_buildScripts_overrideCommand: Option> = None, - /// Rerun proc-macros building/build-scripts running when proc-macro - /// or build-script sources change and are saved. - cargo_buildScripts_rebuildOnSave: bool = true, - /// Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to - /// avoid checking unnecessary things. - cargo_buildScripts_useRustcWrapper: bool = true, - /// List of cfg options to enable with the given values. - cargo_cfgs: FxHashMap> = { - let mut m = FxHashMap::default(); - m.insert("debug_assertions".to_owned(), None); - m.insert("miri".to_owned(), None); - m - }, - /// Extra arguments that are passed to every cargo invocation. - cargo_extraArgs: Vec = vec![], - /// Extra environment variables that will be set when running cargo, rustc - /// or other commands within the workspace. Useful for setting RUSTFLAGS. - cargo_extraEnv: FxHashMap = FxHashMap::default(), - /// List of features to activate. - /// - /// Set this to `"all"` to pass `--all-features` to cargo. - cargo_features: CargoFeaturesDef = CargoFeaturesDef::Selected(vec![]), - /// Whether to pass `--no-default-features` to cargo. - cargo_noDefaultFeatures: bool = false, - /// Relative path to the sysroot, or "discover" to try to automatically find it via - /// "rustc --print sysroot". - /// - /// Unsetting this disables sysroot loading. - /// - /// This option does not take effect until rust-analyzer is restarted. - cargo_sysroot: Option = Some("discover".to_owned()), - /// Relative path to the sysroot library sources. If left unset, this will default to - /// `{cargo.sysroot}/lib/rustlib/src/rust/library`. - /// - /// This option does not take effect until rust-analyzer is restarted. - cargo_sysrootSrc: Option = None, - /// Compilation target override (target triple). - // FIXME(@poliorcetics): move to multiple targets here too, but this will need more work - // than `checkOnSave_target` - cargo_target: Option = None, - /// Optional path to a rust-analyzer specific target directory. - /// This prevents rust-analyzer's `cargo check` and initial build-script and proc-macro - /// building from locking the `Cargo.lock` at the expense of duplicating build artifacts. - /// - /// Set to `true` to use a subdirectory of the existing target directory or - /// set to a path relative to the workspace to use that path. - cargo_targetDir | rust_analyzerTargetDir: Option = None, - /// Run the check command for diagnostics on save. checkOnSave | checkOnSave_enable: bool = true, @@ -430,6 +349,88 @@ config_data! { config_data! { workspace: struct WorkspaceDefaultConfigData <- WorkspaceConfigInput -> { + +/// Pass `--all-targets` to cargo invocation. + cargo_allTargets: bool = true, + /// Automatically refresh project info via `cargo metadata` on + /// `Cargo.toml` or `.cargo/config.toml` changes. + pub(crate) cargo_autoreload: bool = true, + /// Run build scripts (`build.rs`) for more precise code analysis. + cargo_buildScripts_enable: bool = true, + /// Specifies the invocation strategy to use when running the build scripts command. + /// If `per_workspace` is set, the command will be executed for each Rust workspace with the + /// workspace as the working directory. + /// If `once` is set, the command will be executed once with the opened project as the + /// working directory. + /// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#` + /// is set. + cargo_buildScripts_invocationStrategy: InvocationStrategy = InvocationStrategy::PerWorkspace, + /// Override the command rust-analyzer uses to run build scripts and + /// build procedural macros. The command is required to output json + /// and should therefore include `--message-format=json` or a similar + /// option. + /// + /// If there are multiple linked projects/workspaces, this command is invoked for + /// each of them, with the working directory being the workspace root + /// (i.e., the folder containing the `Cargo.toml`). This can be overwritten + /// by changing `#rust-analyzer.cargo.buildScripts.invocationStrategy#`. + /// + /// By default, a cargo invocation will be constructed for the configured + /// targets and features, with the following base command line: + /// + /// ```bash + /// cargo check --quiet --workspace --message-format=json --all-targets --keep-going + /// ``` + /// . + cargo_buildScripts_overrideCommand: Option> = None, + /// Rerun proc-macros building/build-scripts running when proc-macro + /// or build-script sources change and are saved. + cargo_buildScripts_rebuildOnSave: bool = true, + /// Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to + /// avoid checking unnecessary things. + cargo_buildScripts_useRustcWrapper: bool = true, + /// List of cfg options to enable with the given values. + cargo_cfgs: FxHashMap> = { + let mut m = FxHashMap::default(); + m.insert("debug_assertions".to_owned(), None); + m.insert("miri".to_owned(), None); + m + }, + /// Extra arguments that are passed to every cargo invocation. + cargo_extraArgs: Vec = vec![], + /// Extra environment variables that will be set when running cargo, rustc + /// or other commands within the workspace. Useful for setting RUSTFLAGS. + cargo_extraEnv: FxHashMap = FxHashMap::default(), + /// List of features to activate. + /// + /// Set this to `"all"` to pass `--all-features` to cargo. + cargo_features: CargoFeaturesDef = CargoFeaturesDef::Selected(vec![]), + /// Whether to pass `--no-default-features` to cargo. + cargo_noDefaultFeatures: bool = false, + /// Relative path to the sysroot, or "discover" to try to automatically find it via + /// "rustc --print sysroot". + /// + /// Unsetting this disables sysroot loading. + /// + /// This option does not take effect until rust-analyzer is restarted. + cargo_sysroot: Option = Some("discover".to_owned()), + /// Relative path to the sysroot library sources. If left unset, this will default to + /// `{cargo.sysroot}/lib/rustlib/src/rust/library`. + /// + /// This option does not take effect until rust-analyzer is restarted. + cargo_sysrootSrc: Option = None, + /// Compilation target override (target triple). + // FIXME(@poliorcetics): move to multiple targets here too, but this will need more work + // than `checkOnSave_target` + cargo_target: Option = None, + /// Optional path to a rust-analyzer specific target directory. + /// This prevents rust-analyzer's `cargo check` and initial build-script and proc-macro + /// building from locking the `Cargo.lock` at the expense of duplicating build artifacts. + /// + /// Set to `true` to use a subdirectory of the existing target directory or + /// set to a path relative to the workspace to use that path. + cargo_targetDir | rust_analyzerTargetDir: Option = None, + /// Additional arguments to `rustfmt`. rustfmt_extraArgs: Vec = vec![], /// Advanced option, fully override the command rust-analyzer uses for @@ -1728,22 +1729,22 @@ impl Config { } } - pub fn extra_args(&self) -> &Vec { - self.cargo_extraArgs() + pub fn extra_args(&self, source_root: Option) -> &Vec { + self.cargo_extraArgs(source_root) } - pub fn extra_env(&self) -> &FxHashMap { - self.cargo_extraEnv() + pub fn extra_env(&self, source_root: Option) -> &FxHashMap { + self.cargo_extraEnv(source_root) } - pub fn check_extra_args(&self) -> Vec { - let mut extra_args = self.extra_args().clone(); + pub fn check_extra_args(&self, source_root: Option) -> Vec { + let mut extra_args = self.extra_args(source_root).clone(); extra_args.extend_from_slice(self.check_extraArgs()); extra_args } - pub fn check_extra_env(&self) -> FxHashMap { - let mut extra_env = self.cargo_extraEnv().clone(); + pub fn check_extra_env(&self, source_root: Option) -> FxHashMap { + let mut extra_env = self.cargo_extraEnv(source_root).clone(); extra_env.extend(self.check_extraEnv().clone()); extra_env } @@ -1787,15 +1788,15 @@ impl Config { } } - pub fn cargo_autoreload_config(&self) -> bool { - self.cargo_autoreload().to_owned() + pub fn cargo_autoreload_config(&self, source_root: Option) -> bool { + self.cargo_autoreload(source_root).to_owned() } - pub fn run_build_scripts(&self) -> bool { - self.cargo_buildScripts_enable().to_owned() || self.procMacro_enable().to_owned() + pub fn run_build_scripts(&self, source_root: Option) -> bool { + self.cargo_buildScripts_enable(source_root).to_owned() || self.procMacro_enable().to_owned() } - pub fn cargo(&self) -> CargoConfig { + pub fn cargo(&self, source_root: Option) -> CargoConfig { let rustc_source = self.rustc_source().as_ref().map(|rustc_src| { if rustc_src == "discover" { RustLibSource::Discover @@ -1803,7 +1804,7 @@ impl Config { RustLibSource::Path(self.root_path.join(rustc_src)) } }); - let sysroot = self.cargo_sysroot().as_ref().map(|sysroot| { + let sysroot = self.cargo_sysroot(source_root).as_ref().map(|sysroot| { if sysroot == "discover" { RustLibSource::Discover } else { @@ -1811,24 +1812,24 @@ impl Config { } }); let sysroot_src = - self.cargo_sysrootSrc().as_ref().map(|sysroot| self.root_path.join(sysroot)); + self.cargo_sysrootSrc(source_root).as_ref().map(|sysroot| self.root_path.join(sysroot)); CargoConfig { - all_targets: *self.cargo_allTargets(), - features: match &self.cargo_features() { + all_targets: *self.cargo_allTargets(source_root), + features: match &self.cargo_features(source_root) { CargoFeaturesDef::All => CargoFeatures::All, CargoFeaturesDef::Selected(features) => CargoFeatures::Selected { features: features.clone(), - no_default_features: self.cargo_noDefaultFeatures().to_owned(), + no_default_features: self.cargo_noDefaultFeatures(source_root).to_owned(), }, }, - target: self.cargo_target().clone(), + target: self.cargo_target(source_root).clone(), sysroot, sysroot_src, rustc_source, cfg_overrides: project_model::CfgOverrides { global: CfgDiff::new( - self.cargo_cfgs() + self.cargo_cfgs(source_root) .iter() .map(|(key, val)| match val { Some(val) => CfgAtom::KeyValue { @@ -1843,15 +1844,15 @@ impl Config { .unwrap(), selective: Default::default(), }, - wrap_rustc_in_build_scripts: *self.cargo_buildScripts_useRustcWrapper(), - invocation_strategy: match self.cargo_buildScripts_invocationStrategy() { + wrap_rustc_in_build_scripts: *self.cargo_buildScripts_useRustcWrapper(source_root), + invocation_strategy: match self.cargo_buildScripts_invocationStrategy(source_root) { InvocationStrategy::Once => project_model::InvocationStrategy::Once, InvocationStrategy::PerWorkspace => project_model::InvocationStrategy::PerWorkspace, }, - run_build_script_command: self.cargo_buildScripts_overrideCommand().clone(), - extra_args: self.cargo_extraArgs().clone(), - extra_env: self.cargo_extraEnv().clone(), - target_dir: self.target_dir_from_config(), + run_build_script_command: self.cargo_buildScripts_overrideCommand(source_root).clone(), + extra_args: self.cargo_extraArgs(source_root).clone(), + extra_env: self.cargo_extraEnv(source_root).clone(), + target_dir: self.target_dir_from_config(source_root), } } @@ -1873,24 +1874,24 @@ impl Config { *self.check_workspace() } - pub(crate) fn cargo_test_options(&self) -> CargoOptions { + pub(crate) fn cargo_test_options(&self, source_root: Option) -> CargoOptions { CargoOptions { - target_triples: self.cargo_target().clone().into_iter().collect(), + target_triples: self.cargo_target(source_root).clone().into_iter().collect(), all_targets: false, - no_default_features: *self.cargo_noDefaultFeatures(), - all_features: matches!(self.cargo_features(), CargoFeaturesDef::All), - features: match self.cargo_features().clone() { + no_default_features: *self.cargo_noDefaultFeatures(source_root), + all_features: matches!(self.cargo_features(source_root), CargoFeaturesDef::All), + features: match self.cargo_features(source_root).clone() { CargoFeaturesDef::All => vec![], CargoFeaturesDef::Selected(it) => it, }, - extra_args: self.extra_args().clone(), + extra_args: self.extra_args(source_root).clone(), extra_test_bin_args: self.runnables_extraTestBinaryArgs().clone(), - extra_env: self.extra_env().clone(), - target_dir: self.target_dir_from_config(), + extra_env: self.extra_env(source_root).clone(), + target_dir: self.target_dir_from_config(source_root), } } - pub(crate) fn flycheck(&self) -> FlycheckConfig { + pub(crate) fn flycheck(&self, source_root: Option) -> FlycheckConfig { match &self.check_overrideCommand() { Some(args) if !args.is_empty() => { let mut args = args.clone(); @@ -1898,7 +1899,7 @@ impl Config { FlycheckConfig::CustomCommand { command, args, - extra_env: self.check_extra_env(), + extra_env: self.check_extra_env(source_root), invocation_strategy: match self.check_invocationStrategy() { InvocationStrategy::Once => crate::flycheck::InvocationStrategy::Once, InvocationStrategy::PerWorkspace => { @@ -1917,35 +1918,39 @@ impl Config { [] => None, targets => Some(targets.into()), }) - .unwrap_or_else(|| self.cargo_target().clone().into_iter().collect()), - all_targets: self.check_allTargets().unwrap_or(*self.cargo_allTargets()), + .unwrap_or_else(|| { + self.cargo_target(source_root).clone().into_iter().collect() + }), + all_targets: self + .check_allTargets() + .unwrap_or(*self.cargo_allTargets(source_root)), no_default_features: self .check_noDefaultFeatures() - .unwrap_or(*self.cargo_noDefaultFeatures()), + .unwrap_or(*self.cargo_noDefaultFeatures(source_root)), all_features: matches!( - self.check_features().as_ref().unwrap_or(self.cargo_features()), + self.check_features().as_ref().unwrap_or(self.cargo_features(source_root)), CargoFeaturesDef::All ), features: match self .check_features() .clone() - .unwrap_or_else(|| self.cargo_features().clone()) + .unwrap_or_else(|| self.cargo_features(source_root).clone()) { CargoFeaturesDef::All => vec![], CargoFeaturesDef::Selected(it) => it, }, - extra_args: self.check_extra_args(), + extra_args: self.check_extra_args(source_root), extra_test_bin_args: self.runnables_extraTestBinaryArgs().clone(), - extra_env: self.check_extra_env(), - target_dir: self.target_dir_from_config(), + extra_env: self.check_extra_env(source_root), + target_dir: self.target_dir_from_config(source_root), }, ansi_color_output: self.color_diagnostic_output(), }, } } - fn target_dir_from_config(&self) -> Option { - self.cargo_targetDir().as_ref().and_then(|target_dir| match target_dir { + fn target_dir_from_config(&self, source_root: Option) -> Option { + self.cargo_targetDir(source_root).as_ref().and_then(|target_dir| match target_dir { TargetDirectory::UseSubdirectory(true) => { Some(Utf8PathBuf::from("target/rust-analyzer")) } @@ -1959,8 +1964,8 @@ impl Config { *self.checkOnSave() } - pub fn script_rebuild_on_save(&self) -> bool { - *self.cargo_buildScripts_rebuildOnSave() + pub fn script_rebuild_on_save(&self, source_root: Option) -> bool { + *self.cargo_buildScripts_rebuildOnSave(source_root) } pub fn runnables(&self) -> RunnablesConfig { @@ -3522,9 +3527,9 @@ mod tests { })); (config, _, _) = config.apply_change(change); - assert_eq!(config.cargo_targetDir(), &None); + assert_eq!(config.cargo_targetDir(None), &None); assert!( - matches!(config.flycheck(), FlycheckConfig::CargoCommand { options, .. } if options.target_dir.is_none()) + matches!(config.flycheck(None), FlycheckConfig::CargoCommand { options, .. } if options.target_dir.is_none()) ); } @@ -3540,9 +3545,9 @@ mod tests { (config, _, _) = config.apply_change(change); - assert_eq!(config.cargo_targetDir(), &Some(TargetDirectory::UseSubdirectory(true))); + assert_eq!(config.cargo_targetDir(None), &Some(TargetDirectory::UseSubdirectory(true))); assert!( - matches!(config.flycheck(), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("target/rust-analyzer"))) + matches!(config.flycheck(None), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("target/rust-analyzer"))) ); } @@ -3559,11 +3564,11 @@ mod tests { (config, _, _) = config.apply_change(change); assert_eq!( - config.cargo_targetDir(), + config.cargo_targetDir(None), &Some(TargetDirectory::Directory(Utf8PathBuf::from("other_folder"))) ); assert!( - matches!(config.flycheck(), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("other_folder"))) + matches!(config.flycheck(None), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("other_folder"))) ); } diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 9d0082c370..35e1da80bf 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -631,6 +631,10 @@ impl GlobalStateSnapshot { file_id_to_url(&self.vfs_read(), id) } + pub(crate) fn vfs_path_to_file_id(&self, vfs_path: &VfsPath) -> anyhow::Result { + vfs_path_to_file_id(&self.vfs_read(), vfs_path) + } + pub(crate) fn file_line_index(&self, file_id: FileId) -> Cancellable { let endings = self.vfs.read().1[&file_id]; let index = self.analysis.file_line_index(file_id)?; @@ -725,3 +729,9 @@ pub(crate) fn url_to_file_id(vfs: &vfs::Vfs, url: &Url) -> anyhow::Result anyhow::Result { + let res = + vfs.file_id(vfs_path).ok_or_else(|| anyhow::format_err!("file not found: {vfs_path}"))?; + Ok(res) +} diff --git a/crates/rust-analyzer/src/handlers/notification.rs b/crates/rust-analyzer/src/handlers/notification.rs index 38b88ff2d0..1cbdb50867 100644 --- a/crates/rust-analyzer/src/handlers/notification.rs +++ b/crates/rust-analyzer/src/handlers/notification.rs @@ -145,14 +145,21 @@ pub(crate) fn handle_did_save_text_document( state: &mut GlobalState, params: DidSaveTextDocumentParams, ) -> anyhow::Result<()> { - if state.config.script_rebuild_on_save() && state.build_deps_changed { - state.build_deps_changed = false; - state - .fetch_build_data_queue - .request_op("build_deps_changed - save notification".to_owned(), ()); - } + let mut deps_change_processed = false; if let Ok(vfs_path) = from_proto::vfs_path(¶ms.text_document.uri) { + let snap = state.snapshot(); + let file_id = snap.vfs_path_to_file_id(&vfs_path)?; + let sr = snap.analysis.source_root_id(file_id)?; + deps_change_processed = true; + + if state.config.script_rebuild_on_save(Some(sr)) && state.build_deps_changed { + state.build_deps_changed = false; + state + .fetch_build_data_queue + .request_op("build_deps_changed - save notification".to_owned(), ()); + } + // Re-fetch workspaces if a workspace related file has changed if let Some(path) = vfs_path.as_path() { let additional_files = &state @@ -191,6 +198,17 @@ pub(crate) fn handle_did_save_text_document( flycheck.restart_workspace(None); } } + + if !deps_change_processed + && state.config.script_rebuild_on_save(None) + && state.build_deps_changed + { + state.build_deps_changed = false; + state + .fetch_build_data_queue + .request_op("build_deps_changed - save notification".to_owned(), ()); + } + Ok(()) } diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index 1ad5ff0c8c..d220809be8 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -256,7 +256,7 @@ pub(crate) fn handle_run_test( let handle = CargoTestHandle::new( test_path, - state.config.cargo_test_options(), + state.config.cargo_test_options(None), cargo.workspace_root(), test_target, state.test_run_sender.clone(), @@ -2119,7 +2119,7 @@ fn run_rustfmt( RustfmtConfig::Rustfmt { extra_args, enable_range_formatting } => { // FIXME: Set RUSTUP_TOOLCHAIN let mut cmd = process::Command::new(toolchain::Tool::Rustfmt.path()); - cmd.envs(snap.config.extra_env()); + cmd.envs(snap.config.extra_env(source_root_id)); cmd.args(extra_args); if let Some(edition) = edition { @@ -2177,7 +2177,7 @@ fn run_rustfmt( _ => process::Command::new(cmd), }; - cmd.envs(snap.config.extra_env()); + cmd.envs(snap.config.extra_env(source_root_id)); cmd.args(args); cmd } diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 1d4ee71e5c..372f060234 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -455,7 +455,7 @@ impl GlobalState { } } - if self.config.cargo_autoreload_config() + if self.config.cargo_autoreload_config(None) || self.config.discover_workspace_config().is_some() { if let Some((cause, FetchWorkspaceRequest { path, force_crate_graph_reload })) = @@ -973,9 +973,9 @@ impl GlobalState { // When we're running multiple flychecks, we have to include a disambiguator in // the title, or the editor complains. Note that this is a user-facing string. let title = if self.flycheck.len() == 1 { - format!("{}", self.config.flycheck()) + format!("{}", self.config.flycheck(None)) } else { - format!("{} (#{})", self.config.flycheck(), id + 1) + format!("{} (#{})", self.config.flycheck(None), id + 1) }; self.report_progress( &title, diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 68366136ed..7087d7fbd5 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -100,7 +100,7 @@ impl GlobalState { { let req = FetchWorkspaceRequest { path: None, force_crate_graph_reload: false }; self.fetch_workspaces_queue.request_op("discovered projects changed".to_owned(), req) - } else if self.config.flycheck() != old_config.flycheck() { + } else if self.config.flycheck(None) != old_config.flycheck(None) { self.reload_flycheck(); } @@ -122,7 +122,7 @@ impl GlobalState { }; let mut message = String::new(); - if !self.config.cargo_autoreload() + if !self.config.cargo_autoreload(None) && self.is_quiescent() && self.fetch_workspaces_queue.op_requested() && self.config.discover_workspace_config().is_none() @@ -264,7 +264,7 @@ impl GlobalState { .map(ManifestPath::try_from) .filter_map(Result::ok) .collect(); - let cargo_config = self.config.cargo(); + let cargo_config = self.config.cargo(None); let discover_command = self.config.discover_workspace_config().cloned(); let is_quiescent = !(self.discover_workspace_queue.op_in_progress() || self.vfs_progress_config_version < self.vfs_config_version @@ -357,7 +357,7 @@ impl GlobalState { pub(crate) fn fetch_build_data(&mut self, cause: Cause) { info!(%cause, "will fetch build data"); let workspaces = Arc::clone(&self.workspaces); - let config = self.config.cargo(); + let config = self.config.cargo(None); let root_path = self.config.root_path().clone(); self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, move |sender| { @@ -507,7 +507,7 @@ impl GlobalState { // FIXME: can we abort the build scripts here if they are already running? self.workspaces = Arc::new(workspaces); - if self.config.run_build_scripts() { + if self.config.run_build_scripts(None) { self.build_deps_changed = false; self.fetch_build_data_queue.request_op("workspace updated".to_owned(), ()); } @@ -627,7 +627,7 @@ impl GlobalState { .. } => cargo_config_extra_env .iter() - .chain(self.config.extra_env()) + .chain(self.config.extra_env(None)) .map(|(a, b)| (a.clone(), b.clone())) .chain( ws.sysroot @@ -702,7 +702,7 @@ impl GlobalState { vfs.file_id(&vfs_path) }; - ws_to_crate_graph(&self.workspaces, self.config.extra_env(), load) + ws_to_crate_graph(&self.workspaces, self.config.extra_env(None), load) }; let mut change = ChangeWithProcMacros::new(); if self.config.expand_proc_macros() { @@ -791,7 +791,7 @@ impl GlobalState { fn reload_flycheck(&mut self) { let _p = tracing::info_span!("GlobalState::reload_flycheck").entered(); - let config = self.config.flycheck(); + let config = self.config.flycheck(None); let sender = self.flycheck_sender.clone(); let invocation_strategy = match config { FlycheckConfig::CargoCommand { .. } => { diff --git a/crates/rust-analyzer/src/target_spec.rs b/crates/rust-analyzer/src/target_spec.rs index 954e13cbf2..87e964e5a8 100644 --- a/crates/rust-analyzer/src/target_spec.rs +++ b/crates/rust-analyzer/src/target_spec.rs @@ -168,7 +168,7 @@ impl CargoTargetSpec { (Default::default(), Default::default()) }; - let cargo_config = snap.config.cargo(); + let cargo_config = snap.config.cargo(None); match &cargo_config.features { CargoFeatures::All => { From f09997993bec99ce474267c13d370b85018a1bf3 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Thu, 22 Aug 2024 19:07:43 +0200 Subject: [PATCH 02/13] Make checkOnSave workspace --- crates/rust-analyzer/src/config.rs | 11 ++++++----- crates/rust-analyzer/src/handlers/notification.rs | 4 ++-- crates/rust-analyzer/src/main_loop.rs | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 9a8075043e..211e91f7f0 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -76,8 +76,6 @@ config_data! { /// How many worker threads to handle priming caches. The default `0` means to pick automatically. cachePriming_numThreads: NumThreads = NumThreads::Physical, - /// Run the check command for diagnostics on save. - checkOnSave | checkOnSave_enable: bool = true, /// Check all targets and tests (`--all-targets`). Defaults to /// `#rust-analyzer.cargo.allTargets#`. @@ -350,7 +348,7 @@ config_data! { workspace: struct WorkspaceDefaultConfigData <- WorkspaceConfigInput -> { -/// Pass `--all-targets` to cargo invocation. + /// Pass `--all-targets` to cargo invocation. cargo_allTargets: bool = true, /// Automatically refresh project info via `cargo metadata` on /// `Cargo.toml` or `.cargo/config.toml` changes. @@ -431,6 +429,9 @@ config_data! { /// set to a path relative to the workspace to use that path. cargo_targetDir | rust_analyzerTargetDir: Option = None, + /// Run the check command for diagnostics on save. + checkOnSave | checkOnSave_enable: bool = true, + /// Additional arguments to `rustfmt`. rustfmt_extraArgs: Vec = vec![], /// Advanced option, fully override the command rust-analyzer uses for @@ -1960,8 +1961,8 @@ impl Config { }) } - pub fn check_on_save(&self) -> bool { - *self.checkOnSave() + pub fn check_on_save(&self, source_root: Option) -> bool { + *self.checkOnSave(source_root) } pub fn script_rebuild_on_save(&self, source_root: Option) -> bool { diff --git a/crates/rust-analyzer/src/handlers/notification.rs b/crates/rust-analyzer/src/handlers/notification.rs index 1cbdb50867..336b7ea05a 100644 --- a/crates/rust-analyzer/src/handlers/notification.rs +++ b/crates/rust-analyzer/src/handlers/notification.rs @@ -189,10 +189,10 @@ pub(crate) fn handle_did_save_text_document( } } - if !state.config.check_on_save() || run_flycheck(state, vfs_path) { + if !state.config.check_on_save(Some(sr)) || run_flycheck(state, vfs_path) { return Ok(()); } - } else if state.config.check_on_save() { + } else if state.config.check_on_save(None) { // No specific flycheck was triggered, so let's trigger all of them. for flycheck in state.flycheck.iter() { flycheck.restart_workspace(None); diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 372f060234..a90b988907 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -404,7 +404,7 @@ impl GlobalState { if self.is_quiescent() { let became_quiescent = !was_quiescent; if became_quiescent { - if self.config.check_on_save() { + if self.config.check_on_save(None) { // Project has loaded properly, kick off initial flycheck self.flycheck.iter().for_each(|flycheck| flycheck.restart_workspace(None)); } From c3acdc2fa15cdf56a09f4e1955d334e16caf7636 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Thu, 22 Aug 2024 20:44:27 +0200 Subject: [PATCH 03/13] Make check workspace --- crates/rust-analyzer/src/config.rs | 165 +++++++++--------- .../src/handlers/notification.rs | 7 +- crates/rust-analyzer/src/main_loop.rs | 2 +- 3 files changed, 89 insertions(+), 85 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 211e91f7f0..da3dda7e29 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -77,72 +77,6 @@ config_data! { cachePriming_numThreads: NumThreads = NumThreads::Physical, - /// Check all targets and tests (`--all-targets`). Defaults to - /// `#rust-analyzer.cargo.allTargets#`. - check_allTargets | checkOnSave_allTargets: Option = None, - /// Cargo command to use for `cargo check`. - check_command | checkOnSave_command: String = "check".to_owned(), - /// Extra arguments for `cargo check`. - check_extraArgs | checkOnSave_extraArgs: Vec = vec![], - /// Extra environment variables that will be set when running `cargo check`. - /// Extends `#rust-analyzer.cargo.extraEnv#`. - check_extraEnv | checkOnSave_extraEnv: FxHashMap = FxHashMap::default(), - /// List of features to activate. Defaults to - /// `#rust-analyzer.cargo.features#`. - /// - /// Set to `"all"` to pass `--all-features` to Cargo. - check_features | checkOnSave_features: Option = None, - /// List of `cargo check` (or other command specified in `check.command`) diagnostics to ignore. - /// - /// For example for `cargo check`: `dead_code`, `unused_imports`, `unused_variables`,... - check_ignore: FxHashSet = FxHashSet::default(), - /// Specifies the invocation strategy to use when running the check command. - /// If `per_workspace` is set, the command will be executed for each workspace. - /// If `once` is set, the command will be executed once. - /// This config only has an effect when `#rust-analyzer.check.overrideCommand#` - /// is set. - check_invocationStrategy | checkOnSave_invocationStrategy: InvocationStrategy = InvocationStrategy::PerWorkspace, - /// Whether to pass `--no-default-features` to Cargo. Defaults to - /// `#rust-analyzer.cargo.noDefaultFeatures#`. - check_noDefaultFeatures | checkOnSave_noDefaultFeatures: Option = None, - /// Override the command rust-analyzer uses instead of `cargo check` for - /// diagnostics on save. The command is required to output json and - /// should therefore include `--message-format=json` or a similar option - /// (if your client supports the `colorDiagnosticOutput` experimental - /// capability, you can use `--message-format=json-diagnostic-rendered-ansi`). - /// - /// If you're changing this because you're using some tool wrapping - /// Cargo, you might also want to change - /// `#rust-analyzer.cargo.buildScripts.overrideCommand#`. - /// - /// If there are multiple linked projects/workspaces, this command is invoked for - /// each of them, with the working directory being the workspace root - /// (i.e., the folder containing the `Cargo.toml`). This can be overwritten - /// by changing `#rust-analyzer.check.invocationStrategy#`. - /// - /// If `$saved_file` is part of the command, rust-analyzer will pass - /// the absolute path of the saved file to the provided command. This is - /// intended to be used with non-Cargo build systems. - /// Note that `$saved_file` is experimental and may be removed in the future. - /// - /// An example command would be: - /// - /// ```bash - /// cargo check --workspace --message-format=json --all-targets - /// ``` - /// . - check_overrideCommand | checkOnSave_overrideCommand: Option> = None, - /// Check for specific targets. Defaults to `#rust-analyzer.cargo.target#` if empty. - /// - /// Can be a single target, e.g. `"x86_64-unknown-linux-gnu"` or a list of targets, e.g. - /// `["aarch64-apple-darwin", "x86_64-apple-darwin"]`. - /// - /// Aliased as `"checkOnSave.targets"`. - check_targets | checkOnSave_targets | checkOnSave_target: Option = None, - /// Whether `--workspace` should be passed to `cargo check`. - /// If false, `-p ` will be passed instead. - check_workspace: bool = true, - /// List of rust-analyzer diagnostics to disable. diagnostics_disabled: FxHashSet = FxHashSet::default(), /// Whether to show native rust-analyzer diagnostics. @@ -432,6 +366,73 @@ config_data! { /// Run the check command for diagnostics on save. checkOnSave | checkOnSave_enable: bool = true, + +/// Check all targets and tests (`--all-targets`). Defaults to + /// `#rust-analyzer.cargo.allTargets#`. + check_allTargets | checkOnSave_allTargets: Option = None, + /// Cargo command to use for `cargo check`. + check_command | checkOnSave_command: String = "check".to_owned(), + /// Extra arguments for `cargo check`. + check_extraArgs | checkOnSave_extraArgs: Vec = vec![], + /// Extra environment variables that will be set when running `cargo check`. + /// Extends `#rust-analyzer.cargo.extraEnv#`. + check_extraEnv | checkOnSave_extraEnv: FxHashMap = FxHashMap::default(), + /// List of features to activate. Defaults to + /// `#rust-analyzer.cargo.features#`. + /// + /// Set to `"all"` to pass `--all-features` to Cargo. + check_features | checkOnSave_features: Option = None, + /// List of `cargo check` (or other command specified in `check.command`) diagnostics to ignore. + /// + /// For example for `cargo check`: `dead_code`, `unused_imports`, `unused_variables`,... + check_ignore: FxHashSet = FxHashSet::default(), + /// Specifies the invocation strategy to use when running the check command. + /// If `per_workspace` is set, the command will be executed for each workspace. + /// If `once` is set, the command will be executed once. + /// This config only has an effect when `#rust-analyzer.check.overrideCommand#` + /// is set. + check_invocationStrategy | checkOnSave_invocationStrategy: InvocationStrategy = InvocationStrategy::PerWorkspace, + /// Whether to pass `--no-default-features` to Cargo. Defaults to + /// `#rust-analyzer.cargo.noDefaultFeatures#`. + check_noDefaultFeatures | checkOnSave_noDefaultFeatures: Option = None, + /// Override the command rust-analyzer uses instead of `cargo check` for + /// diagnostics on save. The command is required to output json and + /// should therefore include `--message-format=json` or a similar option + /// (if your client supports the `colorDiagnosticOutput` experimental + /// capability, you can use `--message-format=json-diagnostic-rendered-ansi`). + /// + /// If you're changing this because you're using some tool wrapping + /// Cargo, you might also want to change + /// `#rust-analyzer.cargo.buildScripts.overrideCommand#`. + /// + /// If there are multiple linked projects/workspaces, this command is invoked for + /// each of them, with the working directory being the workspace root + /// (i.e., the folder containing the `Cargo.toml`). This can be overwritten + /// by changing `#rust-analyzer.check.invocationStrategy#`. + /// + /// If `$saved_file` is part of the command, rust-analyzer will pass + /// the absolute path of the saved file to the provided command. This is + /// intended to be used with non-Cargo build systems. + /// Note that `$saved_file` is experimental and may be removed in the future. + /// + /// An example command would be: + /// + /// ```bash + /// cargo check --workspace --message-format=json --all-targets + /// ``` + /// . + check_overrideCommand | checkOnSave_overrideCommand: Option> = None, + /// Check for specific targets. Defaults to `#rust-analyzer.cargo.target#` if empty. + /// + /// Can be a single target, e.g. `"x86_64-unknown-linux-gnu"` or a list of targets, e.g. + /// `["aarch64-apple-darwin", "x86_64-apple-darwin"]`. + /// + /// Aliased as `"checkOnSave.targets"`. + check_targets | checkOnSave_targets | checkOnSave_target: Option = None, + /// Whether `--workspace` should be passed to `cargo check`. + /// If false, `-p ` will be passed instead. + check_workspace: bool = true, + /// Additional arguments to `rustfmt`. rustfmt_extraArgs: Vec = vec![], /// Advanced option, fully override the command rust-analyzer uses for @@ -1018,7 +1019,7 @@ impl Config { config.source_root_parent_map = source_root_map; } - if config.check_command().is_empty() { + if config.check_command(None).is_empty() { config.validation_errors.0.push(Arc::new(ConfigErrorInner::Json { config_key: "/check/command".to_owned(), error: serde_json::Error::custom("expected a non-empty string"), @@ -1721,12 +1722,12 @@ impl Config { self.diagnostics_enable().to_owned() } - pub fn diagnostics_map(&self) -> DiagnosticsMapConfig { + pub fn diagnostics_map(&self, source_root: Option) -> DiagnosticsMapConfig { DiagnosticsMapConfig { remap_prefix: self.diagnostics_remapPrefix().clone(), warnings_as_info: self.diagnostics_warningsAsInfo().clone(), warnings_as_hint: self.diagnostics_warningsAsHint().clone(), - check_ignore: self.check_ignore().clone(), + check_ignore: self.check_ignore(source_root).clone(), } } @@ -1740,13 +1741,13 @@ impl Config { pub fn check_extra_args(&self, source_root: Option) -> Vec { let mut extra_args = self.extra_args(source_root).clone(); - extra_args.extend_from_slice(self.check_extraArgs()); + extra_args.extend_from_slice(self.check_extraArgs(source_root)); extra_args } pub fn check_extra_env(&self, source_root: Option) -> FxHashMap { let mut extra_env = self.cargo_extraEnv(source_root).clone(); - extra_env.extend(self.check_extraEnv().clone()); + extra_env.extend(self.check_extraEnv(source_root).clone()); extra_env } @@ -1871,8 +1872,8 @@ impl Config { } } - pub fn flycheck_workspace(&self) -> bool { - *self.check_workspace() + pub fn flycheck_workspace(&self, source_root: Option) -> bool { + *self.check_workspace(source_root) } pub(crate) fn cargo_test_options(&self, source_root: Option) -> CargoOptions { @@ -1893,7 +1894,7 @@ impl Config { } pub(crate) fn flycheck(&self, source_root: Option) -> FlycheckConfig { - match &self.check_overrideCommand() { + match &self.check_overrideCommand(source_root) { Some(args) if !args.is_empty() => { let mut args = args.clone(); let command = args.remove(0); @@ -1901,7 +1902,7 @@ impl Config { command, args, extra_env: self.check_extra_env(source_root), - invocation_strategy: match self.check_invocationStrategy() { + invocation_strategy: match self.check_invocationStrategy(source_root) { InvocationStrategy::Once => crate::flycheck::InvocationStrategy::Once, InvocationStrategy::PerWorkspace => { crate::flycheck::InvocationStrategy::PerWorkspace @@ -1910,10 +1911,10 @@ impl Config { } } Some(_) | None => FlycheckConfig::CargoCommand { - command: self.check_command().clone(), + command: self.check_command(source_root).clone(), options: CargoOptions { target_triples: self - .check_targets() + .check_targets(source_root) .clone() .and_then(|targets| match &targets.0[..] { [] => None, @@ -1923,17 +1924,19 @@ impl Config { self.cargo_target(source_root).clone().into_iter().collect() }), all_targets: self - .check_allTargets() + .check_allTargets(source_root) .unwrap_or(*self.cargo_allTargets(source_root)), no_default_features: self - .check_noDefaultFeatures() + .check_noDefaultFeatures(source_root) .unwrap_or(*self.cargo_noDefaultFeatures(source_root)), all_features: matches!( - self.check_features().as_ref().unwrap_or(self.cargo_features(source_root)), + self.check_features(source_root) + .as_ref() + .unwrap_or(self.cargo_features(source_root)), CargoFeaturesDef::All ), features: match self - .check_features() + .check_features(source_root) .clone() .unwrap_or_else(|| self.cargo_features(source_root).clone()) { diff --git a/crates/rust-analyzer/src/handlers/notification.rs b/crates/rust-analyzer/src/handlers/notification.rs index 336b7ea05a..dc8d40e0ee 100644 --- a/crates/rust-analyzer/src/handlers/notification.rs +++ b/crates/rust-analyzer/src/handlers/notification.rs @@ -306,6 +306,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { let file_id = state.vfs.read().0.file_id(&vfs_path); if let Some(file_id) = file_id { let world = state.snapshot(); + let source_root_id = world.analysis.source_root_id(file_id).ok(); let mut updated = false; let task = move || -> std::result::Result<(), ide::Cancelled> { // Is the target binary? If so we let flycheck run only for the workspace that contains the crate. @@ -391,9 +392,9 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { for (id, package) in workspace_ids.clone() { if id == flycheck.id() { updated = true; - match package - .filter(|_| !world.config.flycheck_workspace() || target.is_some()) - { + match package.filter(|_| { + !world.config.flycheck_workspace(source_root_id) || target.is_some() + }) { Some(package) => flycheck .restart_for_package(package, target.clone().map(TupleExt::head)), None => flycheck.restart_workspace(saved_file.clone()), diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index a90b988907..e034badbcb 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -925,7 +925,7 @@ impl GlobalState { FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic } => { let snap = self.snapshot(); let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( - &self.config.diagnostics_map(), + &self.config.diagnostics_map(None), &diagnostic, &workspace_root, &snap, From 65d39f32d6e93907667a5f12d02999900648b759 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Thu, 22 Aug 2024 20:48:30 +0200 Subject: [PATCH 04/13] Make runnables workspace --- crates/rust-analyzer/src/config.rs | 38 ++++++++++---------- crates/rust-analyzer/src/handlers/request.rs | 3 +- crates/rust-analyzer/src/lsp/to_proto.rs | 3 +- crates/rust-analyzer/src/target_spec.rs | 2 +- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index da3dda7e29..675882e55f 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -124,20 +124,6 @@ config_data! { /// This config takes a map of crate names with the exported proc-macro names to ignore as values. procMacro_ignored: FxHashMap, Box<[Box]>> = FxHashMap::default(), - /// Command to be executed instead of 'cargo' for runnables. - runnables_command: Option = None, - /// Additional arguments to be passed to cargo for runnables such as - /// tests or binaries. For example, it may be `--release`. - runnables_extraArgs: Vec = vec![], - /// Additional arguments to be passed through Cargo to launched tests, benchmarks, or - /// doc-tests. - /// - /// Unless the launched target uses a - /// [custom test harness](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-harness-field), - /// they will end up being interpreted as options to - /// [`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments). - runnables_extraTestBinaryArgs: Vec = vec!["--show-output".to_owned()], - /// Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private /// projects, or "discover" to try to automatically find it if the `rustc-dev` component /// is installed. @@ -367,7 +353,7 @@ config_data! { checkOnSave | checkOnSave_enable: bool = true, -/// Check all targets and tests (`--all-targets`). Defaults to + /// Check all targets and tests (`--all-targets`). Defaults to /// `#rust-analyzer.cargo.allTargets#`. check_allTargets | checkOnSave_allTargets: Option = None, /// Cargo command to use for `cargo check`. @@ -433,6 +419,20 @@ config_data! { /// If false, `-p ` will be passed instead. check_workspace: bool = true, + /// Command to be executed instead of 'cargo' for runnables. + runnables_command: Option = None, + /// Additional arguments to be passed to cargo for runnables such as + /// tests or binaries. For example, it may be `--release`. + runnables_extraArgs: Vec = vec![], + /// Additional arguments to be passed through Cargo to launched tests, benchmarks, or + /// doc-tests. + /// + /// Unless the launched target uses a + /// [custom test harness](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-harness-field), + /// they will end up being interpreted as options to + /// [`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments). + runnables_extraTestBinaryArgs: Vec = vec!["--show-output".to_owned()], + /// Additional arguments to `rustfmt`. rustfmt_extraArgs: Vec = vec![], /// Advanced option, fully override the command rust-analyzer uses for @@ -1972,11 +1972,11 @@ impl Config { *self.cargo_buildScripts_rebuildOnSave(source_root) } - pub fn runnables(&self) -> RunnablesConfig { + pub fn runnables(&self, source_root: Option) -> RunnablesConfig { RunnablesConfig { - override_cargo: self.runnables_command().clone(), - cargo_extra_args: self.runnables_extraArgs().clone(), - extra_test_binary_args: self.runnables_extraTestBinaryArgs().clone(), + override_cargo: self.runnables_command(source_root).clone(), + cargo_extra_args: self.runnables_extraArgs(source_root).clone(), + extra_test_binary_args: self.runnables_extraTestBinaryArgs(source_root).clone(), } } diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index d220809be8..b39552a172 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -852,6 +852,7 @@ pub(crate) fn handle_runnables( ) -> anyhow::Result> { let _p = tracing::info_span!("handle_runnables").entered(); let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; + let source_root = snap.analysis.source_root_id(file_id).ok(); let line_index = snap.file_line_index(file_id)?; let offset = params.position.and_then(|it| from_proto::offset(&line_index, it).ok()); let target_spec = TargetSpec::for_file(&snap, file_id)?; @@ -894,7 +895,7 @@ pub(crate) fn handle_runnables( } // Add `cargo check` and `cargo test` for all targets of the whole package - let config = snap.config.runnables(); + let config = snap.config.runnables(source_root); match target_spec { Some(TargetSpec::Cargo(spec)) => { let is_crate_no_std = snap.analysis.is_crate_no_std(spec.crate_id)?; diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs index eb6bc2a9ce..f5122a722a 100644 --- a/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/crates/rust-analyzer/src/lsp/to_proto.rs @@ -1365,8 +1365,9 @@ pub(crate) fn runnable( snap: &GlobalStateSnapshot, runnable: Runnable, ) -> Cancellable> { - let config = snap.config.runnables(); let target_spec = TargetSpec::for_file(snap, runnable.nav.file_id)?; + let source_root = snap.analysis.source_root_id(runnable.nav.file_id).ok(); + let config = snap.config.runnables(source_root); match target_spec { Some(TargetSpec::Cargo(spec)) => { diff --git a/crates/rust-analyzer/src/target_spec.rs b/crates/rust-analyzer/src/target_spec.rs index 87e964e5a8..b4aa73d278 100644 --- a/crates/rust-analyzer/src/target_spec.rs +++ b/crates/rust-analyzer/src/target_spec.rs @@ -113,7 +113,7 @@ impl CargoTargetSpec { kind: &RunnableKind, cfg: &Option, ) -> (Vec, Vec) { - let config = snap.config.runnables(); + let config = snap.config.runnables(None); let extra_test_binary_args = config.extra_test_binary_args; let mut cargo_args = Vec::new(); From c304ceeb4c5154386fc002fca7a9a94cd6c7f614 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Thu, 22 Aug 2024 20:49:51 +0200 Subject: [PATCH 05/13] Make rustc_* workspace --- crates/rust-analyzer/src/config.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 675882e55f..3499cf9259 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -124,16 +124,6 @@ config_data! { /// This config takes a map of crate names with the exported proc-macro names to ignore as values. procMacro_ignored: FxHashMap, Box<[Box]>> = FxHashMap::default(), - /// Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private - /// projects, or "discover" to try to automatically find it if the `rustc-dev` component - /// is installed. - /// - /// Any project which uses rust-analyzer with the rustcPrivate - /// crates must set `[package.metadata.rust-analyzer] rustc_private=true` to use it. - /// - /// This option does not take effect until rust-analyzer is restarted. - rustc_source: Option = None, - /// Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`]. /// @@ -433,6 +423,16 @@ config_data! { /// [`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments). runnables_extraTestBinaryArgs: Vec = vec!["--show-output".to_owned()], + /// Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private + /// projects, or "discover" to try to automatically find it if the `rustc-dev` component + /// is installed. + /// + /// Any project which uses rust-analyzer with the rustcPrivate + /// crates must set `[package.metadata.rust-analyzer] rustc_private=true` to use it. + /// + /// This option does not take effect until rust-analyzer is restarted. + rustc_source: Option = None, + /// Additional arguments to `rustfmt`. rustfmt_extraArgs: Vec = vec![], /// Advanced option, fully override the command rust-analyzer uses for @@ -1799,7 +1799,7 @@ impl Config { } pub fn cargo(&self, source_root: Option) -> CargoConfig { - let rustc_source = self.rustc_source().as_ref().map(|rustc_src| { + let rustc_source = self.rustc_source(source_root).as_ref().map(|rustc_src| { if rustc_src == "discover" { RustLibSource::Discover } else { From e4edbf46013b43ffb70577dd9f552d34aa5d8716 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Thu, 22 Aug 2024 20:51:49 +0200 Subject: [PATCH 06/13] Make procMacro_* workspace --- crates/rust-analyzer/src/config.rs | 16 ++++++++++------ crates/rust-analyzer/src/reload.rs | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 3499cf9259..e459e7b7f3 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -119,10 +119,6 @@ config_data! { /// Sets the LRU capacity of the specified queries. lru_query_capacities: FxHashMap, u16> = FxHashMap::default(), - /// These proc-macros will be ignored when trying to expand them. - /// - /// This config takes a map of crate names with the exported proc-macro names to ignore as values. - procMacro_ignored: FxHashMap, Box<[Box]>> = FxHashMap::default(), /// Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`]. @@ -409,6 +405,11 @@ config_data! { /// If false, `-p ` will be passed instead. check_workspace: bool = true, + /// These proc-macros will be ignored when trying to expand them. + /// + /// This config takes a map of crate names with the exported proc-macro names to ignore as values. + procMacro_ignored: FxHashMap, Box<[Box]>> = FxHashMap::default(), + /// Command to be executed instead of 'cargo' for runnables. runnables_command: Option = None, /// Additional arguments to be passed to cargo for runnables such as @@ -1764,8 +1765,11 @@ impl Config { Some(AbsPathBuf::try_from(path).unwrap_or_else(|path| self.root_path.join(path))) } - pub fn ignored_proc_macros(&self) -> &FxHashMap, Box<[Box]>> { - self.procMacro_ignored() + pub fn ignored_proc_macros( + &self, + source_root: Option, + ) -> &FxHashMap, Box<[Box]>> { + self.procMacro_ignored(source_root) } pub fn expand_proc_macros(&self) -> bool { diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 7087d7fbd5..5d77b7aa67 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -382,7 +382,7 @@ impl GlobalState { pub(crate) fn fetch_proc_macros(&mut self, cause: Cause, paths: Vec) { info!(%cause, "will load proc macros"); - let ignored_proc_macros = self.config.ignored_proc_macros().clone(); + let ignored_proc_macros = self.config.ignored_proc_macros(None).clone(); let proc_macro_clients = self.proc_macro_clients.clone(); self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, move |sender| { From 3a4efb41413d5abb6f34bf0cc5871df654a7044b Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Thu, 22 Aug 2024 20:53:40 +0200 Subject: [PATCH 07/13] Make workspace_symbol_search_* workspace --- crates/rust-analyzer/src/config.rs | 28 ++++++++++---------- crates/rust-analyzer/src/handlers/request.rs | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index e459e7b7f3..925d650b5b 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -252,8 +252,6 @@ config_data! { config_data! { workspace: struct WorkspaceDefaultConfigData <- WorkspaceConfigInput -> { - - /// Pass `--all-targets` to cargo invocation. cargo_allTargets: bool = true, /// Automatically refresh project info via `cargo metadata` on @@ -447,6 +445,16 @@ config_data! { /// available on a nightly build. rustfmt_rangeFormatting_enable: bool = false, + + /// Workspace symbol search kind. + workspace_symbol_search_kind: WorkspaceSymbolSearchKindDef = WorkspaceSymbolSearchKindDef::OnlyTypes, + /// Limits the number of items returned from a workspace symbol search (Defaults to 128). + /// Some clients like vs-code issue new searches on result filtering and don't require all results to be returned in the initial search. + /// Other clients requires all results upfront and might require a higher limit. + workspace_symbol_search_limit: usize = 128, + /// Workspace symbol search scope. + workspace_symbol_search_scope: WorkspaceSymbolSearchScopeDef = WorkspaceSymbolSearchScopeDef::Workspace, + } } @@ -731,14 +739,6 @@ config_data! { /// Whether to insert closing angle brackets when typing an opening angle bracket of a generic argument list. typing_autoClosingAngleBrackets_enable: bool = false, - /// Workspace symbol search kind. - workspace_symbol_search_kind: WorkspaceSymbolSearchKindDef = WorkspaceSymbolSearchKindDef::OnlyTypes, - /// Limits the number of items returned from a workspace symbol search (Defaults to 128). - /// Some clients like vs-code issue new searches on result filtering and don't require all results to be returned in the initial search. - /// Other clients requires all results upfront and might require a higher limit. - workspace_symbol_search_limit: usize = 128, - /// Workspace symbol search scope. - workspace_symbol_search_scope: WorkspaceSymbolSearchScopeDef = WorkspaceSymbolSearchScopeDef::Workspace, } } @@ -2019,19 +2019,19 @@ impl Config { } } - pub fn workspace_symbol(&self) -> WorkspaceSymbolConfig { + pub fn workspace_symbol(&self, source_root: Option) -> WorkspaceSymbolConfig { WorkspaceSymbolConfig { - search_scope: match self.workspace_symbol_search_scope() { + search_scope: match self.workspace_symbol_search_scope(source_root) { WorkspaceSymbolSearchScopeDef::Workspace => WorkspaceSymbolSearchScope::Workspace, WorkspaceSymbolSearchScopeDef::WorkspaceAndDependencies => { WorkspaceSymbolSearchScope::WorkspaceAndDependencies } }, - search_kind: match self.workspace_symbol_search_kind() { + search_kind: match self.workspace_symbol_search_kind(source_root) { WorkspaceSymbolSearchKindDef::OnlyTypes => WorkspaceSymbolSearchKind::OnlyTypes, WorkspaceSymbolSearchKindDef::AllSymbols => WorkspaceSymbolSearchKind::AllSymbols, }, - search_limit: *self.workspace_symbol_search_limit(), + search_limit: *self.workspace_symbol_search_limit(source_root), } } diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index b39552a172..94487bdbb2 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -565,7 +565,7 @@ pub(crate) fn handle_workspace_symbol( ) -> anyhow::Result> { let _p = tracing::info_span!("handle_workspace_symbol").entered(); - let config = snap.config.workspace_symbol(); + let config = snap.config.workspace_symbol(None); let (all_symbols, libs) = decide_search_scope_and_kind(¶ms, &config); let query = { From eef79b4e474dbe662a1be2b9c1011e5622746fc3 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Thu, 22 Aug 2024 20:57:08 +0200 Subject: [PATCH 08/13] Make diagnostics_* local --- crates/rust-analyzer/src/config.rs | 63 ++++++++++++++------------- crates/rust-analyzer/src/main_loop.rs | 2 +- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 925d650b5b..df03e679f0 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -77,28 +77,6 @@ config_data! { cachePriming_numThreads: NumThreads = NumThreads::Physical, - /// List of rust-analyzer diagnostics to disable. - diagnostics_disabled: FxHashSet = FxHashSet::default(), - /// Whether to show native rust-analyzer diagnostics. - diagnostics_enable: bool = true, - /// Whether to show experimental rust-analyzer diagnostics that might - /// have more false positives than usual. - diagnostics_experimental_enable: bool = false, - /// Map of prefixes to be substituted when parsing diagnostic file paths. - /// This should be the reverse mapping of what is passed to `rustc` as `--remap-path-prefix`. - diagnostics_remapPrefix: FxHashMap = FxHashMap::default(), - /// Whether to run additional style lints. - diagnostics_styleLints_enable: bool = false, - /// List of warnings that should be displayed with hint severity. - /// - /// The warnings will be indicated by faded text or three dots in code - /// and will not show up in the `Problems Panel`. - diagnostics_warningsAsHint: Vec = vec![], - /// List of warnings that should be displayed with info severity. - /// - /// The warnings will be indicated by a blue squiggly underline in code - /// and a blue icon in the `Problems Panel`. - diagnostics_warningsAsInfo: Vec = vec![], /// These directories will be ignored by rust-analyzer. They are /// relative to the workspace root, and globs are not supported. You may @@ -231,6 +209,29 @@ config_data! { /// Term search fuel in "units of work" for assists (Defaults to 1800). assist_termSearch_fuel: usize = 1800, + /// List of rust-analyzer diagnostics to disable. + diagnostics_disabled: FxHashSet = FxHashSet::default(), + /// Whether to show native rust-analyzer diagnostics. + diagnostics_enable: bool = true, + /// Whether to show experimental rust-analyzer diagnostics that might + /// have more false positives than usual. + diagnostics_experimental_enable: bool = false, + /// Map of prefixes to be substituted when parsing diagnostic file paths. + /// This should be the reverse mapping of what is passed to `rustc` as `--remap-path-prefix`. + diagnostics_remapPrefix: FxHashMap = FxHashMap::default(), + /// Whether to run additional style lints. + diagnostics_styleLints_enable: bool = false, + /// List of warnings that should be displayed with hint severity. + /// + /// The warnings will be indicated by faded text or three dots in code + /// and will not show up in the `Problems Panel`. + diagnostics_warningsAsHint: Vec = vec![], + /// List of warnings that should be displayed with info severity. + /// + /// The warnings will be indicated by a blue squiggly underline in code + /// and a blue icon in the `Problems Panel`. + diagnostics_warningsAsInfo: Vec = vec![], + /// Whether to enforce the import granularity setting for all files. If set to false rust-analyzer will try to keep import styles consistent per file. imports_granularity_enforce: bool = false, /// How imports should be grouped into use statements. @@ -1447,11 +1448,11 @@ impl Config { pub fn diagnostics(&self, source_root: Option) -> DiagnosticsConfig { DiagnosticsConfig { - enabled: *self.diagnostics_enable(), + enabled: *self.diagnostics_enable(source_root), proc_attr_macros_enabled: self.expand_proc_attr_macros(), proc_macros_enabled: *self.procMacro_enable(), - disable_experimental: !self.diagnostics_experimental_enable(), - disabled: self.diagnostics_disabled().clone(), + disable_experimental: !self.diagnostics_experimental_enable(source_root), + disabled: self.diagnostics_disabled(source_root).clone(), expr_fill_default: match self.assist_expressionFillDefault(source_root) { ExprFillDefaultDef::Todo => ExprFillDefaultMode::Todo, ExprFillDefaultDef::Default => ExprFillDefaultMode::Default, @@ -1461,7 +1462,7 @@ impl Config { prefer_no_std: self.imports_preferNoStd(source_root).to_owned(), prefer_prelude: self.imports_preferPrelude(source_root).to_owned(), prefer_absolute: self.imports_prefixExternPrelude(source_root).to_owned(), - style_lints: self.diagnostics_styleLints_enable().to_owned(), + style_lints: self.diagnostics_styleLints_enable(source_root).to_owned(), term_search_fuel: self.assist_termSearch_fuel(source_root).to_owned() as u64, term_search_borrowck: self.assist_termSearch_borrowcheck(source_root).to_owned(), } @@ -1719,15 +1720,15 @@ impl Config { self.cachePriming_enable().to_owned() } - pub fn publish_diagnostics(&self) -> bool { - self.diagnostics_enable().to_owned() + pub fn publish_diagnostics(&self, source_root: Option) -> bool { + self.diagnostics_enable(source_root).to_owned() } pub fn diagnostics_map(&self, source_root: Option) -> DiagnosticsMapConfig { DiagnosticsMapConfig { - remap_prefix: self.diagnostics_remapPrefix().clone(), - warnings_as_info: self.diagnostics_warningsAsInfo().clone(), - warnings_as_hint: self.diagnostics_warningsAsHint().clone(), + remap_prefix: self.diagnostics_remapPrefix(source_root).clone(), + warnings_as_info: self.diagnostics_warningsAsInfo(source_root).clone(), + warnings_as_hint: self.diagnostics_warningsAsHint(source_root).clone(), check_ignore: self.check_ignore(source_root).clone(), } } diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index e034badbcb..3e46138aa3 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -434,7 +434,7 @@ impl GlobalState { let project_or_mem_docs_changed = became_quiescent || state_changed || memdocs_added_or_removed; - if project_or_mem_docs_changed && self.config.publish_diagnostics() { + if project_or_mem_docs_changed && self.config.publish_diagnostics(None) { self.update_diagnostics(); } if project_or_mem_docs_changed && self.config.test_explorer() { From a7207f4b64053c7635138c7cad400f887b0e16e1 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Thu, 22 Aug 2024 20:59:14 +0200 Subject: [PATCH 09/13] Make completion_* local --- crates/rust-analyzer/src/config.rs | 148 +++++++++++++++-------------- 1 file changed, 76 insertions(+), 72 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index df03e679f0..ac72193be5 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -209,6 +209,70 @@ config_data! { /// Term search fuel in "units of work" for assists (Defaults to 1800). assist_termSearch_fuel: usize = 1800, + + /// Toggles the additional completions that automatically add imports when completed. + /// Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled. + completion_autoimport_enable: bool = true, + /// Toggles the additional completions that automatically show method calls and field accesses + /// with `self` prefixed to them when inside a method. + completion_autoself_enable: bool = true, + /// Whether to add parenthesis and argument snippets when completing function. + completion_callable_snippets: CallableCompletionDef = CallableCompletionDef::FillArguments, + /// Whether to show full function/method signatures in completion docs. + completion_fullFunctionSignatures_enable: bool = false, + /// Maximum number of completions to return. If `None`, the limit is infinite. + completion_limit: Option = None, + /// Whether to show postfix snippets like `dbg`, `if`, `not`, etc. + completion_postfix_enable: bool = true, + /// Enables completions of private items and fields that are defined in the current workspace even if they are not visible at the current position. + completion_privateEditable_enable: bool = false, + /// Custom completion snippets. + completion_snippets_custom: FxHashMap = serde_json::from_str(r#"{ + "Arc::new": { + "postfix": "arc", + "body": "Arc::new(${receiver})", + "requires": "std::sync::Arc", + "description": "Put the expression into an `Arc`", + "scope": "expr" + }, + "Rc::new": { + "postfix": "rc", + "body": "Rc::new(${receiver})", + "requires": "std::rc::Rc", + "description": "Put the expression into an `Rc`", + "scope": "expr" + }, + "Box::pin": { + "postfix": "pinbox", + "body": "Box::pin(${receiver})", + "requires": "std::boxed::Box", + "description": "Put the expression into a pinned `Box`", + "scope": "expr" + }, + "Ok": { + "postfix": "ok", + "body": "Ok(${receiver})", + "description": "Wrap the expression in a `Result::Ok`", + "scope": "expr" + }, + "Err": { + "postfix": "err", + "body": "Err(${receiver})", + "description": "Wrap the expression in a `Result::Err`", + "scope": "expr" + }, + "Some": { + "postfix": "some", + "body": "Some(${receiver})", + "description": "Wrap the expression in an `Option::Some`", + "scope": "expr" + } + }"#).unwrap(), + /// Whether to enable term search based snippets like `Some(foo.bar().baz())`. + completion_termSearch_enable: bool = false, + /// Term search fuel in "units of work" for autocompletion (Defaults to 1000). + completion_termSearch_fuel: usize = 1000, + /// List of rust-analyzer diagnostics to disable. diagnostics_disabled: FxHashSet = FxHashSet::default(), /// Whether to show native rust-analyzer diagnostics. @@ -463,68 +527,6 @@ config_data! { /// Configs that only make sense when they are set by a client. As such they can only be defined /// by setting them using client's settings (e.g `settings.json` on VS Code). client: struct ClientDefaultConfigData <- ClientConfigInput -> { - /// Toggles the additional completions that automatically add imports when completed. - /// Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled. - completion_autoimport_enable: bool = true, - /// Toggles the additional completions that automatically show method calls and field accesses - /// with `self` prefixed to them when inside a method. - completion_autoself_enable: bool = true, - /// Whether to add parenthesis and argument snippets when completing function. - completion_callable_snippets: CallableCompletionDef = CallableCompletionDef::FillArguments, - /// Whether to show full function/method signatures in completion docs. - completion_fullFunctionSignatures_enable: bool = false, - /// Maximum number of completions to return. If `None`, the limit is infinite. - completion_limit: Option = None, - /// Whether to show postfix snippets like `dbg`, `if`, `not`, etc. - completion_postfix_enable: bool = true, - /// Enables completions of private items and fields that are defined in the current workspace even if they are not visible at the current position. - completion_privateEditable_enable: bool = false, - /// Custom completion snippets. - completion_snippets_custom: FxHashMap = serde_json::from_str(r#"{ - "Arc::new": { - "postfix": "arc", - "body": "Arc::new(${receiver})", - "requires": "std::sync::Arc", - "description": "Put the expression into an `Arc`", - "scope": "expr" - }, - "Rc::new": { - "postfix": "rc", - "body": "Rc::new(${receiver})", - "requires": "std::rc::Rc", - "description": "Put the expression into an `Rc`", - "scope": "expr" - }, - "Box::pin": { - "postfix": "pinbox", - "body": "Box::pin(${receiver})", - "requires": "std::boxed::Box", - "description": "Put the expression into a pinned `Box`", - "scope": "expr" - }, - "Ok": { - "postfix": "ok", - "body": "Ok(${receiver})", - "description": "Wrap the expression in a `Result::Ok`", - "scope": "expr" - }, - "Err": { - "postfix": "err", - "body": "Err(${receiver})", - "description": "Wrap the expression in a `Result::Err`", - "scope": "expr" - }, - "Some": { - "postfix": "some", - "body": "Some(${receiver})", - "description": "Wrap the expression in an `Option::Some`", - "scope": "expr" - } - }"#).unwrap(), - /// Whether to enable term search based snippets like `Some(foo.bar().baz())`. - completion_termSearch_enable: bool = false, - /// Term search fuel in "units of work" for autocompletion (Defaults to 1000). - completion_termSearch_fuel: usize = 1000, /// Controls file watching implementation. files_watcher: FilesWatcherDef = FilesWatcherDef::Client, @@ -879,7 +881,7 @@ impl Config { // IMPORTANT : This holds as long as ` completion_snippets_custom` is declared `client`. config.snippets.clear(); - let snips = self.completion_snippets_custom().to_owned(); + let snips = self.completion_snippets_custom(None).to_owned(); for (name, def) in snips.iter() { if def.prefix.is_empty() && def.postfix.is_empty() { @@ -1417,13 +1419,15 @@ impl Config { pub fn completion(&self, source_root: Option) -> CompletionConfig { CompletionConfig { - enable_postfix_completions: self.completion_postfix_enable().to_owned(), - enable_imports_on_the_fly: self.completion_autoimport_enable().to_owned() + enable_postfix_completions: self.completion_postfix_enable(source_root).to_owned(), + enable_imports_on_the_fly: self.completion_autoimport_enable(source_root).to_owned() && self.caps.completion_item_edit_resolve(), - enable_self_on_the_fly: self.completion_autoself_enable().to_owned(), - enable_private_editable: self.completion_privateEditable_enable().to_owned(), - full_function_signatures: self.completion_fullFunctionSignatures_enable().to_owned(), - callable: match self.completion_callable_snippets() { + enable_self_on_the_fly: self.completion_autoself_enable(source_root).to_owned(), + enable_private_editable: self.completion_privateEditable_enable(source_root).to_owned(), + full_function_signatures: self + .completion_fullFunctionSignatures_enable(source_root) + .to_owned(), + callable: match self.completion_callable_snippets(source_root) { CallableCompletionDef::FillArguments => Some(CallableSnippets::FillArguments), CallableCompletionDef::AddParentheses => Some(CallableSnippets::AddParentheses), CallableCompletionDef::None => None, @@ -1434,9 +1438,9 @@ impl Config { prefer_prelude: self.imports_preferPrelude(source_root).to_owned(), prefer_absolute: self.imports_prefixExternPrelude(source_root).to_owned(), snippets: self.snippets.clone().to_vec(), - limit: self.completion_limit().to_owned(), - enable_term_search: self.completion_termSearch_enable().to_owned(), - term_search_fuel: self.completion_termSearch_fuel().to_owned() as u64, + limit: self.completion_limit(source_root).to_owned(), + enable_term_search: self.completion_termSearch_enable(source_root).to_owned(), + term_search_fuel: self.completion_termSearch_fuel(source_root).to_owned() as u64, } } From 23eb20794e9451e94279ceeb040545634d892762 Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Thu, 22 Aug 2024 21:03:58 +0200 Subject: [PATCH 10/13] Make almost every client config global --- crates/rust-analyzer/src/config.rs | 421 +++++++++++++++-------------- 1 file changed, 211 insertions(+), 210 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index ac72193be5..e7c5f989d9 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -84,6 +84,154 @@ config_data! { files_excludeDirs: Vec = vec![], + + /// Enables highlighting of related references while the cursor is on `break`, `loop`, `while`, or `for` keywords. + highlightRelated_breakPoints_enable: bool = true, + /// Enables highlighting of all captures of a closure while the cursor is on the `|` or move keyword of a closure. + highlightRelated_closureCaptures_enable: bool = true, + /// Enables highlighting of all exit points while the cursor is on any `return`, `?`, `fn`, or return type arrow (`->`). + highlightRelated_exitPoints_enable: bool = true, + /// Enables highlighting of related references while the cursor is on any identifier. + highlightRelated_references_enable: bool = true, + /// Enables highlighting of all break points for a loop or block context while the cursor is on any `async` or `await` keywords. + highlightRelated_yieldPoints_enable: bool = true, + + /// Whether to show `Debug` action. Only applies when + /// `#rust-analyzer.hover.actions.enable#` is set. + hover_actions_debug_enable: bool = true, + /// Whether to show HoverActions in Rust files. + hover_actions_enable: bool = true, + /// Whether to show `Go to Type Definition` action. Only applies when + /// `#rust-analyzer.hover.actions.enable#` is set. + hover_actions_gotoTypeDef_enable: bool = true, + /// Whether to show `Implementations` action. Only applies when + /// `#rust-analyzer.hover.actions.enable#` is set. + hover_actions_implementations_enable: bool = true, + /// Whether to show `References` action. Only applies when + /// `#rust-analyzer.hover.actions.enable#` is set. + hover_actions_references_enable: bool = false, + /// Whether to show `Run` action. Only applies when + /// `#rust-analyzer.hover.actions.enable#` is set. + hover_actions_run_enable: bool = true, + + /// Whether to show documentation on hover. + hover_documentation_enable: bool = true, + /// Whether to show keyword hover popups. Only applies when + /// `#rust-analyzer.hover.documentation.enable#` is set. + hover_documentation_keywords_enable: bool = true, + /// Use markdown syntax for links on hover. + hover_links_enable: bool = true, + /// How to render the align information in a memory layout hover. + hover_memoryLayout_alignment: Option = Some(MemoryLayoutHoverRenderKindDef::Hexadecimal), + /// Whether to show memory layout data on hover. + hover_memoryLayout_enable: bool = true, + /// How to render the niche information in a memory layout hover. + hover_memoryLayout_niches: Option = Some(false), + /// How to render the offset information in a memory layout hover. + hover_memoryLayout_offset: Option = Some(MemoryLayoutHoverRenderKindDef::Hexadecimal), + /// How to render the size information in a memory layout hover. + hover_memoryLayout_size: Option = Some(MemoryLayoutHoverRenderKindDef::Both), + + /// How many variants of an enum to display when hovering on. Show none if empty. + hover_show_enumVariants: Option = Some(5), + /// How many fields of a struct, variant or union to display when hovering on. Show none if empty. + hover_show_fields: Option = Some(5), + /// How many associated items of a trait to display when hovering a trait. + hover_show_traitAssocItems: Option = None, + + /// Whether to show inlay type hints for binding modes. + inlayHints_bindingModeHints_enable: bool = false, + /// Whether to show inlay type hints for method chains. + inlayHints_chainingHints_enable: bool = true, + /// Whether to show inlay hints after a closing `}` to indicate what item it belongs to. + inlayHints_closingBraceHints_enable: bool = true, + /// Minimum number of lines required before the `}` until the hint is shown (set to 0 or 1 + /// to always show them). + inlayHints_closingBraceHints_minLines: usize = 25, + /// Whether to show inlay hints for closure captures. + inlayHints_closureCaptureHints_enable: bool = false, + /// Whether to show inlay type hints for return types of closures. + inlayHints_closureReturnTypeHints_enable: ClosureReturnTypeHintsDef = ClosureReturnTypeHintsDef::Never, + /// Closure notation in type and chaining inlay hints. + inlayHints_closureStyle: ClosureStyle = ClosureStyle::ImplFn, + /// Whether to show enum variant discriminant hints. + inlayHints_discriminantHints_enable: DiscriminantHintsDef = DiscriminantHintsDef::Never, + /// Whether to show inlay hints for type adjustments. + inlayHints_expressionAdjustmentHints_enable: AdjustmentHintsDef = AdjustmentHintsDef::Never, + /// Whether to hide inlay hints for type adjustments outside of `unsafe` blocks. + inlayHints_expressionAdjustmentHints_hideOutsideUnsafe: bool = false, + /// Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc). + inlayHints_expressionAdjustmentHints_mode: AdjustmentHintsModeDef = AdjustmentHintsModeDef::Prefix, + /// Whether to show const generic parameter name inlay hints. + inlayHints_genericParameterHints_const_enable: bool= true, + /// Whether to show generic lifetime parameter name inlay hints. + inlayHints_genericParameterHints_lifetime_enable: bool = false, + /// Whether to show generic type parameter name inlay hints. + inlayHints_genericParameterHints_type_enable: bool = false, + /// Whether to show implicit drop hints. + inlayHints_implicitDrops_enable: bool = false, + /// Whether to show inlay type hints for elided lifetimes in function signatures. + inlayHints_lifetimeElisionHints_enable: LifetimeElisionDef = LifetimeElisionDef::Never, + /// Whether to prefer using parameter names as the name for elided lifetime hints if possible. + inlayHints_lifetimeElisionHints_useParameterNames: bool = false, + /// Maximum length for inlay hints. Set to null to have an unlimited length. + inlayHints_maxLength: Option = Some(25), + /// Whether to show function parameter name inlay hints at the call + /// site. + inlayHints_parameterHints_enable: bool = true, + /// Whether to show exclusive range inlay hints. + inlayHints_rangeExclusiveHints_enable: bool = false, + /// Whether to show inlay hints for compiler inserted reborrows. + /// This setting is deprecated in favor of #rust-analyzer.inlayHints.expressionAdjustmentHints.enable#. + inlayHints_reborrowHints_enable: ReborrowHintsDef = ReborrowHintsDef::Never, + /// Whether to render leading colons for type hints, and trailing colons for parameter hints. + inlayHints_renderColons: bool = true, + /// Whether to show inlay type hints for variables. + inlayHints_typeHints_enable: bool = true, + /// Whether to hide inlay type hints for `let` statements that initialize to a closure. + /// Only applies to closures with blocks, same as `#rust-analyzer.inlayHints.closureReturnTypeHints.enable#`. + inlayHints_typeHints_hideClosureInitialization: bool = false, + /// Whether to hide inlay type hints for constructors. + inlayHints_typeHints_hideNamedConstructor: bool = false, + + /// Enables the experimental support for interpreting tests. + interpret_tests: bool = false, + + /// Join lines merges consecutive declaration and initialization of an assignment. + joinLines_joinAssignments: bool = true, + /// Join lines inserts else between consecutive ifs. + joinLines_joinElseIf: bool = true, + /// Join lines removes trailing commas. + joinLines_removeTrailingComma: bool = true, + /// Join lines unwraps trivial blocks. + joinLines_unwrapTrivialBlock: bool = true, + + /// Whether to show `Debug` lens. Only applies when + /// `#rust-analyzer.lens.enable#` is set. + lens_debug_enable: bool = true, + /// Whether to show CodeLens in Rust files. + lens_enable: bool = true, + /// Whether to show `Implementations` lens. Only applies when + /// `#rust-analyzer.lens.enable#` is set. + lens_implementations_enable: bool = true, + /// Where to render annotations. + lens_location: AnnotationLocation = AnnotationLocation::AboveName, + /// Whether to show `References` lens for Struct, Enum, and Union. + /// Only applies when `#rust-analyzer.lens.enable#` is set. + lens_references_adt_enable: bool = false, + /// Whether to show `References` lens for Enum Variants. + /// Only applies when `#rust-analyzer.lens.enable#` is set. + lens_references_enumVariant_enable: bool = false, + /// Whether to show `Method References` lens. Only applies when + /// `#rust-analyzer.lens.enable#` is set. + lens_references_method_enable: bool = false, + /// Whether to show `References` lens for Trait. + /// Only applies when `#rust-analyzer.lens.enable#` is set. + lens_references_trait_enable: bool = false, + /// Whether to show `Run` lens. Only applies when + /// `#rust-analyzer.lens.enable#` is set. + lens_run_enable: bool = true, + /// Disable project auto-discovery in favor of explicitly specified set /// of projects. /// @@ -97,6 +245,69 @@ config_data! { /// Sets the LRU capacity of the specified queries. lru_query_capacities: FxHashMap, u16> = FxHashMap::default(), + /// Whether to show `can't find Cargo.toml` error message. + notifications_cargoTomlNotFound: bool = true, + + /// How many worker threads in the main loop. The default `null` means to pick automatically. + numThreads: Option = None, + + /// Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set. + procMacro_attributes_enable: bool = true, + /// Enable support for procedural macros, implies `#rust-analyzer.cargo.buildScripts.enable#`. + procMacro_enable: bool = true, + /// Internal config, path to proc-macro server executable. + procMacro_server: Option = None, + + /// Exclude imports from find-all-references. + references_excludeImports: bool = false, + + /// Exclude tests from find-all-references. + references_excludeTests: bool = false, + + /// Inject additional highlighting into doc comments. + /// + /// When enabled, rust-analyzer will highlight rust source in doc comments as well as intra + /// doc links. + semanticHighlighting_doc_comment_inject_enable: bool = true, + /// Whether the server is allowed to emit non-standard tokens and modifiers. + semanticHighlighting_nonStandardTokens: bool = true, + /// Use semantic tokens for operators. + /// + /// When disabled, rust-analyzer will emit semantic tokens only for operator tokens when + /// they are tagged with modifiers. + semanticHighlighting_operator_enable: bool = true, + /// Use specialized semantic tokens for operators. + /// + /// When enabled, rust-analyzer will emit special token types for operator tokens instead + /// of the generic `operator` token type. + semanticHighlighting_operator_specialization_enable: bool = false, + /// Use semantic tokens for punctuation. + /// + /// When disabled, rust-analyzer will emit semantic tokens only for punctuation tokens when + /// they are tagged with modifiers or have a special role. + semanticHighlighting_punctuation_enable: bool = false, + /// When enabled, rust-analyzer will emit a punctuation semantic token for the `!` of macro + /// calls. + semanticHighlighting_punctuation_separate_macro_bang: bool = false, + /// Use specialized semantic tokens for punctuation. + /// + /// When enabled, rust-analyzer will emit special token types for punctuation tokens instead + /// of the generic `punctuation` token type. + semanticHighlighting_punctuation_specialization_enable: bool = false, + /// Use semantic tokens for strings. + /// + /// In some editors (e.g. vscode) semantic tokens override other highlighting grammars. + /// By disabling semantic tokens for strings, other grammars can be used to highlight + /// their contents. + semanticHighlighting_strings_enable: bool = true, + + /// Show full signature of the callable. Only shows parameters if disabled. + signatureInfo_detail: SignatureDetail = SignatureDetail::Full, + /// Show documentation. + signatureInfo_documentation_enable: bool = true, + + /// Whether to insert closing angle brackets when typing an opening angle bracket of a generic argument list. + typing_autoClosingAngleBrackets_enable: bool = false, /// Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`]. @@ -531,216 +742,6 @@ config_data! { /// Controls file watching implementation. files_watcher: FilesWatcherDef = FilesWatcherDef::Client, - /// Enables highlighting of related references while the cursor is on `break`, `loop`, `while`, or `for` keywords. - highlightRelated_breakPoints_enable: bool = true, - /// Enables highlighting of all captures of a closure while the cursor is on the `|` or move keyword of a closure. - highlightRelated_closureCaptures_enable: bool = true, - /// Enables highlighting of all exit points while the cursor is on any `return`, `?`, `fn`, or return type arrow (`->`). - highlightRelated_exitPoints_enable: bool = true, - /// Enables highlighting of related references while the cursor is on any identifier. - highlightRelated_references_enable: bool = true, - /// Enables highlighting of all break points for a loop or block context while the cursor is on any `async` or `await` keywords. - highlightRelated_yieldPoints_enable: bool = true, - - /// Whether to show `Debug` action. Only applies when - /// `#rust-analyzer.hover.actions.enable#` is set. - hover_actions_debug_enable: bool = true, - /// Whether to show HoverActions in Rust files. - hover_actions_enable: bool = true, - /// Whether to show `Go to Type Definition` action. Only applies when - /// `#rust-analyzer.hover.actions.enable#` is set. - hover_actions_gotoTypeDef_enable: bool = true, - /// Whether to show `Implementations` action. Only applies when - /// `#rust-analyzer.hover.actions.enable#` is set. - hover_actions_implementations_enable: bool = true, - /// Whether to show `References` action. Only applies when - /// `#rust-analyzer.hover.actions.enable#` is set. - hover_actions_references_enable: bool = false, - /// Whether to show `Run` action. Only applies when - /// `#rust-analyzer.hover.actions.enable#` is set. - hover_actions_run_enable: bool = true, - - /// Whether to show documentation on hover. - hover_documentation_enable: bool = true, - /// Whether to show keyword hover popups. Only applies when - /// `#rust-analyzer.hover.documentation.enable#` is set. - hover_documentation_keywords_enable: bool = true, - /// Use markdown syntax for links on hover. - hover_links_enable: bool = true, - /// How to render the align information in a memory layout hover. - hover_memoryLayout_alignment: Option = Some(MemoryLayoutHoverRenderKindDef::Hexadecimal), - /// Whether to show memory layout data on hover. - hover_memoryLayout_enable: bool = true, - /// How to render the niche information in a memory layout hover. - hover_memoryLayout_niches: Option = Some(false), - /// How to render the offset information in a memory layout hover. - hover_memoryLayout_offset: Option = Some(MemoryLayoutHoverRenderKindDef::Hexadecimal), - /// How to render the size information in a memory layout hover. - hover_memoryLayout_size: Option = Some(MemoryLayoutHoverRenderKindDef::Both), - - /// How many variants of an enum to display when hovering on. Show none if empty. - hover_show_enumVariants: Option = Some(5), - /// How many fields of a struct, variant or union to display when hovering on. Show none if empty. - hover_show_fields: Option = Some(5), - /// How many associated items of a trait to display when hovering a trait. - hover_show_traitAssocItems: Option = None, - - /// Whether to show inlay type hints for binding modes. - inlayHints_bindingModeHints_enable: bool = false, - /// Whether to show inlay type hints for method chains. - inlayHints_chainingHints_enable: bool = true, - /// Whether to show inlay hints after a closing `}` to indicate what item it belongs to. - inlayHints_closingBraceHints_enable: bool = true, - /// Minimum number of lines required before the `}` until the hint is shown (set to 0 or 1 - /// to always show them). - inlayHints_closingBraceHints_minLines: usize = 25, - /// Whether to show inlay hints for closure captures. - inlayHints_closureCaptureHints_enable: bool = false, - /// Whether to show inlay type hints for return types of closures. - inlayHints_closureReturnTypeHints_enable: ClosureReturnTypeHintsDef = ClosureReturnTypeHintsDef::Never, - /// Closure notation in type and chaining inlay hints. - inlayHints_closureStyle: ClosureStyle = ClosureStyle::ImplFn, - /// Whether to show enum variant discriminant hints. - inlayHints_discriminantHints_enable: DiscriminantHintsDef = DiscriminantHintsDef::Never, - /// Whether to show inlay hints for type adjustments. - inlayHints_expressionAdjustmentHints_enable: AdjustmentHintsDef = AdjustmentHintsDef::Never, - /// Whether to hide inlay hints for type adjustments outside of `unsafe` blocks. - inlayHints_expressionAdjustmentHints_hideOutsideUnsafe: bool = false, - /// Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc). - inlayHints_expressionAdjustmentHints_mode: AdjustmentHintsModeDef = AdjustmentHintsModeDef::Prefix, - /// Whether to show const generic parameter name inlay hints. - inlayHints_genericParameterHints_const_enable: bool= true, - /// Whether to show generic lifetime parameter name inlay hints. - inlayHints_genericParameterHints_lifetime_enable: bool = false, - /// Whether to show generic type parameter name inlay hints. - inlayHints_genericParameterHints_type_enable: bool = false, - /// Whether to show implicit drop hints. - inlayHints_implicitDrops_enable: bool = false, - /// Whether to show inlay type hints for elided lifetimes in function signatures. - inlayHints_lifetimeElisionHints_enable: LifetimeElisionDef = LifetimeElisionDef::Never, - /// Whether to prefer using parameter names as the name for elided lifetime hints if possible. - inlayHints_lifetimeElisionHints_useParameterNames: bool = false, - /// Maximum length for inlay hints. Set to null to have an unlimited length. - inlayHints_maxLength: Option = Some(25), - /// Whether to show function parameter name inlay hints at the call - /// site. - inlayHints_parameterHints_enable: bool = true, - /// Whether to show exclusive range inlay hints. - inlayHints_rangeExclusiveHints_enable: bool = false, - /// Whether to show inlay hints for compiler inserted reborrows. - /// This setting is deprecated in favor of #rust-analyzer.inlayHints.expressionAdjustmentHints.enable#. - inlayHints_reborrowHints_enable: ReborrowHintsDef = ReborrowHintsDef::Never, - /// Whether to render leading colons for type hints, and trailing colons for parameter hints. - inlayHints_renderColons: bool = true, - /// Whether to show inlay type hints for variables. - inlayHints_typeHints_enable: bool = true, - /// Whether to hide inlay type hints for `let` statements that initialize to a closure. - /// Only applies to closures with blocks, same as `#rust-analyzer.inlayHints.closureReturnTypeHints.enable#`. - inlayHints_typeHints_hideClosureInitialization: bool = false, - /// Whether to hide inlay type hints for constructors. - inlayHints_typeHints_hideNamedConstructor: bool = false, - - /// Enables the experimental support for interpreting tests. - interpret_tests: bool = false, - - /// Join lines merges consecutive declaration and initialization of an assignment. - joinLines_joinAssignments: bool = true, - /// Join lines inserts else between consecutive ifs. - joinLines_joinElseIf: bool = true, - /// Join lines removes trailing commas. - joinLines_removeTrailingComma: bool = true, - /// Join lines unwraps trivial blocks. - joinLines_unwrapTrivialBlock: bool = true, - - /// Whether to show `Debug` lens. Only applies when - /// `#rust-analyzer.lens.enable#` is set. - lens_debug_enable: bool = true, - /// Whether to show CodeLens in Rust files. - lens_enable: bool = true, - /// Whether to show `Implementations` lens. Only applies when - /// `#rust-analyzer.lens.enable#` is set. - lens_implementations_enable: bool = true, - /// Where to render annotations. - lens_location: AnnotationLocation = AnnotationLocation::AboveName, - /// Whether to show `References` lens for Struct, Enum, and Union. - /// Only applies when `#rust-analyzer.lens.enable#` is set. - lens_references_adt_enable: bool = false, - /// Whether to show `References` lens for Enum Variants. - /// Only applies when `#rust-analyzer.lens.enable#` is set. - lens_references_enumVariant_enable: bool = false, - /// Whether to show `Method References` lens. Only applies when - /// `#rust-analyzer.lens.enable#` is set. - lens_references_method_enable: bool = false, - /// Whether to show `References` lens for Trait. - /// Only applies when `#rust-analyzer.lens.enable#` is set. - lens_references_trait_enable: bool = false, - /// Whether to show `Run` lens. Only applies when - /// `#rust-analyzer.lens.enable#` is set. - lens_run_enable: bool = true, - - /// Whether to show `can't find Cargo.toml` error message. - notifications_cargoTomlNotFound: bool = true, - - /// How many worker threads in the main loop. The default `null` means to pick automatically. - numThreads: Option = None, - - /// Expand attribute macros. Requires `#rust-analyzer.procMacro.enable#` to be set. - procMacro_attributes_enable: bool = true, - /// Enable support for procedural macros, implies `#rust-analyzer.cargo.buildScripts.enable#`. - procMacro_enable: bool = true, - /// Internal config, path to proc-macro server executable. - procMacro_server: Option = None, - - /// Exclude imports from find-all-references. - references_excludeImports: bool = false, - - /// Exclude tests from find-all-references. - references_excludeTests: bool = false, - - /// Inject additional highlighting into doc comments. - /// - /// When enabled, rust-analyzer will highlight rust source in doc comments as well as intra - /// doc links. - semanticHighlighting_doc_comment_inject_enable: bool = true, - /// Whether the server is allowed to emit non-standard tokens and modifiers. - semanticHighlighting_nonStandardTokens: bool = true, - /// Use semantic tokens for operators. - /// - /// When disabled, rust-analyzer will emit semantic tokens only for operator tokens when - /// they are tagged with modifiers. - semanticHighlighting_operator_enable: bool = true, - /// Use specialized semantic tokens for operators. - /// - /// When enabled, rust-analyzer will emit special token types for operator tokens instead - /// of the generic `operator` token type. - semanticHighlighting_operator_specialization_enable: bool = false, - /// Use semantic tokens for punctuation. - /// - /// When disabled, rust-analyzer will emit semantic tokens only for punctuation tokens when - /// they are tagged with modifiers or have a special role. - semanticHighlighting_punctuation_enable: bool = false, - /// When enabled, rust-analyzer will emit a punctuation semantic token for the `!` of macro - /// calls. - semanticHighlighting_punctuation_separate_macro_bang: bool = false, - /// Use specialized semantic tokens for punctuation. - /// - /// When enabled, rust-analyzer will emit special token types for punctuation tokens instead - /// of the generic `punctuation` token type. - semanticHighlighting_punctuation_specialization_enable: bool = false, - /// Use semantic tokens for strings. - /// - /// In some editors (e.g. vscode) semantic tokens override other highlighting grammars. - /// By disabling semantic tokens for strings, other grammars can be used to highlight - /// their contents. - semanticHighlighting_strings_enable: bool = true, - - /// Show full signature of the callable. Only shows parameters if disabled. - signatureInfo_detail: SignatureDetail = SignatureDetail::Full, - /// Show documentation. - signatureInfo_documentation_enable: bool = true, - - /// Whether to insert closing angle brackets when typing an opening angle bracket of a generic argument list. - typing_autoClosingAngleBrackets_enable: bool = false, } } From 987a9342ad24ae1772e0cbc34319ae618e59a19f Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Thu, 22 Aug 2024 21:50:40 +0200 Subject: [PATCH 11/13] Remove invalid tests --- crates/rust-analyzer/src/config.rs | 72 ------------------------------ 1 file changed, 72 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index e7c5f989d9..8e41b43bfe 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -3585,76 +3585,4 @@ mod tests { matches!(config.flycheck(None), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("other_folder"))) ); } - - #[test] - fn toml_unknown_key() { - let config = - Config::new(AbsPathBuf::assert(project_root()), Default::default(), vec![], None); - - let mut change = ConfigChange::default(); - - change.change_user_config(Some( - toml::toml! { - [cargo.cfgs] - these = "these" - should = "should" - be = "be" - valid = "valid" - - [invalid.config] - err = "error" - - [cargo] - target = "ok" - - // FIXME: This should be an error - [cargo.sysroot] - non-table = "expected" - } - .to_string() - .into(), - )); - - let (config, e, _) = config.apply_change(change); - expect_test::expect![[r#" - ConfigErrors( - [ - Toml { - config_key: "invalid/config/err", - error: Error { - inner: Error { - inner: TomlError { - message: "unexpected field", - raw: None, - keys: [], - span: None, - }, - }, - }, - }, - ], - ) - "#]] - .assert_debug_eq(&e); - let mut change = ConfigChange::default(); - - change.change_user_config(Some( - toml::toml! { - [cargo.cfgs] - these = "these" - should = "should" - be = "be" - valid = "valid" - } - .to_string() - .into(), - )); - let (_, e, _) = config.apply_change(change); - expect_test::expect![[r#" - ConfigErrors( - [], - ) - "#]] - .assert_debug_eq(&e); - } } From 5e6f5b1f386fc3ba40a0624d78a26d1f20e0e55b Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Wed, 28 Aug 2024 19:40:58 +0200 Subject: [PATCH 12/13] Minor errors --- crates/rust-analyzer/src/config.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 8e41b43bfe..0a1bdf49bd 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -1897,7 +1897,7 @@ impl Config { CargoFeaturesDef::Selected(it) => it, }, extra_args: self.extra_args(source_root).clone(), - extra_test_bin_args: self.runnables_extraTestBinaryArgs().clone(), + extra_test_bin_args: self.runnables_extraTestBinaryArgs(source_root).clone(), extra_env: self.extra_env(source_root).clone(), target_dir: self.target_dir_from_config(source_root), } @@ -1954,7 +1954,7 @@ impl Config { CargoFeaturesDef::Selected(it) => it, }, extra_args: self.check_extra_args(source_root), - extra_test_bin_args: self.runnables_extraTestBinaryArgs().clone(), + extra_test_bin_args: self.runnables_extraTestBinaryArgs(source_root).clone(), extra_env: self.check_extra_env(source_root), target_dir: self.target_dir_from_config(source_root), }, From b17f1eee7de06209ec228683f5000bc86de18e6f Mon Sep 17 00:00:00 2001 From: Ali Bektas Date: Sat, 31 Aug 2024 03:01:54 +0200 Subject: [PATCH 13/13] Apply changes, fix path information in a comment in config.rs --- crates/rust-analyzer/src/config.rs | 8 +++----- crates/rust-analyzer/src/handlers/notification.rs | 13 ------------- crates/rust-analyzer/src/reload.rs | 2 +- 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 0a1bdf49bd..c884216b3e 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -62,12 +62,10 @@ mod patch_old_style; // To deprecate an option by replacing it with another name use `new_name | `old_name` so that we keep // parsing the old name. config_data! { - /// Configs that apply on a workspace-wide scope. There are 3 levels on which a global configuration can be configured - // FIXME: 1. and 3. should be split, some configs do not make sense per project + /// Configs that apply on a workspace-wide scope. There are 2 levels on which a global configuration can be configured /// - /// 1. `rust-analyzer.toml` file under user's config directory (e.g ~/.config/rust-analyzer.toml) + /// 1. `rust-analyzer.toml` file under user's config directory (e.g ~/.config/rust-analyzer/rust-analyzer.toml) /// 2. Client's own configurations (e.g `settings.json` on VS Code) - /// 3. `rust-analyzer.toml` file located at the workspace root /// /// A config is searched for by traversing a "config tree" in a bottom up fashion. It is chosen by the nearest first principle. global: struct GlobalDefaultConfigData <- GlobalConfigInput -> { @@ -532,7 +530,7 @@ config_data! { cargo_allTargets: bool = true, /// Automatically refresh project info via `cargo metadata` on /// `Cargo.toml` or `.cargo/config.toml` changes. - pub(crate) cargo_autoreload: bool = true, + cargo_autoreload: bool = true, /// Run build scripts (`build.rs`) for more precise code analysis. cargo_buildScripts_enable: bool = true, /// Specifies the invocation strategy to use when running the build scripts command. diff --git a/crates/rust-analyzer/src/handlers/notification.rs b/crates/rust-analyzer/src/handlers/notification.rs index dc8d40e0ee..e8d1a7e4df 100644 --- a/crates/rust-analyzer/src/handlers/notification.rs +++ b/crates/rust-analyzer/src/handlers/notification.rs @@ -145,13 +145,10 @@ pub(crate) fn handle_did_save_text_document( state: &mut GlobalState, params: DidSaveTextDocumentParams, ) -> anyhow::Result<()> { - let mut deps_change_processed = false; - if let Ok(vfs_path) = from_proto::vfs_path(¶ms.text_document.uri) { let snap = state.snapshot(); let file_id = snap.vfs_path_to_file_id(&vfs_path)?; let sr = snap.analysis.source_root_id(file_id)?; - deps_change_processed = true; if state.config.script_rebuild_on_save(Some(sr)) && state.build_deps_changed { state.build_deps_changed = false; @@ -199,16 +196,6 @@ pub(crate) fn handle_did_save_text_document( } } - if !deps_change_processed - && state.config.script_rebuild_on_save(None) - && state.build_deps_changed - { - state.build_deps_changed = false; - state - .fetch_build_data_queue - .request_op("build_deps_changed - save notification".to_owned(), ()); - } - Ok(()) } diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 5d77b7aa67..12667e3c90 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -122,7 +122,7 @@ impl GlobalState { }; let mut message = String::new(); - if !self.config.cargo_autoreload(None) + if !self.config.cargo_autoreload_config(None) && self.is_quiescent() && self.fetch_workspaces_queue.op_requested() && self.config.discover_workspace_config().is_none()