summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog3
-rw-r--r--lisp/minibuffer.el54
2 files changed, 57 insertions, 0 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 4497176527f..3e9320cfcee 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,8 @@
2008-04-10 Stefan Monnier <monnier@iro.umontreal.ca>
+ * minibuffer.el (minibuffer--double-dollars, read-file-name-internal):
+ New functions.
+
* minibuffer.el (minibuffer--do-completion): Don't forget to propagate
the arg to recursive calls.
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index dbf78e05679..98d28824adf 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -450,5 +450,59 @@ during running `completion-setup-hook'."
(ding))
(exit-minibuffer))
+(defun minibuffer--double-dollars (str)
+ (replace-regexp-in-string "\\$" "$$" str))
+
+(defun read-file-name-internal (string dir action)
+ "Internal subroutine for read-file-name. Do not call this."
+ (setq dir (expand-file-name dir))
+ (if (and (zerop (length string)) (eq 'lambda action))
+ nil ; FIXME: why?
+ (let* ((str (substitute-in-file-name string))
+ (name (file-name-nondirectory str))
+ (specdir (file-name-directory str))
+ (realdir (if specdir (expand-file-name specdir dir)
+ (file-name-as-directory dir))))
+
+ (cond
+ ((null action)
+ (let ((comp (file-name-completion name realdir
+ read-file-name-predicate)))
+ (if (stringp comp)
+ ;; Requote the $s before returning the completion.
+ (minibuffer--double-dollars (concat specdir comp))
+ ;; Requote the $s before checking for changes.
+ (setq str (minibuffer--double-dollars str))
+ (if (string-equal string str)
+ comp
+ ;; If there's no real completion, but substitute-in-file-name
+ ;; changed the string, then return the new string.
+ str))))
+
+ ((eq action t)
+ (let ((all (file-name-all-completions name realdir)))
+ (if (memq read-file-name-predicate '(nil file-exists-p))
+ all
+ (let ((comp ())
+ (pred
+ (if (eq read-file-name-predicate 'file-directory-p)
+ ;; Brute-force speed up for directory checking:
+ ;; Discard strings which don't end in a slash.
+ (lambda (s)
+ (let ((len (length s)))
+ (and (> len 0) (eq (aref s (1- len)) ?/))))
+ ;; Must do it the hard (and slow) way.
+ read-file-name-predicate)))
+ (let ((default-directory realdir))
+ (dolist (tem all)
+ (if (funcall pred tem) (push tem comp))))
+ (nreverse comp)))))
+
+ (t
+ ;; Only other case actually used is ACTION = lambda.
+ (let ((default-directory dir))
+ (funcall (or read-file-name-predicate 'file-exists-p) str)))))))
+
+
(provide 'minibuffer)
;;; minibuffer.el ends here