X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/ac3232837188f7e1c4ffe34b76edede0ccb54f5e..ab1dc14b220747e527d507d40905a24ba5c692d9:/lisp/eshell/esh-opt.el diff --git a/lisp/eshell/esh-opt.el b/lisp/eshell/esh-opt.el index a16a484110..fed2d8f1c6 100644 --- a/lisp/eshell/esh-opt.el +++ b/lisp/eshell/esh-opt.el @@ -1,7 +1,6 @@ ;;; esh-opt.el --- command options processing -;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, -;; 2008 Free Software Foundation, Inc. +;; Copyright (C) 1999-2012 Free Software Foundation, Inc. ;; Author: John Wiegley @@ -22,6 +21,8 @@ ;;; Commentary: +;;; Code: + (provide 'esh-opt) (eval-when-compile (require 'esh-ext)) @@ -34,13 +35,51 @@ Eshell commands implemented in Lisp." ;;; User Functions: -(defmacro eshell-eval-using-options (name macro-args - options &rest body-forms) +(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, settings will be stored in local symbols as declared -by OPTIONS; FORMS will then be evaluated -- assuming all was OK. +After doing so, stores settings in local symbols as declared by OPTIONS; +then evaluates BODY-FORMS -- assuming all was OK. + +OPTIONS is a list, beginning with one or more elements of the form: +\(SHORT LONG VALUE SYMBOL HELP-STRING) +Each of these elements represents a particular command-line switch. + +SHORT is either nil, or a character that can be used as a switch -SHORT. +LONG is either nil, or a string that can be used as a switch --LONG. +At least one of SHORT and LONG must be non-nil. +VALUE is the value associated with the option. It can be either: + t - the option needs a value to be specified after the switch; + nil - the option is given the value t; + anything else - specifies the actual value for the option. +SYMBOL is either nil, or the name of the Lisp symbol that will be bound +to VALUE. A nil SYMBOL calls `eshell-show-usage', and so is appropriate +for a \"--help\" type option. +HELP-STRING is a documentation string for the option. + +Any remaining elements of OPTIONS are :KEYWORD arguments. Some take +arguments, some do not. The recognized :KEYWORDS are: + +:external STRING + STRING is an external command to run if there are unknown switches. -The syntax of OPTIONS is: +:usage STRING + STRING is the initial part of the command's documentation string. + It appears before the options are listed. + +:post-usage STRING + STRING is an optional trailing part of the command's documentation string. + It appears after the options, but before the final part of the + documentation about the associated external command (if there is one). + +:show-usage + If present, then show the usage message if the command is called with no + arguments. + +:preserve-args + If present, do not pass MACRO-ARGS through `eshell-flatten-list' +and `eshell-stringify-list'. + +For example, OPTIONS might look like: '((?C nil nil multi-column \"multi-column display\") (nil \"help\" nil nil \"show this usage display\") @@ -51,8 +90,9 @@ The syntax of OPTIONS is: Sort entries alphabetically across.\") `eshell-eval-using-options' returns the value of the last form in -BODY-FORMS. If instead an external command is run, the tag -`eshell-external' will be thrown with the new process for its value. +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)." @@ -62,13 +102,13 @@ interned variable `args' (created using a `let' form)." macro-args (list 'eshell-stringify-list (list 'eshell-flatten-list macro-args))))) - (let ,(append (mapcar (function - (lambda (opt) - (or (and (listp opt) (nth 3 opt)) - 'eshell-option-stub))) - (cadr options)) + (let ,(append (delq nil (mapcar (lambda (opt) + (and (listp opt) (nth 3 opt))) + (cadr options))) '(usage-msg last-value ext-command args)) - (eshell-do-opt ,name ,options (quote ,body-forms))))) + ;; FIXME: `options' ends up hiding some variable names under `quote', + ;; which is incompatible with lexical scoping!! + (eshell-do-opt ,name ,options (lambda () ,@body-forms))))) ;;; Internal Functions: @@ -76,9 +116,10 @@ interned variable `args' (created using a `let' form)." (defvar last-value) (defvar usage-msg) (defvar ext-command) +;; Documented part of the interface; see eshell-eval-using-options. (defvar args) -(defun eshell-do-opt (name options body-forms) +(defun eshell-do-opt (name options body-fun) "Helper function for `eshell-eval-using-options'. This code doesn't really need to be macro expanded everywhere." (setq args temp-args) @@ -94,8 +135,7 @@ This code doesn't really need to be macro expanded everywhere." (throw 'eshell-usage (eshell-show-usage name options))) (setq args (eshell-process-args name args options) - last-value (eval (append (list 'progn) - body-forms))) + last-value (funcall body-fun)) nil)) (error "%s" usage-msg)))) (throw 'eshell-external @@ -179,10 +219,8 @@ switch is unrecognized." found) (while opts (if (and (listp (car opts)) - (nth kind (car opts)) - (if (= kind 0) - (eq switch (nth kind (car opts))) - (string= switch (nth kind (car opts))))) + (nth kind (car opts)) + (equal switch (nth kind (car opts)))) (progn (eshell-set-option name ai (car opts) options) (setq found t opts nil)) @@ -199,7 +237,7 @@ switch is unrecognized." (defun eshell-process-args (name args options) "Process the given ARGS using OPTIONS. -This assumes that symbols have been intern'd by `eshell-with-options'." +This assumes that symbols have been intern'd by `eshell-eval-using-options'." (let ((ai 0) arg) (while (< ai (length args)) (setq arg (nth ai args)) @@ -222,7 +260,4 @@ This assumes that symbols have been intern'd by `eshell-with-options'." (setq index (1+ index))))))))) args) -;;; Code: - -;; arch-tag: 45c6c2d0-8091-46a1-a205-2f4bafd8230c ;;; esh-opt.el ends here