emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] trunk r114305: * lisp/eshell/esh-opt.el: Fix last change t


From: Stefan Monnier
Subject: [Emacs-diffs] trunk r114305: * lisp/eshell/esh-opt.el: Fix last change to set lexical-vars properly.
Date: Mon, 16 Sep 2013 18:23:38 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 114305
revision-id: address@hidden
parent: address@hidden
fixes bug: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15379
committer: Stefan Monnier <address@hidden>
branch nick: trunk
timestamp: Mon 2013-09-16 14:23:30 -0400
message:
  * 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.
modified:
  lisp/ChangeLog                 changelog-20091113204419-o5vbwnq5f7feedwu-1432
  lisp/eshell/esh-opt.el         eshopt.el-20091113204419-o5vbwnq5f7feedwu-1873
  lisp/eshell/esh-util.el        eshutil.el-20091113204419-o5vbwnq5f7feedwu-1849
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2013-09-15 23:42:26 +0000
+++ b/lisp/ChangeLog    2013-09-16 18:23:30 +0000
@@ -1,3 +1,19 @@
+2013-09-16  Stefan Monnier  <address@hidden>
+
+       * 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  <address@hidden>
 
        * progmodes/ruby-mode.el (ruby-operator-re): Consider line

=== modified file 'lisp/eshell/esh-opt.el'
--- a/lisp/eshell/esh-opt.el    2013-09-12 20:15:53 +0000
+++ b/lisp/eshell/esh-opt.el    2013-09-16 18:23:30 +0000
@@ -98,45 +98,44 @@
 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 @@
 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 @@
                (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 @@
                      "%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 @@
            (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

=== modified file 'lisp/eshell/esh-util.el'
--- a/lisp/eshell/esh-util.el   2013-09-13 07:12:44 +0000
+++ b/lisp/eshell/esh-util.el   2013-09-16 18:23:30 +0000
@@ -144,7 +144,7 @@
 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))


reply via email to

[Prev in Thread] Current Thread [Next in Thread]