1 ;;; termdev.el --- functions for dealing with terminals
3 ;; Copyright (C) 2005 Free Software Foundation, Inc.
5 ;; Author: Karoly Lorentey <karoly@lorentey.hu>
9 ;; This file is part of GNU Emacs.
11 ;; GNU Emacs is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 ;; Boston, MA 02110-1301, USA.
26 (substitute-key-definition 'suspend-emacs
'suspend-frame global-map
)
28 (defun terminal-id (terminal)
29 "Return the numerical id of terminal TERMINAL.
31 TERMINAL can be a terminal id (an integer), a frame, or
32 nil (meaning the selected frame's terminal). Alternatively,
33 TERMINAL may be the name of an X display
34 device (HOST.SERVER.SCREEN) or a tty device file."
37 (if (display-live-p terminal
)
39 (signal 'wrong-type-argument
(list 'display-live-p terminal
))))
40 ((or (null terminal
) (framep terminal
))
41 (frame-display terminal
))
43 (let ((f (car (filtered-frame-list (lambda (frame)
44 (or (equal (frame-parameter frame
'display
) terminal
)
45 (equal (frame-parameter frame
'tty
) terminal
)))))))
46 (or f
(error "Display %s does not exist" terminal
))
49 (error "Invalid argument %s in `terminal-id'" terminal
))))
51 (defun terminal-getenv (variable &optional terminal global-ok
)
52 "Get the value of VARIABLE in the client environment of TERMINAL.
53 VARIABLE should be a string. Value is nil if VARIABLE is undefined in
54 the environment. Otherwise, value is a string.
56 If TERMINAL has an associated emacsclient process, then
57 `terminal-getenv' looks up VARIABLE in the environment of that
58 process; otherwise the function consults the global environment,
59 i.e., the environment of the Emacs process itself.
61 If GLOBAL-OK is non-nil, and VARIABLE is not defined in the
62 terminal-local environment, then `terminal-getenv' will return
63 its value in the global environment instead.
65 TERMINAL can be a terminal id, a frame, or nil (meaning the
66 selected frame's terminal)."
67 (setq terminal
(terminal-id terminal
))
68 (if (null (terminal-parameter terminal
'environment
))
70 (if (multibyte-string-p variable
)
71 (setq variable
(encode-coding-string variable locale-coding-system
)))
72 (let ((env (terminal-parameter terminal
'environment
))
74 (while (and env
(null result
))
77 (if (and (> (length entry
) (length variable
))
78 (eq ?
= (aref entry
(length variable
)))
79 (equal variable
(substring entry
0 (length variable
))))
80 (setq result
(substring entry
(+ (length variable
) 1)))))
81 (if (and global-ok
(null result
))
83 (and result
(decode-coding-string result locale-coding-system
))))))
85 (defun terminal-setenv (variable &optional value terminal
)
86 "Set the value of VARIABLE in the environment of TERMINAL.
87 VARIABLE should be string. VALUE is optional; if not provided or
88 nil, the environment variable VARIABLE is removed. Returned
89 value is the new value of VARIABLE, or nil if it was removed from
92 If TERMINAL was created by an emacsclient invocation, then the
93 variable is set in the environment of the emacsclient process;
94 otherwise the function changes the environment of the Emacs
97 TERMINAL can be a terminal id, a frame, or nil (meaning the
98 selected frame's terminal)."
99 (if (null (terminal-parameter terminal
'environment
))
100 (setenv variable value
)
101 (with-terminal-environment terminal variable
102 (setenv variable value
))))
104 (defun terminal-setenv-internal (variable value terminal
)
105 "Set the value of VARIABLE in the environment of TERMINAL.
106 The caller is responsible to ensure that both VARIABLE and VALUE
107 are usable in environment variables and that TERMINAL is a
109 (if (multibyte-string-p variable
)
110 (setq variable
(encode-coding-string variable locale-coding-system
)))
111 (if (and value
(multibyte-string-p value
))
112 (setq value
(encode-coding-string value locale-coding-system
)))
113 (let ((env (terminal-parameter terminal
'environment
))
115 (while (and env
(not found
))
116 (if (and (> (length (car env
)) (length variable
))
117 (eq ?
= (aref (car env
) (length variable
)))
118 (equal variable
(substring (car env
) 0 (length variable
))))
121 (setcar env
(concat variable
"=" value
))
122 (set-terminal-parameter terminal
'environment
124 (terminal-parameter terminal
127 (setq env
(cdr env
))))
130 (setcar env
(concat variable
"=" value
)))
131 ((and value
(not found
))
132 (set-terminal-parameter terminal
'environment
133 (cons (concat variable
"=" value
)
134 (terminal-parameter terminal
136 ((and (not value
) found
)
137 (set-terminal-parameter terminal
'environment
139 (terminal-parameter terminal
142 (defmacro with-terminal-environment
(terminal vars
&rest body
)
143 "Evaluate BODY with environment variables VARS set to those of TERMINAL.
144 The environment variables are then restored to their previous values.
146 VARS should be a single string, a list of strings, or t for all
147 environment variables.
149 TERMINAL can be a terminal id, a frame, or nil (meaning the
150 selected frame's terminal).
152 If BODY uses `setenv' to change environment variables in VARS,
153 then the new variable values will be remembered for TERMINAL, and
154 `terminal-getenv' will return them even outside BODY."
156 (let ((var (make-symbol "var"))
157 (term (make-symbol "term"))
158 (v (make-symbol "v"))
159 (old-env (make-symbol "old-env")))
160 `(let ((,term
,terminal
) ; Evaluate arguments only once.
165 ((null (terminal-parameter ,term
'environment
))
166 ;; Not a remote terminal; nothing to do.
169 ;; Switch the entire process-environment.
170 (let (,old-env process-environment
)
171 (setq process-environment
(terminal-parameter ,term
'environment
))
174 (set-terminal-parameter ,term
'environment process-environment
)
175 (setq process-environment
,old-env
))))
177 ;; Do only a set of variables.
180 (setq ,old-env
(cons (cons ,var
(getenv ,var
)) ,old-env
))
181 (setenv ,var
(terminal-getenv ,var
,term
)))
184 ;; Split storing new values and restoring old ones so
185 ;; that we DTRT even if a variable is specified twice in
188 (terminal-setenv-internal ,var
(getenv ,var
) ,term
))
189 (dolist (,var
,old-env
)
190 (setenv (car ,var
) (cdr ,var
))))))))))
194 ;;; arch-tag: 4c4df277-1ec1-4f56-bfde-7f156fe62fb2
195 ;;; termdev.el ends here