diff --git a/crates/vite_select/src/lib.rs b/crates/vite_select/src/lib.rs index a2bac06b..2082ce8c 100644 --- a/crates/vite_select/src/lib.rs +++ b/crates/vite_select/src/lib.rs @@ -95,6 +95,16 @@ fn non_interactive( before_render(&mut filtered, query.unwrap_or_default()); let len = filtered.len(); + // When there are no matching items, just print the header (if any) and + // return early — avoids showing a redundant "No matching tasks." line + // after a "not found" header. + if filtered.is_empty() { + if let Some(h) = header { + writeln!(writer, "{h}")?; + } + return Ok(()); + } + render_items( writer, &RenderParams { diff --git a/crates/vite_task/src/session/mod.rs b/crates/vite_task/src/session/mod.rs index 833c2e8f..dfbd2c83 100644 --- a/crates/vite_task/src/session/mod.rs +++ b/crates/vite_task/src/session/mod.rs @@ -378,12 +378,20 @@ impl<'a> Session<'a> { }) .collect(); - // Build header: interactive says "not found.", non-interactive "did you mean:" suffix + // Build header: interactive says "not found.", non-interactive adds + // "Did you mean:" suffix only when there are fuzzy matches to show. let header = not_found_name.map(|name| { if is_interactive { vite_str::format!("Task \"{name}\" not found.") } else { - vite_str::format!("Task \"{name}\" not found. Did you mean:") + let labels: Vec<&str> = + select_items.iter().map(|item| item.label.as_str()).collect(); + let has_suggestions = !vite_select::fuzzy_match(name, &labels).is_empty(); + if has_suggestions { + vite_str::format!("Task \"{name}\" not found. Did you mean:") + } else { + vite_str::format!("Task \"{name}\" not found.") + } } }); diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots.toml b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots.toml index 1d0fd7ed..5d553a8e 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots.toml +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots.toml @@ -12,6 +12,13 @@ steps = [ "echo '' | vp run buid", ] +# Non-interactive: typo with no fuzzy matches hides "did you mean" +[[e2e]] +name = "non-interactive no suggestions" +steps = [ + "echo '' | vp run zzzzz", +] + # Non-interactive: typo with -r flag errors (not cwd_only) [[e2e]] name = "non-interactive recursive typo errors" diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/non-interactive no suggestions.snap b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/non-interactive no suggestions.snap new file mode 100644 index 00000000..ded69c93 --- /dev/null +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/task-select/snapshots/non-interactive no suggestions.snap @@ -0,0 +1,6 @@ +--- +source: crates/vite_task_bin/tests/e2e_snapshots/main.rs +expression: e2e_outputs +--- +[1]> echo '' | vp run zzzzz +Task "zzzzz" not found.