changeset 95172:894bae45bf1b

(completion-all-sorted-completions): New var. (completion--flush-all-sorted-completions) (completion-all-sorted-completions): New functions. (minibuffer-force-complete): New command.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Wed, 21 May 2008 20:52:44 +0000
parents a0c9f454ff18
children aa6446d89833
files etc/NEWS lisp/ChangeLog lisp/minibuffer.el
diffstat 3 files changed, 67 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS	Wed May 21 10:14:56 2008 +0000
+++ b/etc/NEWS	Wed May 21 20:52:44 2008 +0000
@@ -64,7 +64,10 @@
 * Changes in Emacs 23.1
 
 ** Completion.
-*** `completion-style' can be customized to choose your favorite completion.
+*** `completion-styles' can be customized to choose your favorite completion.
+*** The default completion styles include a form of partial-completion.
+*** The new command `minibuffer-force-complete chooses one of the possible
+completions, rather than stopping at the common prefix.
 *** `completion-auto-help' can be set to `lazy' to list the completions only
 if you repeat the completion.  This was already supported in
 `partial-completion-mode'.
--- a/lisp/ChangeLog	Wed May 21 10:14:56 2008 +0000
+++ b/lisp/ChangeLog	Wed May 21 20:52:44 2008 +0000
@@ -1,3 +1,10 @@
+2008-05-21  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* minibuffer.el (completion-all-sorted-completions): New var.
+	(completion--flush-all-sorted-completions)
+	(completion-all-sorted-completions): New functions.
+	(minibuffer-force-complete): New command.
+
 2008-05-21  Glenn Morris  <rgm@gnu.org>
 
 	* files.el (c-postprocess-file-styles): Declare for compiler.
--- a/lisp/minibuffer.el	Wed May 21 10:14:56 2008 +0000
+++ b/lisp/minibuffer.el	Wed May 21 20:52:44 2008 +0000
@@ -489,6 +489,59 @@
                t)
         (t     t)))))
 
+(defvar completion-all-sorted-completions nil)
+(make-variable-buffer-local 'completion-all-sorted-completions)
+
+(defun completion--flush-all-sorted-completions (&rest ignore)
+  (setq completion-all-sorted-completions nil))
+
+(defun completion-all-sorted-completions ()
+  (or completion-all-sorted-completions
+      (let* ((start (field-beginning))
+             (end (field-end))
+             (all (completion-all-completions (buffer-substring start end)
+                                              minibuffer-completion-table
+                                              minibuffer-completion-predicate
+                                              (- (point) start)))
+             (last (last all))
+             (base-size (or (cdr last) 0)))
+        (when last
+          (setcdr last nil)
+          ;; Prefer shorter completions.
+          (setq all (sort all (lambda (c1 c2) (< (length c1) (length c2)))))
+          ;; Prefer recently used completions.
+          (let ((hist (symbol-value minibuffer-history-variable)))
+            (setq all (sort all (lambda (c1 c2)
+                                  (> (length (member c1 hist))
+                                     (length (member c2 hist)))))))
+          ;; Cache the result.  This is not just for speed, but also so that
+          ;; repeated calls to minibuffer-force-complete can cycle through
+          ;; all possibilities.
+          (add-hook 'after-change-functions
+                    'completion--flush-all-sorted-completions nil t)
+          (setq completion-all-sorted-completions
+                (nconc all base-size))))))
+
+(defun minibuffer-force-complete ()
+  "Complete the minibuffer to an exact match.
+Repeated uses step through the possible completions."
+  (interactive)
+  ;; FIXME: Need to deal with the extra-size issue here as well.
+  (let* ((start (field-beginning))
+         (end (field-end))
+         (all (completion-all-sorted-completions)))
+    (if (not (consp all))
+        (minibuffer-message (if all "No more completions" "No completions"))
+      (goto-char end)
+      (insert (car all))
+      (delete-region (+ start (cdr (last all))) end)
+      ;; If completing file names, (car all) may be a directory, so we'd now
+      ;; have a new set of possible completions and might want to reset
+      ;; completion-all-sorted-completions to nil, but we prefer not to,
+      ;; so that repeated calls minibuffer-force-complete still cycle
+      ;; through the previous possible completions.
+      (setq completion-all-sorted-completions (cdr all)))))
+
 (defun minibuffer-complete-and-exit ()
   "If the minibuffer contents is a valid completion then exit.
 Otherwise try to complete it.  If completion leads to a valid completion,
@@ -861,6 +914,9 @@
 
 (let ((map minibuffer-local-completion-map))
   (define-key map "\t" 'minibuffer-complete)
+  ;; M-TAB is already abused for many other purposes, so we should find
+  ;; another binding for it.
+  ;; (define-key map "\e\t" 'minibuffer-force-complete)
   (define-key map " " 'minibuffer-complete-word)
   (define-key map "?" 'minibuffer-completion-help))