* net/tramp.el (tramp-open-connection-setup-interactive-shell):
[bpt/emacs.git] / lisp / minibuffer.el
index 223817d..a4ab526 100644 (file)
@@ -1,6 +1,6 @@
 ;;; minibuffer.el --- Minibuffer completion functions
 
-;; Copyright (C) 2008, 2009  Free Software Foundation, Inc.
+;; Copyright (C) 2008, 2009, 2010  Free Software Foundation, Inc.
 
 ;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
 
 
 ;;; Todo:
 
-;; - make partial-complete-mode obsolete:
+;; - extend `boundaries' to provide various other meta-data about the
+;;   output of `all-completions':
+;;   - preferred sorting order when displayed in *Completions*.
+;;   - annotations/text-properties to add when displayed in *Completions*.
+;;   - quoting/unquoting (so we can complete files names with envvars
+;;     and backslashes, and all-completion can list names without
+;;     quoting backslashes and dollars).
+;;   - indicate how to turn all-completion's output into
+;;     try-completion's output: e.g. completion-ignored-extensions.
+;;     maybe that could be merged with the "quote" operation above.
+;;   - completion hook to run when the completion is
+;;     selected/inserted (maybe this should be provided some other
+;;     way, e.g. as text-property, so `try-completion can also return it?)
+;;     both for when it's inserted via TAB or via choose-completion.
+;;   - indicate that `all-completions' doesn't do prefix-completion
+;;     but just returns some list that relates in some other way to
+;;     the provided string (as is the case in filecache.el), in which
+;;     case partial-completion (for example) doesn't make any sense
+;;     and neither does the completions-first-difference highlight.
+
+;; - make partial-completion-mode obsolete:
 ;;   - (?) <foo.h> style completion for file names.
 ;;     This can't be done identically just by tweaking completion,
 ;;     because partial-completion-mode's behavior is to expand <string.h>
@@ -109,8 +129,8 @@ the closest directory separators."
   "Apply FUN to each element of XS in turn.
 Return the first non-nil returned value.
 Like CL's `some'."
-  (let ((firsterror nil)
-        res)
+  (lexical-let ((firsterror nil)
+               res)
     (while (and (not res) xs)
       (condition-case err
           (setq res (funcall fun (pop xs)))
@@ -361,18 +381,32 @@ the second failed attempt to complete."
 (defconst completion-styles-alist
   '((emacs21
      completion-emacs21-try-completion completion-emacs21-all-completions
-     "Simple prefix-based completion.")
+     "Simple prefix-based completion.
+I.e. when completing \"foo_bar\" (where _ is the position of point),
+it will consider all completions candidates matching the glob
+pattern \"foobar*\".")
     (emacs22
      completion-emacs22-try-completion completion-emacs22-all-completions
-     "Prefix completion that only operates on the text before point.")
+     "Prefix completion that only operates on the text before point.
+I.e. when completing \"foo_bar\" (where _ is the position of point),
+it will consider all completions candidates matching the glob
+pattern \"foo*\" and will add back \"bar\" to the end of it.")
     (basic
      completion-basic-try-completion completion-basic-all-completions
-     "Completion of the prefix before point and the suffix after point.")
+     "Completion of the prefix before point and the suffix after point.
+I.e. when completing \"foo_bar\" (where _ is the position of point),
+it will consider all completions candidates matching the glob
+pattern \"foo*bar*\".")
     (partial-completion
      completion-pcm-try-completion completion-pcm-all-completions
      "Completion of multiple words, each one taken as a prefix.
-E.g. M-x l-c-h can complete to list-command-history
-and C-x C-f /u/m/s to /usr/monnier/src.")
+I.e. when completing \"l-co_h\" (where _ is the position of point),
+it will consider all completions candidates matching the glob
+pattern \"l*-co*h*\".
+Furthermore, for completions that are done step by step in subfields,
+the method is applied to all the preceding fields that do not yet match.
+E.g. C-x C-f /u/mo/s TAB could complete to /usr/monnier/src.
+Additionally the user can use the char \"*\" as a glob pattern.")
     (initials
      completion-initials-try-completion completion-initials-all-completions
      "Completion of acronyms and initialisms.
@@ -387,7 +421,19 @@ ALL-COMPLETIONS is the function that lists the completions (it should
 follow the calling convention of `completion-all-completions'),
 and DOC describes the way this style of completion works.")
 
-(defcustom completion-styles '(basic partial-completion emacs22)
+(defcustom completion-styles
+  ;; First, use `basic' because prefix completion has been the standard
+  ;; for "ever" and works well in most cases, so using it first
+  ;; ensures that we obey previous behavior in most cases.
+  '(basic
+    ;; Then use `partial-completion' because it has proven to
+    ;; be a very convenient extension.
+    partial-completion
+    ;; Finally use `emacs22' so as to maintain (in many/most cases)
+    ;; the previous behavior that when completing "foobar" with point
+    ;; between "foo" and "bar" the completion try to complete "foo"
+    ;; and simply add "bar" to the end of the result.
+    emacs22)
   "List of completion styles to use.
 The available styles are listed in `completion-styles-alist'."
   :type `(repeat (choice ,@(mapcar (lambda (x) (list 'const (car x)))
@@ -414,8 +460,8 @@ Only the elements of table that satisfy predicate PRED are considered.
 POINT is the position of point within STRING.
 The return value is a list of completions and may contain the base-size
 in the last `cdr'."
-  ;; FIXME: We need to additionally return completion-extra-size (similar
-  ;; to completion-base-size but for the text after point).
+  ;; FIXME: We need to additionally return the info needed for the
+  ;; second part of completion-base-position.
   (completion--some (lambda (style)
                       (funcall (nth 2 (assq style completion-styles-alist))
                                string table pred point))
@@ -426,6 +472,37 @@ in the last `cdr'."
           (if completions 2 0)
           (if exact       1 0)))
 
+(defun completion--replace (beg end newtext)
+  "Replace the buffer text between BEG and END with NEWTEXT.
+Moves point to the end of the new text."
+  ;; Maybe this should be in subr.el.
+  ;; You'd think this is trivial to do, but details matter if you want
+  ;; to keep markers "at the right place" and be robust in the face of
+  ;; after-change-functions that may themselves modify the buffer.
+  (let ((prefix-len 0))
+    ;; Don't touch markers in the shared prefix (if any).
+    (while (and (< prefix-len (length newtext))
+                (< (+ beg prefix-len) end)
+                (eq (char-after (+ beg prefix-len))
+                    (aref newtext prefix-len)))
+      (setq prefix-len (1+ prefix-len)))
+    (unless (zerop prefix-len)
+      (setq beg (+ beg prefix-len))
+      (setq newtext (substring newtext prefix-len))))
+  (let ((suffix-len 0))
+    ;; Don't touch markers in the shared suffix (if any).
+    (while (and (< suffix-len (length newtext))
+                (< beg (- end suffix-len))
+                (eq (char-before (- end suffix-len))
+                    (aref newtext (- (length newtext) suffix-len 1))))
+      (setq suffix-len (1+ suffix-len)))
+    (unless (zerop suffix-len)
+      (setq end (- end suffix-len))
+      (setq newtext (substring newtext 0 (- suffix-len)))))
+  (goto-char beg)
+  (insert newtext)
+  (delete-region (point) (+ (point) (- end beg))))
+
 (defun completion--do-completion (&optional try-completion-function)
   "Do the completion and return a summary of what happened.
 M = completion was performed, the text was Modified.
@@ -441,15 +518,16 @@ E = after completion we now have an Exact match.
  101  5 ??? impossible
  110  6 some completion happened
  111  7 completed to an exact completion"
-  (let* ((beg (field-beginning))
-         (end (field-end))
-         (string (buffer-substring beg end))
-         (comp (funcall (or try-completion-function
-                           'completion-try-completion)
-                       string
-                       minibuffer-completion-table
-                       minibuffer-completion-predicate
-                       (- (point) beg))))
+  (lexical-let*
+      ((beg (field-beginning))
+       (end (field-end))
+       (string (buffer-substring beg end))
+       (comp (funcall (or try-completion-function
+                         'completion-try-completion)
+                     string
+                     minibuffer-completion-table
+                     minibuffer-completion-predicate
+                     (- (point) beg))))
     (cond
      ((null comp)
       (minibuffer-hide-completions)
@@ -462,20 +540,19 @@ E = after completion we now have an Exact match.
       ;; `completed' should be t if some completion was done, which doesn't
       ;; include simply changing the case of the entered string.  However,
       ;; for appearance, the string is rewritten if the case changes.
-      (let* ((comp-pos (cdr comp))
-            (completion (car comp))
-            (completed (not (eq t (compare-strings completion nil nil
-                                                   string nil nil t))))
-            (unchanged (eq t (compare-strings completion nil nil
-                                              string nil nil nil))))
-        (unless unchanged
-
+      (lexical-let*
+         ((comp-pos (cdr comp))
+          (completion (car comp))
+          (completed (not (eq t (compare-strings completion nil nil
+                                                 string nil nil t))))
+          (unchanged (eq t (compare-strings completion nil nil
+                                            string nil nil nil))))
+        (if unchanged
+           (goto-char end)
           ;; Insert in minibuffer the chars we got.
-          (goto-char end)
-          (insert completion)
-          (delete-region beg end))
-       ;; Move point.
-       (goto-char (+ beg comp-pos))
+          (completion--replace beg end completion))
+       ;; Move point to its completion-mandated destination.
+       (forward-char (- comp-pos (length completion)))
 
         (if (not (or unchanged completed))
           ;; The case of the string changed, but that's all.  We're not sure
@@ -618,14 +695,20 @@ If `minibuffer-completion-confirm' is `confirm-after-completion',
  `minibuffer-confirm-exit-commands', and accept the input
  otherwise."
   (interactive)
-  (let ((beg (field-beginning))
-        (end (field-end)))
+  (lexical-let ((beg (field-beginning))
+               (end (field-end)))
     (cond
      ;; Allow user to specify null string
      ((= beg end) (exit-minibuffer))
      ((test-completion (buffer-substring beg end)
                        minibuffer-completion-table
                        minibuffer-completion-predicate)
+      ;; FIXME: completion-ignore-case has various slightly
+      ;; incompatible meanings.  E.g. it can reflect whether the user
+      ;; wants completion to pay attention to case, or whether the
+      ;; string will be used in a context where case is significant.
+      ;; E.g. usually try-completion should obey the first, whereas
+      ;; test-completion should obey the second.
       (when completion-ignore-case
         ;; Fixup case of the field, if necessary.
         (let* ((string (buffer-substring beg end))
@@ -633,7 +716,7 @@ If `minibuffer-completion-confirm' is `confirm-after-completion',
                        string
                        minibuffer-completion-table
                        minibuffer-completion-predicate)))
-          (when (and (stringp compl)
+          (when (and (stringp compl) (not (equal string compl))
                      ;; If it weren't for this piece of paranoia, I'd replace
                      ;; the whole thing with a call to do-completion.
                      ;; This is important, e.g. when the current minibuffer's
@@ -646,22 +729,19 @@ If `minibuffer-completion-confirm' is `confirm-after-completion',
             (delete-region beg end))))
       (exit-minibuffer))
 
-     ((eq minibuffer-completion-confirm 'confirm)
+     ((memq minibuffer-completion-confirm '(confirm confirm-after-completion))
       ;; The user is permitted to exit with an input that's rejected
       ;; by test-completion, after confirming her choice.
-      (if (eq last-command this-command)
+      (if (or (eq last-command this-command)
+              ;; For `confirm-after-completion' we only ask for confirmation
+              ;; if trying to exit immediately after typing TAB (this
+              ;; catches most minibuffer typos).
+              (and (eq minibuffer-completion-confirm 'confirm-after-completion)
+                   (not (memq last-command minibuffer-confirm-exit-commands))))
           (exit-minibuffer)
         (minibuffer-message "Confirm")
         nil))
 
-     ((eq minibuffer-completion-confirm 'confirm-after-completion)
-      ;; Similar to the above, but only if trying to exit immediately
-      ;; after typing TAB (this catches most minibuffer typos).
-      (if (memq last-command minibuffer-confirm-exit-commands)
-         (progn (minibuffer-message "Confirm")
-                nil)
-       (exit-minibuffer)))
-
      (t
       ;; Call do-completion, but ignore errors.
       (case (condition-case nil
@@ -778,6 +858,16 @@ Return nil if there is no valid completion, else t."
 (defface completions-annotations '((t :inherit italic))
   "Face to use for annotations in the *Completions* buffer.")
 
+(defcustom completions-format nil
+  "Define the appearance and sorting of completions.
+If the value is `vertical', display completions sorted vertically
+in columns in the *Completions* buffer.
+If the value is `horizontal' or nil, display completions sorted
+horizontally in alphabetical order, rather than down the screen."
+  :type '(choice (const nil) (const horizontal) (const vertical))
+  :group 'minibuffer
+  :version "23.2")
+
 (defun completion--insert-strings (strings)
   "Insert a list of STRINGS into the current buffer.
 Uses columns to keep the listing readable but compact.
@@ -800,6 +890,8 @@ It also eliminates runs of equal strings."
                     (max 1 (/ (length strings) 2))))
           (colwidth (/ wwidth columns))
            (column 0)
+          (rows (/ (length strings) columns))
+          (row 0)
           (laststring nil))
       ;; The insertion should be "sensible" no matter what choices were made
       ;; for the parameters above.
@@ -810,20 +902,38 @@ It also eliminates runs of equal strings."
                             (+ (string-width (car str))
                                (string-width (cadr str)))
                           (string-width str))))
-            (unless (bolp)
-              (if (< wwidth (+ (max colwidth length) column))
-                  ;; No space for `str' at point, move to next line.
-                  (progn (insert "\n") (setq column 0))
-                (insert " \t")
-                ;; Leave the space unpropertized so that in the case we're
-                ;; already past the goal column, there is still
-                ;; a space displayed.
-                (set-text-properties (- (point) 1) (point)
-                                     ;; We can't just set tab-width, because
-                                     ;; completion-setup-function will kill all
-                                     ;; local variables :-(
-                                     `(display (space :align-to ,column)))
-                nil))
+            (cond
+            ((eq completions-format 'vertical)
+             ;; Vertical format
+             (when (> row rows)
+               (forward-line (- -1 rows))
+               (setq row 0 column (+ column colwidth)))
+             (when (> column 0)
+               (end-of-line)
+               (while (> (current-column) column)
+                 (if (eobp)
+                     (insert "\n")
+                   (forward-line 1)
+                   (end-of-line)))
+               (insert " \t")
+               (set-text-properties (- (point) 1) (point)
+                                    `(display (space :align-to ,column)))))
+            (t
+             ;; Horizontal format
+             (unless (bolp)
+               (if (< wwidth (+ (max colwidth length) column))
+                   ;; No space for `str' at point, move to next line.
+                   (progn (insert "\n") (setq column 0))
+                 (insert " \t")
+                 ;; Leave the space unpropertized so that in the case we're
+                 ;; already past the goal column, there is still
+                 ;; a space displayed.
+                 (set-text-properties (- (point) 1) (point)
+                                      ;; We can't just set tab-width, because
+                                      ;; completion-setup-function will kill all
+                                      ;; local variables :-(
+                                      `(display (space :align-to ,column)))
+                 nil))))
             (if (not (consp str))
                 (put-text-property (point) (progn (insert str) (point))
                                    'mouse-face 'highlight)
@@ -831,11 +941,20 @@ It also eliminates runs of equal strings."
                                  'mouse-face 'highlight)
               (add-text-properties (point) (progn (insert (cadr str)) (point))
                                    '(mouse-face nil
-                                     face completions-annotations)))
-            ;; Next column to align to.
-            (setq column (+ column
-                            ;; Round up to a whole number of columns.
-                            (* colwidth (ceiling length colwidth))))))))))
+                                               face completions-annotations)))
+           (cond
+            ((eq completions-format 'vertical)
+             ;; Vertical format
+             (if (> column 0)
+                 (forward-line)
+               (insert "\n"))
+             (setq row (1+ row)))
+            (t
+             ;; Horizontal format
+             ;; Next column to align to.
+             (setq column (+ column
+                             ;; Round up to a whole number of columns.
+                             (* colwidth (ceiling length colwidth))))))))))))
 
 (defvar completion-common-substring nil)
 (make-obsolete-variable 'completion-common-substring nil "23.1")
@@ -954,20 +1073,25 @@ variables.")
   "Display a list of possible completions of the current minibuffer contents."
   (interactive)
   (message "Making completion list...")
-  (let* ((start (field-beginning))
-         (string (field-string))
-         (completions (completion-all-completions
-                       string
-                       minibuffer-completion-table
-                       minibuffer-completion-predicate
-                       (- (point) (field-beginning)))))
+  (lexical-let* ((start (field-beginning))
+                (string (field-string))
+                (completions (completion-all-completions
+                              string
+                              minibuffer-completion-table
+                              minibuffer-completion-predicate
+                              (- (point) (field-beginning)))))
     (message nil)
     (if (and completions
              (or (consp (cdr completions))
                  (not (equal (car completions) string))))
-        (with-output-to-temp-buffer "*Completions*"
-          (let* ((last (last completions))
-                 (base-size (cdr last)))
+        (let* ((last (last completions))
+               (base-size (cdr last))
+               ;; If the *Completions* buffer is shown in a new
+               ;; window, mark it as softly-dedicated, so bury-buffer in
+               ;; minibuffer-hide-completions will know whether to
+               ;; delete the window or not.
+               (display-buffer-mark-dedicated 'soft))
+          (with-output-to-temp-buffer "*Completions*"
             ;; Remove the base-size tail because `sort' requires a properly
             ;; nil-terminated list.
             (when last (setcdr last nil))
@@ -980,11 +1104,11 @@ variables.")
                                 (if ann (list s ann) s)))
                             completions)))
             (with-current-buffer standard-output
-             (set (make-local-variable 'completion-base-position)
-                  ;; FIXME: We should provide the END part as well, but
-                  ;; currently completion-all-completions does not give
-                  ;; us the necessary information.
-                  (list (+ start base-size) nil)))
+              (set (make-local-variable 'completion-base-position)
+                   ;; FIXME: We should provide the END part as well, but
+                   ;; currently completion-all-completions does not give
+                   ;; us the necessary information.
+                   (list (+ start base-size) nil)))
             (display-completion-list completions)))
 
       ;; If there are no completions, or if the current input is already the
@@ -1023,21 +1147,19 @@ variables.")
   (exit-minibuffer))
 
 (defvar completion-in-region-functions nil
-  "Wrapper hook around `complete-in-region'.
+  "Wrapper hook around `completion-in-region'.
 The functions on this special hook are called with 5 arguments:
   NEXT-FUN START END COLLECTION PREDICATE.
 NEXT-FUN is a function of four arguments (START END COLLECTION PREDICATE)
-that performs the default operation.  The other four argument are like
-the ones passed to `complete-in-region'.  The functions on this hook
+that performs the default operation.  The other four arguments are like
+the ones passed to `completion-in-region'.  The functions on this hook
 are expected to perform completion on START..END using COLLECTION
 and PREDICATE, either by calling NEXT-FUN or by doing it themselves.")
 
 (defun completion-in-region (start end collection &optional predicate)
   "Complete the text between START and END using COLLECTION.
+Return nil if there is no valid completion, else t.
 Point needs to be somewhere between START and END."
-  ;; FIXME: some callers need to setup completion-ignore-case,
-  ;; completion-ignored-extensions.  The latter can be embedded in the
-  ;; completion tables, but the first cannot (actually, maybe it should).
   (assert (<= start (point)) (<= (point) end))
   ;; FIXME: undisplay the *Completions* buffer once the completion is done.
   (with-wrapper-hook
@@ -1050,6 +1172,42 @@ Point needs to be somewhere between START and END."
           (call-interactively 'minibuffer-complete)
         (delete-overlay ol)))))
 
+(defvar completion-at-point-functions nil
+  "Special hook to find the completion table for the thing at point.
+It is called without any argument and should return either nil,
+or a function of no argument to perform completion (discouraged),
+or a list of the form (START END COLLECTION &rest PROPS) where
+ START and END delimit the entity to complete and should include point,
+ COLLECTION is the completion table to use to complete it, and
+ PROPS is a property list for additional information.
+Currently supported properties are:
+ `:predicate'           a predicate that completion candidates need to satisfy.
+ `:annotation-function' the value to use for `completion-annotate-function'.")
+
+(defun completion-at-point ()
+  "Complete the thing at point according to local mode.
+This runs the hook `completion-at-point-functions' until a member returns
+non-nil."
+  (interactive)
+  (let ((res (run-hook-with-args-until-success
+              'completion-at-point-functions)))
+    (cond
+     ((functionp res) (funcall res))
+     (res
+      (let* ((plist (nthcdr 3 res))
+             (start (nth 0 res))
+             (end (nth 1 res))
+             (completion-annotate-function
+              (or (plist-get plist :annotation-function)
+                  completion-annotate-function)))
+        (completion-in-region start end (nth 2 res)
+                              (plist-get plist :predicate)))))))
+
+;;; Key bindings.
+
+(define-obsolete-variable-alias 'minibuffer-local-must-match-filename-map
+  'minibuffer-local-filename-must-match-map "23.1")
+
 (let ((map minibuffer-local-map))
   (define-key map "\C-g" 'abort-recursive-edit)
   (define-key map "\r" 'exit-minibuffer)
@@ -1202,6 +1360,8 @@ except that it passes the file name through `substitute-in-file-name'."
     ;; substitute-in-file-name turns "fo-$TO-ba" into "fo-o/b-ba", there's
     ;; no way for us to return proper boundaries info, because the
     ;; boundary is not (yet) in `string'.
+    ;; FIXME: Actually there is a way to return correct boundaries info,
+    ;; at the condition of modifying the all-completions return accordingly.
     (let ((start (length (file-name-directory string)))
           (end (string-match-p "/" (cdr action))))
       (list* 'boundaries start end)))
@@ -1277,6 +1437,32 @@ such as making the current buffer visit no file in the case of
 (declare-function x-file-dialog "xfns.c"
                   (prompt dir &optional default-filename mustmatch only-dir-p))
 
+(defun read-file-name-defaults (&optional dir initial)
+  (let ((default
+         (cond
+          ;; With non-nil `initial', use `dir' as the first default.
+          ;; Essentially, this mean reversing the normal order of the
+          ;; current directory name and the current file name, i.e.
+          ;; 1. with normal file reading:
+          ;; 1.1. initial input is the current directory
+          ;; 1.2. the first default is the current file name
+          ;; 2. with non-nil `initial' (e.g. for `find-alternate-file'):
+          ;; 2.2. initial input is the current file name
+          ;; 2.1. the first default is the current directory
+          (initial (abbreviate-file-name dir))
+          ;; In file buffers, try to get the current file name
+          (buffer-file-name
+           (abbreviate-file-name buffer-file-name))))
+       (file-name-at-point
+        (run-hook-with-args-until-success 'file-name-at-point-functions)))
+    (when file-name-at-point
+      (setq default (delete-dups
+                    (delete "" (delq nil (list file-name-at-point default))))))
+    ;; Append new defaults to the end of existing `minibuffer-default'.
+    (append
+     (if (listp minibuffer-default) minibuffer-default (list minibuffer-default))
+     (if (listp default) default (list default)))))
+
 (defun read-file-name (prompt &optional dir default-filename mustmatch initial predicate)
   "Read file name, prompting with PROMPT and completing in directory DIR.
 Value is not expanded---you must call `expand-file-name' yourself.
@@ -1360,7 +1546,24 @@ and `read-file-name-function'."
                     (lexical-let ((dir (file-name-as-directory
                                         (expand-file-name dir))))
                       (minibuffer-with-setup-hook
-                          (lambda () (setq default-directory dir))
+                          (lambda ()
+                           (setq default-directory dir)
+                           ;; When the first default in `minibuffer-default'
+                           ;; duplicates initial input `insdef',
+                           ;; reset `minibuffer-default' to nil.
+                           (when (equal (or (car-safe insdef) insdef)
+                                        (or (car-safe minibuffer-default)
+                                            minibuffer-default))
+                             (setq minibuffer-default
+                                   (cdr-safe minibuffer-default)))
+                           ;; On the first request on `M-n' fill
+                           ;; `minibuffer-default' with a list of defaults
+                           ;; relevant for file-name reading.
+                           (set (make-local-variable 'minibuffer-default-add-function)
+                                (lambda ()
+                                  (with-current-buffer
+                                      (window-buffer (minibuffer-selected-window))
+                                    (read-file-name-defaults dir initial)))))
                         (completing-read prompt 'read-file-name-internal
                                          pred mustmatch insdef
                                          'file-name-history default-filename)))
@@ -1506,9 +1709,10 @@ Return the new suffix."
     suffix))
 
 (defun completion-basic-try-completion (string table pred point)
-  (let* ((beforepoint (substring string 0 point))
-         (afterpoint (substring string point))
-         (bounds (completion-boundaries beforepoint table pred afterpoint)))
+  (lexical-let*
+      ((beforepoint (substring string 0 point))
+       (afterpoint (substring string point))
+       (bounds (completion-boundaries beforepoint table pred afterpoint)))
     (if (zerop (cdr bounds))
         ;; `try-completion' may return a subtly different result
         ;; than `all+merge', so try to use it whenever possible.
@@ -1519,28 +1723,30 @@ Return the new suffix."
              (concat completion
                      (completion--merge-suffix completion point afterpoint))
              (length completion))))
-      (let* ((suffix (substring afterpoint (cdr bounds)))
-             (prefix (substring beforepoint 0 (car bounds)))
-             (pattern (delete
-                       "" (list (substring beforepoint (car bounds))
-                                'point
-                                (substring afterpoint 0 (cdr bounds)))))
-             (all (completion-pcm--all-completions prefix pattern table pred)))
+      (lexical-let*
+         ((suffix (substring afterpoint (cdr bounds)))
+          (prefix (substring beforepoint 0 (car bounds)))
+          (pattern (delete
+                    "" (list (substring beforepoint (car bounds))
+                             'point
+                             (substring afterpoint 0 (cdr bounds)))))
+          (all (completion-pcm--all-completions prefix pattern table pred)))
         (if minibuffer-completing-file-name
             (setq all (completion-pcm--filename-try-filter all)))
         (completion-pcm--merge-try pattern all prefix suffix)))))
 
 (defun completion-basic-all-completions (string table pred point)
-  (let* ((beforepoint (substring string 0 point))
-         (afterpoint (substring string point))
-         (bounds (completion-boundaries beforepoint table pred afterpoint))
-         (suffix (substring afterpoint (cdr bounds)))
-         (prefix (substring beforepoint 0 (car bounds)))
-         (pattern (delete
-                   "" (list (substring beforepoint (car bounds))
-                            'point
-                            (substring afterpoint 0 (cdr bounds)))))
-         (all (completion-pcm--all-completions prefix pattern table pred)))
+  (lexical-let*
+      ((beforepoint (substring string 0 point))
+       (afterpoint (substring string point))
+       (bounds (completion-boundaries beforepoint table pred afterpoint))
+       (suffix (substring afterpoint (cdr bounds)))
+       (prefix (substring beforepoint 0 (car bounds)))
+       (pattern (delete
+                "" (list (substring beforepoint (car bounds))
+                         'point
+                         (substring afterpoint 0 (cdr bounds)))))
+       (all (completion-pcm--all-completions prefix pattern table pred)))
     (completion-hilit-commonality all point (car bounds))))
 
 ;;; Partial-completion-mode style completion.
@@ -1556,7 +1762,7 @@ from lowercase to uppercase characters).")
 (defun completion-pcm--prepare-delim-re (delims)
   (setq completion-pcm--delim-wild-regex (concat "[" delims "*]")))
 
-(defcustom completion-pcm-word-delimiters "-_. "
+(defcustom completion-pcm-word-delimiters "-_./: "
   "A string of characters treated as word delimiters for completion.
 Some arcane rules:
 If `]' is in this string, it must come first.
@@ -1671,7 +1877,6 @@ PATTERN is as returned by `completion-pcm--string->pattern'."
   (when completions
     (let* ((re (completion-pcm--pattern->regex pattern '(point)))
            (case-fold-search completion-ignore-case))
-      ;; Remove base-size during mapcar, and add it back later.
       (mapcar
        (lambda (str)
         ;; Don't modify the string itself.
@@ -1696,12 +1901,13 @@ POINT is a position inside STRING.
 FILTER is a function applied to the return value, that can be used, e.g. to
 filter out additional entries (because TABLE migth not obey PRED)."
   (unless filter (setq filter 'identity))
-  (let* ((beforepoint (substring string 0 point))
-         (afterpoint (substring string point))
-         (bounds (completion-boundaries beforepoint table pred afterpoint))
-         (prefix (substring beforepoint 0 (car bounds)))
-         (suffix (substring afterpoint (cdr bounds)))
-         firsterror)
+  (lexical-let*
+      ((beforepoint (substring string 0 point))
+       (afterpoint (substring string point))
+       (bounds (completion-boundaries beforepoint table pred afterpoint))
+       (prefix (substring beforepoint 0 (car bounds)))
+       (suffix (substring afterpoint (cdr bounds)))
+       firsterror)
     (setq string (substring string (car bounds) (+ point (cdr bounds))))
     (let* ((relpoint (- point (car bounds)))
            (pattern (completion-pcm--string->pattern string relpoint))
@@ -1897,7 +2103,9 @@ filter out additional entries (because TABLE migth not obey PRED)."
             ;; order of preference) either at the old point, or at
             ;; the last place where there's something to choose, or
             ;; at the very end.
-             (pointpat (or (memq 'point mergedpat) (memq 'any mergedpat)
+             (pointpat (or (memq 'point mergedpat)
+                           (memq 'any   mergedpat)
+                           (memq 'star  mergedpat)
                           mergedpat))
              ;; New pos from the start.
              (newpos (length (completion-pcm--pattern->string pointpat)))
@@ -1919,9 +2127,12 @@ filter out additional entries (because TABLE migth not obey PRED)."
 ;; Complete /ums to /usr/monnier/src or lch to list-command-history.
 
 (defun completion-initials-expand (str table pred)
-  (unless (or (zerop (length str))
-              (string-match completion-pcm--delim-wild-regex str))
-    (let ((bounds (completion-boundaries str table pred "")))
+  (let ((bounds (completion-boundaries str table pred "")))
+    (unless (or (zerop (length str))
+                ;; Only check within the boundaries, since the
+                ;; boundary char (e.g. /) might be in delim-regexp.
+                (string-match completion-pcm--delim-wild-regex str
+                              (car bounds)))
       (if (zerop (car bounds))
           (mapconcat 'string str "-")
         ;; If there's a boundary, it's trickier.  The main use-case
@@ -1953,6 +2164,17 @@ filter out additional entries (because TABLE migth not obey PRED)."
     (when newstr
       (completion-pcm-try-completion newstr table pred (length newstr)))))
 
+\f
+;; Miscellaneous
+
+(defun minibuffer-insert-file-name-at-point ()
+  "Get a file name at point in original buffer and insert it to minibuffer."
+  (interactive)
+  (let ((file-name-at-point
+        (with-current-buffer (window-buffer (minibuffer-selected-window))
+          (run-hook-with-args-until-success 'file-name-at-point-functions))))
+    (when file-name-at-point
+      (insert file-name-at-point))))
 
 (provide 'minibuffer)