Mention possible run options in the task modal placeholder (#8449)

Kirill Bulatov and Piotr Osiewicz created

Release Notes:

- Improved run task modal's placeholder

---------

Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>

Change summary

crates/gpui/src/window.rs                     | 16 ++++++++++++++++
crates/recent_projects/src/recent_projects.rs | 18 ++----------------
crates/tasks_ui/src/modal.rs                  | 10 ++++++----
3 files changed, 24 insertions(+), 20 deletions(-)

Detailed changes

crates/gpui/src/window.rs 🔗

@@ -1124,6 +1124,22 @@ impl<'a> WindowContext<'a> {
         false
     }
 
+    /// Represent this action as a key binding string, to display in the UI.
+    pub fn keystroke_text_for(&self, action: &dyn Action) -> String {
+        self.bindings_for_action(action)
+            .into_iter()
+            .next()
+            .map(|binding| {
+                binding
+                    .keystrokes()
+                    .iter()
+                    .map(ToString::to_string)
+                    .collect::<Vec<_>>()
+                    .join(" ")
+            })
+            .unwrap_or_else(|| action.name().to_string())
+    }
+
     /// Dispatch a mouse or keyboard event on the window.
     #[profiling::function]
     pub fn dispatch_event(&mut self, event: PlatformInput) -> bool {

crates/recent_projects/src/recent_projects.rs 🔗

@@ -147,24 +147,10 @@ impl PickerDelegate for RecentProjectsDelegate {
     type ListItem = ListItem;
 
     fn placeholder_text(&self, cx: &mut WindowContext) -> Arc<str> {
-        let action_binding_text = |action: &dyn gpui::Action| {
-            cx.bindings_for_action(action)
-                .into_iter()
-                .next()
-                .map(|binding| {
-                    binding
-                        .keystrokes()
-                        .into_iter()
-                        .map(ToString::to_string)
-                        .collect::<Vec<_>>()
-                        .join(" ")
-                })
-                .unwrap_or_else(|| format!("{action:?}"))
-        };
         Arc::from(format!(
             "{} reuses the window, {} opens a new one",
-            action_binding_text(&menu::Confirm),
-            action_binding_text(&menu::SecondaryConfirm),
+            cx.keystroke_text_for(&menu::Confirm),
+            cx.keystroke_text_for(&menu::SecondaryConfirm),
         ))
     }
 

crates/tasks_ui/src/modal.rs 🔗

@@ -23,7 +23,6 @@ pub(crate) struct TasksModalDelegate {
     candidates: Vec<Arc<dyn Task>>,
     matches: Vec<StringMatch>,
     selected_index: usize,
-    placeholder_text: Arc<str>,
     workspace: WeakView<Workspace>,
     last_prompt: String,
 }
@@ -36,7 +35,6 @@ impl TasksModalDelegate {
             candidates: Vec::new(),
             matches: Vec::new(),
             selected_index: 0,
-            placeholder_text: Arc::from("Select task..."),
             last_prompt: String::default(),
         }
     }
@@ -115,8 +113,12 @@ impl PickerDelegate for TasksModalDelegate {
         self.selected_index = ix;
     }
 
-    fn placeholder_text(&self, _cx: &mut WindowContext) -> Arc<str> {
-        self.placeholder_text.clone()
+    fn placeholder_text(&self, cx: &mut WindowContext) -> Arc<str> {
+        Arc::from(format!(
+            "{} runs the selected task, {} spawns a bash-like task from the prompt",
+            cx.keystroke_text_for(&menu::Confirm),
+            cx.keystroke_text_for(&menu::SecondaryConfirm),
+        ))
     }
 
     fn update_matches(