editor: Wrap placeholder if text overflows (#37919)
This fixes an issue where long placeholders would be cut off, e.g. in a Claude Code thread: <img width="387" height="115" alt="image" src="https://github.com/user-attachments/assets/831a54aa-cf2b-4d87-af86-e368a5936f6b" /> Now: <img width="354" height="115" alt="image" src="https://github.com/user-attachments/assets/e5df5e05-0869-4db2-8dee-38611263191c" /> Most of the changes in this PR are caused by us requiring `&mut Window` in `set_placeholder_text`. Release Notes: - Fixed an issue where placeholders inside editors would not wrap --------- Co-authored-by: Agus Zubiaga <agus@zed.dev>
This commit is contained in:
co-authored by
Agus Zubiaga
parent
fb3c991112
commit
acb3406eb8
@@ -91,7 +91,7 @@ impl MessageEditor {
|
||||
prompt_capabilities: Rc<Cell<acp::PromptCapabilities>>,
|
||||
available_commands: Rc<RefCell<Vec<acp::AvailableCommand>>>,
|
||||
agent_name: SharedString,
|
||||
placeholder: impl Into<Arc<str>>,
|
||||
placeholder: &str,
|
||||
mode: EditorMode,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
@@ -117,7 +117,7 @@ impl MessageEditor {
|
||||
let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx));
|
||||
|
||||
let mut editor = Editor::new(mode, buffer, None, window, cx);
|
||||
editor.set_placeholder_text(placeholder, cx);
|
||||
editor.set_placeholder_text(placeholder, window, cx);
|
||||
editor.set_show_indent_guides(false, cx);
|
||||
editor.set_soft_wrap();
|
||||
editor.set_use_modal_editing(true);
|
||||
|
||||
@@ -70,7 +70,7 @@ impl AcpThreadHistory {
|
||||
) -> Self {
|
||||
let search_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("Search threads...", cx);
|
||||
editor.set_placeholder_text("Search threads...", window, cx);
|
||||
editor
|
||||
});
|
||||
|
||||
|
||||
@@ -250,6 +250,7 @@ impl ThreadFeedbackState {
|
||||
);
|
||||
editor.set_placeholder_text(
|
||||
"What went wrong? Share your feedback so we can improve.",
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
editor
|
||||
@@ -355,7 +356,7 @@ impl AcpThreadView {
|
||||
prompt_capabilities.clone(),
|
||||
available_commands.clone(),
|
||||
agent.name(),
|
||||
placeholder,
|
||||
&placeholder,
|
||||
editor::EditorMode::AutoHeight {
|
||||
min_lines: MIN_EDITOR_LINES,
|
||||
max_lines: Some(MAX_EDITOR_LINES),
|
||||
|
||||
@@ -1742,6 +1742,7 @@ impl ActiveThread {
|
||||
);
|
||||
editor.set_placeholder_text(
|
||||
"What went wrong? Share your feedback so we can improve.",
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
editor
|
||||
|
||||
@@ -156,7 +156,7 @@ impl ManageProfilesModal {
|
||||
) {
|
||||
let name_editor = cx.new(|cx| Editor::single_line(window, cx));
|
||||
name_editor.update(cx, |editor, cx| {
|
||||
editor.set_placeholder_text("Profile name", cx);
|
||||
editor.set_placeholder_text("Profile name", window, cx);
|
||||
});
|
||||
|
||||
self.mode = Mode::NewProfile(NewProfileMode {
|
||||
|
||||
@@ -229,7 +229,7 @@ impl<T: 'static> PromptEditor<T> {
|
||||
self.editor = cx.new(|cx| {
|
||||
let mut editor = Editor::auto_height(1, Self::MAX_LINES as usize, window, cx);
|
||||
editor.set_soft_wrap_mode(language::language_settings::SoftWrap::EditorWidth, cx);
|
||||
editor.set_placeholder_text("Add a prompt…", cx);
|
||||
editor.set_placeholder_text("Add a prompt…", window, cx);
|
||||
editor.set_text(prompt, window, cx);
|
||||
insert_message_creases(
|
||||
&mut editor,
|
||||
@@ -782,7 +782,7 @@ impl PromptEditor<BufferCodegen> {
|
||||
// always show the cursor (even when it isn't focused) because
|
||||
// typing in one will make what you typed appear in all of them.
|
||||
editor.set_show_cursor_when_unfocused(true, cx);
|
||||
editor.set_placeholder_text(Self::placeholder_text(&mode, window, cx), cx);
|
||||
editor.set_placeholder_text(&Self::placeholder_text(&mode, window, cx), window, cx);
|
||||
editor.register_addon(ContextCreasesAddon::new());
|
||||
editor.set_context_menu_options(ContextMenuOptions {
|
||||
min_entries_visible: 12,
|
||||
@@ -949,7 +949,7 @@ impl PromptEditor<TerminalCodegen> {
|
||||
cx,
|
||||
);
|
||||
editor.set_soft_wrap_mode(language::language_settings::SoftWrap::EditorWidth, cx);
|
||||
editor.set_placeholder_text(Self::placeholder_text(&mode, window, cx), cx);
|
||||
editor.set_placeholder_text(&Self::placeholder_text(&mode, window, cx), window, cx);
|
||||
editor.set_context_menu_options(ContextMenuOptions {
|
||||
min_entries_visible: 12,
|
||||
max_entries_visible: 12,
|
||||
|
||||
@@ -124,7 +124,7 @@ pub(crate) fn create_editor(
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
editor.set_placeholder_text("Message the agent – @ to include context", cx);
|
||||
editor.set_placeholder_text("Message the agent – @ to include context", window, cx);
|
||||
editor.disable_word_completions();
|
||||
editor.set_show_indent_guides(false, cx);
|
||||
editor.set_soft_wrap();
|
||||
|
||||
@@ -73,7 +73,7 @@ impl ThreadHistory {
|
||||
) -> Self {
|
||||
let search_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("Search threads...", cx);
|
||||
editor.set_placeholder_text("Search threads...", window, cx);
|
||||
editor
|
||||
});
|
||||
|
||||
|
||||
@@ -280,7 +280,7 @@ impl CollabPanel {
|
||||
cx.new(|cx| {
|
||||
let filter_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("Filter...", cx);
|
||||
editor.set_placeholder_text("Filter...", window, cx);
|
||||
editor
|
||||
});
|
||||
|
||||
|
||||
@@ -803,12 +803,12 @@ impl ConfigureMode {
|
||||
pub(super) fn new(window: &mut Window, cx: &mut App) -> Entity<Self> {
|
||||
let program = cx.new(|cx| Editor::single_line(window, cx));
|
||||
program.update(cx, |this, cx| {
|
||||
this.set_placeholder_text("ENV=Zed ~/bin/program --option", cx);
|
||||
this.set_placeholder_text("ENV=Zed ~/bin/program --option", window, cx);
|
||||
});
|
||||
|
||||
let cwd = cx.new(|cx| Editor::single_line(window, cx));
|
||||
cwd.update(cx, |this, cx| {
|
||||
this.set_placeholder_text("Ex: $ZED_WORKTREE_ROOT", cx);
|
||||
this.set_placeholder_text("Ex: $ZED_WORKTREE_ROOT", window, cx);
|
||||
});
|
||||
|
||||
cx.new(|_| Self {
|
||||
|
||||
@@ -219,7 +219,7 @@ impl BreakpointList {
|
||||
});
|
||||
|
||||
self.input.update(cx, |this, cx| {
|
||||
this.set_placeholder_text(placeholder, cx);
|
||||
this.set_placeholder_text(placeholder, window, cx);
|
||||
this.set_read_only(is_exception_breakpoint);
|
||||
this.set_text(active_value.as_deref().unwrap_or(""), window, cx);
|
||||
});
|
||||
|
||||
@@ -83,7 +83,7 @@ impl Console {
|
||||
let this = cx.weak_entity();
|
||||
let query_bar = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("Evaluate an expression", cx);
|
||||
editor.set_placeholder_text("Evaluate an expression", window, cx);
|
||||
editor.set_use_autoclose(false);
|
||||
editor.set_show_gutter(false, cx);
|
||||
editor.set_show_wrap_guides(false, cx);
|
||||
|
||||
@@ -428,14 +428,14 @@ impl MemoryView {
|
||||
if !self.is_writing_memory {
|
||||
self.query_editor.update(cx, |this, cx| {
|
||||
this.clear(window, cx);
|
||||
this.set_placeholder_text("Write to Selected Memory Range", cx);
|
||||
this.set_placeholder_text("Write to Selected Memory Range", window, cx);
|
||||
});
|
||||
self.is_writing_memory = true;
|
||||
self.query_editor.focus_handle(cx).focus(window);
|
||||
} else {
|
||||
self.query_editor.update(cx, |this, cx| {
|
||||
this.clear(window, cx);
|
||||
this.set_placeholder_text("Go to Memory Address / Expression", cx);
|
||||
this.set_placeholder_text("Go to Memory Address / Expression", window, cx);
|
||||
});
|
||||
self.is_writing_memory = false;
|
||||
}
|
||||
|
||||
+47
-16
@@ -1008,6 +1008,7 @@ pub struct Editor {
|
||||
/// Map of how text in the buffer should be displayed.
|
||||
/// Handles soft wraps, folds, fake inlay text insertions, etc.
|
||||
pub display_map: Entity<DisplayMap>,
|
||||
placeholder_display_map: Option<Entity<DisplayMap>>,
|
||||
pub selections: SelectionsCollection,
|
||||
pub scroll_manager: ScrollManager,
|
||||
/// When inline assist editors are linked, they all render cursors because
|
||||
@@ -1057,7 +1058,6 @@ pub struct Editor {
|
||||
show_breakpoints: Option<bool>,
|
||||
show_wrap_guides: Option<bool>,
|
||||
show_indent_guides: Option<bool>,
|
||||
placeholder_text: Option<Arc<str>>,
|
||||
highlight_order: usize,
|
||||
highlighted_rows: HashMap<TypeId, Vec<RowHighlight>>,
|
||||
background_highlights: HashMap<HighlightKey, BackgroundHighlight>,
|
||||
@@ -1209,7 +1209,7 @@ pub struct EditorSnapshot {
|
||||
show_breakpoints: Option<bool>,
|
||||
git_blame_gutter_max_author_length: Option<usize>,
|
||||
pub display_snapshot: DisplaySnapshot,
|
||||
pub placeholder_text: Option<Arc<str>>,
|
||||
pub placeholder_display_snapshot: Option<DisplaySnapshot>,
|
||||
is_focused: bool,
|
||||
scroll_anchor: ScrollAnchor,
|
||||
ongoing_scroll: OngoingScroll,
|
||||
@@ -2066,6 +2066,7 @@ impl Editor {
|
||||
last_focused_descendant: None,
|
||||
buffer: buffer.clone(),
|
||||
display_map: display_map.clone(),
|
||||
placeholder_display_map: None,
|
||||
selections,
|
||||
scroll_manager: ScrollManager::new(cx),
|
||||
columnar_selection_state: None,
|
||||
@@ -2109,7 +2110,6 @@ impl Editor {
|
||||
show_breakpoints: None,
|
||||
show_wrap_guides: None,
|
||||
show_indent_guides,
|
||||
placeholder_text: None,
|
||||
highlight_order: 0,
|
||||
highlighted_rows: HashMap::default(),
|
||||
background_highlights: HashMap::default(),
|
||||
@@ -2728,9 +2728,12 @@ impl Editor {
|
||||
show_breakpoints: self.show_breakpoints,
|
||||
git_blame_gutter_max_author_length,
|
||||
display_snapshot: self.display_map.update(cx, |map, cx| map.snapshot(cx)),
|
||||
placeholder_display_snapshot: self
|
||||
.placeholder_display_map
|
||||
.as_ref()
|
||||
.map(|display_map| display_map.update(cx, |map, cx| map.snapshot(cx))),
|
||||
scroll_anchor: self.scroll_manager.anchor(),
|
||||
ongoing_scroll: self.scroll_manager.ongoing_scroll(),
|
||||
placeholder_text: self.placeholder_text.clone(),
|
||||
is_focused: self.focus_handle.is_focused(window),
|
||||
current_line_highlight: self
|
||||
.current_line_highlight
|
||||
@@ -2826,20 +2829,37 @@ impl Editor {
|
||||
self.refresh_edit_prediction(false, false, window, cx);
|
||||
}
|
||||
|
||||
pub fn placeholder_text(&self) -> Option<&str> {
|
||||
self.placeholder_text.as_deref()
|
||||
pub fn placeholder_text(&self, cx: &mut App) -> Option<String> {
|
||||
self.placeholder_display_map
|
||||
.as_ref()
|
||||
.map(|display_map| display_map.update(cx, |map, cx| map.snapshot(cx)).text())
|
||||
}
|
||||
|
||||
pub fn set_placeholder_text(
|
||||
&mut self,
|
||||
placeholder_text: impl Into<Arc<str>>,
|
||||
placeholder_text: &str,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let placeholder_text = Some(placeholder_text.into());
|
||||
if self.placeholder_text != placeholder_text {
|
||||
self.placeholder_text = placeholder_text;
|
||||
cx.notify();
|
||||
}
|
||||
let multibuffer = cx
|
||||
.new(|cx| MultiBuffer::singleton(cx.new(|cx| Buffer::local(placeholder_text, cx)), cx));
|
||||
|
||||
let style = window.text_style();
|
||||
|
||||
self.placeholder_display_map = Some(cx.new(|cx| {
|
||||
DisplayMap::new(
|
||||
multibuffer,
|
||||
style.font(),
|
||||
style.font_size.to_pixels(window.rem_size()),
|
||||
None,
|
||||
FILE_HEADER_HEIGHT,
|
||||
MULTI_BUFFER_EXCERPT_HEADER_HEIGHT,
|
||||
Default::default(),
|
||||
DiagnosticSeverity::Off,
|
||||
cx,
|
||||
)
|
||||
}));
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn set_cursor_shape(&mut self, cursor_shape: CursorShape, cx: &mut Context<Self>) {
|
||||
@@ -18895,8 +18915,16 @@ impl Editor {
|
||||
// Called by the element. This method is not designed to be called outside of the editor
|
||||
// element's layout code because it does not notify when rewrapping is computed synchronously.
|
||||
pub(crate) fn set_wrap_width(&self, width: Option<Pixels>, cx: &mut App) -> bool {
|
||||
self.display_map
|
||||
.update(cx, |map, cx| map.set_wrap_width(width, cx))
|
||||
if self.is_empty(cx) {
|
||||
self.placeholder_display_map
|
||||
.as_ref()
|
||||
.map_or(false, |display_map| {
|
||||
display_map.update(cx, |map, cx| map.set_wrap_width(width, cx))
|
||||
})
|
||||
} else {
|
||||
self.display_map
|
||||
.update(cx, |map, cx| map.set_wrap_width(width, cx))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_soft_wrap(&mut self) {
|
||||
@@ -23011,8 +23039,10 @@ impl EditorSnapshot {
|
||||
self.is_focused
|
||||
}
|
||||
|
||||
pub fn placeholder_text(&self) -> Option<&Arc<str>> {
|
||||
self.placeholder_text.as_ref()
|
||||
pub fn placeholder_text(&self) -> Option<String> {
|
||||
self.placeholder_display_snapshot
|
||||
.as_ref()
|
||||
.map(|display_map| display_map.text())
|
||||
}
|
||||
|
||||
pub fn scroll_position(&self) -> gpui::Point<f32> {
|
||||
@@ -24003,6 +24033,7 @@ impl BreakpointPromptEditor {
|
||||
BreakpointPromptEditAction::Condition => "Condition when a breakpoint is hit. Expressions within {} are interpolated.",
|
||||
BreakpointPromptEditAction::HitCondition => "How many breakpoint hits to ignore",
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
|
||||
|
||||
@@ -3453,12 +3453,15 @@ impl EditorElement {
|
||||
|
||||
let placeholder_lines = placeholder_text
|
||||
.as_ref()
|
||||
.map_or("", AsRef::as_ref)
|
||||
.split('\n')
|
||||
.map_or(Vec::new(), |text| text.split('\n').collect::<Vec<_>>());
|
||||
|
||||
let placeholder_line_count = placeholder_lines.len();
|
||||
|
||||
placeholder_lines
|
||||
.into_iter()
|
||||
.skip(rows.start.0 as usize)
|
||||
.chain(iter::repeat(""))
|
||||
.take(rows.len());
|
||||
placeholder_lines
|
||||
.take(cmp::max(rows.len(), placeholder_line_count))
|
||||
.map(move |line| {
|
||||
let run = TextRun {
|
||||
len: line.len(),
|
||||
@@ -10743,7 +10746,7 @@ mod tests {
|
||||
let style = cx.update(|_, cx| editor.read(cx).style().unwrap().clone());
|
||||
window
|
||||
.update(cx, |editor, window, cx| {
|
||||
editor.set_placeholder_text("hello", cx);
|
||||
editor.set_placeholder_text("hello", window, cx);
|
||||
editor.insert_blocks(
|
||||
[BlockProperties {
|
||||
style: BlockStyle::Fixed,
|
||||
|
||||
@@ -327,7 +327,7 @@ impl ExtensionsPage {
|
||||
|
||||
let query_editor = cx.new(|cx| {
|
||||
let mut input = Editor::single_line(window, cx);
|
||||
input.set_placeholder_text("Search extensions...", cx);
|
||||
input.set_placeholder_text("Search extensions...", window, cx);
|
||||
if let Some(id) = focus_extension_id {
|
||||
input.set_text(format!("id:{id}"), window, cx);
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ impl CommitModal {
|
||||
&& commit_message.is_empty()
|
||||
{
|
||||
commit_editor.update(cx, |editor, cx| {
|
||||
editor.set_placeholder_text(suggested_commit_message, cx);
|
||||
editor.set_placeholder_text(&suggested_commit_message, window, cx);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -420,7 +420,7 @@ pub(crate) fn commit_message_editor(
|
||||
commit_editor.set_show_wrap_guides(false, cx);
|
||||
commit_editor.set_show_indent_guides(false, cx);
|
||||
let placeholder = placeholder.unwrap_or("Enter commit message".into());
|
||||
commit_editor.set_placeholder_text(placeholder, cx);
|
||||
commit_editor.set_placeholder_text(&placeholder, window, cx);
|
||||
commit_editor
|
||||
}
|
||||
|
||||
@@ -445,10 +445,10 @@ impl GitPanel {
|
||||
.detach();
|
||||
|
||||
let mut was_sort_by_path = GitPanelSettings::get_global(cx).sort_by_path;
|
||||
cx.observe_global::<SettingsStore>(move |this, cx| {
|
||||
cx.observe_global_in::<SettingsStore>(window, move |this, window, cx| {
|
||||
let is_sort_by_path = GitPanelSettings::get_global(cx).sort_by_path;
|
||||
if is_sort_by_path != was_sort_by_path {
|
||||
this.update_visible_entries(cx);
|
||||
this.update_visible_entries(window, cx);
|
||||
}
|
||||
was_sort_by_path = is_sort_by_path
|
||||
})
|
||||
@@ -1053,7 +1053,7 @@ impl GitPanel {
|
||||
let filename = path.path.file_name()?.to_string_lossy();
|
||||
|
||||
if !entry.status.is_created() {
|
||||
self.perform_checkout(vec![entry.clone()], cx);
|
||||
self.perform_checkout(vec![entry.clone()], window, cx);
|
||||
} else {
|
||||
let prompt = prompt(&format!("Trash {}?", filename), None, window, cx);
|
||||
cx.spawn_in(window, async move |_, cx| {
|
||||
@@ -1082,7 +1082,12 @@ impl GitPanel {
|
||||
});
|
||||
}
|
||||
|
||||
fn perform_checkout(&mut self, entries: Vec<GitStatusEntry>, cx: &mut Context<Self>) {
|
||||
fn perform_checkout(
|
||||
&mut self,
|
||||
entries: Vec<GitStatusEntry>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let workspace = self.workspace.clone();
|
||||
let Some(active_repository) = self.active_repository.clone() else {
|
||||
return;
|
||||
@@ -1095,7 +1100,7 @@ impl GitPanel {
|
||||
entries: entries.clone(),
|
||||
finished: false,
|
||||
});
|
||||
self.update_visible_entries(cx);
|
||||
self.update_visible_entries(window, cx);
|
||||
let task = cx.spawn(async move |_, cx| {
|
||||
let tasks: Vec<_> = workspace.update(cx, |workspace, cx| {
|
||||
workspace.project().update(cx, |project, cx| {
|
||||
@@ -1142,16 +1147,16 @@ impl GitPanel {
|
||||
Ok(())
|
||||
});
|
||||
|
||||
cx.spawn(async move |this, cx| {
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
let result = task.await;
|
||||
|
||||
this.update(cx, |this, cx| {
|
||||
this.update_in(cx, |this, window, cx| {
|
||||
for pending in this.pending.iter_mut() {
|
||||
if pending.op_id == op_id {
|
||||
pending.finished = true;
|
||||
if result.is_err() {
|
||||
pending.target_status = TargetStatus::Unchanged;
|
||||
this.update_visible_entries(cx);
|
||||
this.update_visible_entries(window, cx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1207,10 +1212,10 @@ impl GitPanel {
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
cx.spawn(async move |this, cx| {
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
if let Ok(RestoreCancel::RestoreTrackedFiles) = prompt.await {
|
||||
this.update(cx, |this, cx| {
|
||||
this.perform_checkout(entries, cx);
|
||||
this.update_in(cx, |this, window, cx| {
|
||||
this.perform_checkout(entries, window, cx);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
@@ -2642,7 +2647,7 @@ impl GitPanel {
|
||||
if clear_pending {
|
||||
git_panel.clear_pending();
|
||||
}
|
||||
git_panel.update_visible_entries(cx);
|
||||
git_panel.update_visible_entries(window, cx);
|
||||
git_panel.update_scrollbar_properties(window, cx);
|
||||
})
|
||||
.ok();
|
||||
@@ -2695,7 +2700,7 @@ impl GitPanel {
|
||||
self.pending.retain(|v| !v.finished)
|
||||
}
|
||||
|
||||
fn update_visible_entries(&mut self, cx: &mut Context<Self>) {
|
||||
fn update_visible_entries(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let bulk_staging = self.bulk_staging.take();
|
||||
let last_staged_path_prev_index = bulk_staging
|
||||
.as_ref()
|
||||
@@ -2870,7 +2875,7 @@ impl GitPanel {
|
||||
let placeholder_text = suggested_commit_message.unwrap_or("Enter commit message".into());
|
||||
|
||||
self.commit_editor.update(cx, |editor, cx| {
|
||||
editor.set_placeholder_text(Arc::from(placeholder_text), cx)
|
||||
editor.set_placeholder_text(&placeholder_text, window, cx)
|
||||
});
|
||||
|
||||
cx.notify();
|
||||
|
||||
@@ -637,7 +637,7 @@ impl GitCloneModal {
|
||||
pub fn show(panel: Entity<GitPanel>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let repo_input = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("Enter repository URL…", cx);
|
||||
editor.set_placeholder_text("Enter repository URL…", window, cx);
|
||||
editor
|
||||
});
|
||||
let focus_handle = repo_input.focus_handle(cx);
|
||||
|
||||
@@ -103,17 +103,20 @@ impl GoToLine {
|
||||
return;
|
||||
};
|
||||
editor.update(cx, |editor, cx| {
|
||||
if let Some(placeholder_text) = editor.placeholder_text()
|
||||
if let Some(placeholder_text) = editor.placeholder_text(cx)
|
||||
&& editor.text(cx).is_empty()
|
||||
{
|
||||
let placeholder_text = placeholder_text.to_string();
|
||||
editor.set_text(placeholder_text, window, cx);
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
editor.set_placeholder_text(format!("{line}{FILE_ROW_COLUMN_DELIMITER}{column}"), cx);
|
||||
editor.set_placeholder_text(
|
||||
&format!("{line}{FILE_ROW_COLUMN_DELIMITER}{column}"),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
editor
|
||||
});
|
||||
let line_editor_change = cx.subscribe_in(&line_editor, window, Self::on_line_editor_event);
|
||||
@@ -691,11 +694,11 @@ mod tests {
|
||||
let go_to_line_view = open_go_to_line_view(workspace, cx);
|
||||
go_to_line_view.update(cx, |go_to_line_view, cx| {
|
||||
assert_eq!(
|
||||
go_to_line_view
|
||||
.line_editor
|
||||
.read(cx)
|
||||
.placeholder_text()
|
||||
.expect("No placeholder text"),
|
||||
go_to_line_view.line_editor.update(cx, |line_editor, cx| {
|
||||
line_editor
|
||||
.placeholder_text(cx)
|
||||
.expect("No placeholder text")
|
||||
}),
|
||||
format!(
|
||||
"{}:{}",
|
||||
expected_placeholder.line, expected_placeholder.character
|
||||
|
||||
@@ -442,7 +442,7 @@ impl KeymapEditor {
|
||||
|
||||
let filter_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("Filter action names…", cx);
|
||||
editor.set_placeholder_text("Filter action names…", window, cx);
|
||||
editor
|
||||
});
|
||||
|
||||
@@ -2804,7 +2804,7 @@ impl ActionArgumentsEditor {
|
||||
editor.set_text(arguments, window, cx);
|
||||
} else {
|
||||
// TODO: default value from schema?
|
||||
editor.set_placeholder_text("Action Arguments", cx);
|
||||
editor.set_placeholder_text("Action Arguments", window, cx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -969,7 +969,7 @@ impl ConfigurationView {
|
||||
Self {
|
||||
api_key_editor: cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text(Self::PLACEHOLDER_TEXT, cx);
|
||||
editor.set_placeholder_text(Self::PLACEHOLDER_TEXT, window, cx);
|
||||
editor
|
||||
}),
|
||||
state,
|
||||
|
||||
@@ -1053,22 +1053,22 @@ impl ConfigurationView {
|
||||
Self {
|
||||
access_key_id_editor: cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text(Self::PLACEHOLDER_ACCESS_KEY_ID_TEXT, cx);
|
||||
editor.set_placeholder_text(Self::PLACEHOLDER_ACCESS_KEY_ID_TEXT, window, cx);
|
||||
editor
|
||||
}),
|
||||
secret_access_key_editor: cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text(Self::PLACEHOLDER_SECRET_ACCESS_KEY_TEXT, cx);
|
||||
editor.set_placeholder_text(Self::PLACEHOLDER_SECRET_ACCESS_KEY_TEXT, window, cx);
|
||||
editor
|
||||
}),
|
||||
session_token_editor: cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text(Self::PLACEHOLDER_SESSION_TOKEN_TEXT, cx);
|
||||
editor.set_placeholder_text(Self::PLACEHOLDER_SESSION_TOKEN_TEXT, window, cx);
|
||||
editor
|
||||
}),
|
||||
region_editor: cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text(Self::PLACEHOLDER_REGION, cx);
|
||||
editor.set_placeholder_text(Self::PLACEHOLDER_REGION, window, cx);
|
||||
editor
|
||||
}),
|
||||
state,
|
||||
|
||||
@@ -575,7 +575,7 @@ impl ConfigurationView {
|
||||
fn new(state: Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let api_key_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("sk-00000000000000000000000000000000", cx);
|
||||
editor.set_placeholder_text("sk-00000000000000000000000000000000", window, cx);
|
||||
editor
|
||||
});
|
||||
|
||||
|
||||
@@ -842,7 +842,7 @@ impl ConfigurationView {
|
||||
Self {
|
||||
api_key_editor: cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("AIzaSy...", cx);
|
||||
editor.set_placeholder_text("AIzaSy...", window, cx);
|
||||
editor
|
||||
}),
|
||||
target_agent,
|
||||
|
||||
@@ -744,7 +744,7 @@ impl ConfigurationView {
|
||||
fn new(state: gpui::Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let api_key_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("0aBCDEFGhIjKLmNOpqrSTUVwxyzabCDE1f2", cx);
|
||||
editor.set_placeholder_text("0aBCDEFGhIjKLmNOpqrSTUVwxyzabCDE1f2", window, cx);
|
||||
editor
|
||||
});
|
||||
|
||||
|
||||
@@ -787,8 +787,11 @@ impl ConfigurationView {
|
||||
fn new(state: gpui::Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let api_key_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor
|
||||
.set_placeholder_text("sk_or_000000000000000000000000000000000000000000000000", cx);
|
||||
editor.set_placeholder_text(
|
||||
"sk_or_000000000000000000000000000000000000000000000000",
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
editor
|
||||
});
|
||||
|
||||
|
||||
@@ -737,7 +737,7 @@ impl OutlinePanel {
|
||||
cx.new(|cx| {
|
||||
let filter_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("Filter...", cx);
|
||||
editor.set_placeholder_text("Filter...", window, cx);
|
||||
editor
|
||||
});
|
||||
let filter_update_subscription = cx.subscribe_in(
|
||||
|
||||
@@ -23,7 +23,7 @@ impl Head {
|
||||
) -> Self {
|
||||
let editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text(placeholder_text, cx);
|
||||
editor.set_placeholder_text(placeholder_text.as_ref(), window, cx);
|
||||
editor
|
||||
});
|
||||
cx.subscribe_in(&editor, window, edit_handler).detach();
|
||||
|
||||
@@ -615,7 +615,7 @@ impl<D: PickerDelegate> Picker<D> {
|
||||
Head::Editor(editor) => {
|
||||
let placeholder = self.delegate.placeholder_text(window, cx);
|
||||
editor.update(cx, |editor, cx| {
|
||||
editor.set_placeholder_text(placeholder, cx);
|
||||
editor.set_placeholder_text(placeholder.as_ref(), window, cx);
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ impl EditNicknameState {
|
||||
.and_then(|state| state.nickname)
|
||||
.filter(|text| !text.is_empty());
|
||||
this.editor.update(cx, |this, cx| {
|
||||
this.set_placeholder_text("Add a nickname for this server", cx);
|
||||
this.set_placeholder_text("Add a nickname for this server", window, cx);
|
||||
if let Some(starting_text) = starting_text {
|
||||
this.set_text(starting_text, window, cx);
|
||||
}
|
||||
@@ -1038,13 +1038,14 @@ impl RemoteServerProjects {
|
||||
fn render_create_remote_server(
|
||||
&self,
|
||||
state: &CreateRemoteServer,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> impl IntoElement {
|
||||
let ssh_prompt = state.ssh_prompt.clone();
|
||||
|
||||
state.address_editor.update(cx, |editor, cx| {
|
||||
if editor.text(cx).is_empty() {
|
||||
editor.set_placeholder_text("ssh user@example -p 2222", cx);
|
||||
editor.set_placeholder_text("ssh user@example -p 2222", window, cx);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1731,7 +1732,7 @@ impl Render for RemoteServerProjects {
|
||||
.into_any_element(),
|
||||
Mode::ProjectPicker(element) => element.clone().into_any_element(),
|
||||
Mode::CreateRemoteServer(state) => self
|
||||
.render_create_remote_server(state, cx)
|
||||
.render_create_remote_server(state, window, cx)
|
||||
.into_any_element(),
|
||||
Mode::EditNickname(state) => self
|
||||
.render_edit_nickname(state, window, cx)
|
||||
|
||||
@@ -612,7 +612,7 @@ impl RulesLibrary {
|
||||
Ok(rule) => {
|
||||
let title_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("Untitled", cx);
|
||||
editor.set_placeholder_text("Untitled", window, cx);
|
||||
editor.set_text(rule_metadata.title.unwrap_or_default(), window, cx);
|
||||
if prompt_id.is_built_in() {
|
||||
editor.set_read_only(true);
|
||||
|
||||
@@ -154,16 +154,14 @@ impl Render for BufferSearchBar {
|
||||
find_in_results,
|
||||
} = self.supported_options(cx);
|
||||
|
||||
if self.query_editor.update(cx, |query_editor, _cx| {
|
||||
query_editor.placeholder_text().is_none()
|
||||
}) {
|
||||
self.query_editor.update(cx, |editor, cx| {
|
||||
editor.set_placeholder_text("Search…", cx);
|
||||
});
|
||||
}
|
||||
self.query_editor.update(cx, |query_editor, cx| {
|
||||
if query_editor.placeholder_text(cx).is_none() {
|
||||
query_editor.set_placeholder_text("Search…", window, cx);
|
||||
}
|
||||
});
|
||||
|
||||
self.replacement_editor.update(cx, |editor, cx| {
|
||||
editor.set_placeholder_text("Replace with…", cx);
|
||||
editor.set_placeholder_text("Replace with…", window, cx);
|
||||
});
|
||||
|
||||
let mut color_override = None;
|
||||
|
||||
@@ -766,7 +766,7 @@ impl ProjectSearchView {
|
||||
|
||||
let query_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("Search all files…", cx);
|
||||
editor.set_placeholder_text("Search all files…", window, cx);
|
||||
editor.set_text(query_text, window, cx);
|
||||
editor
|
||||
});
|
||||
@@ -789,7 +789,7 @@ impl ProjectSearchView {
|
||||
);
|
||||
let replacement_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("Replace in project…", cx);
|
||||
editor.set_placeholder_text("Replace in project…", window, cx);
|
||||
if let Some(text) = replacement_text {
|
||||
editor.set_text(text, window, cx);
|
||||
}
|
||||
@@ -815,7 +815,7 @@ impl ProjectSearchView {
|
||||
|
||||
let included_files_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("Include: crates/**/*.toml", cx);
|
||||
editor.set_placeholder_text("Include: crates/**/*.toml", window, cx);
|
||||
|
||||
editor
|
||||
});
|
||||
@@ -828,7 +828,7 @@ impl ProjectSearchView {
|
||||
|
||||
let excluded_files_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("Exclude: vendor/*, *.lock", cx);
|
||||
editor.set_placeholder_text("Exclude: vendor/*, *.lock", window, cx);
|
||||
|
||||
editor
|
||||
});
|
||||
|
||||
@@ -55,7 +55,7 @@ impl SingleLineInput {
|
||||
|
||||
let editor = cx.new(|cx| {
|
||||
let mut input = Editor::single_line(window, cx);
|
||||
input.set_placeholder_text(placeholder_text.clone(), cx);
|
||||
input.set_placeholder_text(&placeholder_text, window, cx);
|
||||
input
|
||||
});
|
||||
|
||||
|
||||
@@ -291,7 +291,7 @@ impl RateCompletionModal {
|
||||
editor.set_show_wrap_guides(false, cx);
|
||||
editor.set_show_indent_guides(false, cx);
|
||||
editor.set_show_edit_predictions(Some(false), window, cx);
|
||||
editor.set_placeholder_text("Add your feedback…", cx);
|
||||
editor.set_placeholder_text("Add your feedback…", window, cx);
|
||||
if focus {
|
||||
cx.focus_self(window);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user