summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2012-11-08 10:10:08 -0500
committerStefan Monnier <monnier@iro.umontreal.ca>2012-11-08 10:10:08 -0500
commit3b11e6ac60fa5c99b97fca3e588947e0b137a250 (patch)
tree5f7204f5c1736ed5036c115615ec3b9d9183b2c3 /lisp
parente703069f9c23dd94b65e1d81ce57758c7f905bb2 (diff)
downloademacs-3b11e6ac60fa5c99b97fca3e588947e0b137a250.tar.gz
emacs-3b11e6ac60fa5c99b97fca3e588947e0b137a250.tar.bz2
emacs-3b11e6ac60fa5c99b97fca3e588947e0b137a250.zip
* lisp/env.el (env--substitute-vars-regexp): New const.
(substitute-env-vars): Use it. Add `only-defined' arg. * lisp/net/tramp.el (tramp-replace-environment-variables): Use it.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog4
-rw-r--r--lisp/env.el26
-rw-r--r--lisp/minibuffer.el8
-rw-r--r--lisp/net/tramp.el32
4 files changed, 44 insertions, 26 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index e44f1a7cdff..c040c71cbd4 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,9 @@
2012-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
+ * env.el (env--substitute-vars-regexp): New const.
+ (substitute-env-vars): Use it. Add `only-defined' arg.
+ * net/tramp.el (tramp-replace-environment-variables): Use it.
+
* emacs-lisp/bytecomp.el (byte-compile-initial-macro-environment):
Byte-compile *before* eval in eval-and-compile.
(byte-compile-log-warning): Remove redundant inhibit-read-only.
diff --git a/lisp/env.el b/lisp/env.el
index d0d8ed0b998..f770dd27d75 100644
--- a/lisp/env.el
+++ b/lisp/env.el
@@ -57,31 +57,31 @@ If it is also not t, RET does not exit if it does non-null completion."
;; History list for VALUE argument to setenv.
(defvar setenv-history nil)
+(defconst env--substitute-vars-regexp
+ (rx "$"
+ (or (submatch-n 1 (1+ (regexp "[[:alnum:]_]")))
+ (and "{" (submatch-n 1 (minimal-match (0+ anything))) "}")
+ "$")))
-(defun substitute-env-vars (string)
+(defun substitute-env-vars (string &optional only-defined)
"Substitute environment variables referred to in STRING.
`$FOO' where FOO is an environment variable name means to substitute
the value of that variable. The variable name should be terminated
with a character not a letter, digit or underscore; otherwise, enclose
the entire variable name in braces. For instance, in `ab$cd-x',
`$cd' is treated as an environment variable.
+If ONLY-DEFINED is nil, references to undefined environment variables
+are replaced by the empty string; if it is non-nil, they are left unchanged.
Use `$$' to insert a single dollar sign."
(let ((start 0))
- (while (string-match
- (eval-when-compile
- (rx (or (and "$" (submatch (1+ (regexp "[[:alnum:]_]"))))
- (and "${" (submatch (minimal-match (0+ anything))) "}")
- "$$")))
- string start)
+ (while (string-match env--substitute-vars-regexp string start)
(cond ((match-beginning 1)
(let ((value (getenv (match-string 1 string))))
+ (if (and (null value) only-defined)
+ (setq start (match-end 0))
(setq string (replace-match (or value "") t t string)
- start (+ (match-beginning 0) (length value)))))
- ((match-beginning 2)
- (let ((value (getenv (match-string 2 string))))
- (setq string (replace-match (or value "") t t string)
- start (+ (match-beginning 0) (length value)))))
+ start (+ (match-beginning 0) (length value))))))
(t
(setq string (replace-match "$" t t string)
start (+ (match-beginning 0) 1)))))
@@ -185,7 +185,7 @@ VARIABLE should be a string. Value is nil if VARIABLE is undefined in
the environment. Otherwise, value is a string.
If optional parameter FRAME is non-nil, then it should be a
-frame. This function will look up VARIABLE in its 'environment
+frame. This function will look up VARIABLE in its `environment'
parameter.
Otherwise, this function searches `process-environment' for
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 38347f23f7d..6e704fad807 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.
@@ -2048,6 +2054,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:]_]*\\|{\\([^}]*\\)\\)\\'"))
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 874c0aa7fef..caaae5d553e 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -1748,20 +1748,26 @@ value of `default-file-modes', without execute permissions."
(or (file-modes filename)
(logand (default-file-modes) (tramp-compat-octal-to-decimal "0666"))))
-(defun tramp-replace-environment-variables (filename)
- "Replace environment variables in FILENAME.
+(defalias 'tramp-replace-environment-variables
+ (if (ignore-errors
+ (equal "${ tramp?}" (substitute-env-vars "${ tramp?}" 'only-defined)))
+ (lambda (filename)
+ "Like `substitute-env-vars' with `only-defined' non-nil."
+ (substitute-env-vars filename 'only-defined))
+ (lambda (filename)
+ "Replace environment variables in FILENAME.
Return the string with the replaced variables."
- (save-match-data
- (let ((idx (string-match "$\\(\\w+\\)" filename)))
- ;; `$' is coded as `$$'.
- (when (and idx
- (or (zerop idx) (not (eq ?$ (aref filename (1- idx)))))
- (getenv (match-string 1 filename)))
- (setq filename
- (replace-match
- (substitute-in-file-name (match-string 0 filename))
- t nil filename)))
- filename)))
+ (save-match-data
+ (let ((idx (string-match "$\\(\\w+\\)" filename)))
+ ;; `$' is coded as `$$'.
+ (when (and idx
+ (or (zerop idx) (not (eq ?$ (aref filename (1- idx)))))
+ (getenv (match-string 1 filename)))
+ (setq filename
+ (replace-match
+ (substitute-in-file-name (match-string 0 filename))
+ t nil filename)))
+ filename)))))
;; In XEmacs, electricity is implemented via a key map for ?/ and ?~,
;; which calls corresponding functions (see minibuf.el).