diff options
| author | Karoly Lorentey | 2005-12-29 01:28:33 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2005-12-29 01:28:33 +0000 |
| commit | 5990851d423fbd407f2d8cb4eb09b1fdc0b3c44e (patch) | |
| tree | 3576481025a018195a655faa39652bc57f3f2f04 /lisp | |
| parent | b2a300dc19a9449c4b8b0138937193ac36b39b1c (diff) | |
| download | emacs-5990851d423fbd407f2d8cb4eb09b1fdc0b3c44e.tar.gz emacs-5990851d423fbd407f2d8cb4eb09b1fdc0b3c44e.zip | |
Fix semantics of let-binding `process-environment'.
* lisp/env.el: Require cl for byte compilation. (For `block' and `return'.)
(read-envvar-name): Update for rename. Include `process-environment'
as well.
(setenv): Update for rename also handle `process-environment'. Update doc.
(getenv): Update doc.
(environment): New function.
(let-environment): New macro.
* lisp/font-lock.el (lisp-font-lock-keywords-2): Add `let-environment'.
* src/callproc.c (Vglobal_environment): New variable, taking over the
previous role of `Vprocess_environment', which is now something else.
(add_env): New function.
(child_setup): Use it.
(child_setup, getenv_internal): Rename Vprocess_environment to
Vglobal_environment. Handle the new Vprocess_environment.
(Fgetenv_internal, egetenv): Update doc.
(set_process_environment): Rename to `set_global_environment'. Rename
Vprocess_environment to Vglobal_environment.
(syms_of_callproc): Rename process-environment to global-environment,
add new process-environment, update docs.
* src/emacs.c (main): Call set_global_environment instead of
set_process_environment.
* fileio.c (Fread_file_name): Update comment.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-465
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/env.el | 191 | ||||
| -rw-r--r-- | lisp/font-lock.el | 2 |
2 files changed, 149 insertions, 44 deletions
diff --git a/lisp/env.el b/lisp/env.el index 378b7f078be..7099a72ca2c 100644 --- a/lisp/env.el +++ b/lisp/env.el | |||
| @@ -36,6 +36,8 @@ | |||
| 36 | 36 | ||
| 37 | ;;; Code: | 37 | ;;; Code: |
| 38 | 38 | ||
| 39 | (eval-when-compile (require 'cl)) | ||
| 40 | |||
| 39 | ;; History list for environment variable names. | 41 | ;; History list for environment variable names. |
| 40 | (defvar read-envvar-name-history nil) | 42 | (defvar read-envvar-name-history nil) |
| 41 | 43 | ||
| @@ -52,8 +54,9 @@ If it is also not t, RET does not exit if it does non-null completion." | |||
| 52 | locale-coding-system t) | 54 | locale-coding-system t) |
| 53 | (substring enventry 0 | 55 | (substring enventry 0 |
| 54 | (string-match "=" enventry))))) | 56 | (string-match "=" enventry))))) |
| 55 | (append (terminal-parameter nil 'environment) | 57 | (append process-environment |
| 56 | process-environment)) | 58 | (terminal-parameter nil 'environment) |
| 59 | global-environment)) | ||
| 57 | nil mustmatch nil 'read-envvar-name-history)) | 60 | nil mustmatch nil 'read-envvar-name-history)) |
| 58 | 61 | ||
| 59 | ;; History list for VALUE argument to setenv. | 62 | ;; History list for VALUE argument to setenv. |
| @@ -89,7 +92,7 @@ Use `$$' to insert a single dollar sign." | |||
| 89 | start (+ (match-beginning 0) 1))))) | 92 | start (+ (match-beginning 0) 1))))) |
| 90 | string)) | 93 | string)) |
| 91 | 94 | ||
| 92 | ;; Fixme: Should `process-environment' be recoded if LC_CTYPE &c is set? | 95 | ;; Fixme: Should the environment be recoded if LC_CTYPE &c is set? |
| 93 | 96 | ||
| 94 | (defun setenv (variable &optional value unset substitute-env-vars terminal) | 97 | (defun setenv (variable &optional value unset substitute-env-vars terminal) |
| 95 | "Set the value of the environment variable named VARIABLE to VALUE. | 98 | "Set the value of the environment variable named VARIABLE to VALUE. |
| @@ -106,15 +109,16 @@ Interactively, the current value (if any) of the variable | |||
| 106 | appears at the front of the history list when you type in the new value. | 109 | appears at the front of the history list when you type in the new value. |
| 107 | Interactively, always replace environment variables in the new value. | 110 | Interactively, always replace environment variables in the new value. |
| 108 | 111 | ||
| 112 | If VARIABLE is set in `process-environment', then this function | ||
| 113 | modifies its value there. Otherwise, this function works by | ||
| 114 | modifying either `global-environment' or the environment | ||
| 115 | belonging to the terminal device of the selected frame, depending | ||
| 116 | on the value of `local-environment-variables'. | ||
| 117 | |||
| 109 | If optional parameter TERMINAL is non-nil, then it should be a | 118 | If optional parameter TERMINAL is non-nil, then it should be a |
| 110 | terminal id or a frame. If the specified terminal device has its own | 119 | terminal id or a frame. If the specified terminal device has its own |
| 111 | set of environment variables, this function will modify VAR in it. | 120 | set of environment variables, this function will modify VAR in it. |
| 112 | 121 | ||
| 113 | Otherwise, this function works by modifying either | ||
| 114 | `process-environment' or the environment belonging to the | ||
| 115 | terminal device of the selected frame, depending on the value of | ||
| 116 | `local-environment-variables'. | ||
| 117 | |||
| 118 | As a special case, setting variable `TZ' calls `set-time-zone-rule' as | 122 | As a special case, setting variable `TZ' calls `set-time-zone-rule' as |
| 119 | a side-effect." | 123 | a side-effect." |
| 120 | (interactive | 124 | (interactive |
| @@ -147,41 +151,55 @@ a side-effect." | |||
| 147 | (setq value (encode-coding-string value locale-coding-system))) | 151 | (setq value (encode-coding-string value locale-coding-system))) |
| 148 | (if (string-match "=" variable) | 152 | (if (string-match "=" variable) |
| 149 | (error "Environment variable name `%s' contains `='" variable)) | 153 | (error "Environment variable name `%s' contains `='" variable)) |
| 150 | (let* ((pattern (concat "\\`" (regexp-quote (concat variable "=")))) | 154 | (let ((pattern (concat "\\`" (regexp-quote variable) "\\(=\\|\\'\\)")) |
| 151 | (case-fold-search nil) | 155 | (case-fold-search nil) |
| 152 | (local-var-p (and (terminal-parameter terminal 'environment) | 156 | (terminal-env (terminal-parameter terminal 'environment)) |
| 153 | (or terminal | 157 | (scan process-environment) |
| 154 | (eq t local-environment-variables) | 158 | found) |
| 155 | (member variable local-environment-variables)))) | ||
| 156 | (scan (if local-var-p | ||
| 157 | (terminal-parameter terminal 'environment) | ||
| 158 | process-environment)) | ||
| 159 | found) | ||
| 160 | (if (string-equal "TZ" variable) | 159 | (if (string-equal "TZ" variable) |
| 161 | (set-time-zone-rule value)) | 160 | (set-time-zone-rule value)) |
| 162 | (while scan | 161 | (block nil |
| 163 | (cond ((string-match pattern (car scan)) | 162 | ;; Look for an existing entry for VARIABLE; try `process-environment' first. |
| 164 | (setq found t) | 163 | (while (and scan (stringp (car scan))) |
| 165 | (if (eq nil value) | 164 | (when (string-match pattern (car scan)) |
| 166 | (if local-var-p | 165 | (if value |
| 167 | (set-terminal-parameter terminal 'environment | 166 | (setcar scan (concat variable "=" value)) |
| 168 | (delq (car scan) | 167 | ;; Leave unset variables in `process-environment', |
| 169 | (terminal-parameter terminal 'environment))) | 168 | ;; otherwise the overridden value in `global-environment' |
| 170 | (setq process-environment (delq (car scan) | 169 | ;; or terminal-env would become unmasked. |
| 171 | process-environment))) | 170 | (setcar scan variable)) |
| 172 | (setcar scan (concat variable "=" value))) | 171 | (return value)) |
| 173 | (setq scan nil))) | 172 | (setq scan (cdr scan))) |
| 174 | (setq scan (cdr scan))) | 173 | |
| 175 | (or found | 174 | ;; Look in the local or global environment, whichever is relevant. |
| 175 | (let ((local-var-p (and terminal-env | ||
| 176 | (or terminal | ||
| 177 | (eq t local-environment-variables) | ||
| 178 | (member variable local-environment-variables))))) | ||
| 179 | (setq scan (if local-var-p | ||
| 180 | terminal-env | ||
| 181 | global-environment)) | ||
| 182 | (while scan | ||
| 183 | (when (string-match pattern (car scan)) | ||
| 184 | (if value | ||
| 185 | (setcar scan (concat variable "=" value)) | ||
| 186 | (if local-var-p | ||
| 187 | (set-terminal-parameter terminal 'environment | ||
| 188 | (delq (car scan) terminal-env)) | ||
| 189 | (setq global-environment (delq (car scan) global-environment))) | ||
| 190 | (return value))) | ||
| 191 | (setq scan (cdr scan))) | ||
| 192 | |||
| 193 | ;; VARIABLE is not in any environment list. | ||
| 176 | (if value | 194 | (if value |
| 177 | (if local-var-p | 195 | (if local-var-p |
| 178 | (set-terminal-parameter nil 'environment | 196 | (set-terminal-parameter nil 'environment |
| 179 | (cons (concat variable "=" value) | 197 | (cons (concat variable "=" value) |
| 180 | (terminal-parameter nil 'environment))) | 198 | terminal-env)) |
| 181 | (setq process-environment | 199 | (setq global-environment |
| 182 | (cons (concat variable "=" value) | 200 | (cons (concat variable "=" value) |
| 183 | process-environment)))))) | 201 | global-environment)))) |
| 184 | value) | 202 | (return value))))) |
| 185 | 203 | ||
| 186 | (defun getenv (variable &optional terminal) | 204 | (defun getenv (variable &optional terminal) |
| 187 | "Get the value of environment variable VARIABLE. | 205 | "Get the value of environment variable VARIABLE. |
| @@ -190,14 +208,14 @@ the environment. Otherwise, value is a string. | |||
| 190 | 208 | ||
| 191 | If optional parameter TERMINAL is non-nil, then it should be a | 209 | If optional parameter TERMINAL is non-nil, then it should be a |
| 192 | terminal id or a frame. If the specified terminal device has its own | 210 | terminal id or a frame. If the specified terminal device has its own |
| 193 | set of environment variables, this function will look up VAR in it. | 211 | set of environment variables, this function will look up VARIABLE in |
| 194 | 212 | it. | |
| 195 | Otherwise, if `local-environment-variables' specifies that VAR is a | ||
| 196 | local environment variable, then this function consults the | ||
| 197 | environment variables belonging to the terminal device of the selected | ||
| 198 | frame. | ||
| 199 | 213 | ||
| 200 | Otherwise, the value of VAR will come from `process-environment'." | 214 | Otherwise, this function searches `process-environment' for VARIABLE. |
| 215 | If it was not found there, then it continues the search in either | ||
| 216 | `global-environment' or the local environment list of the current | ||
| 217 | terminal device, depending on the value of | ||
| 218 | `local-environment-variables'." | ||
| 201 | (interactive (list (read-envvar-name "Get environment variable: " t))) | 219 | (interactive (list (read-envvar-name "Get environment variable: " t))) |
| 202 | (let ((value (getenv-internal (if (multibyte-string-p variable) | 220 | (let ((value (getenv-internal (if (multibyte-string-p variable) |
| 203 | (encode-coding-string | 221 | (encode-coding-string |
| @@ -209,6 +227,93 @@ Otherwise, the value of VAR will come from `process-environment'." | |||
| 209 | (message "%s" (if value value "Not set"))) | 227 | (message "%s" (if value value "Not set"))) |
| 210 | value)) | 228 | value)) |
| 211 | 229 | ||
| 230 | (defun environment () | ||
| 231 | "Return a list of environment variables with their values. | ||
| 232 | Each entry in the list is a string of the form NAME=VALUE. | ||
| 233 | |||
| 234 | The returned list can not be used to change environment | ||
| 235 | variables, only read them. See `setenv' to do that. | ||
| 236 | |||
| 237 | The list is constructed from elements of `process-environment', | ||
| 238 | `global-environment' and the local environment list of the | ||
| 239 | current terminal, as specified by `local-environment-variables'. | ||
| 240 | |||
| 241 | Non-ASCII characters are encoded according to the initial value of | ||
| 242 | `locale-coding-system', i.e. the elements must normally be decoded for use. | ||
| 243 | See `setenv' and `getenv'." | ||
| 244 | (let ((env (cond ((or (not local-environment-variables) | ||
| 245 | (not (terminal-parameter nil 'environment))) | ||
| 246 | (append process-environment global-environment nil)) | ||
| 247 | ((consp local-environment-variables) | ||
| 248 | (let ((e (reverse process-environment))) | ||
| 249 | (dolist (entry local-environment-variables) | ||
| 250 | (setq e (cons (getenv entry) e))) | ||
| 251 | (append (nreverse e) global-environment nil))) | ||
| 252 | (t | ||
| 253 | (append process-environment (terminal-parameter nil 'environment) nil)))) | ||
| 254 | scan seen) | ||
| 255 | ;; Find the first valid entry in env. | ||
| 256 | (while (and env (stringp (car env)) | ||
| 257 | (or (not (string-match "=" (car env))) | ||
| 258 | (member (substring (car env) 0 (string-match "=" (car env))) seen))) | ||
| 259 | (setq seen (cons (car env) seen) | ||
| 260 | env (cdr env))) | ||
| 261 | (setq scan env) | ||
| 262 | (while (and (cdr scan) (stringp (cadr scan))) | ||
| 263 | (let* ((match (string-match "=" (cadr scan))) | ||
| 264 | (name (substring (cadr scan) 0 match))) | ||
| 265 | (cond ((not match) | ||
| 266 | ;; Unset variable. | ||
| 267 | (setq seen (cons name seen)) | ||
| 268 | (setcdr scan (cddr scan))) | ||
| 269 | ((member name seen) | ||
| 270 | ;; Duplicate variable. | ||
| 271 | (setcdr scan (cddr scan))) | ||
| 272 | (t | ||
| 273 | ;; New variable. | ||
| 274 | (setq seen (cons name seen) | ||
| 275 | scan (cdr scan)))))) | ||
| 276 | env)) | ||
| 277 | |||
| 278 | (defmacro let-environment (varlist &rest body) | ||
| 279 | "Evaluate BODY with environment variables set according to VARLIST. | ||
| 280 | The environment variables are then restored to their previous | ||
| 281 | values. | ||
| 282 | The value of the last form in BODY is returned. | ||
| 283 | |||
| 284 | Each element of VARLIST is either a string (which variable is | ||
| 285 | then removed from the environment), or a list (NAME | ||
| 286 | VALUEFORM) (which sets NAME to the value of VALUEFORM, a string). | ||
| 287 | All the VALUEFORMs are evaluated before any variables are set." | ||
| 288 | (declare (indent 2)) | ||
| 289 | (let ((old-env (make-symbol "old-env")) | ||
| 290 | (name (make-symbol "name")) | ||
| 291 | (value (make-symbol "value")) | ||
| 292 | (entry (make-symbol "entry")) | ||
| 293 | (frame (make-symbol "frame"))) | ||
| 294 | `(let ((,frame (selected-frame)) | ||
| 295 | ,old-env) | ||
| 296 | ;; Evaluate VALUEFORMs and replace them in VARLIST with their values. | ||
| 297 | (dolist (,entry ,varlist) | ||
| 298 | (unless (stringp ,entry) | ||
| 299 | (if (cdr (cdr ,entry)) | ||
| 300 | (error "`let-environment' bindings can have only one value-form")) | ||
| 301 | (setcdr ,entry (eval (cadr ,entry))))) | ||
| 302 | ;; Set the variables. | ||
| 303 | (dolist (,entry ,varlist) | ||
| 304 | (let ((,name (if (stringp ,entry) ,entry (car ,entry))) | ||
| 305 | (,value (if (consp ,entry) (cdr ,entry)))) | ||
| 306 | (setq ,old-env (cons (cons ,name (getenv ,name)) ,old-env)) | ||
| 307 | (setenv ,name ,value))) | ||
| 308 | (unwind-protect | ||
| 309 | (progn ,@body) | ||
| 310 | ;; Restore old values. | ||
| 311 | (with-selected-frame (if (frame-live-p ,frame) | ||
| 312 | ,frame | ||
| 313 | (selected-frame)) | ||
| 314 | (dolist (,entry ,old-env) | ||
| 315 | (setenv (car ,entry) (cdr ,entry)))))))) | ||
| 316 | |||
| 212 | (provide 'env) | 317 | (provide 'env) |
| 213 | 318 | ||
| 214 | ;;; arch-tag: b7d6a8f7-bc81-46db-8e39-8d721d4ed0b8 | 319 | ;;; arch-tag: b7d6a8f7-bc81-46db-8e39-8d721d4ed0b8 |
diff --git a/lisp/font-lock.el b/lisp/font-lock.el index 45feee19744..49e576e59db 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el | |||
| @@ -1996,7 +1996,7 @@ This function could be MATCHER in a MATCH-ANCHORED `font-lock-keywords' item." | |||
| 1996 | `(;; Control structures. Emacs Lisp forms. | 1996 | `(;; Control structures. Emacs Lisp forms. |
| 1997 | (,(concat | 1997 | (,(concat |
| 1998 | "(" (regexp-opt | 1998 | "(" (regexp-opt |
| 1999 | '("cond" "if" "while" "while-no-input" "let" "let*" | 1999 | '("cond" "if" "while" "while-no-input" "let" "let*" "let-environment" |
| 2000 | "prog" "progn" "progv" "prog1" "prog2" "prog*" | 2000 | "prog" "progn" "progv" "prog1" "prog2" "prog*" |
| 2001 | "inline" "lambda" "save-restriction" "save-excursion" | 2001 | "inline" "lambda" "save-restriction" "save-excursion" |
| 2002 | "save-window-excursion" "save-selected-window" | 2002 | "save-window-excursion" "save-selected-window" |