1 |
;;; env.el --- functions to manipulate environment variables |
;;; env.el --- functions to manipulate environment variables |
2 |
|
|
3 |
;; Copyright (C) 1991, 1994, 2000, 2001 Free Software Foundation, Inc. |
;; Copyright (C) 1991, 1994, 2000, 2001, 2003 Free Software Foundation, Inc. |
4 |
|
|
5 |
;; Maintainer: FSF |
;; Maintainer: FSF |
6 |
;; Keywords: processes, unix |
;; Keywords: processes, unix |
29 |
;; program options. This package permits you to set environment variables |
;; program options. This package permits you to set environment variables |
30 |
;; to be passed to any sub-process run under Emacs. |
;; to be passed to any sub-process run under Emacs. |
31 |
|
|
32 |
|
;; Note that the environment string `process-environment' is not |
33 |
|
;; decoded, but the args of `setenv' and `getenv' are normally |
34 |
|
;; multibyte text and get coding conversion. |
35 |
|
|
36 |
;;; Code: |
;;; Code: |
37 |
|
|
38 |
;; History list for environment variable names. |
;; History list for environment variable names. |
43 |
Optional second arg MUSTMATCH, if non-nil, means require existing envvar name. |
Optional second arg MUSTMATCH, if non-nil, means require existing envvar name. |
44 |
If it is also not t, RET does not exit if it does non-null completion." |
If it is also not t, RET does not exit if it does non-null completion." |
45 |
(completing-read prompt |
(completing-read prompt |
46 |
(mapcar (function |
(mapcar (lambda (enventry) |
47 |
(lambda (enventry) |
(list (if enable-multibyte-characters |
48 |
(list (substring enventry 0 |
(decode-coding-string |
49 |
(string-match "=" enventry))))) |
(substring enventry 0 |
50 |
|
(string-match "=" enventry)) |
51 |
|
locale-coding-system t) |
52 |
|
(substring enventry 0 |
53 |
|
(string-match "=" enventry))))) |
54 |
process-environment) |
process-environment) |
55 |
nil mustmatch nil 'read-envvar-name-history)) |
nil mustmatch nil 'read-envvar-name-history)) |
56 |
|
|
63 |
`$FOO' where FOO is an environment variable name means to substitute |
`$FOO' where FOO is an environment variable name means to substitute |
64 |
the value of that variable. The variable name should be terminated |
the value of that variable. The variable name should be terminated |
65 |
with a character not a letter, digit or underscore; otherwise, enclose |
with a character not a letter, digit or underscore; otherwise, enclose |
66 |
the entire variable name in braces. Use `$$' to insert a single |
the entire variable name in braces. Use `$$' to insert a single |
67 |
dollar sign." |
dollar sign." |
68 |
(let ((start 0)) |
(let ((start 0)) |
69 |
(while (string-match |
(while (string-match |
70 |
(rx (or (and "$" (submatch (1+ (in "a-zA-Z0-9_")))) |
(eval-when-compile |
71 |
(and "${" (submatch (minimal-match (0+ anything))) "}") |
(rx (or (and "$" (submatch (1+ (regexp "[:alnum:]_")))) |
72 |
"$$")) |
(and "${" (submatch (minimal-match (0+ anything))) "}") |
73 |
|
"$$"))) |
74 |
string start) |
string start) |
75 |
(cond ((match-beginning 1) |
(cond ((match-beginning 1) |
76 |
(let ((value (getenv (match-string 1 string)))) |
(let ((value (getenv (match-string 1 string)))) |
85 |
start (+ (match-beginning 0) 1))))) |
start (+ (match-beginning 0) 1))))) |
86 |
string)) |
string)) |
87 |
|
|
88 |
|
;; Fixme: Should `process-environment' be recoded if LC_CTYPE &c is set? |
89 |
|
|
90 |
(defun setenv (variable &optional value unset substitute-env-vars) |
(defun setenv (variable &optional value unset substitute-env-vars) |
91 |
"Set the value of the environment variable named VARIABLE to VALUE. |
"Set the value of the environment variable named VARIABLE to VALUE. |
102 |
appears at the front of the history list when you type in the new value. |
appears at the front of the history list when you type in the new value. |
103 |
Interactively, always replace environment variables in the new value. |
Interactively, always replace environment variables in the new value. |
104 |
|
|
105 |
This function works by modifying `process-environment'." |
This function works by modifying `process-environment'. |
106 |
|
|
107 |
|
As a special case, setting variable `TZ' calls `set-time-zone-rule' as |
108 |
|
a side-effect." |
109 |
(interactive |
(interactive |
110 |
(if current-prefix-arg |
(if current-prefix-arg |
111 |
(list (read-envvar-name "Clear environment variable: " 'exact) nil t) |
(list (read-envvar-name "Clear environment variable: " 'exact) nil t) |
114 |
(when value |
(when value |
115 |
(push value setenv-history)) |
(push value setenv-history)) |
116 |
;; Here finally we specify the args to give call setenv with. |
;; Here finally we specify the args to give call setenv with. |
117 |
(list var |
(list var |
118 |
(read-from-minibuffer (format "Set %s to value: " var) |
(read-from-minibuffer (format "Set %s to value: " var) |
119 |
nil nil nil 'setenv-history |
nil nil nil 'setenv-history |
120 |
value) |
value) |
121 |
nil |
nil |
122 |
t)))) |
t)))) |
123 |
|
(if (and (multibyte-string-p variable) locale-coding-system) |
124 |
|
(let ((codings (find-coding-systems-string (concat variable value)))) |
125 |
|
(unless (or (eq 'undecided (car codings)) |
126 |
|
(memq (coding-system-base locale-coding-system) codings)) |
127 |
|
(error "Can't encode `%s=%s' with `locale-coding-system'" |
128 |
|
variable (or value ""))))) |
129 |
(if unset |
(if unset |
130 |
(setq value nil) |
(setq value nil) |
131 |
(if substitute-env-vars |
(if substitute-env-vars |
132 |
(setq value (substitute-env-vars value)))) |
(setq value (substitute-env-vars value)))) |
133 |
|
(if (multibyte-string-p variable) |
134 |
|
(setq variable (encode-coding-string variable locale-coding-system))) |
135 |
|
(if (and value (multibyte-string-p value)) |
136 |
|
(setq value (encode-coding-string value locale-coding-system))) |
137 |
(if (string-match "=" variable) |
(if (string-match "=" variable) |
138 |
(error "Environment variable name `%s' contains `='" variable) |
(error "Environment variable name `%s' contains `='" variable) |
139 |
(let ((pattern (concat "\\`" (regexp-quote (concat variable "=")))) |
(let ((pattern (concat "\\`" (regexp-quote (concat variable "=")))) |
146 |
(cond ((string-match pattern (car scan)) |
(cond ((string-match pattern (car scan)) |
147 |
(setq found t) |
(setq found t) |
148 |
(if (eq nil value) |
(if (eq nil value) |
149 |
(setq process-environment (delq (car scan) process-environment)) |
(setq process-environment (delq (car scan) |
150 |
|
process-environment)) |
151 |
(setcar scan (concat variable "=" value))) |
(setcar scan (concat variable "=" value))) |
152 |
(setq scan nil))) |
(setq scan nil))) |
153 |
(setq scan (cdr scan))) |
(setq scan (cdr scan))) |
166 |
This function consults the variable `process-environment' |
This function consults the variable `process-environment' |
167 |
for its value." |
for its value." |
168 |
(interactive (list (read-envvar-name "Get environment variable: " t))) |
(interactive (list (read-envvar-name "Get environment variable: " t))) |
169 |
(let ((value (getenv-internal variable))) |
(let ((value (getenv-internal (if (multibyte-string-p variable) |
170 |
|
(encode-coding-string |
171 |
|
variable locale-coding-system) |
172 |
|
variable)))) |
173 |
|
(if (and enable-multibyte-characters value) |
174 |
|
(setq value (decode-coding-string value locale-coding-system))) |
175 |
(when (interactive-p) |
(when (interactive-p) |
176 |
(message "%s" (if value value "Not set"))) |
(message "%s" (if value value "Not set"))) |
177 |
value)) |
value)) |