From 7b1131adf62f649daeb197b07327f5729d20a2b7 Mon Sep 17 00:00:00 2001
From: Michael Davis <mcarsondavis@gmail.com>
Date: Wed, 6 Mar 2024 11:04:37 -0500
Subject: [PATCH] global_search: Suggest latest '/' register value

---
 helix-term/src/commands.rs  | 14 +++++---------
 helix-term/src/ui/picker.rs | 22 ++++++++++++++++------
 helix-term/src/ui/prompt.rs | 21 +++++++++++++++------
 3 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index b7ffeeb7..1df25ba5 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -2407,7 +2407,10 @@ fn global_search(cx: &mut Context) {
         .boxed()
     };
 
-    let mut picker = Picker::new(
+    let reg = cx.register.unwrap_or('/');
+    cx.editor.registers.last_search_register = reg;
+
+    let picker = Picker::new(
         columns,
         1, // contents
         vec![],
@@ -2443,16 +2446,9 @@ fn global_search(cx: &mut Context) {
     .with_preview(|_editor, FileResult { path, line_num, .. }| {
         Some((path.clone().into(), Some((*line_num, *line_num))))
     })
+    .with_history_register(Some(reg))
     .with_dynamic_query(get_files, Some(275));
 
-    if let Some((reg, line)) = cx
-        .register
-        .and_then(|reg| Some((reg, cx.editor.registers.first(reg, cx.editor)?)))
-    {
-        picker = picker.with_line(line.into_owned(), cx.editor);
-        cx.editor.registers.last_search_register = reg;
-    }
-
     cx.push_layer(Box::new(overlaid(picker)));
 }
 
diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs
index bfec9ddb..76a1805a 100644
--- a/helix-term/src/ui/picker.rs
+++ b/helix-term/src/ui/picker.rs
@@ -391,9 +391,8 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
         self
     }
 
-    pub fn with_line(mut self, line: String, editor: &Editor) -> Self {
-        self.prompt.set_line(line, editor);
-        self.handle_prompt_change();
+    pub fn with_history_register(mut self, history_register: Option<char>) -> Self {
+        self.prompt.with_history_register(history_register);
         self
     }
 
@@ -977,10 +976,21 @@ impl<I: 'static + Send + Sync, D: 'static + Send + Sync> Component for Picker<I,
                 }
             }
             key!(Enter) => {
-                if let Some(option) = self.selection() {
-                    (self.callback_fn)(ctx, option, Action::Replace);
+                // If the prompt has a history completion and is empty, use enter to accept
+                // that completion
+                if let Some(completion) = self
+                    .prompt
+                    .first_history_completion(ctx.editor)
+                    .filter(|_| self.prompt.line().is_empty())
+                {
+                    self.prompt.set_line(completion.to_string(), ctx.editor);
+                    self.handle_prompt_change();
+                } else {
+                    if let Some(option) = self.selection() {
+                        (self.callback_fn)(ctx, option, Action::Replace);
+                    }
+                    return close_fn(self);
                 }
-                return close_fn(self);
             }
             ctrl!('s') => {
                 if let Some(option) = self.selection() {
diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs
index 19183470..8e889618 100644
--- a/helix-term/src/ui/prompt.rs
+++ b/helix-term/src/ui/prompt.rs
@@ -117,6 +117,19 @@ impl Prompt {
         &self.line
     }
 
+    pub fn with_history_register(&mut self, history_register: Option<char>) -> &mut Self {
+        self.history_register = history_register;
+        self
+    }
+
+    pub(crate) fn first_history_completion<'a>(
+        &'a self,
+        editor: &'a Editor,
+    ) -> Option<Cow<'a, str>> {
+        self.history_register
+            .and_then(|reg| editor.registers.first(reg, editor))
+    }
+
     pub fn recalculate_completion(&mut self, editor: &Editor) {
         self.exit_selection();
         self.completion = (self.completion_fn)(editor, &self.line);
@@ -480,10 +493,7 @@ impl Prompt {
         let line_area = area.clip_left(self.prompt.len() as u16).clip_top(line);
         if self.line.is_empty() {
             // Show the most recently entered value as a suggestion.
-            if let Some(suggestion) = self
-                .history_register
-                .and_then(|reg| cx.editor.registers.first(reg, cx.editor))
-            {
+            if let Some(suggestion) = self.first_history_completion(cx.editor) {
                 surface.set_string(line_area.x, line_area.y, suggestion, suggestion_color);
             }
         } else if let Some((language, loader)) = self.language.as_ref() {
@@ -578,8 +588,7 @@ impl Component for Prompt {
                     self.recalculate_completion(cx.editor);
                 } else {
                     let last_item = self
-                        .history_register
-                        .and_then(|reg| cx.editor.registers.first(reg, cx.editor))
+                        .first_history_completion(cx.editor)
                         .map(|entry| entry.to_string())
                         .unwrap_or_else(|| String::from(""));