aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp')
-rw-r--r--lisp/env.el193
-rw-r--r--lisp/frame.el3
2 files changed, 91 insertions, 105 deletions
diff --git a/lisp/env.el b/lisp/env.el
index d0c2208fc6f..96ff1f37c3a 100644
--- a/lisp/env.el
+++ b/lisp/env.el
@@ -55,8 +55,7 @@ If it is also not t, RET does not exit if it does non-null completion."
55 (substring enventry 0 55 (substring enventry 0
56 (string-match "=" enventry))))) 56 (string-match "=" enventry)))))
57 (append process-environment 57 (append process-environment
58 (frame-parameter (frame-with-environment) 'environment) 58 (frame-parameter (frame-with-environment) 'environment)))
59 global-environment))
60 nil mustmatch nil 'read-envvar-name-history)) 59 nil mustmatch nil 'read-envvar-name-history))
61 60
62;; History list for VALUE argument to setenv. 61;; History list for VALUE argument to setenv.
@@ -92,6 +91,40 @@ Use `$$' to insert a single dollar sign."
92 start (+ (match-beginning 0) 1))))) 91 start (+ (match-beginning 0) 1)))))
93 string)) 92 string))
94 93
94
95(defun setenv-internal (env variable value keep-empty)
96 "Set VARIABLE to VALUE in ENV, adding empty entries if KEEP-EMPTY.
97Changes ENV by side-effect, and returns its new value."
98 (let ((pattern (concat "\\`" (regexp-quote variable) "\\(=\\|\\'\\)"))
99 (case-fold-search nil)
100 (scan env)
101 prev found)
102 ;; Handle deletions from the beginning of the list specially.
103 (if (and (null value)
104 (not keep-empty)
105 env
106 (stringp (car env))
107 (string-match pattern (car env)))
108 (cdr env)
109 ;; Try to find existing entry for VARIABLE in ENV.
110 (while (and scan (stringp (car scan)))
111 (when (string-match pattern (car scan))
112 (if value
113 (setcar scan (concat variable "=" value))
114 (if keep-empty
115 (setcar scan variable)
116 (setcdr prev (cdr scan))))
117 (setq found t
118 scan nil))
119 (setq prev scan
120 scan (cdr scan)))
121 (if (and (not found) (or value keep-empty))
122 (cons (if value
123 (concat variable "=" value)
124 variable)
125 env)
126 env))))
127
95;; Fixme: Should the environment be recoded if LC_CTYPE &c is set? 128;; Fixme: Should the environment be recoded if LC_CTYPE &c is set?
96 129
97(defun setenv (variable &optional value substitute-env-vars frame) 130(defun setenv (variable &optional value substitute-env-vars frame)
@@ -105,26 +138,23 @@ the front of the history list when you type in the new value.
105This function always replaces environment variables in the new 138This function always replaces environment variables in the new
106value when called interactively. 139value when called interactively.
107 140
108If VARIABLE is set in `process-environment', then this function
109modifies its value there. Otherwise, this function works by
110modifying either `global-environment' or the environment
111belonging to the selected frame, depending on the value of
112`local-environment-variables'.
113
114SUBSTITUTE-ENV-VARS, if non-nil, means to substitute environment 141SUBSTITUTE-ENV-VARS, if non-nil, means to substitute environment
115variables in VALUE with `substitute-env-vars', which see. 142variables in VALUE with `substitute-env-vars', which see.
116This is normally used only for interactive calls. 143This is normally used only for interactive calls.
117 144
145If optional parameter FRAME is non-nil, this function modifies
146only the frame-local value of VARIABLE on FRAME, ignoring
147`process-environment'. Note that frames on the same terminal
148device usually share their environment, so calling `setenv' on
149one of them affects the others as well.
150
151If FRAME is nil, `setenv' changes the global value of VARIABLE by
152modifying `process-environment'. Note that the global value
153overrides any frame-local values.
154
118The return value is the new value of VARIABLE, or nil if 155The return value is the new value of VARIABLE, or nil if
119it was removed from the environment. 156it was removed from the environment.
120 157
121If optional parameter FRAME is non-nil, then it should be a a
122frame. If the specified frame has its own set of environment
123variables, this function will modify VARIABLE in it. Note that
124frames on the same terminal device usually share their
125environment, so calling `setenv' on one of them affects the
126others as well.
127
128As a special case, setting variable `TZ' calls `set-time-zone-rule' as 158As a special case, setting variable `TZ' calls `set-time-zone-rule' as
129a side-effect." 159a side-effect."
130 (interactive 160 (interactive
@@ -155,57 +185,16 @@ a side-effect."
155 (setq value (encode-coding-string value locale-coding-system))) 185 (setq value (encode-coding-string value locale-coding-system)))
156 (if (string-match "=" variable) 186 (if (string-match "=" variable)
157 (error "Environment variable name `%s' contains `='" variable)) 187 (error "Environment variable name `%s' contains `='" variable))
158 (let ((pattern (concat "\\`" (regexp-quote variable) "\\(=\\|\\'\\)")) 188 (if (string-equal "TZ" variable)
159 (case-fold-search nil) 189 (set-time-zone-rule value))
160 (frame-env (frame-parameter (frame-with-environment frame) 'environment)) 190 (if (null frame)
161 (frame-forced (not frame)) 191 (setq process-environment (setenv-internal process-environment
162 (scan process-environment) 192 variable value t))
163 found)
164 (setq frame (frame-with-environment frame)) 193 (setq frame (frame-with-environment frame))
165 (if (string-equal "TZ" variable) 194 (set-frame-parameter frame 'environment
166 (set-time-zone-rule value)) 195 (setenv-internal (frame-parameter frame 'environment)
167 (block nil 196 variable value nil)))
168 ;; Look for an existing entry for VARIABLE; try `process-environment' first. 197 value)
169 (while (and scan (stringp (car scan)))
170 (when (string-match pattern (car scan))
171 (if value
172 (setcar scan (concat variable "=" value))
173 ;; Leave unset variables in `process-environment',
174 ;; otherwise the overridden value in `global-environment'
175 ;; or frame-env would become unmasked.
176 (setcar scan variable))
177 (return value))
178 (setq scan (cdr scan)))
179
180 ;; Look in the local or global environment, whichever is relevant.
181 (let ((local-var-p (and frame-env
182 (or frame-forced
183 (eq t local-environment-variables)
184 (member variable local-environment-variables)))))
185 (setq scan (if local-var-p
186 frame-env
187 global-environment))
188 (while scan
189 (when (string-match pattern (car scan))
190 (if value
191 (setcar scan (concat variable "=" value))
192 (if local-var-p
193 (set-frame-parameter frame 'environment
194 (delq (car scan) frame-env))
195 (setq global-environment (delq (car scan) global-environment))))
196 (return value))
197 (setq scan (cdr scan)))
198
199 ;; VARIABLE is not in any environment list.
200 (if value
201 (if local-var-p
202 (set-frame-parameter frame 'environment
203 (cons (concat variable "=" value)
204 frame-env))
205 (setq global-environment
206 (cons (concat variable "=" value)
207 global-environment))))
208 (return value)))))
209 198
210(defun getenv (variable &optional frame) 199(defun getenv (variable &optional frame)
211 "Get the value of environment variable VARIABLE. 200 "Get the value of environment variable VARIABLE.
@@ -213,14 +202,12 @@ VARIABLE should be a string. Value is nil if VARIABLE is undefined in
213the environment. Otherwise, value is a string. 202the environment. Otherwise, value is a string.
214 203
215If optional parameter FRAME is non-nil, then it should be a 204If optional parameter FRAME is non-nil, then it should be a
216frame. If that frame has its own set of environment variables, 205frame. This function will look up VARIABLE in its 'environment
217this function will look up VARIABLE in there. 206parameter.
218 207
219Otherwise, this function searches `process-environment' for 208Otherwise, this function searches `process-environment' for
220VARIABLE. If it is not found there, then it continues the 209VARIABLE. If it is not found there, then it continues the search
221search in either `global-environment' or the environment list of 210in the environment list of the selected frame."
222the selected frame, depending on the value of
223`local-environment-variables'."
224 (interactive (list (read-envvar-name "Get environment variable: " t))) 211 (interactive (list (read-envvar-name "Get environment variable: " t)))
225 (let ((value (getenv-internal (if (multibyte-string-p variable) 212 (let ((value (getenv-internal (if (multibyte-string-p variable)
226 (encode-coding-string 213 (encode-coding-string
@@ -239,47 +226,43 @@ Each entry in the list is a string of the form NAME=VALUE.
239The returned list can not be used to change environment 226The returned list can not be used to change environment
240variables, only read them. See `setenv' to do that. 227variables, only read them. See `setenv' to do that.
241 228
242The list is constructed from elements of `process-environment', 229The list is constructed by concatenating the elements of
243`global-environment' and the local environment list of the 230`process-environment' and the 'environment parameter of the
244selected frame, as specified by `local-environment-variables'. 231selected frame, and removing duplicated and empty values.
245 232
246Non-ASCII characters are encoded according to the initial value of 233Non-ASCII characters are encoded according to the initial value of
247`locale-coding-system', i.e. the elements must normally be decoded for use. 234`locale-coding-system', i.e. the elements must normally be decoded for use.
248See `setenv' and `getenv'." 235See `setenv' and `getenv'."
249 (let ((env (let ((local-env (frame-parameter (frame-with-environment) 236 (let* ((env (append process-environment
250 'environment))) 237 (frame-parameter (frame-with-environment)
251 (cond ((or (not local-environment-variables) 238 'environment)
252 (not local-env)) 239 nil))
253 (append process-environment global-environment nil)) 240 (scan env)
254 ((consp local-environment-variables) 241 prev seen)
255 (let ((e (reverse process-environment))) 242 ;; Remove unset variables from the beginning of the list.
256 (dolist (entry local-environment-variables) 243 (while (and env
257 (setq e (cons (getenv entry) e))) 244 (or (not (stringp (car env)))
258 (append (nreverse e) global-environment nil))) 245 (not (string-match "=" (car env)))))
259 (t 246 (or (member (car env) seen)
260 (append process-environment local-env nil))))) 247 (setq seen (cons (car env) seen)))
261 scan seen) 248 (setq env (cdr env)
262 ;; Find the first valid entry in env. 249 scan env))
263 (while (and env (stringp (car env)) 250 (let (name)
264 (or (not (string-match "=" (car env))) 251 (while scan
265 (member (substring (car env) 0 (string-match "=" (car env))) seen))) 252 (cond ((or (not (stringp (car scan)))
266 (setq seen (cons (car env) seen) 253 (not (string-match "=" (car scan))))
267 env (cdr env)))
268 (setq scan env)
269 (while (and (cdr scan) (stringp (cadr scan)))
270 (let* ((match (string-match "=" (cadr scan)))
271 (name (substring (cadr scan) 0 match)))
272 (cond ((not match)
273 ;; Unset variable. 254 ;; Unset variable.
274 (setq seen (cons name seen)) 255 (or (member (car scan) seen)
275 (setcdr scan (cddr scan))) 256 (setq seen (cons (car scan) seen)))
276 ((member name seen) 257 (setcdr prev (cdr scan)))
277 ;; Duplicate variable. 258 ((member (setq name (substring (car scan) 0 (string-match "=" (car scan)))) seen)
278 (setcdr scan (cddr scan))) 259 ;; Duplicated variable.
260 (setcdr prev (cdr scan)))
279 (t 261 (t
280 ;; New variable. 262 ;; New variable.
281 (setq seen (cons name seen) 263 (setq seen (cons name seen))))
282 scan (cdr scan)))))) 264 (setq prev scan
265 scan (cdr scan))))
283 env)) 266 env))
284 267
285(defmacro let-environment (varlist &rest body) 268(defmacro let-environment (varlist &rest body)
diff --git a/lisp/frame.el b/lisp/frame.el
index 0f255ac77a1..f5d3f4b0c37 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -238,6 +238,9 @@ Pass it BUFFER as first arg, and (cdr ARGS) gives the rest of the args."
238 ;; because that would override explicit user resizing. 238 ;; because that would override explicit user resizing.
239 (setq initial-frame-alist 239 (setq initial-frame-alist
240 (frame-remove-geometry-params initial-frame-alist)))) 240 (frame-remove-geometry-params initial-frame-alist))))
241 ;; Copy the environment of the Emacs process into the new frame.
242 (set-frame-parameter frame-initial-frame 'environment
243 (frame-parameter terminal-frame 'environment))
241 ;; At this point, we know that we have a frame open, so we 244 ;; At this point, we know that we have a frame open, so we
242 ;; can delete the terminal frame. 245 ;; can delete the terminal frame.
243 (delete-frame terminal-frame) 246 (delete-frame terminal-frame)