* 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
This commit is contained in:
parent
3f386383dc
commit
70568a90a1
3 changed files with 76 additions and 52 deletions
|
@ -1,3 +1,19 @@
|
|||
2013-09-16 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* eshell/esh-opt.el: Fix last change to set lexical-vars properly
|
||||
(bug#15379).
|
||||
(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.
|
||||
|
||||
2013-09-15 Dmitry Gutov <dgutov@yandex.ru>
|
||||
|
||||
* progmodes/ruby-mode.el (ruby-operator-re): Consider line
|
||||
|
|
|
@ -98,45 +98,44 @@ the new process for its value.
|
|||
Lastly, any remaining arguments will be available in a locally
|
||||
interned variable `args' (created using a `let' form)."
|
||||
(declare (debug (form form sexp body)))
|
||||
`(let ((temp-args
|
||||
,(if (memq ':preserve-args (cadr options))
|
||||
macro-args
|
||||
(list 'eshell-stringify-list
|
||||
(list 'eshell-flatten-list macro-args)))))
|
||||
(let ,(delq nil (mapcar (lambda (opt)
|
||||
(and (listp opt) (nth 3 opt)))
|
||||
(cadr options)))
|
||||
;; FIXME: `options' ends up hiding some variable names under `quote',
|
||||
;; which is incompatible with lexical scoping!!
|
||||
(eshell-do-opt ,name ,options (lambda (args) ,@body-forms) temp-args))))
|
||||
`(let* ((temp-args
|
||||
,(if (memq ':preserve-args (cadr options))
|
||||
macro-args
|
||||
(list 'eshell-stringify-list
|
||||
(list 'eshell-flatten-list macro-args))))
|
||||
(processed-args (eshell--do-opts ,name ,options temp-args))
|
||||
,@(delete-dups
|
||||
(delq nil (mapcar (lambda (opt)
|
||||
(and (listp opt) (nth 3 opt)
|
||||
`(,(nth 3 opt) (pop processed-args))))
|
||||
;; `options' is of the form (quote OPTS).
|
||||
(cadr options))))
|
||||
(args processed-args))
|
||||
,@body-forms))
|
||||
|
||||
;;; Internal Functions:
|
||||
|
||||
;; Documented part of the interface; see eshell-eval-using-options.
|
||||
(defvar eshell--args)
|
||||
|
||||
(defun eshell-do-opt (name options body-fun args)
|
||||
(defun eshell--do-opts (name options args)
|
||||
"Helper function for `eshell-eval-using-options'.
|
||||
This code doesn't really need to be macro expanded everywhere."
|
||||
(let* (last-value
|
||||
(ext-command
|
||||
(catch 'eshell-ext-command
|
||||
(let ((usage-msg
|
||||
(catch 'eshell-usage
|
||||
(setq last-value nil)
|
||||
(if (and (= (length args) 0)
|
||||
(memq ':show-usage options))
|
||||
(throw 'eshell-usage
|
||||
(eshell-show-usage name options)))
|
||||
(setq args (eshell-process-args name args options)
|
||||
last-value (funcall body-fun args))
|
||||
nil)))
|
||||
(when usage-msg
|
||||
(error "%s" usage-msg))))))
|
||||
(let ((ext-command
|
||||
(catch 'eshell-ext-command
|
||||
(let ((usage-msg
|
||||
(catch 'eshell-usage
|
||||
(if (and (= (length args) 0)
|
||||
(memq ':show-usage options))
|
||||
(eshell-show-usage name options)
|
||||
(setq args (eshell--process-args name args options))
|
||||
nil))))
|
||||
(when usage-msg
|
||||
(error "%s" usage-msg))))))
|
||||
(if ext-command
|
||||
(throw 'eshell-external
|
||||
(eshell-external-command ext-command args))
|
||||
last-value)))
|
||||
(throw 'eshell-external
|
||||
(eshell-external-command ext-command args))
|
||||
args)))
|
||||
|
||||
(defun eshell-show-usage (name options)
|
||||
"Display the usage message for NAME, using OPTIONS."
|
||||
|
@ -185,23 +184,24 @@ passed to this command, the external version '%s'
|
|||
will be called instead." extcmd)))))
|
||||
(throw 'eshell-usage usage)))
|
||||
|
||||
(defun eshell-set-option (name ai opt options)
|
||||
(defun eshell--set-option (name ai opt options opt-vals)
|
||||
"Using NAME's remaining args (index AI), set the OPT within OPTIONS.
|
||||
If the option consumes an argument for its value, the argument list
|
||||
will be modified."
|
||||
(if (not (nth 3 opt))
|
||||
(eshell-show-usage name options)
|
||||
(if (eq (nth 2 opt) t)
|
||||
(if (> ai (length eshell--args))
|
||||
(error "%s: missing option argument" name)
|
||||
(set (nth 3 opt) (nth ai eshell--args))
|
||||
(if (> ai 0)
|
||||
(setcdr (nthcdr (1- ai) eshell--args)
|
||||
(nthcdr (1+ ai) eshell--args))
|
||||
(setq eshell--args (cdr eshell--args))))
|
||||
(set (nth 3 opt) (or (nth 2 opt) t)))))
|
||||
(setcdr (assq (nth 3 opt) opt-vals)
|
||||
(if (eq (nth 2 opt) t)
|
||||
(if (> ai (length eshell--args))
|
||||
(error "%s: missing option argument" name)
|
||||
(prog1 (nth ai eshell--args)
|
||||
(if (> ai 0)
|
||||
(setcdr (nthcdr (1- ai) eshell--args)
|
||||
(nthcdr (1+ ai) eshell--args))
|
||||
(setq eshell--args (cdr eshell--args)))))
|
||||
(or (nth 2 opt) t)))))
|
||||
|
||||
(defun eshell-process-option (name switch kind ai options)
|
||||
(defun eshell--process-option (name switch kind ai options opt-vals)
|
||||
"For NAME, process SWITCH (of type KIND), from args at index AI.
|
||||
The SWITCH will be looked up in the set of OPTIONS.
|
||||
|
||||
|
@ -219,7 +219,7 @@ switch is unrecognized."
|
|||
(nth kind (car opts))
|
||||
(equal switch (nth kind (car opts))))
|
||||
(progn
|
||||
(eshell-set-option name ai (car opts) options)
|
||||
(eshell--set-option name ai (car opts) options opt-vals)
|
||||
(setq found t opts nil))
|
||||
(setq opts (cdr opts))))
|
||||
(unless found
|
||||
|
@ -232,11 +232,18 @@ switch is unrecognized."
|
|||
"%s: unrecognized option --%s")
|
||||
name switch)))))))
|
||||
|
||||
(defun eshell-process-args (name args options)
|
||||
"Process the given ARGS using OPTIONS.
|
||||
This assumes that symbols have been intern'd by `eshell-eval-using-options'."
|
||||
(let ((ai 0) arg
|
||||
(eshell--args args))
|
||||
(defun eshell--process-args (name args options)
|
||||
"Process the given ARGS using OPTIONS."
|
||||
(let* ((seen ())
|
||||
(opt-vals (delq nil (mapcar (lambda (opt)
|
||||
(when (listp opt)
|
||||
(let ((sym (nth 3 opt)))
|
||||
(when (and sym (not (memq sym seen)))
|
||||
(push sym seen)
|
||||
(list sym)))))
|
||||
options)))
|
||||
(ai 0) arg
|
||||
(eshell--args args))
|
||||
(while (< ai (length args))
|
||||
(setq arg (nth ai args))
|
||||
(if (not (and (stringp arg)
|
||||
|
@ -249,13 +256,14 @@ This assumes that symbols have been intern'd by `eshell-eval-using-options'."
|
|||
(setcdr (nthcdr (1- ai) args) (nthcdr (1+ ai) args)))
|
||||
(if dash
|
||||
(if (> (length switch) 0)
|
||||
(eshell-process-option name switch 1 ai options)
|
||||
(eshell--process-option name switch 1 ai options opt-vals)
|
||||
(setq ai (length args)))
|
||||
(let ((len (length switch))
|
||||
(index 0))
|
||||
(while (< index len)
|
||||
(eshell-process-option name (aref switch index) 0 ai options)
|
||||
(setq index (1+ index)))))))))
|
||||
args)
|
||||
(eshell--process-option name (aref switch index)
|
||||
0 ai options opt-vals)
|
||||
(setq index (1+ index))))))))
|
||||
(nconc (mapcar #'cdr opt-vals) args)))
|
||||
|
||||
;;; esh-opt.el ends here
|
||||
|
|
|
@ -144,7 +144,7 @@ function `string-to-number'."
|
|||
Otherwise, evaluates FORM with no error handling."
|
||||
(declare (indent 2))
|
||||
(if eshell-handle-errors
|
||||
`(condition-case ,tag
|
||||
`(condition-case-unless-debug ,tag
|
||||
,form
|
||||
,@handlers)
|
||||
form))
|
||||
|
|
Loading…
Add table
Reference in a new issue