Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/rust-analyzer/src/flycheck.rs52
-rw-r--r--crates/rust-analyzer/src/global_state.rs2
-rw-r--r--crates/rust-analyzer/src/main_loop.rs27
-rw-r--r--crates/rust-analyzer/src/reload.rs1
4 files changed, 62 insertions, 20 deletions
diff --git a/crates/rust-analyzer/src/flycheck.rs b/crates/rust-analyzer/src/flycheck.rs
index 7f814121e9..6dcae76c93 100644
--- a/crates/rust-analyzer/src/flycheck.rs
+++ b/crates/rust-analyzer/src/flycheck.rs
@@ -309,13 +309,18 @@ impl fmt::Debug for FlycheckMessage {
#[derive(Debug)]
pub(crate) enum Progress {
- DidStart,
+ DidStart {
+ /// The user sees this in VSCode, etc. May be a shortened version of the command we actually
+ /// executed, otherwise it is way too long.
+ user_facing_command: String,
+ },
DidCheckCrate(String),
DidFinish(io::Result<()>),
DidCancel,
DidFailToRestart(String),
}
+#[derive(Debug, Clone)]
enum FlycheckScope {
Workspace,
Package {
@@ -346,6 +351,16 @@ impl PackageSpecifier {
}
}
+#[derive(Debug)]
+enum FlycheckCommandOrigin {
+ /// Regular cargo invocation
+ Cargo,
+ /// Configured via check_overrideCommand
+ CheckOverrideCommand,
+ /// From a runnable with [project_json::RunnableKind::Flycheck]
+ ProjectJsonRunnable,
+}
+
enum StateChange {
Restart {
generation: DiagnosticsGeneration,
@@ -529,16 +544,28 @@ impl FlycheckActor {
}
let command = self.check_command(&scope, saved_file.as_deref(), target);
- self.scope = scope;
+ self.scope = scope.clone();
self.generation = generation;
- let Some(command) = command else {
+ let Some((command, origin)) = command else {
+ tracing::debug!(?scope, "failed to build flycheck command");
continue;
};
- let formatted_command = format!("{command:?}");
+ let debug_command = format!("{command:?}");
+ let user_facing_command = match origin {
+ // Don't show all the --format=json-with-blah-blah args, just the simple
+ // version
+ FlycheckCommandOrigin::Cargo => self.config.to_string(),
+ // show them the full command but pretty printed. advanced user
+ FlycheckCommandOrigin::ProjectJsonRunnable
+ | FlycheckCommandOrigin::CheckOverrideCommand => display_command(
+ &command,
+ Some(std::path::Path::new(self.root.as_path())),
+ ),
+ };
- tracing::debug!(?command, "will restart flycheck");
+ tracing::debug!(?origin, ?command, "will restart flycheck");
let (sender, receiver) = unbounded();
match CommandHandle::spawn(
command,
@@ -575,14 +602,14 @@ impl FlycheckActor {
},
) {
Ok(command_handle) => {
- tracing::debug!(command = formatted_command, "did restart flycheck");
+ tracing::debug!(?origin, command = %debug_command, "did restart flycheck");
self.command_handle = Some(command_handle);
self.command_receiver = Some(receiver);
- self.report_progress(Progress::DidStart);
+ self.report_progress(Progress::DidStart { user_facing_command });
}
Err(error) => {
self.report_progress(Progress::DidFailToRestart(format!(
- "Failed to run the following command: {formatted_command} error={error}"
+ "Failed to run the following command: {debug_command} origin={origin:?} error={error}"
)));
}
}
@@ -789,7 +816,7 @@ impl FlycheckActor {
scope: &FlycheckScope,
saved_file: Option<&AbsPath>,
target: Option<Target>,
- ) -> Option<Command> {
+ ) -> Option<(Command, FlycheckCommandOrigin)> {
match &self.config {
FlycheckConfig::CargoCommand { command, options, ansi_color_output } => {
// Only use the rust-project.json's flycheck config when no check_overrideCommand
@@ -803,7 +830,8 @@ impl FlycheckActor {
// Completely handle according to rust-project.json.
// We don't consider this to be "using cargo" so we will not apply any of the
// CargoOptions to the command.
- return self.explicit_check_command(scope, saved_file);
+ let cmd = self.explicit_check_command(scope, saved_file)?;
+ return Some((cmd, FlycheckCommandOrigin::ProjectJsonRunnable));
}
let mut cmd =
@@ -864,7 +892,7 @@ impl FlycheckActor {
self.ws_target_dir.as_ref().map(Utf8PathBuf::as_path),
);
cmd.args(&options.extra_args);
- Some(cmd)
+ Some((cmd, FlycheckCommandOrigin::Cargo))
}
FlycheckConfig::CustomCommand { command, args, extra_env, invocation_strategy } => {
let root = match invocation_strategy {
@@ -892,7 +920,7 @@ impl FlycheckActor {
let subs = Substitutions { label, saved_file: saved_file.map(|x| x.as_str()) };
let cmd = subs.substitute(&runnable, extra_env)?;
- Some(cmd)
+ Some((cmd, FlycheckCommandOrigin::CheckOverrideCommand))
}
}
}
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index 0cfd0a141b..39b4aaa647 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -112,6 +112,7 @@ pub(crate) struct GlobalState {
pub(crate) flycheck_sender: Sender<FlycheckMessage>,
pub(crate) flycheck_receiver: Receiver<FlycheckMessage>,
pub(crate) last_flycheck_error: Option<String>,
+ pub(crate) flycheck_formatted_commands: Vec<String>,
// Test explorer
pub(crate) test_run_session: Option<Vec<CargoTestHandle>>,
@@ -288,6 +289,7 @@ impl GlobalState {
flycheck_sender,
flycheck_receiver,
last_flycheck_error: None,
+ flycheck_formatted_commands: vec![],
test_run_session: None,
test_run_sender,
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index dd0813c144..62a3b3a17b 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -1179,8 +1179,24 @@ impl GlobalState {
kind: ClearDiagnosticsKind::OlderThan(generation, ClearScope::Package(package_id)),
} => self.diagnostics.clear_check_older_than_for_package(id, package_id, generation),
FlycheckMessage::Progress { id, progress } => {
+ let format_with_id = |user_facing_command: String| {
+ if self.flycheck.len() == 1 {
+ user_facing_command
+ } else {
+ format!("{user_facing_command} (#{})", id + 1)
+ }
+ };
+
+ self.flycheck_formatted_commands
+ .resize_with(self.flycheck.len().max(id + 1), || {
+ format_with_id(self.config.flycheck(None).to_string())
+ });
+
let (state, message) = match progress {
- flycheck::Progress::DidStart => (Progress::Begin, None),
+ flycheck::Progress::DidStart { user_facing_command } => {
+ self.flycheck_formatted_commands[id] = format_with_id(user_facing_command);
+ (Progress::Begin, None)
+ }
flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)),
flycheck::Progress::DidCancel => {
self.last_flycheck_error = None;
@@ -1200,13 +1216,8 @@ 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(None))
- } else {
- format!("{} (#{})", self.config.flycheck(None), id + 1)
- };
+ // Clone because we &mut self for report_progress
+ let title = self.flycheck_formatted_commands[id].clone();
self.report_progress(
&title,
state,
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index 0a16b7a561..ccafbd7b30 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -942,6 +942,7 @@ impl GlobalState {
}
}
.into();
+ self.flycheck_formatted_commands = vec![];
}
}