From 9acb5825e66f694406a52f3757faa6d203998dff Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 20 Dec 2023 13:00:52 -0700 Subject: [PATCH 1/2] Compute the query editor placeholder text with a focus handle So we're not beholden to the current focus. --- crates/editor2/src/editor.rs | 7 +++++-- crates/editor2/src/element.rs | 3 ++- crates/search2/src/buffer_search.rs | 5 +++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index 58f8e857a9..aa627db2a3 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -2003,8 +2003,11 @@ impl Editor { placeholder_text: impl Into>, cx: &mut ViewContext, ) { - self.placeholder_text = Some(placeholder_text.into()); - cx.notify(); + let placeholder_text = Some(placeholder_text.into()); + if self.placeholder_text != placeholder_text { + self.placeholder_text = placeholder_text; + cx.notify(); + } } pub fn set_cursor_shape(&mut self, cursor_shape: CursorShape, cx: &mut ViewContext) { diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index 8031bc5db6..9dab9d00ae 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -1722,11 +1722,12 @@ impl EditorElement { return Vec::new(); } - // When the editor is empty and unfocused, then show the placeholder. + // Show the placeholder when the editor is empty if snapshot.is_empty() { let font_size = self.style.text.font_size.to_pixels(cx.rem_size()); let placeholder_color = cx.theme().styles.colors.text_placeholder; let placeholder_text = snapshot.placeholder_text(); + let placeholder_lines = placeholder_text .as_ref() .map_or("", AsRef::as_ref) diff --git a/crates/search2/src/buffer_search.rs b/crates/search2/src/buffer_search.rs index ebaf111e60..f84db72c13 100644 --- a/crates/search2/src/buffer_search.rs +++ b/crates/search2/src/buffer_search.rs @@ -113,8 +113,9 @@ impl Render for BufferSearchBar { } let supported_options = self.supported_options(); + let query_focus_handle = self.query_editor.focus_handle(cx); let previous_query_keystrokes = cx - .bindings_for_action(&PreviousHistoryQuery {}) + .bindings_for_action_in(&PreviousHistoryQuery {}, &query_focus_handle) .into_iter() .next() .map(|binding| { @@ -125,7 +126,7 @@ impl Render for BufferSearchBar { .collect::>() }); let next_query_keystrokes = cx - .bindings_for_action(&NextHistoryQuery {}) + .bindings_for_action_in(&NextHistoryQuery {}, &query_focus_handle) .into_iter() .next() .map(|binding| { From d499cccebb02257d43eef8345d283370fb3d549d Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 20 Dec 2023 14:47:56 -0700 Subject: [PATCH 2/2] Only compute placeholder text once --- crates/editor2/src/editor.rs | 4 ++ crates/search2/src/buffer_search.rs | 97 +++++++++++++---------------- 2 files changed, 48 insertions(+), 53 deletions(-) diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index aa627db2a3..cb607a7e6c 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -1998,6 +1998,10 @@ impl Editor { self.collaboration_hub = Some(hub); } + pub fn placeholder_text(&self) -> Option<&str> { + self.placeholder_text.as_deref() + } + pub fn set_placeholder_text( &mut self, placeholder_text: impl Into>, diff --git a/crates/search2/src/buffer_search.rs b/crates/search2/src/buffer_search.rs index f84db72c13..5b4113aee2 100644 --- a/crates/search2/src/buffer_search.rs +++ b/crates/search2/src/buffer_search.rs @@ -102,66 +102,57 @@ impl EventEmitter for BufferSearchBar {} impl EventEmitter for BufferSearchBar {} impl Render for BufferSearchBar { type Element = Div; + fn render(&mut self, cx: &mut ViewContext) -> Self::Element { - // let query_container_style = if self.query_contains_error { - // theme.search.invalid_editor - // } else { - // theme.search.editor.input.container - // }; if self.dismissed { return div(); } + let supported_options = self.supported_options(); - let query_focus_handle = self.query_editor.focus_handle(cx); - let previous_query_keystrokes = cx - .bindings_for_action_in(&PreviousHistoryQuery {}, &query_focus_handle) - .into_iter() - .next() - .map(|binding| { - binding - .keystrokes() - .iter() - .map(|k| k.to_string()) - .collect::>() - }); - let next_query_keystrokes = cx - .bindings_for_action_in(&NextHistoryQuery {}, &query_focus_handle) - .into_iter() - .next() - .map(|binding| { - binding - .keystrokes() - .iter() - .map(|k| k.to_string()) - .collect::>() - }); - let new_placeholder_text = match (previous_query_keystrokes, next_query_keystrokes) { - (Some(previous_query_keystrokes), Some(next_query_keystrokes)) => { - format!( - "Search ({}/{} for previous/next query)", - previous_query_keystrokes.join(" "), - next_query_keystrokes.join(" ") - ) + if self.query_editor.read(cx).placeholder_text().is_none() { + let query_focus_handle = self.query_editor.focus_handle(cx); + let up_keystrokes = cx + .bindings_for_action_in(&PreviousHistoryQuery {}, &query_focus_handle) + .into_iter() + .next() + .map(|binding| { + binding + .keystrokes() + .iter() + .map(|k| k.to_string()) + .collect::>() + }); + let down_keystrokes = cx + .bindings_for_action_in(&NextHistoryQuery {}, &query_focus_handle) + .into_iter() + .next() + .map(|binding| { + binding + .keystrokes() + .iter() + .map(|k| k.to_string()) + .collect::>() + }); + + let placeholder_text = + up_keystrokes + .zip(down_keystrokes) + .map(|(up_keystrokes, down_keystrokes)| { + Arc::from(format!( + "Search ({}/{} for previous/next query)", + up_keystrokes.join(" "), + down_keystrokes.join(" ") + )) + }); + + if let Some(placeholder_text) = placeholder_text { + self.query_editor.update(cx, |editor, cx| { + editor.set_placeholder_text(placeholder_text, cx); + }); } - (None, Some(next_query_keystrokes)) => { - format!( - "Search ({} for next query)", - next_query_keystrokes.join(" ") - ) - } - (Some(previous_query_keystrokes), None) => { - format!( - "Search ({} for previous query)", - previous_query_keystrokes.join(" ") - ) - } - (None, None) => String::new(), - }; - let new_placeholder_text = Arc::from(new_placeholder_text); - self.query_editor.update(cx, |editor, cx| { - editor.set_placeholder_text(new_placeholder_text, cx); - }); + } + self.replacement_editor.update(cx, |editor, cx| { editor.set_placeholder_text("Replace with...", cx); });