X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/ae5e4c483a4700fed927f546eebf06d1b1e92057..2b84d7639569b9476aa32c8301cb25dd58792e0f:/lisp/eshell/esh-opt.el diff --git a/lisp/eshell/esh-opt.el b/lisp/eshell/esh-opt.el index e9252cb540..3f5bcb641a 100644 --- a/lisp/eshell/esh-opt.el +++ b/lisp/eshell/esh-opt.el @@ -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))))) - -(defun eshell-process-option (name switch kind ai options) + (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 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