From 884b5acd35ddf4d4649f33a7447bcbce1abbfeba Mon Sep 17 00:00:00 2001 From: cyq <15000851237@163.com> Date: Tue, 2 Jun 2026 02:02:40 +0800 Subject: [PATCH 1/2] fix(tui): hint mention depth cap on misses --- crates/tui/src/tui/file_mention.rs | 15 ++++++++++++++- crates/tui/src/tui/ui/tests.rs | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/crates/tui/src/tui/file_mention.rs b/crates/tui/src/tui/file_mention.rs index 86d237c22..3a04e7073 100644 --- a/crates/tui/src/tui/file_mention.rs +++ b/crates/tui/src/tui/file_mention.rs @@ -270,7 +270,10 @@ pub fn try_autocomplete_file_mention(app: &mut App) -> bool { let ws = workspace_for_app(app); let candidates = find_file_mention_completions(&ws, &partial, FILE_MENTION_COMPLETION_LIMIT); if candidates.is_empty() { - app.status_message = Some(format!("No files match @{partial}")); + app.status_message = Some(no_file_mention_matches_status( + &partial, + app.mention_walk_depth, + )); return true; } if candidates.len() == 1 { @@ -297,6 +300,16 @@ pub fn try_autocomplete_file_mention(app: &mut App) -> bool { true } +fn no_file_mention_matches_status(partial: &str, walk_depth: usize) -> String { + if walk_depth > 0 && (partial.contains('/') || partial.contains('\\')) { + format!( + "No files match @{partial} (mention_walk_depth={walk_depth}; use /config set mention_walk_depth 0 to search deeper)" + ) + } else { + format!("No files match @{partial}") + } +} + /// Splice a completion into the input, replacing the `@` token at /// `byte_start` with `@`. Cursor moves to the end of the new /// token so further keystrokes extend (or escape via space) naturally. diff --git a/crates/tui/src/tui/ui/tests.rs b/crates/tui/src/tui/ui/tests.rs index 166031371..5c566cf1f 100644 --- a/crates/tui/src/tui/ui/tests.rs +++ b/crates/tui/src/tui/ui/tests.rs @@ -4694,6 +4694,25 @@ fn try_autocomplete_file_mention_no_match_reports_status() { ); } +#[test] +fn try_autocomplete_file_mention_no_match_mentions_depth_cap_for_path_like_partial() { + let tmpdir = TempDir::new().expect("tempdir"); + + let mut app = create_test_app(); + app.workspace = tmpdir.path().to_path_buf(); + app.mention_walk_depth = 6; + app.input = "@a/b/c/d/e/f/g/target".to_string(); + app.cursor_position = app.input.chars().count(); + + assert!(try_autocomplete_file_mention(&mut app)); + assert_eq!( + app.status_message.as_deref(), + Some( + "No files match @a/b/c/d/e/f/g/target (mention_walk_depth=6; use /config set mention_walk_depth 0 to search deeper)" + ) + ); +} + #[test] fn try_autocomplete_file_mention_returns_false_outside_mention() { let mut app = create_test_app(); From 637b2f40770e65924eb28cccac12c8b1c9a43e70 Mon Sep 17 00:00:00 2001 From: cyq <15000851237@163.com> Date: Tue, 2 Jun 2026 02:11:31 +0800 Subject: [PATCH 2/2] fix(tui): narrow mention depth hint --- crates/tui/src/tui/file_mention.rs | 13 +++++++++++- crates/tui/src/tui/ui/tests.rs | 34 ++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/crates/tui/src/tui/file_mention.rs b/crates/tui/src/tui/file_mention.rs index 3a04e7073..4e9e2d368 100644 --- a/crates/tui/src/tui/file_mention.rs +++ b/crates/tui/src/tui/file_mention.rs @@ -301,7 +301,7 @@ pub fn try_autocomplete_file_mention(app: &mut App) -> bool { } fn no_file_mention_matches_status(partial: &str, walk_depth: usize) -> String { - if walk_depth > 0 && (partial.contains('/') || partial.contains('\\')) { + if path_partial_reaches_walk_depth(partial, walk_depth) { format!( "No files match @{partial} (mention_walk_depth={walk_depth}; use /config set mention_walk_depth 0 to search deeper)" ) @@ -310,6 +310,17 @@ fn no_file_mention_matches_status(partial: &str, walk_depth: usize) -> String { } } +fn path_partial_reaches_walk_depth(partial: &str, walk_depth: usize) -> bool { + if walk_depth == 0 { + return false; + } + let component_count = partial + .split(['/', '\\']) + .filter(|component| !component.is_empty()) + .count(); + component_count >= walk_depth +} + /// Splice a completion into the input, replacing the `@` token at /// `byte_start` with `@`. Cursor moves to the end of the new /// token so further keystrokes extend (or escape via space) naturally. diff --git a/crates/tui/src/tui/ui/tests.rs b/crates/tui/src/tui/ui/tests.rs index 5c566cf1f..a1420dbb8 100644 --- a/crates/tui/src/tui/ui/tests.rs +++ b/crates/tui/src/tui/ui/tests.rs @@ -4713,6 +4713,40 @@ fn try_autocomplete_file_mention_no_match_mentions_depth_cap_for_path_like_parti ); } +#[test] +fn try_autocomplete_file_mention_no_match_skips_depth_hint_for_shallow_path() { + let tmpdir = TempDir::new().expect("tempdir"); + + let mut app = create_test_app(); + app.workspace = tmpdir.path().to_path_buf(); + app.mention_walk_depth = 6; + app.input = "@shallow_missing/main.rs".to_string(); + app.cursor_position = app.input.chars().count(); + + assert!(try_autocomplete_file_mention(&mut app)); + assert_eq!( + app.status_message.as_deref(), + Some("No files match @shallow_missing/main.rs") + ); +} + +#[test] +fn try_autocomplete_file_mention_no_match_skips_depth_hint_when_unlimited() { + let tmpdir = TempDir::new().expect("tempdir"); + + let mut app = create_test_app(); + app.workspace = tmpdir.path().to_path_buf(); + app.mention_walk_depth = 0; + app.input = "@a/b/c/d/e/f/g/target".to_string(); + app.cursor_position = app.input.chars().count(); + + assert!(try_autocomplete_file_mention(&mut app)); + assert_eq!( + app.status_message.as_deref(), + Some("No files match @a/b/c/d/e/f/g/target") + ); +} + #[test] fn try_autocomplete_file_mention_returns_false_outside_mention() { let mut app = create_test_app();