aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2012-11-08 10:10:08 -0500
committerStefan Monnier2012-11-08 10:10:08 -0500
commit3b11e6ac60fa5c99b97fca3e588947e0b137a250 (patch)
tree5f7204f5c1736ed5036c115615ec3b9d9183b2c3
parente703069f9c23dd94b65e1d81ce57758c7f905bb2 (diff)
downloademacs-3b11e6ac60fa5c99b97fca3e588947e0b137a250.tar.gz
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.
-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 @@
12012-11-08 Stefan Monnier <monnier@iro.umontreal.ca> 12012-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3 * env.el (env--substitute-vars-regexp): New const.
4 (substitute-env-vars): Use it. Add `only-defined' arg.
5 * net/tramp.el (tramp-replace-environment-variables): Use it.
6
3 * emacs-lisp/bytecomp.el (byte-compile-initial-macro-environment): 7 * emacs-lisp/bytecomp.el (byte-compile-initial-macro-environment):
4 Byte-compile *before* eval in eval-and-compile. 8 Byte-compile *before* eval in eval-and-compile.
5 (byte-compile-log-warning): Remove redundant inhibit-read-only. 9 (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."
57;; History list for VALUE argument to setenv. 57;; History list for VALUE argument to setenv.
58(defvar setenv-history nil) 58(defvar setenv-history nil)
59 59
60(defconst env--substitute-vars-regexp
61 (rx "$"
62 (or (submatch-n 1 (1+ (regexp "[[:alnum:]_]")))
63 (and "{" (submatch-n 1 (minimal-match (0+ anything))) "}")
64 "$")))
60 65
61(defun substitute-env-vars (string) 66(defun substitute-env-vars (string &optional only-defined)
62 "Substitute environment variables referred to in STRING. 67 "Substitute environment variables referred to in STRING.
63`$FOO' where FOO is an environment variable name means to substitute 68`$FOO' where FOO is an environment variable name means to substitute
64the value of that variable. The variable name should be terminated 69the value of that variable. The variable name should be terminated
65with a character not a letter, digit or underscore; otherwise, enclose 70with a character not a letter, digit or underscore; otherwise, enclose
66the entire variable name in braces. For instance, in `ab$cd-x', 71the entire variable name in braces. For instance, in `ab$cd-x',
67`$cd' is treated as an environment variable. 72`$cd' is treated as an environment variable.
73If ONLY-DEFINED is nil, references to undefined environment variables
74are replaced by the empty string; if it is non-nil, they are left unchanged.
68 75
69Use `$$' to insert a single dollar sign." 76Use `$$' to insert a single dollar sign."
70 (let ((start 0)) 77 (let ((start 0))
71 (while (string-match 78 (while (string-match env--substitute-vars-regexp string start)
72 (eval-when-compile
73 (rx (or (and "$" (submatch (1+ (regexp "[[:alnum:]_]"))))
74 (and "${" (submatch (minimal-match (0+ anything))) "}")
75 "$$")))
76 string start)
77 (cond ((match-beginning 1) 79 (cond ((match-beginning 1)
78 (let ((value (getenv (match-string 1 string)))) 80 (let ((value (getenv (match-string 1 string))))
81 (if (and (null value) only-defined)
82 (setq start (match-end 0))
79 (setq string (replace-match (or value "") t t string) 83 (setq string (replace-match (or value "") t t string)
80 start (+ (match-beginning 0) (length value))))) 84 start (+ (match-beginning 0) (length value))))))
81 ((match-beginning 2)
82 (let ((value (getenv (match-string 2 string))))
83 (setq string (replace-match (or value "") t t string)
84 start (+ (match-beginning 0) (length value)))))
85 (t 85 (t
86 (setq string (replace-match "$" t t string) 86 (setq string (replace-match "$" t t string)
87 start (+ (match-beginning 0) 1))))) 87 start (+ (match-beginning 0) 1)))))
@@ -185,7 +185,7 @@ VARIABLE should be a string. Value is nil if VARIABLE is undefined in
185the environment. Otherwise, value is a string. 185the environment. Otherwise, value is a string.
186 186
187If optional parameter FRAME is non-nil, then it should be a 187If optional parameter FRAME is non-nil, then it should be a
188frame. This function will look up VARIABLE in its 'environment 188frame. This function will look up VARIABLE in its `environment'
189parameter. 189parameter.
190 190
191Otherwise, this function searches `process-environment' for 191Otherwise, 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 @@
51 51
52;;; Todo: 52;;; Todo:
53 53
54;; - Make *Completions* readable even if some of the completion
55;; entries have LF chars or spaces in them (including at
56;; beginning/end) or are very long.
54;; - for M-x, cycle-sort commands that have no key binding first. 57;; - for M-x, cycle-sort commands that have no key binding first.
55;; - Make things like icomplete-mode or lightning-completion work with 58;; - Make things like icomplete-mode or lightning-completion work with
56;; completion-in-region-mode. 59;; completion-in-region-mode.
@@ -74,6 +77,9 @@
74;; - whether the user wants completion to pay attention to case. 77;; - whether the user wants completion to pay attention to case.
75;; e.g. we may want to make it possible for the user to say "first try 78;; e.g. we may want to make it possible for the user to say "first try
76;; completion case-sensitively, and if that fails, try to ignore case". 79;; completion case-sensitively, and if that fails, try to ignore case".
80;; Maybe the trick is that we should distinguish completion-ignore-case in
81;; try/all-completions (obey user's preference) from its use in
82;; test-completion (obey the underlying object's semantics).
77 83
78;; - add support for ** to pcm. 84;; - add support for ** to pcm.
79;; - Add vc-file-name-completion-table to read-file-name-internal. 85;; - 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.")
2048 process-environment)) 2054 process-environment))
2049 2055
2050(defconst completion--embedded-envvar-re 2056(defconst completion--embedded-envvar-re
2057 ;; We can't reuse env--substitute-vars-regexp because we need to match only
2058 ;; potentially-unfinished envvars at end of string.
2051 (concat "\\(?:^\\|[^$]\\(?:\\$\\$\\)*\\)" 2059 (concat "\\(?:^\\|[^$]\\(?:\\$\\$\\)*\\)"
2052 "$\\([[:alnum:]_]*\\|{\\([^}]*\\)\\)\\'")) 2060 "$\\([[:alnum:]_]*\\|{\\([^}]*\\)\\)\\'"))
2053 2061
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."
1748 (or (file-modes filename) 1748 (or (file-modes filename)
1749 (logand (default-file-modes) (tramp-compat-octal-to-decimal "0666")))) 1749 (logand (default-file-modes) (tramp-compat-octal-to-decimal "0666"))))
1750 1750
1751(defun tramp-replace-environment-variables (filename) 1751(defalias 'tramp-replace-environment-variables
1752 "Replace environment variables in FILENAME. 1752 (if (ignore-errors
1753 (equal "${ tramp?}" (substitute-env-vars "${ tramp?}" 'only-defined)))
1754 (lambda (filename)
1755 "Like `substitute-env-vars' with `only-defined' non-nil."
1756 (substitute-env-vars filename 'only-defined))
1757 (lambda (filename)
1758 "Replace environment variables in FILENAME.
1753Return the string with the replaced variables." 1759Return the string with the replaced variables."
1754 (save-match-data 1760 (save-match-data
1755 (let ((idx (string-match "$\\(\\w+\\)" filename))) 1761 (let ((idx (string-match "$\\(\\w+\\)" filename)))
1756 ;; `$' is coded as `$$'. 1762 ;; `$' is coded as `$$'.
1757 (when (and idx 1763 (when (and idx
1758 (or (zerop idx) (not (eq ?$ (aref filename (1- idx))))) 1764 (or (zerop idx) (not (eq ?$ (aref filename (1- idx)))))
1759 (getenv (match-string 1 filename))) 1765 (getenv (match-string 1 filename)))
1760 (setq filename 1766 (setq filename
1761 (replace-match 1767 (replace-match
1762 (substitute-in-file-name (match-string 0 filename)) 1768 (substitute-in-file-name (match-string 0 filename))
1763 t nil filename))) 1769 t nil filename)))
1764 filename))) 1770 filename)))))
1765 1771
1766;; In XEmacs, electricity is implemented via a key map for ?/ and ?~, 1772;; In XEmacs, electricity is implemented via a key map for ?/ and ?~,
1767;; which calls corresponding functions (see minibuf.el). 1773;; which calls corresponding functions (see minibuf.el).