agent_ui: Add file name and line number to symbol completions (#40508)

Symbol completions in the context picker now show "SymbolName
filename.txt L123" instead of just "SymbolName". This helps distinguish
between symbols with the same name in different files.

## Motivation

I noticed that the message prompt editor only showed symbol names
without any context, making it hard to use in large projects with many
symbols sharing the same name. The inline prompt editor already includes
file context for symbol completions, so I brought that same UX
improvement to the message prompt editor. I've decided to match the
highlighting style with directory completion entries from the message
editor.

## Changes

- Extract file name from both InProject and OutsideProject symbol
locations
- Add `build_symbol_label` helper to format labels with file context
- Update test expectation for new label format

## Screenshots
Inline Prompt Editor
<img width="843" height="334" alt="Screenshot 2025-10-17 at 17 47 52"
src="https://github.com/user-attachments/assets/16752e1a-0b8c-4f58-a0b2-25ae5130f18c"
/>
Old Message Editor:
<img width="466" height="363" alt="Screenshot 2025-10-17 at 17 31 44"
src="https://github.com/user-attachments/assets/900659f3-0632-4dff-bc9a-ab2dad351964"
/>
New Message Editor:
<img width="482" height="359" alt="Screenshot 2025-10-17 at 17 31 23"
src="https://github.com/user-attachments/assets/bf382167-f88b-4f3d-ba3e-1e251a8df962"
/>


Release Notes:

- Added file names and line numbers to symbol completions in the agent
panel
This commit is contained in:
Paweł Kondzior
2025-10-28 16:43:48 +01:00
committed by GitHub
parent 233a1eb46e
commit d00ad02b05
2 changed files with 24 additions and 8 deletions
+23 -7
View File
@@ -253,17 +253,22 @@ impl ContextPickerCompletionProvider {
) -> Option<Completion> {
let project = workspace.read(cx).project().clone();
let label = CodeLabel::plain(symbol.name.clone(), None);
let abs_path = match &symbol.path {
SymbolLocation::InProject(project_path) => {
project.read(cx).absolute_path(&project_path, cx)?
}
let (abs_path, file_name) = match &symbol.path {
SymbolLocation::InProject(project_path) => (
project.read(cx).absolute_path(&project_path, cx)?,
project_path.path.file_name()?.to_string().into(),
),
SymbolLocation::OutsideProject {
abs_path,
signature: _,
} => PathBuf::from(abs_path.as_ref()),
} => (
PathBuf::from(abs_path.as_ref()),
abs_path.file_name().map(|f| f.to_string_lossy())?,
),
};
let label = build_symbol_label(&symbol.name, &file_name, symbol.range.start.0.row + 1, cx);
let uri = MentionUri::Symbol {
abs_path,
name: symbol.name.clone(),
@@ -674,6 +679,17 @@ impl ContextPickerCompletionProvider {
}
}
fn build_symbol_label(symbol_name: &str, file_name: &str, line: u32, cx: &App) -> CodeLabel {
let comment_id = cx.theme().syntax().highlight_id("comment").map(HighlightId);
let mut label = CodeLabelBuilder::default();
label.push_str(symbol_name, None);
label.push_str(" ", None);
label.push_str(&format!("{} L{}", file_name, line), comment_id);
label.build()
}
fn build_code_label_for_full_path(file_name: &str, directory: Option<&str>, cx: &App) -> CodeLabel {
let comment_id = cx.theme().syntax().highlight_id("comment").map(HighlightId);
let mut label = CodeLabelBuilder::default();
+1 -1
View File
@@ -2473,7 +2473,7 @@ mod tests {
format!("Lorem [@one.txt]({url_one}) Ipsum [@eight.txt]({url_eight}) @symbol ")
);
assert!(editor.has_visible_completions_menu());
assert_eq!(current_completion_labels(editor), &["MySymbol"]);
assert_eq!(current_completion_labels(editor), &["MySymbol one.txt L1"]);
});
editor.update_in(&mut cx, |editor, window, cx| {