From ef7066c87a807635c8afaae28e6d94c7155125ab Mon Sep 17 00:00:00 2001 From: Eshel Yaron Date: Mon, 8 Jul 2024 22:49:22 +0200 Subject: [PATCH] Improve and extend minibuffer prompt indicators --- lisp/emacs-lisp/crm.el | 25 +++++++++++- lisp/minibuffer.el | 91 ++++++++++++++++++++++++++++-------------- 2 files changed, 86 insertions(+), 30 deletions(-) diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el index 53623e167e1..af87e881f14 100644 --- a/lisp/emacs-lisp/crm.el +++ b/lisp/emacs-lisp/crm.el @@ -303,6 +303,10 @@ that fails this command prompts you for the separator to use." "Face for highlighting input separators in multi-input minibuffers." :version "30.1") +(defface crm-prompt-indicator-highlight + '((t :inherit mode-line-highlight)) + "Face for minibuffer multi-inputs prompt indicator when mouse is over it.") + (defun crm-highlight-separators (beg end &optional _) "Highlight current minibuffer input separators between BEG and END." (let* ((bob (minibuffer-prompt-end)) @@ -332,6 +336,21 @@ that fails this command prompts you for the separator to use." "C-x ," #'crm-change-separator "C-," #'crm-complete-and-insert-separator) +(defcustom crm-prompt-indicator "+" + "String to show in minibuffer prompt when reading multiple inputs." + :type 'string + :version "31.1" + :group 'minibuffer + :risky t) + +(defvar crm-prompt-indicator-format + '(completing-read-multiple-mode + (:propertize crm-prompt-indicator + help-echo "Reading multiple inputs" + mouse-face crm-prompt-indicator-highlight))) + +(put 'crm-prompt-indicator-format 'risky-local-variable t) + (define-minor-mode completing-read-multiple-mode "Minor mode for reading multiple strings in the minibuffer." :interactive nil @@ -339,12 +358,16 @@ that fails this command prompts you for the separator to use." (progn (add-hook 'completion-setup-hook #'crm-completions-setup 10 t) (add-hook 'after-change-functions #'crm-highlight-separators nil t) + (setq-local minibuffer-extra-prompt-indicators-format + (list "" 'crm-prompt-indicator-format + minibuffer-extra-prompt-indicators-format)) (crm-highlight-separators (minibuffer-prompt-end) (point-max))) (remove-hook 'completion-setup-hook #'crm-completions-setup t) (remove-hook 'after-change-functions #'crm-highlight-separators t) (mapc #'delete-overlay (seq-filter (lambda (ov) (overlay-get ov 'crm-separator)) - (overlays-in (minibuffer-prompt-end) (point-max)))))) + (overlays-in (minibuffer-prompt-end) (point-max))))) + (minibuffer-update-prompt-indicators)) (defun crm--table (table s p a) (let ((beg 0)) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 1c4a0e5ac6b..56c830a34ae 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -4262,36 +4262,69 @@ possible completions." (defun minibuffer-record-command () (setq-local current-minibuffer-command this-command)) -(defvar-local minibuffer-prompt-indications-overlay nil) - -(defun minibuffer-update-prompt-indications () - (let ((cmp minibuffer-completion-table) - (act (minibuffer-action))) - (if (not (or cmp act)) - (when (overlayp minibuffer-prompt-indications-overlay) - (delete-overlay minibuffer-prompt-indications-overlay) - (setq-local minibuffer-prompt-indications-overlay nil)) - (unless (overlayp minibuffer-prompt-indications-overlay) - (setq-local minibuffer-prompt-indications-overlay - (make-overlay (point-min) (point-min)))) - (overlay-put - minibuffer-prompt-indications-overlay 'before-string - ;; TODO: Make indicators clickable, and indicate strictness. - (apply #'propertize - (concat - (when-let ((desc (cdr (minibuffer-action)))) - (propertize "<" 'help-echo - (concat - "\\\\[minibuffer-apply]: " - desc))) - (when minibuffer-completion-table - (propertize ">" 'help-echo "Completion available")) - " ") - (append minibuffer-prompt-properties - (list 'front-sticky t 'rear-nonsticky t 'field t))))))) +(defvar-local minibuffer-prompt-indicators-overlay nil) + +(defface minibuffer-action-prompt-indicator-highlight + '((t :inherit mode-line-highlight)) + "Face for minibuffer action prompt indicator when mouse is over it.") + +(defface minibuffer-completion-prompt-indicator-highlight + '((t :inherit mode-line-highlight)) + "Face for minibuffer completion prompt indicator when mouse is over it.") + +(defcustom minibuffer-action-prompt-indicator "<" + "String to show in minibuffer prompt when there's an available action." + :type 'string + :version "31.1" + :group 'minibuffer + :risky t) + +(defcustom minibuffer-completion-prompt-indicator ">" + "String to show in minibuffer prompt when completion is available." + :type 'string + :version "31.1" + :group 'minibuffer + :risky t) + +(defvar minibuffer-action-prompt-indicator-format + '(:eval + (when-let ((desc (cdr (minibuffer-action)))) + (propertize + minibuffer-action-prompt-indicator + 'help-echo (concat "\\\\[minibuffer-apply]: " desc) + 'mouse-face 'minibuffer-action-prompt-indicator-highlight)))) + +(defvar minibuffer-extra-prompt-indicators-format nil) + +(defvar minibuffer-completion-prompt-indicator-format + '(minibuffer-completion-table + (:propertize minibuffer-completion-prompt-indicator + help-echo "Completion available" + mouse-face minibuffer-completion-prompt-indicator-highlight))) + +(dolist (sym '(minibuffer-action-prompt-indicator-format + minibuffer-extra-prompt-indicators-format + minibuffer-completion-prompt-indicator-format)) + (put sym 'risky-local-variable t)) + +(defvar minibuffer-prompt-indicators-format + '("" + minibuffer-action-prompt-indicator-format + minibuffer-extra-prompt-indicators-format + minibuffer-completion-prompt-indicator-format) + "Mode line construct used for formatting minibuffer prompt indicators.") + +(defun minibuffer-update-prompt-indicators () + (unless (overlayp minibuffer-prompt-indicators-overlay) + (setq-local minibuffer-prompt-indicators-overlay + (make-overlay (point-min) (point-min)))) + (let ((ind (format-mode-line minibuffer-prompt-indicators-format 'minibuffer-prompt))) + (unless (or (string-empty-p ind) (string-suffix-p " " ind)) + (setq ind (concat ind " "))) + (overlay-put minibuffer-prompt-indicators-overlay 'before-string ind))) (add-hook 'minibuffer-setup-hook #'minibuffer-record-command) -(add-hook 'minibuffer-setup-hook #'minibuffer-update-prompt-indications 95) +(add-hook 'minibuffer-setup-hook #'minibuffer-update-prompt-indicators 95) (defun minibuffer-action () "Return the minibuffer action function for the current minibuffer." @@ -4405,7 +4438,7 @@ possible completions." (or (and (symbolp action-fn) (cdr (minibuffer--get-action action-fn))) "custom action"))) - (minibuffer-update-prompt-indications)) + (minibuffer-update-prompt-indicators)) ;;; Old-style completion, used in Emacs-21 and Emacs-22. -- 2.39.2