From 04a79780d8987ae92a340a1e701e294e4f095018 Mon Sep 17 00:00:00 2001 From: Bennet Bo Fenner Date: Fri, 21 Jun 2024 11:48:52 +0200 Subject: [PATCH] assistant: Include worktree name in diagnostics slash command (#13354) Files included with the diagnostics command now include the worktree name, making it more consistent with the way other commands work (`/active`, `/tabs`, `/file`). Also, the diagnostics command will now insert nothing when there are no diagnostics. Release Notes: - N/A --- .../src/slash_command/diagnostics_command.rs | 36 ++++++++++++++----- .../src/assistant_slash_command.rs | 1 + 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/crates/assistant/src/slash_command/diagnostics_command.rs b/crates/assistant/src/slash_command/diagnostics_command.rs index 677b43e6f7..1f72a5b635 100644 --- a/crates/assistant/src/slash_command/diagnostics_command.rs +++ b/crates/assistant/src/slash_command/diagnostics_command.rs @@ -10,6 +10,7 @@ use language::{ use project::{DiagnosticSummary, PathMatchCandidateSet, Project}; use rope::Point; use std::fmt::Write; +use std::path::PathBuf; use std::{ ops::Range, sync::{atomic::AtomicBool, Arc}, @@ -57,7 +58,7 @@ impl DiagnosticsCommand { include_ignored: worktree .root_entry() .map_or(false, |entry| entry.is_ignored), - include_root_name: false, + include_root_name: true, candidates: project::Candidates::Entries, } }) @@ -161,7 +162,10 @@ impl SlashCommand for DiagnosticsCommand { let task = collect_diagnostics(workspace.read(cx).project().clone(), options, cx); cx.spawn(move |_| async move { - let (text, sections) = task.await?; + let Some((text, sections)) = task.await? else { + return Ok(SlashCommandOutput::default()); + }; + Ok(SlashCommandOutput { text, sections: sections @@ -257,7 +261,7 @@ fn collect_diagnostics( project: Model, options: Options, cx: &mut AppContext, -) -> Task, PlaceholderType)>)>> { +) -> Task, PlaceholderType)>)>>> { let error_source = if let Some(path_matcher) = &options.path_matcher { debug_assert_eq!(path_matcher.sources().len(), 1); Some(path_matcher.sources().first().cloned().unwrap_or_default()) @@ -266,7 +270,16 @@ fn collect_diagnostics( }; let project_handle = project.downgrade(); - let diagnostic_summaries: Vec<_> = project.read(cx).diagnostic_summaries(false, cx).collect(); + let diagnostic_summaries: Vec<_> = project + .read(cx) + .diagnostic_summaries(false, cx) + .flat_map(|(path, _, summary)| { + let worktree = project.read(cx).worktree_for_id(path.worktree_id, cx)?; + let mut path_buf = PathBuf::from(worktree.read(cx).root_name()); + path_buf.push(&path.path); + Some((path, path_buf, summary)) + }) + .collect(); cx.spawn(|mut cx| async move { let mut text = String::new(); @@ -278,9 +291,9 @@ fn collect_diagnostics( let mut sections: Vec<(Range, PlaceholderType)> = Vec::new(); let mut project_summary = DiagnosticSummary::default(); - for (project_path, _, summary) in diagnostic_summaries { + for (project_path, path, summary) in diagnostic_summaries { if let Some(path_matcher) = &options.path_matcher { - if !path_matcher.is_match(&project_path.path) { + if !path_matcher.is_match(&path) { continue; } } @@ -293,7 +306,7 @@ fn collect_diagnostics( } let last_end = text.len(); - let file_path = project_path.path.to_string_lossy().to_string(); + let file_path = path.to_string_lossy().to_string(); writeln!(&mut text, "{file_path}").unwrap(); if let Some(buffer) = project_handle @@ -314,12 +327,17 @@ fn collect_diagnostics( PlaceholderType::File(file_path), )) } + + // No diagnostics found + if sections.is_empty() { + return Ok(None); + } + sections.push(( 0..text.len(), PlaceholderType::Root(project_summary, error_source), )); - - Ok((text, sections)) + Ok(Some((text, sections))) }) } diff --git a/crates/assistant_slash_command/src/assistant_slash_command.rs b/crates/assistant_slash_command/src/assistant_slash_command.rs index 374cb817df..c468d134fe 100644 --- a/crates/assistant_slash_command/src/assistant_slash_command.rs +++ b/crates/assistant_slash_command/src/assistant_slash_command.rs @@ -50,6 +50,7 @@ pub type RenderFoldPlaceholder = Arc< + Fn(ElementId, Arc, &mut WindowContext) -> AnyElement, >; +#[derive(Default)] pub struct SlashCommandOutput { pub text: String, pub sections: Vec>,