diff options
Diffstat (limited to 'lisp/minibuffer.el')
-rw-r--r-- | lisp/minibuffer.el | 55 |
1 files changed, 42 insertions, 13 deletions
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 44ce0b78a3e..e18f4c9c77f 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -51,6 +51,9 @@ ;;; Todo: +;; - Make *Completions* readable even if some of the completion +;; entries have LF chars or spaces in them (including at +;; beginning/end) or are very long. ;; - for M-x, cycle-sort commands that have no key binding first. ;; - Make things like icomplete-mode or lightning-completion work with ;; completion-in-region-mode. @@ -74,6 +77,9 @@ ;; - whether the user wants completion to pay attention to case. ;; e.g. we may want to make it possible for the user to say "first try ;; completion case-sensitively, and if that fails, try to ignore case". +;; Maybe the trick is that we should distinguish completion-ignore-case in +;; try/all-completions (obey user's preference) from its use in +;; test-completion (obey the underlying object's semantics). ;; - add support for ** to pcm. ;; - Add vc-file-name-completion-table to read-file-name-internal. @@ -1100,6 +1106,13 @@ scroll the window of possible completions." (sort-fun (completion-metadata-get all-md 'cycle-sort-function))) (when last (setcdr last nil) + + ;; Delete duplicates: do it after setting last's cdr to nil (so + ;; it's a proper list), and be careful to reset `last' since it + ;; may be a different cons-cell. + (setq all (delete-dups all)) + (setq last (last all)) + (setq all (if sort-fun (funcall sort-fun all) ;; Prefer shorter completions, by default. (sort all (lambda (c1 c2) (< (length c1) (length c2)))))) @@ -1114,6 +1127,15 @@ scroll the window of possible completions." ;; all possibilities. (completion--cache-all-sorted-completions (nconc all base-size)))))) +(defun minibuffer-force-complete-and-exit () + "Complete the minibuffer with first of the matches and exit." + (interactive) + (minibuffer-force-complete) + (minibuffer--complete-and-exit + ;; If the previous completion completed to an element which fails + ;; test-completion, then we shouldn't exit, but that should be rare. + (lambda () (minibuffer-message "Incomplete")))) + (defun minibuffer-force-complete () "Complete the minibuffer to an exact match. Repeated uses step through the possible completions." @@ -1186,6 +1208,22 @@ If `minibuffer-completion-confirm' is `confirm-after-completion', `minibuffer-confirm-exit-commands', and accept the input otherwise." (interactive) + (minibuffer--complete-and-exit + (lambda () + (pcase (condition-case nil + (completion--do-completion nil 'expect-exact) + (error 1)) + ((or #b001 #b011) (exit-minibuffer)) + (#b111 (if (not minibuffer-completion-confirm) + (exit-minibuffer) + (minibuffer-message "Confirm") + nil)) + (_ nil))))) + +(defun minibuffer--complete-and-exit (completion-function) + "Exit from `require-match' minibuffer. +COMPLETION-FUNCTION is called if the current buffer's content does not +appear to be a match." (let ((beg (field-beginning)) (end (field-end))) (cond @@ -1233,15 +1271,7 @@ If `minibuffer-completion-confirm' is `confirm-after-completion', (t ;; Call do-completion, but ignore errors. - (pcase (condition-case nil - (completion--do-completion nil 'expect-exact) - (error 1)) - ((or #b001 #b011) (exit-minibuffer)) - (#b111 (if (not minibuffer-completion-confirm) - (exit-minibuffer) - (minibuffer-message "Confirm") - nil)) - (_ nil)))))) + (funcall completion-function))))) (defun completion--try-word-completion (string table predicate point md) (let ((comp (completion-try-completion string table predicate point md))) @@ -2015,10 +2045,7 @@ with `minibuffer-local-must-match-map'.") (define-key map "i" 'info) (define-key map "m" 'mail) (define-key map "n" 'make-frame) - (define-key map [mouse-1] (lambda () (interactive) - (with-current-buffer "*Messages*" - (goto-char (point-max)) - (display-buffer (current-buffer))))) + (define-key map [mouse-1] 'view-echo-area-messages) ;; So the global down-mouse-1 binding doesn't clutter the execution of the ;; above mouse-1 binding. (define-key map [down-mouse-1] #'ignore) @@ -2048,6 +2075,8 @@ This is only used when the minibuffer area has no active minibuffer.") process-environment)) (defconst completion--embedded-envvar-re + ;; We can't reuse env--substitute-vars-regexp because we need to match only + ;; potentially-unfinished envvars at end of string. (concat "\\(?:^\\|[^$]\\(?:\\$\\$\\)*\\)" "$\\([[:alnum:]_]*\\|{\\([^}]*\\)\\)\\'")) |