]> git.eshelyaron.com Git - emacs.git/commitdiff
Add 'minibuffer-hint-mode'
authorEshel Yaron <me@eshelyaron.com>
Thu, 28 Mar 2024 21:16:40 +0000 (22:16 +0100)
committerEshel Yaron <me@eshelyaron.com>
Thu, 28 Mar 2024 21:16:40 +0000 (22:16 +0100)
lisp/minibuffer.el

index f337cda318302b262180a97c706603c3e5ffb843..899ab54796c2d066e10611afb3cd99b4e5147120 100644 (file)
@@ -6168,5 +6168,75 @@ This applies to `completions-auto-update-mode', which see."
 (defvar minibuffer-help-form nil "Unused obsolete variable.")
 (make-obsolete-variable 'minibuffer-help-form 'help-form "30.1")
 
+(defvar-local minibuffer-hint-timer nil)
+
+(defcustom minibuffer-hint-idle-time 0.4
+  "Number for seconds to wait before showing a hint in the minibuffer."
+  :type 'float)
+
+(defun minibuffer-hint ()
+  (if-let ((all (let ((completion--input completion--input)
+                      (completion-lazy-hilit t)
+                      completion-all-sorted-completions)
+                  (completion-all-sorted-completions))))
+      (let ((minibuffer-message-timeout))
+        (minibuffer-message
+         (concat (propertize (car all) 'face 'bold)
+                 (when (consp (cdr all))
+                   (propertize
+                    (concat
+                     "/"
+                     (number-to-string (let ((n 1))
+                                         (while (consp (cdr all))
+                                           (setq n (1+ n)
+                                                 all (cdr all)))
+                                         n)))
+                    'face 'shadow)))))
+    (completion--fail)))
+
+(defun minibuffer-hint-cancel-timer ()
+  (when (timerp minibuffer-hint-timer)
+    (cancel-timer minibuffer-hint-timer)
+    (setq minibuffer-hint-timer nil)))
+
+(defun minibuffer-hint-fn (minib)
+  "Return a function that shows a hint in minibuffer MINIB."
+  (lambda ()
+    (when (equal (current-buffer) minib)
+      (minibuffer-hint))
+    (when (buffer-live-p minib)
+      (with-current-buffer minib (minibuffer-hint-cancel-timer)))))
+
+(defun minibuffer-hint-start-timer ()
+  (unless (or (timerp minibuffer-hint-timer)
+              ;; Let `completions-auto-update-mode' do its thing.
+              (and completions-auto-update-mode
+                   (get-buffer-window "*Completions*" 0)))
+    (setq minibuffer-hint-timer
+          (run-with-idle-timer minibuffer-hint-idle-time
+                               nil (minibuffer-hint-fn (current-buffer))))))
+
+(define-minor-mode minibuffer-hint-mode
+  "Display a hint in the minibuffer after a short delay.
+
+Add this function to `minibuffer-setup-hook' to have Emacs display a
+hint whenever you pause while typing in the minibuffer.  The hint shows
+the top completion candidate that matches your current input, the total
+number of matching candidates in case there is more than one.  To exit
+the minibuffer with the candidate that the hint shows, use \
+\\<minibuffer-local-completion-map>\\[minibuffer-force-complete-and-exit].
+If there are no matching completion candidates, the hint tells you so."
+  :interactive nil
+  (if minibuffer-hint-mode
+      (if (not minibuffer-completion-table)
+          (setq minibuffer-hint-mode nil)
+        (add-hook 'post-self-insert-hook #'minibuffer-hint-start-timer nil t)
+        (add-hook 'minibuffer-exit-hook #'minibuffer-hint-cancel-timer nil t)
+        (add-hook 'pre-command-hook #'minibuffer-hint-cancel-timer nil t))
+    (remove-hook 'post-self-insert-hook #'minibuffer-hint-start-timer t)
+    (remove-hook 'minibuffer-exit-hook #'minibuffer-hint-cancel-timer t)
+    (remove-hook 'pre-command-hook #'minibuffer-hint-cancel-timer t)
+    (minibuffer-hint-cancel-timer)))
+
 (provide 'minibuffer)
 ;;; minibuffer.el ends here