mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-10 10:01:43 -10:00
fix(tui): attach every line range when one file is mentioned twice (#7259)
* fix(tui): attach every line range when one file is mentioned twice Mentions are deduplicated before they are attached, and a resolved file is keyed by its path alone. `compare @notes.txt:1-1 with @notes.txt:4-4` therefore attached lines 1-1 and dropped 4-4, while the composer showed a "resolved on send" chip for each and the model got no hint that the second range was missing. Key a ranged mention by path and range. Repeating the same range, or the whole file, still deduplicates as before. Signed-off-by: Lstarsky0 <[email protected]> * fix(tui): keep a range key from matching a literal file name The range was joined to the path with `:`, which a file name can contain. With files `notes.txt` and `notes.txt:1-1`, `@notes.txt:01-01 @notes.txt:1-1` gave both the key `notes.txt:1-1`, and the literal file was dropped. Join them with a NUL, which no path contains. Signed-off-by: Lstarsky0 <[email protected]> --------- Signed-off-by: Lstarsky0 <[email protected]>
This commit is contained in:
1 parent
0f00f50a62
commit
3c8eb5540c
1 file changed
+30
-1
@@ -1119,7 +1119,10 @@ fn local_context_from_file_mentions(
|
||||
// Missing mentions dedup on the typed token: there is no resolved
|
||||
// path to key on, and the workspace-root guess must not become one.
|
||||
let dedup_key = if exists {
|
||||
display_path.clone()
|
||||
match range {
|
||||
Some(FileRange { start, end }) => format!("{display_path}\0{start}-{end}"),
|
||||
None => display_path.clone(),
|
||||
}
|
||||
} else {
|
||||
format!("missing:{mention}")
|
||||
};
|
||||
@@ -1737,6 +1740,32 @@ mod tests {
|
||||
assert!(!content.contains("<missing-file"), "got: {content}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn two_ranges_of_one_file_are_both_attached() {
|
||||
let tmp = TempDir::new().expect("tempdir");
|
||||
std::fs::write(tmp.path().join("notes.txt"), "one\ntwo\nthree\nfour\n").expect("write");
|
||||
|
||||
let content = user_request_with_file_mentions(
|
||||
"compare @notes.txt:1-1 with @notes.txt:4-4",
|
||||
tmp.path(),
|
||||
None,
|
||||
);
|
||||
|
||||
assert!(content.contains("lines=\"1-1\">\none\n"), "got: {content}");
|
||||
assert!(content.contains("lines=\"4-4\">\nfour\n"), "got: {content}");
|
||||
|
||||
if cfg!(unix) {
|
||||
std::fs::write(tmp.path().join("notes.txt:1-1"), "literal\n").expect("write");
|
||||
let content = user_request_with_file_mentions(
|
||||
"@notes.txt:01-01 @notes.txt:1-1",
|
||||
tmp.path(),
|
||||
None,
|
||||
);
|
||||
assert!(content.contains("lines=\"1-1\">\none\n"), "got: {content}");
|
||||
assert!(content.contains("literal\n"), "got: {content}");
|
||||
}
|
||||
}
|
||||
|
||||
/// Negative test: a truly missing path still produces `<missing-file>`
|
||||
/// so the user gets an explicit signal instead of silent failure.
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user