diff options
Diffstat (limited to 'lisp/eshell/esh-opt.el')
-rw-r--r-- | lisp/eshell/esh-opt.el | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/lisp/eshell/esh-opt.el b/lisp/eshell/esh-opt.el index 6f37a29004a..3ea5873cafd 100644 --- a/lisp/eshell/esh-opt.el +++ b/lisp/eshell/esh-opt.el @@ -23,9 +23,6 @@ ;;; Code: -(provide 'esh-opt) - -(require 'esh-ext) ;; Unused. ;; (defgroup eshell-opt nil @@ -36,6 +33,10 @@ ;;; User Functions: +;; Macro expansion of eshell-eval-using-options refers to eshell-stringify-list +;; defined in esh-util. +(require 'esh-util) + (defmacro eshell-eval-using-options (name macro-args options &rest body-forms) "Process NAME's MACRO-ARGS using a set of command line OPTIONS. After doing so, stores settings in local symbols as declared by OPTIONS; @@ -77,9 +78,13 @@ arguments, some do not. The recognized :KEYWORDS are: arguments. :preserve-args - If present, do not pass MACRO-ARGS through `eshell-flatten-list' + If present, do not pass MACRO-ARGS through `flatten-tree' and `eshell-stringify-list'. +:parse-leading-options-only + If present, do not parse dash or switch arguments after the first +positional argument. Instead, treat them as positional arguments themselves. + For example, OPTIONS might look like: ((?C nil nil multi-column \"multi-column display\") @@ -95,14 +100,14 @@ BODY-FORMS. If instead an external command is run (because of an unknown option), the tag `eshell-external' will be thrown with the new process for its value. -Lastly, any remaining arguments will be available in a locally -interned variable `args' (created using a `let' form)." +Lastly, any remaining arguments will be available in the locally +let-bound variable `args'." (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)))) + (list 'flatten-tree macro-args)))) (processed-args (eshell--do-opts ,name ,options temp-args)) ,@(delete-dups (delq nil (mapcar (lambda (opt) @@ -111,6 +116,8 @@ interned variable `args' (created using a `let' form)." ;; `options' is of the form (quote OPTS). (cadr options)))) (args processed-args)) + ;; Silence unused lexical variable warning if body does not use `args'. + (ignore args) ,@body-forms)) ;;; Internal Functions: @@ -121,6 +128,8 @@ interned variable `args' (created using a `let' form)." (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." + (require 'esh-ext) + (declare-function eshell-external-command "esh-ext" (command args)) (let ((ext-command (catch 'eshell-ext-command (let ((usage-msg @@ -139,6 +148,8 @@ This code doesn't really need to be macro expanded everywhere." (defun eshell-show-usage (name options) "Display the usage message for NAME, using OPTIONS." + (require 'esh-ext) + (declare-function eshell-search-path "esh-ext" (name)) (let ((usage (format "usage: %s %s\n\n" name (cadr (memq ':usage options)))) (extcmd (memq ':external options)) @@ -194,11 +205,7 @@ will be modified." (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))))) + (pop (nthcdr ai eshell--args))) (or (nth 2 opt) t))))) (defun eshell--process-option (name switch kind ai options opt-vals) @@ -243,18 +250,22 @@ switch is unrecognized." (list sym))))) options))) (ai 0) arg - (eshell--args args)) - (while (< ai (length eshell--args)) + (eshell--args args) + (pos-argument-found nil)) + (while (and (< ai (length eshell--args)) + ;; Abort if we saw the first pos argument and option is set + (not (and pos-argument-found + (memq :parse-leading-options-only options)))) (setq arg (nth ai eshell--args)) (if (not (and (stringp arg) (string-match "^-\\(-\\)?\\(.*\\)" arg))) - (setq ai (1+ ai)) + ;; Positional argument found, skip + (setq ai (1+ ai) + pos-argument-found t) + ;; dash or switch argument found, parse (let* ((dash (match-string 1 arg)) (switch (match-string 2 arg))) - (if (= ai 0) - (setq eshell--args (cdr eshell--args)) - (setcdr (nthcdr (1- ai) eshell--args) - (nthcdr (1+ ai) eshell--args))) + (pop (nthcdr ai eshell--args)) (if dash (if (> (length switch) 0) (eshell--process-option name switch 1 ai options opt-vals) @@ -267,4 +278,5 @@ switch is unrecognized." (setq index (1+ index)))))))) (nconc (mapcar #'cdr opt-vals) eshell--args))) +(provide 'esh-opt) ;;; esh-opt.el ends here |