mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 06:03:58 +00:00
feat: Allow cargo check to run on only the current package
This commit is contained in:
parent
bcc8a09a0d
commit
0258f60cfe
7 changed files with 68 additions and 28 deletions
|
@ -100,9 +100,14 @@ impl FlycheckHandle {
|
||||||
FlycheckHandle { id, sender, _thread: thread }
|
FlycheckHandle { id, sender, _thread: thread }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Schedule a re-start of the cargo check worker.
|
/// Schedule a re-start of the cargo check worker to do a workspace wide check.
|
||||||
pub fn restart(&self) {
|
pub fn restart_workspace(&self) {
|
||||||
self.sender.send(StateChange::Restart).unwrap();
|
self.sender.send(StateChange::Restart(None)).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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stop this cargo check worker.
|
/// Stop this cargo check worker.
|
||||||
|
@ -153,7 +158,7 @@ pub enum Progress {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum StateChange {
|
enum StateChange {
|
||||||
Restart,
|
Restart(Option<String>),
|
||||||
Cancel,
|
Cancel,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +218,7 @@ impl FlycheckActor {
|
||||||
tracing::debug!(flycheck_id = self.id, "flycheck cancelled");
|
tracing::debug!(flycheck_id = self.id, "flycheck cancelled");
|
||||||
self.cancel_check_process();
|
self.cancel_check_process();
|
||||||
}
|
}
|
||||||
Event::RequestStateChange(StateChange::Restart) => {
|
Event::RequestStateChange(StateChange::Restart(package)) => {
|
||||||
// Cancel the previously spawned process
|
// Cancel the previously spawned process
|
||||||
self.cancel_check_process();
|
self.cancel_check_process();
|
||||||
while let Ok(restart) = inbox.recv_timeout(Duration::from_millis(50)) {
|
while let Ok(restart) = inbox.recv_timeout(Duration::from_millis(50)) {
|
||||||
|
@ -223,7 +228,7 @@ impl FlycheckActor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let command = self.check_command();
|
let command = self.check_command(package.as_deref());
|
||||||
let formatted_command = format!("{:?}", command);
|
let formatted_command = format!("{:?}", command);
|
||||||
|
|
||||||
tracing::debug!(?command, "will restart flycheck");
|
tracing::debug!(?command, "will restart flycheck");
|
||||||
|
@ -297,7 +302,7 @@ impl FlycheckActor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_command(&self) -> Command {
|
fn check_command(&self, package: Option<&str>) -> Command {
|
||||||
let (mut cmd, args) = match &self.config {
|
let (mut cmd, args) = match &self.config {
|
||||||
FlycheckConfig::CargoCommand {
|
FlycheckConfig::CargoCommand {
|
||||||
command,
|
command,
|
||||||
|
@ -314,7 +319,11 @@ impl FlycheckActor {
|
||||||
let mut cmd = Command::new(toolchain::cargo());
|
let mut cmd = Command::new(toolchain::cargo());
|
||||||
cmd.arg(command);
|
cmd.arg(command);
|
||||||
cmd.current_dir(&self.root);
|
cmd.current_dir(&self.root);
|
||||||
cmd.arg("--workspace");
|
|
||||||
|
match package {
|
||||||
|
Some(pkg) => cmd.arg("-p").arg(pkg),
|
||||||
|
None => cmd.arg("--workspace"),
|
||||||
|
};
|
||||||
|
|
||||||
cmd.arg(if *ansi_color_output {
|
cmd.arg(if *ansi_color_output {
|
||||||
"--message-format=json-diagnostic-rendered-ansi"
|
"--message-format=json-diagnostic-rendered-ansi"
|
||||||
|
|
|
@ -223,6 +223,9 @@ config_data! {
|
||||||
///
|
///
|
||||||
/// Aliased as `"checkOnSave.targets"`.
|
/// Aliased as `"checkOnSave.targets"`.
|
||||||
check_targets | checkOnSave_targets | checkOnSave_target: Option<CheckOnSaveTargets> = "null",
|
check_targets | checkOnSave_targets | checkOnSave_target: Option<CheckOnSaveTargets> = "null",
|
||||||
|
/// Whether `--workspace` should be passed to `cargo check`.
|
||||||
|
/// If false, `-p <package>` will be passed instead.
|
||||||
|
check_workspace: bool = "true",
|
||||||
|
|
||||||
/// Toggles the additional completions that automatically add imports when completed.
|
/// 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.
|
/// Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.
|
||||||
|
@ -1323,6 +1326,10 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn flycheck_workspace(&self) -> bool {
|
||||||
|
self.data.check_workspace
|
||||||
|
}
|
||||||
|
|
||||||
pub fn flycheck(&self) -> FlycheckConfig {
|
pub fn flycheck(&self) -> FlycheckConfig {
|
||||||
match &self.data.check_overrideCommand {
|
match &self.data.check_overrideCommand {
|
||||||
Some(args) if !args.is_empty() => {
|
Some(args) if !args.is_empty() => {
|
||||||
|
|
|
@ -160,7 +160,7 @@ pub(crate) fn handle_did_save_text_document(
|
||||||
} else if state.config.check_on_save() {
|
} else if state.config.check_on_save() {
|
||||||
// No specific flycheck was triggered, so let's trigger all of them.
|
// No specific flycheck was triggered, so let's trigger all of them.
|
||||||
for flycheck in state.flycheck.iter() {
|
for flycheck in state.flycheck.iter() {
|
||||||
flycheck.restart();
|
flycheck.restart_workspace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -281,27 +281,40 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
|
||||||
let crate_root_paths: Vec<_> = crate_root_paths.iter().map(Deref::deref).collect();
|
let crate_root_paths: Vec<_> = crate_root_paths.iter().map(Deref::deref).collect();
|
||||||
|
|
||||||
// Find all workspaces that have at least one target containing the saved file
|
// Find all workspaces that have at least one target containing the saved file
|
||||||
let workspace_ids = world.workspaces.iter().enumerate().filter(|(_, ws)| match ws {
|
let workspace_ids = world.workspaces.iter().enumerate().filter_map(|(idx, ws)| {
|
||||||
project_model::ProjectWorkspace::Cargo { cargo, .. } => {
|
let package = match ws {
|
||||||
cargo.packages().any(|pkg| {
|
project_model::ProjectWorkspace::Cargo { cargo, .. } => {
|
||||||
cargo[pkg]
|
cargo.packages().find_map(|pkg| {
|
||||||
.targets
|
let has_target_with_root = cargo[pkg]
|
||||||
.iter()
|
.targets
|
||||||
.any(|&it| crate_root_paths.contains(&cargo[it].root.as_path()))
|
.iter()
|
||||||
})
|
.any(|&it| crate_root_paths.contains(&cargo[it].root.as_path()));
|
||||||
}
|
has_target_with_root.then(|| cargo[pkg].name.clone())
|
||||||
project_model::ProjectWorkspace::Json { project, .. } => {
|
})
|
||||||
project.crates().any(|(c, _)| crate_ids.iter().any(|&crate_id| crate_id == c))
|
}
|
||||||
}
|
project_model::ProjectWorkspace::Json { project, .. } => {
|
||||||
project_model::ProjectWorkspace::DetachedFiles { .. } => false,
|
if !project
|
||||||
|
.crates()
|
||||||
|
.any(|(c, _)| crate_ids.iter().any(|&crate_id| crate_id == c))
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
project_model::ProjectWorkspace::DetachedFiles { .. } => return None,
|
||||||
|
};
|
||||||
|
Some((idx, package))
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find and trigger corresponding flychecks
|
// Find and trigger corresponding flychecks
|
||||||
for flycheck in world.flycheck.iter() {
|
for flycheck in world.flycheck.iter() {
|
||||||
for (id, _) in workspace_ids.clone() {
|
for (id, package) in workspace_ids.clone() {
|
||||||
if id == flycheck.id() {
|
if id == flycheck.id() {
|
||||||
updated = true;
|
updated = true;
|
||||||
flycheck.restart();
|
match package.filter(|_| !world.config.flycheck_workspace()) {
|
||||||
|
Some(package) => flycheck.restart_for_package(package),
|
||||||
|
None => flycheck.restart_workspace(),
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,7 +322,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
|
||||||
// No specific flycheck was triggered, so let's trigger all of them.
|
// No specific flycheck was triggered, so let's trigger all of them.
|
||||||
if !updated {
|
if !updated {
|
||||||
for flycheck in world.flycheck.iter() {
|
for flycheck in world.flycheck.iter() {
|
||||||
flycheck.restart();
|
flycheck.restart_workspace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -351,7 +364,7 @@ pub(crate) fn handle_run_flycheck(
|
||||||
}
|
}
|
||||||
// No specific flycheck was triggered, so let's trigger all of them.
|
// No specific flycheck was triggered, so let's trigger all of them.
|
||||||
for flycheck in state.flycheck.iter() {
|
for flycheck in state.flycheck.iter() {
|
||||||
flycheck.restart();
|
flycheck.restart_workspace();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -314,7 +314,7 @@ impl GlobalState {
|
||||||
if became_quiescent {
|
if became_quiescent {
|
||||||
if self.config.check_on_save() {
|
if self.config.check_on_save() {
|
||||||
// Project has loaded properly, kick off initial flycheck
|
// Project has loaded properly, kick off initial flycheck
|
||||||
self.flycheck.iter().for_each(FlycheckHandle::restart);
|
self.flycheck.iter().for_each(FlycheckHandle::restart_workspace);
|
||||||
}
|
}
|
||||||
if self.config.prefill_caches() {
|
if self.config.prefill_caches() {
|
||||||
self.prime_caches_queue.request_op("became quiescent".to_string(), ());
|
self.prime_caches_queue.request_op("became quiescent".to_string(), ());
|
||||||
|
|
|
@ -503,7 +503,7 @@ impl GlobalState {
|
||||||
let mut crate_graph_file_dependencies = FxHashSet::default();
|
let mut crate_graph_file_dependencies = FxHashSet::default();
|
||||||
|
|
||||||
let mut load = |path: &AbsPath| {
|
let mut load = |path: &AbsPath| {
|
||||||
let _p = tracing::span!(tracing::Level::INFO, "switch_workspaces::load").entered();
|
let _p = tracing::span!(tracing::Level::DEBUG, "switch_workspaces::load").entered();
|
||||||
let vfs_path = vfs::VfsPath::from(path.to_path_buf());
|
let vfs_path = vfs::VfsPath::from(path.to_path_buf());
|
||||||
crate_graph_file_dependencies.insert(vfs_path.clone());
|
crate_graph_file_dependencies.insert(vfs_path.clone());
|
||||||
match vfs.file_id(&vfs_path) {
|
match vfs.file_id(&vfs_path) {
|
||||||
|
|
|
@ -251,6 +251,12 @@ Can be a single target, e.g. `"x86_64-unknown-linux-gnu"` or a list of targets,
|
||||||
|
|
||||||
Aliased as `"checkOnSave.targets"`.
|
Aliased as `"checkOnSave.targets"`.
|
||||||
--
|
--
|
||||||
|
[[rust-analyzer.check.workspace]]rust-analyzer.check.workspace (default: `true`)::
|
||||||
|
+
|
||||||
|
--
|
||||||
|
Whether `--workspace` should be passed to `cargo check`.
|
||||||
|
If false, `-p <package>` will be passed instead.
|
||||||
|
--
|
||||||
[[rust-analyzer.completion.autoimport.enable]]rust-analyzer.completion.autoimport.enable (default: `true`)::
|
[[rust-analyzer.completion.autoimport.enable]]rust-analyzer.completion.autoimport.enable (default: `true`)::
|
||||||
+
|
+
|
||||||
--
|
--
|
||||||
|
|
|
@ -803,6 +803,11 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"rust-analyzer.check.workspace": {
|
||||||
|
"markdownDescription": "Whether `--workspace` should be passed to `cargo check`.\nIf false, `-p <package>` will be passed instead.",
|
||||||
|
"default": true,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"rust-analyzer.completion.autoimport.enable": {
|
"rust-analyzer.completion.autoimport.enable": {
|
||||||
"markdownDescription": "Toggles the additional completions that automatically add imports when completed.\nNote that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.",
|
"markdownDescription": "Toggles the additional completions that automatically add imports when completed.\nNote that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.",
|
||||||
"default": true,
|
"default": true,
|
||||||
|
|
Loading…
Reference in a new issue