diff options
| author | Stefan Monnier | 2013-09-16 14:23:30 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2013-09-16 14:23:30 -0400 |
| commit | 70568a90a17f4ea136d99f0c8eed5088322fb5ed (patch) | |
| tree | 022ae34040299419764dcca7889134167f4b875f /lisp/eshell | |
| parent | 3f386383dc0459fb857c0831aeecb9072f7085d7 (diff) | |
| download | emacs-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.el | 112 | ||||
| -rw-r--r-- | lisp/eshell/esh-util.el | 2 |
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. | |||
| 98 | Lastly, any remaining arguments will be available in a locally | 98 | Lastly, any remaining arguments will be available in a locally |
| 99 | interned variable `args' (created using a `let' form)." | 99 | interned 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'. |
| 120 | This code doesn't really need to be macro expanded everywhere." | 123 | This 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' | |||
| 185 | will be called instead." extcmd))))) | 184 | will 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. |
| 190 | If the option consumes an argument for its value, the argument list | 189 | If the option consumes an argument for its value, the argument list |
| 191 | will be modified." | 190 | will 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. |
| 206 | The SWITCH will be looked up in the set of OPTIONS. | 206 | The 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." |
| 237 | This 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'." | |||
| 144 | Otherwise, evaluates FORM with no error handling." | 144 | Otherwise, 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)) |