-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feature: Substitute $saved_file in custom check commands #15476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,7 @@ use std::{ | |
|
||
use command_group::{CommandGroup, GroupChild}; | ||
use crossbeam_channel::{never, select, unbounded, Receiver, Sender}; | ||
use paths::AbsPathBuf; | ||
use paths::{AbsPath, AbsPathBuf}; | ||
use rustc_hash::FxHashMap; | ||
use serde::Deserialize; | ||
use stdx::process::streaming_output; | ||
|
@@ -102,13 +102,15 @@ impl FlycheckHandle { | |
} | ||
|
||
/// Schedule a re-start of the cargo check worker to do a workspace wide check. | ||
pub fn restart_workspace(&self) { | ||
self.sender.send(StateChange::Restart(None)).unwrap(); | ||
pub fn restart_workspace(&self, saved_file: Option<AbsPathBuf>) { | ||
self.sender.send(StateChange::Restart { package: None, saved_file }).unwrap(); | ||
} | ||
|
||
/// Schedule a re-start of the cargo check worker to do a package wide check. | ||
pub fn restart_for_package(&self, package: String) { | ||
self.sender.send(StateChange::Restart(Some(package))).unwrap(); | ||
self.sender | ||
.send(StateChange::Restart { package: Some(package), saved_file: None }) | ||
.unwrap(); | ||
} | ||
|
||
/// Stop this cargo check worker. | ||
|
@@ -159,7 +161,7 @@ pub enum Progress { | |
} | ||
|
||
enum StateChange { | ||
Restart(Option<String>), | ||
Restart { package: Option<String>, saved_file: Option<AbsPathBuf> }, | ||
Cancel, | ||
} | ||
|
||
|
@@ -186,6 +188,8 @@ enum Event { | |
CheckEvent(Option<CargoMessage>), | ||
} | ||
|
||
const SAVED_FILE_PLACEHOLDER: &str = "$saved_file"; | ||
|
||
impl FlycheckActor { | ||
fn new( | ||
id: usize, | ||
|
@@ -221,7 +225,7 @@ impl FlycheckActor { | |
tracing::debug!(flycheck_id = self.id, "flycheck cancelled"); | ||
self.cancel_check_process(); | ||
} | ||
Event::RequestStateChange(StateChange::Restart(package)) => { | ||
Event::RequestStateChange(StateChange::Restart { package, saved_file }) => { | ||
// Cancel the previously spawned process | ||
self.cancel_check_process(); | ||
while let Ok(restart) = inbox.recv_timeout(Duration::from_millis(50)) { | ||
|
@@ -231,7 +235,11 @@ impl FlycheckActor { | |
} | ||
} | ||
|
||
let command = self.check_command(package.as_deref()); | ||
let command = | ||
match self.check_command(package.as_deref(), saved_file.as_deref()) { | ||
Some(c) => c, | ||
None => continue, | ||
}; | ||
let formatted_command = format!("{:?}", command); | ||
|
||
tracing::debug!(?command, "will restart flycheck"); | ||
|
@@ -305,7 +313,14 @@ impl FlycheckActor { | |
} | ||
} | ||
|
||
fn check_command(&self, package: Option<&str>) -> Command { | ||
/// Construct a `Command` object for checking the user's code. If the user | ||
/// has specified a custom command with placeholders that we cannot fill, | ||
/// return None. | ||
fn check_command( | ||
&self, | ||
package: Option<&str>, | ||
saved_file: Option<&AbsPath>, | ||
) -> Option<Command> { | ||
let (mut cmd, args) = match &self.config { | ||
FlycheckConfig::CargoCommand { | ||
command, | ||
|
@@ -358,7 +373,7 @@ impl FlycheckActor { | |
cmd.arg("--target-dir").arg(target_dir); | ||
} | ||
cmd.envs(extra_env); | ||
(cmd, extra_args) | ||
(cmd, extra_args.clone()) | ||
} | ||
FlycheckConfig::CustomCommand { | ||
command, | ||
|
@@ -387,12 +402,34 @@ impl FlycheckActor { | |
} | ||
} | ||
|
||
(cmd, args) | ||
if args.contains(&SAVED_FILE_PLACEHOLDER.to_owned()) { | ||
// If the custom command has a $saved_file placeholder, and | ||
// we're saving a file, replace the placeholder in the arguments. | ||
if let Some(saved_file) = saved_file { | ||
let args = args | ||
.iter() | ||
.map(|arg| { | ||
if arg == SAVED_FILE_PLACEHOLDER { | ||
saved_file.to_string() | ||
} else { | ||
arg.clone() | ||
} | ||
}) | ||
.collect(); | ||
(cmd, args) | ||
} else { | ||
// The custom command has a $saved_file placeholder, | ||
// but we had an IDE event that wasn't a file save. Do nothing. | ||
return None; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This means there's going to be no initial check when loading the project, but I don't see any way around it without configuring two check commands. I guess this is not a problem for you, but Cargo users trying this might still be surprised (ref. #12882). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An example this should work for is I reckon: If the command has $saved_file in it, return None. If it doesn't, return Some, as it does not require substitution. That brings back the current behaviour until you start using $saved_file. |
||
} | ||
} else { | ||
(cmd, args.clone()) | ||
} | ||
} | ||
}; | ||
|
||
cmd.args(args); | ||
cmd | ||
Some(cmd) | ||
} | ||
|
||
fn send(&self, check_task: Message) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -234,6 +234,11 @@ each of them, with the working directory being the workspace root | |
by changing `#rust-analyzer.check.invocationStrategy#` and | ||
`#rust-analyzer.check.invocationLocation#`. | ||
|
||
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. | ||
Comment on lines
+237
to
+239
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given my comment, let's make clear that this is only a temporary thing and will likely be removed in the future |
||
Note that `$saved_file` is experimental and may be removed in the futureg. | ||
|
||
An example command would be: | ||
|
||
```bash | ||
|
Uh oh!
There was an error while loading. Please reload this page.