Detailed changes
@@ -0,0 +1,4 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M8.00156 10.3996C9.32705 10.3996 10.4016 9.32509 10.4016 7.99961C10.4016 6.67413 9.32705 5.59961 8.00156 5.59961C6.67608 5.59961 5.60156 6.67413 5.60156 7.99961C5.60156 9.32509 6.67608 10.3996 8.00156 10.3996Z" stroke="black" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M10.4 5.6V8.6C10.4 9.07739 10.5896 9.53523 10.9272 9.8728C11.2648 10.2104 11.7226 10.4 12.2 10.4C12.6774 10.4 13.1352 10.2104 13.4728 9.8728C13.8104 9.53523 14 9.07739 14 8.6V8C14 6.64839 13.5436 5.33636 12.7048 4.27651C11.8661 3.21665 10.694 2.47105 9.37852 2.16051C8.06306 1.84997 6.68129 1.99269 5.45707 2.56554C4.23285 3.13838 3.23791 4.1078 2.63344 5.31672C2.02898 6.52565 1.85041 7.90325 2.12667 9.22633C2.40292 10.5494 3.11782 11.7405 4.15552 12.6065C5.19323 13.4726 6.49295 13.9629 7.84411 13.998C9.19527 14.0331 10.5187 13.611 11.6 12.8" stroke="black" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>
@@ -694,14 +694,18 @@ fn build_symbol_label(symbol_name: &str, file_name: &str, line: u32, cx: &App) -
}
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 path = cx
+ .theme()
+ .syntax()
+ .highlight_id("variable")
+ .map(HighlightId);
let mut label = CodeLabelBuilder::default();
label.push_str(file_name, None);
label.push_str(" ", None);
if let Some(directory) = directory {
- label.push_str(directory, comment_id);
+ label.push_str(directory, path);
}
label.build()
@@ -15,6 +15,7 @@ use editor::{
EditorEvent, EditorMode, EditorSnapshot, EditorStyle, ExcerptId, FoldPlaceholder, Inlay,
MultiBuffer, ToOffset,
actions::Paste,
+ code_context_menus::CodeContextMenu,
display_map::{Crease, CreaseId, FoldId},
scroll::Autoscroll,
};
@@ -272,6 +273,15 @@ impl MessageEditor {
self.editor.read(cx).is_empty(cx)
}
+ pub fn is_completions_menu_visible(&self, cx: &App) -> bool {
+ self.editor
+ .read(cx)
+ .context_menu()
+ .borrow()
+ .as_ref()
+ .is_some_and(|menu| matches!(menu, CodeContextMenu::Completions(_)) && menu.visible())
+ }
+
pub fn mentions(&self) -> HashSet<MentionUri> {
self.mention_set
.mentions
@@ -836,6 +846,45 @@ impl MessageEditor {
cx.emit(MessageEditorEvent::Send)
}
+ pub fn trigger_completion_menu(&mut self, window: &mut Window, cx: &mut Context<Self>) {
+ let editor = self.editor.clone();
+
+ cx.spawn_in(window, async move |_, cx| {
+ editor
+ .update_in(cx, |editor, window, cx| {
+ let menu_is_open =
+ editor.context_menu().borrow().as_ref().is_some_and(|menu| {
+ matches!(menu, CodeContextMenu::Completions(_)) && menu.visible()
+ });
+
+ let has_at_sign = {
+ let snapshot = editor.display_snapshot(cx);
+ let cursor = editor.selections.newest::<text::Point>(&snapshot).head();
+ let offset = cursor.to_offset(&snapshot);
+ if offset > 0 {
+ snapshot
+ .buffer_snapshot()
+ .reversed_chars_at(offset)
+ .next()
+ .map(|sign| sign == '@')
+ .unwrap_or(false)
+ } else {
+ false
+ }
+ };
+
+ if menu_is_open && has_at_sign {
+ return;
+ }
+
+ editor.insert("@", window, cx);
+ editor.show_completions(&editor::actions::ShowCompletions, window, cx);
+ })
+ .log_err();
+ })
+ .detach();
+ }
+
fn chat(&mut self, _: &Chat, _: &mut Window, cx: &mut Context<Self>) {
self.send(cx);
}
@@ -4188,6 +4188,8 @@ impl AcpThreadView {
.justify_between()
.child(
h_flex()
+ .gap_0p5()
+ .child(self.render_add_context_button(cx))
.child(self.render_follow_toggle(cx))
.children(self.render_burn_mode_toggle(cx)),
)
@@ -4502,6 +4504,29 @@ impl AcpThreadView {
}))
}
+ fn render_add_context_button(&self, cx: &mut Context<Self>) -> impl IntoElement {
+ let message_editor = self.message_editor.clone();
+ let menu_visible = message_editor.read(cx).is_completions_menu_visible(cx);
+
+ IconButton::new("add-context", IconName::AtSign)
+ .icon_size(IconSize::Small)
+ .icon_color(Color::Muted)
+ .when(!menu_visible, |this| {
+ this.tooltip(move |_window, cx| {
+ Tooltip::with_meta("Add Context", None, "Or type @ to include context", cx)
+ })
+ })
+ .on_click(cx.listener(move |_this, _, window, cx| {
+ let message_editor_clone = message_editor.clone();
+
+ window.defer(cx, move |window, cx| {
+ message_editor_clone.update(cx, |message_editor, cx| {
+ message_editor.trigger_completion_menu(window, cx);
+ });
+ });
+ }))
+ }
+
fn render_markdown(&self, markdown: Entity<Markdown>, style: MarkdownStyle) -> MarkdownElement {
let workspace = self.workspace.clone();
MarkdownElement::new(markdown, style).on_url_click(move |text, window, cx| {
@@ -35,6 +35,7 @@ pub enum IconName {
ArrowUp,
ArrowUpRight,
Attach,
+ AtSign,
AudioOff,
AudioOn,
Backspace,