aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/eshell
diff options
context:
space:
mode:
authorStefan Monnier2013-09-16 14:23:30 -0400
committerStefan Monnier2013-09-16 14:23:30 -0400
commit70568a90a17f4ea136d99f0c8eed5088322fb5ed (patch)
tree022ae34040299419764dcca7889134167f4b875f /lisp/eshell
parent3f386383dc0459fb857c0831aeecb9072f7085d7 (diff)
downloademacs-70568a90a17f4ea136d99f0c8eed5088322fb5ed.tar.gz
emacs-70568a90a17f4ea136d99f0c8eed5088322fb5ed.zip
* lisp/eshell/esh-opt.el: Fix last change to set lexical-vars properly.
(eshell--do-opts): Rename from eshell-do-opt, remove arg `body-fun', return args and options. (eshell-eval-using-options): Use the new return value of eshell--do-opts to set the options's vars in their scope. (eshell--set-option): Rename from eshell-set-option. Add arg `opt-vals'. (eshell--process-option): Rename from eshell-process-option. Add arg `opt-vals'. (eshell--process-args): Use an `opt-vals' alist to store the options's values during their processing and return them additionally to the remaining args. Fixes: debbugs:15379
Diffstat (limited to 'lisp/eshell')
-rw-r--r--lisp/eshell/esh-opt.el112
-rw-r--r--lisp/eshell/esh-util.el2
2 files changed, 61 insertions, 53 deletions
diff --git a/lisp/eshell/esh-opt.el b/lisp/eshell/esh-opt.el
index e9252cb540e..3f5bcb641ac 100644
--- a/lisp/eshell/esh-opt.el
+++ b/lisp/eshell/esh-opt.el
@@ -98,45 +98,44 @@ the new process for its value.
98Lastly, any remaining arguments will be available in a locally 98Lastly, any remaining arguments will be available in a locally
99interned variable `args' (created using a `let' form)." 99interned variable `args' (created using a `let' form)."
100 (declare (debug (form form sexp body))) 100 (declare (debug (form form sexp body)))
101 `(let ((temp-args 101 `(let* ((temp-args
102 ,(if (memq ':preserve-args (cadr options)) 102 ,(if (memq ':preserve-args (cadr options))
103 macro-args 103 macro-args
104 (list 'eshell-stringify-list 104 (list 'eshell-stringify-list
105 (list 'eshell-flatten-list macro-args))))) 105 (list 'eshell-flatten-list macro-args))))
106 (let ,(delq nil (mapcar (lambda (opt) 106 (processed-args (eshell--do-opts ,name ,options temp-args))
107 (and (listp opt) (nth 3 opt))) 107 ,@(delete-dups
108 (cadr options))) 108 (delq nil (mapcar (lambda (opt)
109 ;; FIXME: `options' ends up hiding some variable names under `quote', 109 (and (listp opt) (nth 3 opt)
110 ;; which is incompatible with lexical scoping!! 110 `(,(nth 3 opt) (pop processed-args))))
111 (eshell-do-opt ,name ,options (lambda (args) ,@body-forms) temp-args)))) 111 ;; `options' is of the form (quote OPTS).
112 (cadr options))))
113 (args processed-args))
114 ,@body-forms))
112 115
113;;; Internal Functions: 116;;; Internal Functions:
114 117
115;; Documented part of the interface; see eshell-eval-using-options. 118;; Documented part of the interface; see eshell-eval-using-options.
116(defvar eshell--args) 119(defvar eshell--args)
117 120
118(defun eshell-do-opt (name options body-fun args) 121(defun eshell--do-opts (name options args)
119 "Helper function for `eshell-eval-using-options'. 122 "Helper function for `eshell-eval-using-options'.
120This code doesn't really need to be macro expanded everywhere." 123This code doesn't really need to be macro expanded everywhere."
121 (let* (last-value 124 (let ((ext-command
122 (ext-command 125 (catch 'eshell-ext-command
123 (catch 'eshell-ext-command 126 (let ((usage-msg
124 (let ((usage-msg 127 (catch 'eshell-usage
125 (catch 'eshell-usage 128 (if (and (= (length args) 0)
126 (setq last-value nil) 129 (memq ':show-usage options))
127 (if (and (= (length args) 0) 130 (eshell-show-usage name options)
128 (memq ':show-usage options)) 131 (setq args (eshell--process-args name args options))
129 (throw 'eshell-usage 132 nil))))
130 (eshell-show-usage name options))) 133 (when usage-msg
131 (setq args (eshell-process-args name args options) 134 (error "%s" usage-msg))))))
132 last-value (funcall body-fun args))
133 nil)))
134 (when usage-msg
135 (error "%s" usage-msg))))))
136 (if ext-command 135 (if ext-command
137 (throw 'eshell-external 136 (throw 'eshell-external
138 (eshell-external-command ext-command args)) 137 (eshell-external-command ext-command args))
139 last-value))) 138 args)))
140 139
141(defun eshell-show-usage (name options) 140(defun eshell-show-usage (name options)
142 "Display the usage message for NAME, using OPTIONS." 141 "Display the usage message for NAME, using OPTIONS."
@@ -185,23 +184,24 @@ passed to this command, the external version '%s'
185will be called instead." extcmd))))) 184will be called instead." extcmd)))))
186 (throw 'eshell-usage usage))) 185 (throw 'eshell-usage usage)))
187 186
188(defun eshell-set-option (name ai opt options) 187(defun eshell--set-option (name ai opt options opt-vals)
189 "Using NAME's remaining args (index AI), set the OPT within OPTIONS. 188 "Using NAME's remaining args (index AI), set the OPT within OPTIONS.
190If the option consumes an argument for its value, the argument list 189If the option consumes an argument for its value, the argument list
191will be modified." 190will be modified."
192 (if (not (nth 3 opt)) 191 (if (not (nth 3 opt))
193 (eshell-show-usage name options) 192 (eshell-show-usage name options)
194 (if (eq (nth 2 opt) t) 193 (setcdr (assq (nth 3 opt) opt-vals)
195 (if (> ai (length eshell--args)) 194 (if (eq (nth 2 opt) t)
196 (error "%s: missing option argument" name) 195 (if (> ai (length eshell--args))
197 (set (nth 3 opt) (nth ai eshell--args)) 196 (error "%s: missing option argument" name)
198 (if (> ai 0) 197 (prog1 (nth ai eshell--args)
199 (setcdr (nthcdr (1- ai) eshell--args) 198 (if (> ai 0)
200 (nthcdr (1+ ai) eshell--args)) 199 (setcdr (nthcdr (1- ai) eshell--args)
201 (setq eshell--args (cdr eshell--args)))) 200 (nthcdr (1+ ai) eshell--args))
202 (set (nth 3 opt) (or (nth 2 opt) t))))) 201 (setq eshell--args (cdr eshell--args)))))
203 202 (or (nth 2 opt) t)))))
204(defun eshell-process-option (name switch kind ai options) 203
204(defun eshell--process-option (name switch kind ai options opt-vals)
205 "For NAME, process SWITCH (of type KIND), from args at index AI. 205 "For NAME, process SWITCH (of type KIND), from args at index AI.
206The SWITCH will be looked up in the set of OPTIONS. 206The SWITCH will be looked up in the set of OPTIONS.
207 207
@@ -219,7 +219,7 @@ switch is unrecognized."
219 (nth kind (car opts)) 219 (nth kind (car opts))
220 (equal switch (nth kind (car opts)))) 220 (equal switch (nth kind (car opts))))
221 (progn 221 (progn
222 (eshell-set-option name ai (car opts) options) 222 (eshell--set-option name ai (car opts) options opt-vals)
223 (setq found t opts nil)) 223 (setq found t opts nil))
224 (setq opts (cdr opts)))) 224 (setq opts (cdr opts))))
225 (unless found 225 (unless found
@@ -232,11 +232,18 @@ switch is unrecognized."
232 "%s: unrecognized option --%s") 232 "%s: unrecognized option --%s")
233 name switch))))))) 233 name switch)))))))
234 234
235(defun eshell-process-args (name args options) 235(defun eshell--process-args (name args options)
236 "Process the given ARGS using OPTIONS. 236 "Process the given ARGS using OPTIONS."
237This assumes that symbols have been intern'd by `eshell-eval-using-options'." 237 (let* ((seen ())
238 (let ((ai 0) arg 238 (opt-vals (delq nil (mapcar (lambda (opt)
239 (eshell--args args)) 239 (when (listp opt)
240 (let ((sym (nth 3 opt)))
241 (when (and sym (not (memq sym seen)))
242 (push sym seen)
243 (list sym)))))
244 options)))
245 (ai 0) arg
246 (eshell--args args))
240 (while (< ai (length args)) 247 (while (< ai (length args))
241 (setq arg (nth ai args)) 248 (setq arg (nth ai args))
242 (if (not (and (stringp arg) 249 (if (not (and (stringp arg)
@@ -249,13 +256,14 @@ This assumes that symbols have been intern'd by `eshell-eval-using-options'."
249 (setcdr (nthcdr (1- ai) args) (nthcdr (1+ ai) args))) 256 (setcdr (nthcdr (1- ai) args) (nthcdr (1+ ai) args)))
250 (if dash 257 (if dash
251 (if (> (length switch) 0) 258 (if (> (length switch) 0)
252 (eshell-process-option name switch 1 ai options) 259 (eshell--process-option name switch 1 ai options opt-vals)
253 (setq ai (length args))) 260 (setq ai (length args)))
254 (let ((len (length switch)) 261 (let ((len (length switch))
255 (index 0)) 262 (index 0))
256 (while (< index len) 263 (while (< index len)
257 (eshell-process-option name (aref switch index) 0 ai options) 264 (eshell--process-option name (aref switch index)
258 (setq index (1+ index))))))))) 265 0 ai options opt-vals)
259 args) 266 (setq index (1+ index))))))))
267 (nconc (mapcar #'cdr opt-vals) args)))
260 268
261;;; esh-opt.el ends here 269;;; esh-opt.el ends here
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el
index 5fa591a3082..5e0aad8345f 100644
--- a/lisp/eshell/esh-util.el
+++ b/lisp/eshell/esh-util.el
@@ -144,7 +144,7 @@ function `string-to-number'."
144Otherwise, evaluates FORM with no error handling." 144Otherwise, evaluates FORM with no error handling."
145 (declare (indent 2)) 145 (declare (indent 2))
146 (if eshell-handle-errors 146 (if eshell-handle-errors
147 `(condition-case ,tag 147 `(condition-case-unless-debug ,tag
148 ,form 148 ,form
149 ,@handlers) 149 ,@handlers)
150 form)) 150 form))