]> git.eshelyaron.com Git - emacs.git/commitdiff
New command 'minibuffer-apply'
authorEshel Yaron <me@eshelyaron.com>
Wed, 21 Feb 2024 16:23:57 +0000 (17:23 +0100)
committerEshel Yaron <me@eshelyaron.com>
Wed, 21 Feb 2024 16:23:57 +0000 (17:23 +0100)
* lisp/minibuffer.el (completions-used-input): New face.
(minibuffer-completion-action): New variable and function.
(minibuffer-completion-command): New variable.
(completing-read-default): Set it to 'this-command'.
(minibuffer-current-input): New function.
(minibuffer-apply): New command.
(minibuffer-local-completion-map): Bind it to 'C-j'.
(minibuffer-local-must-match-map): Unbind 'C-j'.

* lisp/cus-edit.el (customize-toggle-option): Set
'minibuffer-action' property to non-nil.

* etc/NEWS: Announce it.

etc/NEWS
lisp/cus-edit.el
lisp/minibuffer.el

index 23aa469a8dfa90819af6a26db95f62ee38050ef5..c1bbd466556ff27b0ccdf849010f4cdf158581f4 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -802,6 +802,12 @@ Bound to '<up>' and '<down>' arrow keys, respectively, they navigate
 the "*Completions*" buffer vertically by lines, wrapping at the
 top/bottom when 'completion-auto-wrap' is non-nil.
 
+*** New command 'minibuffer-apply'.
+This command, bound to 'C-j' in the minibuffer during completion, acts
+on the current input without exiting the minibuffer.  The action that
+this command performs mirrors what the command that initiated the
+minibuffer does.
+
 +++
 *** New value 'historical' for user option 'completions-sort'.
 When 'completions-sort' is set to 'historical', completion candidates
index ff634b666ce696b447c430562219dc7a23ce0fd3..200ca387014d4ef7a45b0d829e01e7605856d772 100644 (file)
@@ -1285,6 +1285,8 @@ prefix argument, completion candidates include all user options instead."
                  (propertize "ON" 'face 'success)
                (propertize "OFF" 'face 'error)))))
 
+(put 'customize-toggle-option 'minibuffer-action t)
+
 ;;;###autoload
 (defalias 'toggle-option #'customize-toggle-option)
 
index 4fc95f4e7b4b1ecf4a54d92475fab094de0c5c50..1de425b364023e68b0a5d08e5f7466e181ed519b 100644 (file)
@@ -2600,6 +2600,9 @@ when you select this sort order."
 (defface completions-previous-input '((t :underline "violet"))
   "Face for highlighting previous inputs in the *Completions* buffer.")
 
+(defface completions-used-input '((t :inherit link-visited))
+  "Face for highlighting used inputs in the *Completions* buffer.")
+
 (defcustom completions-highlight-previous-inputs t
   "Whether to highlight previously used inputs in the *Completions* buffer."
   :version "30.1"
@@ -3431,13 +3434,13 @@ The completion method is determined by `completion-at-point-functions'."
   "M-RET"     #'minibuffer-choose-completion
   "C-x C-v"   #'minibuffer-sort-completions
   "C-x n"     'minibuffer-narrow-completions-map
-  "C-x /"     #'minibuffer-set-completion-styles)
+  "C-x /"     #'minibuffer-set-completion-styles
+  "C-j"       #'minibuffer-apply)
 
 (defvar-keymap minibuffer-local-must-match-map
   :doc "Local keymap for minibuffer input with completion, for exact match."
   :parent minibuffer-local-completion-map
-  "RET" #'minibuffer-complete-and-exit
-  "C-j" #'minibuffer-complete-and-exit)
+  "RET" #'minibuffer-complete-and-exit)
 
 (defvar-keymap minibuffer-local-filename-completion-map
   :doc "This variable is obsolete and no longer used.")
@@ -4176,6 +4179,54 @@ possible completions."
 (define-obsolete-function-alias 'internal-complete-buffer
   'completion-buffer-name-table "30.1")
 
+(defvar-local minibuffer-completion-action nil
+  "Function that `minibuffer-apply' applies to the current input, or nil.")
+
+(defvar-local minibuffer-completion-command nil
+  "The command currently reading input from the minibuffer.")
+
+(defun minibuffer-current-input ()
+  (let* ((beg-end (minibuffer--completion-boundaries))
+         (beg (car beg-end)) (end (cdr beg-end))
+         (str (buffer-substring beg end))
+         (prf (buffer-substring (minibuffer-prompt-end) beg)))
+    (when-let ((adjust-fn (alist-get 'adjust-base-function
+                                     (completion-metadata
+                                      (concat prf str)
+                                      minibuffer-completion-table
+                                      minibuffer-completion-predicate))))
+      (setq prf (funcall adjust-fn prf)))
+    (cons str prf)))
+
+(defun minibuffer-completion-action ()
+  "Return the completion action function for the current minibuffer."
+  (or minibuffer-completion-action
+      (and (symbolp minibuffer-completion-command)
+           (get minibuffer-completion-command
+                'minibuffer-action)
+           minibuffer-completion-command)
+      (error "No applicable action")))
+
+(defun minibuffer-apply (action input &optional prefix)
+  "Apply ACTION to current minibuffer INPUT prefixed by PREFIX."
+  (interactive (let* ((input-prefix (minibuffer-current-input))
+                      (input (car input-prefix))
+                      (prefix (cdr input-prefix)))
+                 (list (minibuffer-completion-action) input prefix)))
+  (funcall action (concat prefix input))
+  (when-let ((buf (get-buffer "*Completions*"))
+             (win (get-buffer-window buf 0)))
+    (with-current-buffer buf
+      (save-excursion
+        (goto-char (point-min))
+        (when-let ((pm (text-property-search-forward
+                        'completion--string input t)))
+          (goto-char (prop-match-beginning pm))
+          (setq pm (text-property-search-forward 'cursor-face))
+          (let ((inhibit-read-only t))
+            (add-face-text-property (prop-match-beginning pm) (point)
+                                    'completions-used-input)))))))
+
 ;;; Old-style completion, used in Emacs-21 and Emacs-22.
 
 (defun completion-emacs21-try-completion (string table pred _point)
@@ -5174,6 +5225,9 @@ See `completing-read' for the meaning of the arguments."
          (result
           (minibuffer-with-setup-hook
               (lambda ()
+                (setq-local minibuffer-completion-command
+                            (car (last (cons this-command
+                                             (function-alias-p this-command)))))
                 (setq-local minibuffer-completion-table collection)
                 (setq-local minibuffer-completion-predicate predicate)
                 ;; FIXME: Remove/rename this var, see the next one.