]> code.delx.au - gnu-emacs/blobdiff - lisp/complete.el
Add defgroups, and use defcustom.
[gnu-emacs] / lisp / complete.el
index b9c759588bc2b56f2ef832e3572d71992f77aeb7..c12e2ce95cb66c423aa381c04821a7f383912d0f 100644 (file)
@@ -1,8 +1,9 @@
-;; complete.el -- partial completion mechanism plus other goodies.
+;;; complete.el --- partial completion mechanism plus other goodies
 
 ;; Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
 
 ;; Author: Dave Gillespie <daveg@synaptics.com>
+;; Keywords: abbrev
 ;; Version: 2.02
 ;; Special thanks to Hallvard Furuseth for his many ideas and contributions.
 
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
 
-;; Commentary:
+;;; Commentary:
 
 ;; Extended completion for the Emacs minibuffer.
 ;;
@@ -94,7 +96,7 @@
 ;; is supported in include file names.
 
 
-;; Code:
+;;; Code:
 
 (defvar PC-meta-flag t
   "*If nil, TAB does normal Emacs completion and M-TAB does Partial Completion.
@@ -176,7 +178,21 @@ Word-delimiters for the purposes of Partial Completion are \"-\", \"_\",
   (interactive)
   (if (PC-was-meta-key)
       (minibuffer-complete)
-    (PC-do-completion nil)))
+    ;; If the previous command was not this one,
+    ;; never scroll, always retry completion.
+    (or (eq last-command this-command)
+       (setq minibuffer-scroll-window nil))
+    (let ((window minibuffer-scroll-window))
+      ;; If there's a fresh completion window with a live buffer,
+      ;; and this command is repeated, scroll that window.
+      (if (and window (window-buffer window)
+              (buffer-name (window-buffer window)))
+         (save-excursion
+           (set-buffer (window-buffer window))
+           (if (pos-visible-in-window-p (point-max) window)
+               (set-window-start window (point-min) nil)
+             (scroll-other-window)))
+       (PC-do-completion nil)))))
 
 
 (defun PC-complete-word ()
@@ -228,7 +244,7 @@ See `PC-complete' for details."
           (if (or (eq flag 'complete)
                   (not minibuffer-completion-confirm))
               (exit-minibuffer)
-            (PC-temp-minibuffer-message " (Confirm)"))))))
+            (PC-temp-minibuffer-message " [Confirm]"))))))
 
 
 (defun PC-completion-help ()
@@ -255,14 +271,23 @@ See `PC-complete' for details."
 (defvar PC-ndelims-regex nil)
 (defvar PC-delims-list nil)
 
+(defvar PC-completion-as-file-name-predicate
+  (function
+   (lambda ()
+     (memq minibuffer-completion-table
+          '(read-file-name-internal read-directory-name-internal))))
+   "A function testing whether a minibuffer completion now will work filename-style.
+The function takes no arguments, and typically looks at the value
+of `minibuffer-completion-table' and the minibuffer contents.")
+
 (defun PC-do-completion (&optional mode beg end)
   (or beg (setq beg (point-min)))
   (or end (setq end (point-max)))
   (let* ((table minibuffer-completion-table)
         (pred minibuffer-completion-predicate)
-        (filename (memq table '(read-file-name-internal
-                                read-directory-name-internal)))
+        (filename (funcall PC-completion-as-file-name-predicate))
         (dirname nil)
+        dirlength
         (str (buffer-substring beg end))
         (incname (and filename (string-match "<\\([^\"<>]*\\)>?$" str)))
         (ambig nil)
@@ -278,6 +303,13 @@ See `PC-complete' for details."
             (PC-is-complete-p str table pred))
        'complete
 
+      ;; Record how many characters at the beginning are not included
+      ;; in completion.
+      (setq dirlength
+           (if filename
+               (length (file-name-directory str))
+             0))
+
       ;; Do substitutions in directory names
       (and filename
           (not (equal str (setq p (substitute-in-file-name str))))
@@ -377,7 +409,9 @@ See `PC-complete' for details."
          (setq p compl)
          (while p
            (and (string-match regex (car p))
-                (setq poss (cons (car p) poss)))
+                (progn
+                  (set-text-properties 0 (length (car p)) '() (car p))
+                  (setq poss (cons (car p) poss))))
            (setq p (cdr p)))))
 
       ;; Now we have a list of possible completions
@@ -392,10 +426,10 @@ See `PC-complete' for details."
              (PC-do-completion 'word))
          (beep)
          (PC-temp-minibuffer-message (if ambig
-                                         " (Ambiguous dir name)"
+                                         " [Ambiguous dir name]"
                                        (if (eq mode 'help)
-                                           " (No completions)"
-                                         " (No match)")))
+                                           " [No completions]"
+                                         " [No match]")))
          nil))
 
        ;; More than one valid completion found
@@ -431,14 +465,14 @@ See `PC-complete' for details."
        ;; Is the actual string one of the possible completions?
        (setq p (and (not (eq mode 'help)) poss))
        (while (and p
-                   (not (equal (car p) basestr)))
+                   (not (string-equal (car p) basestr)))
          (setq p (cdr p)))
-       (if p
-
-           (progn
-             (if (null mode)
-                 (PC-temp-minibuffer-message " (Complete, but not unique)"))
-             t)
+       (and p (null mode)
+            (PC-temp-minibuffer-message " [Complete, but not unique]"))
+       (if (and p
+                (not (and (null mode)
+                          (eq this-command last-command))))
+           t
 
          ;; If ambiguous, try for a partial completion
          (let ((improved nil)
@@ -475,8 +509,7 @@ See `PC-complete' for details."
                                             (delete-char 1)
                                             (setq end (1- end))))
                                      (setq improved t))
-                                   ;; Use format to discard text properties.
-                                   (insert (format "%s" (substring prefix i (1+ i))))
+                                   (insert (substring prefix i (1+ i)))
                                    (setq end (1+ end)))
                                  (setq i (1+ i)))
                                (or pt (equal (point) beg)
@@ -523,16 +556,22 @@ See `PC-complete' for details."
                ;; If totally ambiguous, display a list of completions
                (if (or completion-auto-help
                        (eq mode 'help))
-                   (with-output-to-temp-buffer " *Completions*"
-                     (display-completion-list (sort helpposs 'string-lessp)))
-                 (PC-temp-minibuffer-message " (Next char not unique)"))
+                   (with-output-to-temp-buffer "*Completions*"
+                     (display-completion-list (sort helpposs 'string-lessp))
+                     (save-excursion
+                       (set-buffer standard-output)
+                       ;; Record which part of the buffer we are completing
+                       ;; so that choosing a completion from the list
+                       ;; knows how much old text to replace.
+                       (setq completion-base-size dirlength)))
+                 (PC-temp-minibuffer-message " [Next char not unique]"))
                nil)))))
 
        ;; Only one possible completion
        (t
        (if (equal basestr (car poss))
            (if (null mode)
-               (PC-temp-minibuffer-message " (Sole completion)"))
+               (PC-temp-minibuffer-message " [Sole completion]"))
          (delete-region beg end)
          (insert (format "%s"
                          (if filename
@@ -637,16 +676,20 @@ or properties are considered."
        (kill-buffer (current-buffer))
        (or files
            (error "No matching files"))
+       ;; Bring the other files (not the first) into buffers.
        (save-window-excursion
          (while (setq next (cdr next))
            (let ((buf (find-file-noselect (car next))))
+             ;; Put this buffer at the front of the buffer list.
              (switch-to-buffer buf))))
-       ;; This modifies the "buf" variable inside find-file-noselect.
+       ;; This modifies the `buf' variable inside find-file-noselect.
        (setq buf (get-file-buffer first))
        (if buf
            nil   ; should do verify-visited-file-modtime stuff.
          (setq filename first)
          (setq buf (create-file-buffer filename))
+         ;; This modified `truename' inside find-file-noselect.
+         (setq truename (abbreviate-file-name (file-truename filename)))
          (set-buffer buf)
          (erase-buffer)
          (insert-file-contents filename t))