diff --git a/crates/agent_ui/src/acp/message_editor.rs b/crates/agent_ui/src/acp/message_editor.rs index de5421c0907674cc9c62c6e326239aa9ffc726f2..02ee46e840299b9307253603f3c165bbd525d377 100644 --- a/crates/agent_ui/src/acp/message_editor.rs +++ b/crates/agent_ui/src/acp/message_editor.rs @@ -91,7 +91,7 @@ impl MessageEditor { prompt_capabilities: Rc>, available_commands: Rc>>, agent_name: SharedString, - placeholder: impl Into>, + placeholder: &str, mode: EditorMode, window: &mut Window, cx: &mut Context, @@ -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); diff --git a/crates/agent_ui/src/acp/thread_history.rs b/crates/agent_ui/src/acp/thread_history.rs index a49dae25b3a736a6e37509cd35c32eec5efffda1..015a2548d54ac5545f06984ec31bce2d3d58a56e 100644 --- a/crates/agent_ui/src/acp/thread_history.rs +++ b/crates/agent_ui/src/acp/thread_history.rs @@ -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 }); diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index dc427dfd37ccd84a0d1ae3eacc9eb78ba7c86441..370e070d7c6843fb373662790b7267e1691b6760 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -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), diff --git a/crates/agent_ui/src/active_thread.rs b/crates/agent_ui/src/active_thread.rs index dad2e282a515071405de789ef4cb0268cc672d8a..6dfadb691f3f9f7200991079da8e18bf11ce8853 100644 --- a/crates/agent_ui/src/active_thread.rs +++ b/crates/agent_ui/src/active_thread.rs @@ -1742,6 +1742,7 @@ impl ActiveThread { ); editor.set_placeholder_text( "What went wrong? Share your feedback so we can improve.", + window, cx, ); editor diff --git a/crates/agent_ui/src/agent_configuration/manage_profiles_modal.rs b/crates/agent_ui/src/agent_configuration/manage_profiles_modal.rs index 7fcf76d1cbec64ab99f3f97998600d6d9889207a..3bd5ed40d2f265287f6fe22dfbc2a19487149c37 100644 --- a/crates/agent_ui/src/agent_configuration/manage_profiles_modal.rs +++ b/crates/agent_ui/src/agent_configuration/manage_profiles_modal.rs @@ -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 { diff --git a/crates/agent_ui/src/inline_prompt_editor.rs b/crates/agent_ui/src/inline_prompt_editor.rs index b6517a54339df71659805ff38718e94be7192fa8..0e817ca8073d71022f47b0aa08d34101f622f470 100644 --- a/crates/agent_ui/src/inline_prompt_editor.rs +++ b/crates/agent_ui/src/inline_prompt_editor.rs @@ -229,7 +229,7 @@ impl PromptEditor { 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 { // 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 { 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, diff --git a/crates/agent_ui/src/message_editor.rs b/crates/agent_ui/src/message_editor.rs index 6f0ad2767a46fb23b40e0116fd9cf85f06c28aca..f08ff6f24b551d0eef5ba796c857a8f88eadac3d 100644 --- a/crates/agent_ui/src/message_editor.rs +++ b/crates/agent_ui/src/message_editor.rs @@ -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(); diff --git a/crates/agent_ui/src/thread_history.rs b/crates/agent_ui/src/thread_history.rs index 4ec2078e5db376fbe45c528d9cce2c13e3175ba5..73d3b705b74c18e367298cf5ed74852459e68b2e 100644 --- a/crates/agent_ui/src/thread_history.rs +++ b/crates/agent_ui/src/thread_history.rs @@ -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 }); diff --git a/crates/collab_ui/src/collab_panel.rs b/crates/collab_ui/src/collab_panel.rs index b9ef535f1dbc781405cfe74584ca03f461f66c34..82e0f84105b57baa47999db9e086542a4f99adf7 100644 --- a/crates/collab_ui/src/collab_panel.rs +++ b/crates/collab_ui/src/collab_panel.rs @@ -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 }); diff --git a/crates/debugger_ui/src/new_process_modal.rs b/crates/debugger_ui/src/new_process_modal.rs index ee6289187ba990d5bbaa040631a1c32619857e53..efa5e4700af31b91c29803f56527a7b166c16b9e 100644 --- a/crates/debugger_ui/src/new_process_modal.rs +++ b/crates/debugger_ui/src/new_process_modal.rs @@ -803,12 +803,12 @@ impl ConfigureMode { pub(super) fn new(window: &mut Window, cx: &mut App) -> Entity { 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 { diff --git a/crates/debugger_ui/src/session/running/breakpoint_list.rs b/crates/debugger_ui/src/session/running/breakpoint_list.rs index 233dba4c52e28c6e1f1b9205cb7481d487040fb1..9fc952a2ea46ac5e5c58c9ddff1f4860447b77b3 100644 --- a/crates/debugger_ui/src/session/running/breakpoint_list.rs +++ b/crates/debugger_ui/src/session/running/breakpoint_list.rs @@ -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); }); diff --git a/crates/debugger_ui/src/session/running/console.rs b/crates/debugger_ui/src/session/running/console.rs index 43d86d95c4a5ad6cc0b7729a3f3579b27e1dfee7..92c5ace8f0128e47db08c6b772376679213ffbe1 100644 --- a/crates/debugger_ui/src/session/running/console.rs +++ b/crates/debugger_ui/src/session/running/console.rs @@ -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); diff --git a/crates/debugger_ui/src/session/running/memory_view.rs b/crates/debugger_ui/src/session/running/memory_view.rs index e7b7963d3f0775c18489ceb306badce1725a6268..a134b916a2200013bcdc9e03e00028a09227e05a 100644 --- a/crates/debugger_ui/src/session/running/memory_view.rs +++ b/crates/debugger_ui/src/session/running/memory_view.rs @@ -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; } diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 34134ad001afe3f0c7536f05582d32a6b234bf65..217b3d4bf3c342051f56e1e817df10979aac1fcd 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -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, + placeholder_display_map: Option>, 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, show_wrap_guides: Option, show_indent_guides: Option, - placeholder_text: Option>, highlight_order: usize, highlighted_rows: HashMap>, background_highlights: HashMap, @@ -1209,7 +1209,7 @@ pub struct EditorSnapshot { show_breakpoints: Option, git_blame_gutter_max_author_length: Option, pub display_snapshot: DisplaySnapshot, - pub placeholder_text: Option>, + pub placeholder_display_snapshot: Option, 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 { + 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>, + placeholder_text: &str, + window: &mut Window, cx: &mut Context, ) { - 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) { @@ -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, 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> { - self.placeholder_text.as_ref() + pub fn placeholder_text(&self) -> Option { + self.placeholder_display_snapshot + .as_ref() + .map(|display_map| display_map.text()) } pub fn scroll_position(&self) -> gpui::Point { @@ -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, ); diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index d25cf2e611b8f87f23f47802382ff822580cc882..ff7816afe1504fea31c8fbb342b72b72bcafdd5e 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -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::>()); + + 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, diff --git a/crates/extensions_ui/src/extensions_ui.rs b/crates/extensions_ui/src/extensions_ui.rs index 0b925dceb1544d97a77082881626bc1e97f3d1b0..82ee54174567987d00478815f6a4eefd94333202 100644 --- a/crates/extensions_ui/src/extensions_ui.rs +++ b/crates/extensions_ui/src/extensions_ui.rs @@ -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); } diff --git a/crates/git_ui/src/commit_modal.rs b/crates/git_ui/src/commit_modal.rs index cae4d28a83b01a8195c891d2a7569803cfecd697..a2f84726543af50312dc24d0fcd9e0486b51d9c5 100644 --- a/crates/git_ui/src/commit_modal.rs +++ b/crates/git_ui/src/commit_modal.rs @@ -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); }); } diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index f64f001241e1f84f1b3785b78f8495f17c23deb1..31c3f5e77ace726ec42998977d623d3d77b20c5d 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -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::(move |this, cx| { + cx.observe_global_in::(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, cx: &mut Context) { + fn perform_checkout( + &mut self, + entries: Vec, + window: &mut Window, + cx: &mut Context, + ) { 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) { + fn update_visible_entries(&mut self, window: &mut Window, cx: &mut Context) { 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(); diff --git a/crates/git_ui/src/git_ui.rs b/crates/git_ui/src/git_ui.rs index ffb1a74728eef2a16200ba9e7b05b3a7ab3bd134..fcb2be0bd4d21609161369a29d30997df2d80872 100644 --- a/crates/git_ui/src/git_ui.rs +++ b/crates/git_ui/src/git_ui.rs @@ -637,7 +637,7 @@ impl GitCloneModal { pub fn show(panel: Entity, window: &mut Window, cx: &mut Context) -> 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); diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index 2afc72e989b1a112c481d1c1438d216ececec626..9b573d7071b64c7470e81079e7be5a5f048fc5eb 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -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 diff --git a/crates/keymap_editor/src/keymap_editor.rs b/crates/keymap_editor/src/keymap_editor.rs index 7e0a96d47a52b7051793017a2d5f68d64bfdcd65..4040ac2e2f87c16cc9a4bd667d48d581de13168f 100644 --- a/crates/keymap_editor/src/keymap_editor.rs +++ b/crates/keymap_editor/src/keymap_editor.rs @@ -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); } } diff --git a/crates/language_models/src/provider/anthropic.rs b/crates/language_models/src/provider/anthropic.rs index d246976cda4eb46a46c857f1e94757697ddf5f65..ca7763e2c5cda3c07c5cb51389cb3173a55865e2 100644 --- a/crates/language_models/src/provider/anthropic.rs +++ b/crates/language_models/src/provider/anthropic.rs @@ -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, diff --git a/crates/language_models/src/provider/bedrock.rs b/crates/language_models/src/provider/bedrock.rs index 178c767950e640801ada7291cd8eb317fcba232c..49a976d5b18d2c7a2ca3162c632f53706b385cb0 100644 --- a/crates/language_models/src/provider/bedrock.rs +++ b/crates/language_models/src/provider/bedrock.rs @@ -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, diff --git a/crates/language_models/src/provider/deepseek.rs b/crates/language_models/src/provider/deepseek.rs index 8c7f8bcc351851ebb9cc90aaa9c9fa2eed59119e..82bf067cd475fe031630767da9e4302afa4d78ec 100644 --- a/crates/language_models/src/provider/deepseek.rs +++ b/crates/language_models/src/provider/deepseek.rs @@ -575,7 +575,7 @@ impl ConfigurationView { fn new(state: Entity, window: &mut Window, cx: &mut Context) -> 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 }); diff --git a/crates/language_models/src/provider/google.rs b/crates/language_models/src/provider/google.rs index f252ab7aa3ed723b24d7883371c48f7ceb7f4dff..939cf0ca60d92d713b90a5d62e8ec7f6dac7ec46 100644 --- a/crates/language_models/src/provider/google.rs +++ b/crates/language_models/src/provider/google.rs @@ -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, diff --git a/crates/language_models/src/provider/mistral.rs b/crates/language_models/src/provider/mistral.rs index 3f8c2e2a678d019aad1ff90688b145ffe6c740dd..c9824bf89ea7a919f4517f492a5091a2cda7b43b 100644 --- a/crates/language_models/src/provider/mistral.rs +++ b/crates/language_models/src/provider/mistral.rs @@ -744,7 +744,7 @@ impl ConfigurationView { fn new(state: gpui::Entity, window: &mut Window, cx: &mut Context) -> 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 }); diff --git a/crates/language_models/src/provider/open_router.rs b/crates/language_models/src/provider/open_router.rs index f73a97e6426f80e1ad8d1b8214e16bf361d0f0ce..698e9d23cc74c56b00daa48359b663ff034c1abe 100644 --- a/crates/language_models/src/provider/open_router.rs +++ b/crates/language_models/src/provider/open_router.rs @@ -787,8 +787,11 @@ impl ConfigurationView { fn new(state: gpui::Entity, window: &mut Window, cx: &mut Context) -> 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 }); diff --git a/crates/outline_panel/src/outline_panel.rs b/crates/outline_panel/src/outline_panel.rs index a8d5046f90f3136ef4c913ea0e87fd55f77dcd6a..2491c65a7f6d8aed6224b76401328770c8e7bc50 100644 --- a/crates/outline_panel/src/outline_panel.rs +++ b/crates/outline_panel/src/outline_panel.rs @@ -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( diff --git a/crates/picker/src/head.rs b/crates/picker/src/head.rs index aba7b8a1d05afdc1f485574178914f50f55bc12c..700896e3412bf96ceff25891c106d5a4dbc51460 100644 --- a/crates/picker/src/head.rs +++ b/crates/picker/src/head.rs @@ -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(); diff --git a/crates/picker/src/picker.rs b/crates/picker/src/picker.rs index 34af5fed02e66fe242c398ebcf910bc89d81a256..4bd8ac99cbd9b5fe793e8b0cfe1926732920d0a1 100644 --- a/crates/picker/src/picker.rs +++ b/crates/picker/src/picker.rs @@ -615,7 +615,7 @@ impl Picker { 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(); }); } diff --git a/crates/recent_projects/src/remote_servers.rs b/crates/recent_projects/src/remote_servers.rs index 3cf084bef76a56cf85973f67bb5713aee59fb1bc..99a1695a3f859dd48ebcb2ddf88093f1d1e474e1 100644 --- a/crates/recent_projects/src/remote_servers.rs +++ b/crates/recent_projects/src/remote_servers.rs @@ -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, ) -> 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) diff --git a/crates/rules_library/src/rules_library.rs b/crates/rules_library/src/rules_library.rs index 3d7962fa17d7fa4a4c3b12e88c90adcecd06667d..c11dde072fe2a89ca3373f4490384709cff901e7 100644 --- a/crates/rules_library/src/rules_library.rs +++ b/crates/rules_library/src/rules_library.rs @@ -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); diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 92992dced6066d7242ad15f666de5a3b98f76ed0..c8e16e256cbd9d1761bb9440cc988ff2bea57819 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -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; diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 80ed0958b747320481636f1d583aed1298d012c0..834967902f48ddd75ac9c2b64d9cff17f79c26d7 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -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 }); diff --git a/crates/ui_input/src/ui_input.rs b/crates/ui_input/src/ui_input.rs index 39a701c8e8d5c839204a9df6d33f307cc4214289..86a569b53200cc5ef3ed144841e76cecd94ef94e 100644 --- a/crates/ui_input/src/ui_input.rs +++ b/crates/ui_input/src/ui_input.rs @@ -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 }); diff --git a/crates/zeta/src/rate_completion_modal.rs b/crates/zeta/src/rate_completion_modal.rs index 0cd814388ae92adb381ecd6dde7099a24991bcf9..f572a0a1aa797a8afda72d9c86ad82c850cc6d9b 100644 --- a/crates/zeta/src/rate_completion_modal.rs +++ b/crates/zeta/src/rate_completion_modal.rs @@ -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); }