agent_ui: Ensure message editor placeholder text is accurate (#42375)

This PR creates a dedicated function for the agent panel message
editor's placeholder text so that we can wait for the agent
initialization to capture whether they support slash commands or not. On
the one (nice) hand, this allow us to stop matching agents by name and
make this a bit more generic. On the other (bad) hand, the "/ for
commands" bit should take a little second to show up because we can only
know whether an agent supports it after it is initialized.

This is particularly relevant now that we have agents coming from
extensions and for them, we would obviously not be able to match by
name.

Release Notes:

- agent: Fixed agent panel message editor's placeholder text by making
it more accurate as to whether agents support slash commands,
particularly those coming from extensions.
This commit is contained in:
Danilo Leal
2025-11-10 16:50:52 -03:00
committed by GitHub
parent c24f9e47b4
commit 2c375e2e0a
2 changed files with 32 additions and 13 deletions
+11
View File
@@ -1195,6 +1195,17 @@ impl MessageEditor {
self.editor.read(cx).text(cx)
}
pub fn set_placeholder_text(
&mut self,
placeholder: &str,
window: &mut Window,
cx: &mut Context<Self>,
) {
self.editor.update(cx, |editor, cx| {
editor.set_placeholder_text(placeholder, window, cx);
});
}
#[cfg(test)]
pub fn set_text(&mut self, text: &str, window: &mut Window, cx: &mut Context<Self>) {
self.editor.update(cx, |editor, cx| {
+21 -13
View File
@@ -337,19 +337,7 @@ impl AcpThreadView {
let prompt_capabilities = Rc::new(RefCell::new(acp::PromptCapabilities::default()));
let available_commands = Rc::new(RefCell::new(vec![]));
let placeholder = if agent.name() == "Zed Agent" {
format!("Message the {} — @ to include context", agent.name())
} else if agent.name() == "Claude Code"
|| agent.name() == "Codex"
|| !available_commands.borrow().is_empty()
{
format!(
"Message {} — @ to include context, / for commands",
agent.name()
)
} else {
format!("Message {} — @ to include context", agent.name())
};
let placeholder = placeholder_text(agent.name().as_ref(), false);
let message_editor = cx.new(|cx| {
let mut editor = MessageEditor::new(
@@ -1456,7 +1444,14 @@ impl AcpThreadView {
});
}
let has_commands = !available_commands.is_empty();
self.available_commands.replace(available_commands);
let new_placeholder = placeholder_text(self.agent.name().as_ref(), has_commands);
self.message_editor.update(cx, |editor, cx| {
editor.set_placeholder_text(&new_placeholder, window, cx);
});
}
AcpThreadEvent::ModeUpdated(_mode) => {
// The connection keeps track of the mode
@@ -5708,6 +5703,19 @@ fn loading_contents_spinner(size: IconSize) -> AnyElement {
.into_any_element()
}
fn placeholder_text(agent_name: &str, has_commands: bool) -> String {
if agent_name == "Zed Agent" {
format!("Message the {} — @ to include context", agent_name)
} else if has_commands {
format!(
"Message {} — @ to include context, / for commands",
agent_name
)
} else {
format!("Message {} — @ to include context", agent_name)
}
}
impl Focusable for AcpThreadView {
fn focus_handle(&self, cx: &App) -> FocusHandle {
match self.thread_state {