emacs-diffs
[Top][All Lists]
Advanced

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

master ccb62321d23 1/2: Fix handling of Eshell debug modes


From: Jim Porter
Subject: master ccb62321d23 1/2: Fix handling of Eshell debug modes
Date: Thu, 31 Aug 2023 21:53:33 -0400 (EDT)

branch: master
commit ccb62321d234993a66287c4e1a3cfdea63d140ff
Author: Jim Porter <jporterbugs@gmail.com>
Commit: Jim Porter <jporterbugs@gmail.com>

    Fix handling of Eshell debug modes
    
    Previously, these were enabled/disabled at byte-compilation time, but
    we want to control them at runtime.
    
    * lisp/eshell/esh-cmd.el (eshell-eval-command): Call
    'eshell-debug-command-start'.
    (eshell-manipulate): Check 'eshell-debug-command' at runtime.  Update
    callers.
    (eshell-debug-command): Move to "esh-util.el".
    (eshell/eshell-debug, pcomplate/eshell-mode/eshell-debug): Move to
    "em-basic.el".
    (eshell-debug-show-parsed-args): Update implementation.
    
    * lisp/eshell/esh-util.el (eshell-debug-command): Move from
    "esh-cmd.el" and convert to a list.
    (eshell-debug-command-buffer): New variable.
    (eshell-condition-case): Check 'eshell-handle-errors' at runtime.
    (eshell-debug-command-start): New function.
    (eshell-debug-command): Move from "esh-cmd.el" and convert to a macro.
    
    * lisp/eshell/em-basic.el (eshell/eshell-debug)
    (pcomplete/eshell-mode/eshell-debug): Move from "esh-cmd.el" and
    reimplement.
    
    * lisp/eshell/eshell.el (eshell-command): Pass the original input to
    'eshell-eval-command'.
    
    * doc/misc/eshell.texi (Built-ins): Update documentation for
    'eshell-debug'.
---
 doc/misc/eshell.texi    |  17 ++++++--
 lisp/eshell/em-basic.el |  31 ++++++++++++++
 lisp/eshell/esh-cmd.el  | 105 +++++++++++-------------------------------------
 lisp/eshell/esh-util.el |  44 +++++++++++++++++---
 lisp/eshell/eshell.el   |   3 +-
 5 files changed, 108 insertions(+), 92 deletions(-)

diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi
index f8f60bae13a..ee6c0f10b34 100644
--- a/doc/misc/eshell.texi
+++ b/doc/misc/eshell.texi
@@ -619,10 +619,19 @@ environment.
 @item eshell-debug
 @cmindex eshell-debug
 Toggle debugging information for Eshell itself.  You can pass this
-command the argument @code{errors} to enable/disable Eshell trapping
-errors when evaluating commands, or the argument @code{commands} to
-show/hide command execution progress in the buffer @code{*eshell last
-cmd*}.
+command one or more of the following arguments:
+
+@itemize @bullet
+
+@item
+@code{error}, to enable/disable Eshell trapping errors when
+evaluating commands; or
+
+@item
+@code{form}, to show/hide Eshell command form manipulation in the
+buffer @code{*eshell last cmd*}.
+
+@end itemize
 
 @item exit
 @cmindex exit
diff --git a/lisp/eshell/em-basic.el b/lisp/eshell/em-basic.el
index 016afe811b2..554ee83b015 100644
--- a/lisp/eshell/em-basic.el
+++ b/lisp/eshell/em-basic.el
@@ -188,6 +188,37 @@ or `eshell-printn' for display."
 
 (put 'eshell/umask 'eshell-no-numeric-conversions t)
 
+(defun eshell/eshell-debug (&rest args)
+  "A command for toggling certain debug variables."
+  (eshell-eval-using-options
+   "eshell-debug" args
+   '((?h "help" nil nil "display this usage message")
+     :usage "[KIND]...
+This command is used to aid in debugging problems related to Eshell
+itself.  It is not useful for anything else.  The recognized `kinds'
+are:
+
+   error       stops Eshell from trapping errors
+   form        shows command form manipulation in `*eshell last cmd*'")
+   (if args
+       (dolist (kind args)
+         (if (equal kind "error")
+             (setq eshell-handle-errors (not eshell-handle-errors))
+           (let ((kind-sym (intern kind)))
+             (if (memq kind-sym eshell-debug-command)
+                 (setq eshell-debug-command
+                       (delq kind-sym eshell-debug-command))
+               (push kind-sym eshell-debug-command)))))
+     ;; Output the currently-enabled debug kinds.
+     (unless eshell-handle-errors
+       (eshell-print "errors\n"))
+     (dolist (kind eshell-debug-command)
+       (eshell-printn (symbol-name kind))))))
+
+(defun pcomplete/eshell-mode/eshell-debug ()
+  "Completion for the `debug' command."
+  (while (pcomplete-here '("error" "form"))))
+
 (provide 'em-basic)
 
 ;; Local Variables:
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index 80066263396..ed2d6c71fc8 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -237,17 +237,6 @@ return non-nil if the command is complex."
   :version "24.1"                     ; removed eshell-cmd-initialize
   :type 'hook)
 
-(defcustom eshell-debug-command nil
-  "If non-nil, enable Eshell debugging code.
-This is slow, and only useful for debugging problems with Eshell.
-If you change this without using customize after Eshell has loaded,
-you must re-load `esh-cmd.el'."
-  :initialize 'custom-initialize-default
-  :set (lambda (symbol value)
-        (set symbol value)
-        (load "esh-cmd"))
-  :type 'boolean)
-
 (defcustom eshell-deferrable-commands
   '(eshell-named-command
     eshell-lisp-command
@@ -436,22 +425,9 @@ hooks should be run before and after the command."
                             (run-hooks 'eshell-post-command-hook)))
       (macroexp-progn commands))))
 
-(defun eshell-debug-command (tag subform)
-  "Output a debugging message to `*eshell last cmd*'."
-  (let ((buf (get-buffer-create "*eshell last cmd*"))
-       (text (eshell-stringify eshell-current-command)))
-    (with-current-buffer buf
-      (if (not tag)
-         (erase-buffer)
-       (insert "\n\C-l\n" tag "\n\n" text
-               (if subform
-                   (concat "\n\n" (eshell-stringify subform)) ""))))))
-
 (defun eshell-debug-show-parsed-args (terms)
   "Display parsed arguments in the debug buffer."
-  (ignore
-   (if eshell-debug-command
-       (eshell-debug-command "parsed arguments" terms))))
+  (ignore (eshell-debug-command 'form "parsed arguments" terms)))
 
 (defun eshell-no-command-conversion (terms)
   "Don't convert the command argument."
@@ -942,38 +918,6 @@ This avoids the need to use `let*'."
 ;; finishes, it will resume the evaluation using the remainder of the
 ;; command tree.
 
-(defun eshell/eshell-debug (&rest args)
-  "A command for toggling certain debug variables."
-  (ignore
-   (cond
-    ((not args)
-     (if eshell-handle-errors
-        (eshell-print "errors\n"))
-     (if eshell-debug-command
-        (eshell-print "commands\n")))
-    ((member (car args) '("-h" "--help"))
-     (eshell-print "usage: eshell-debug [kinds]
-
-This command is used to aid in debugging problems related to Eshell
-itself.  It is not useful for anything else.  The recognized `kinds'
-at the moment are:
-
-  errors       stops Eshell from trapping errors
-  commands     shows command execution progress in `*eshell last cmd*'
-"))
-    (t
-     (while args
-       (cond
-       ((string= (car args) "errors")
-        (setq eshell-handle-errors (not eshell-handle-errors)))
-       ((string= (car args) "commands")
-        (setq eshell-debug-command (not eshell-debug-command))))
-       (setq args (cdr args)))))))
-
-(defun pcomplete/eshell-mode/eshell-debug ()
-  "Completion for the `debug' command."
-  (while (pcomplete-here '("errors" "commands"))))
-
 (iter-defun eshell--find-subcommands (haystack)
   "Recursively search for subcommand forms in HAYSTACK.
 This yields the SUBCOMMANDs when found in forms like
@@ -1049,10 +993,7 @@ process(es) in a cons cell like:
                        (if here
                            (eshell-update-markers here))
                        (eshell-do-eval ',command))))
-    (and eshell-debug-command
-         (with-current-buffer (get-buffer-create "*eshell last cmd*")
-           (erase-buffer)
-           (insert "command: \"" input "\"\n")))
+    (eshell-debug-command-start input)
     (setq eshell-current-command command)
     (let* (result
            (delim (catch 'eshell-incomplete
@@ -1088,17 +1029,17 @@ process(es) in a cons cell like:
     (error
      (error (error-message-string err)))))
 
-(defmacro eshell-manipulate (tag &rest commands)
-  "Manipulate a COMMAND form, with TAG as a debug identifier."
-  (declare (indent 1))
-  ;; Check `bound'ness since at compile time the code until here has not
-  ;; executed yet.
-  (if (not (and (boundp 'eshell-debug-command) eshell-debug-command))
-      `(progn ,@commands)
-    `(progn
-       (eshell-debug-command ,(eval tag) form)
-       ,@commands
-       (eshell-debug-command ,(concat "done " (eval tag)) form))))
+(defmacro eshell-manipulate (form tag &rest body)
+  "Manipulate a command FORM with BODY, using TAG as a debug identifier."
+  (declare (indent 2))
+  (let ((tag-symbol (make-symbol "tag")))
+    `(if (not (memq 'form eshell-debug-command))
+         (progn ,@body)
+       (let ((,tag-symbol ,tag))
+         (eshell-debug-command 'form ,tag-symbol ,form 'always)
+         ,@body
+         (eshell-debug-command 'form (concat "done " ,tag-symbol) ,form
+                               'always)))))
 
 (defun eshell-do-eval (form &optional synchronous-p)
   "Evaluate FORM, simplifying it as we go.
@@ -1125,8 +1066,8 @@ have been replaced by constants."
     ;; we can modify any `let' forms to evaluate only once.
     (if (macrop (car form))
         (let ((exp (copy-tree (macroexpand form))))
-         (eshell-manipulate (format-message "expanding macro `%s'"
-                                            (symbol-name (car form)))
+          (eshell-manipulate form
+              (format-message "expanding macro `%s'" (symbol-name (car form)))
            (setcar form (car exp))
            (setcdr form (cdr exp)))))
     (let ((args (cdr form)))
@@ -1138,7 +1079,7 @@ have been replaced by constants."
         (let ((new-form (copy-tree `(let ((eshell--command-body nil)
                                           (eshell--test-body nil))
                                       (eshell--wrapped-while ,@args)))))
-          (eshell-manipulate "modifying while form"
+          (eshell-manipulate form "modifying while form"
             (setcar form (car new-form))
             (setcdr form (cdr new-form)))
           (eshell-do-eval form synchronous-p)))
@@ -1161,7 +1102,7 @@ have been replaced by constants."
           (setq eshell--command-body nil
                 eshell--test-body (copy-tree (car args)))))
        ((eq (car form) 'if)
-        (eshell-manipulate "evaluating if condition"
+        (eshell-manipulate form "evaluating if condition"
           (setcar args (eshell-do-eval (car args) synchronous-p)))
         (eshell-do-eval
          (cond
@@ -1180,7 +1121,7 @@ have been replaced by constants."
        (eval form))
        ((eq (car form) 'let)
         (unless (eq (car-safe (cadr args)) 'eshell-do-eval)
-          (eshell-manipulate "evaluating let args"
+          (eshell-manipulate form "evaluating let args"
             (dolist (letarg (car args))
               (when (and (listp letarg)
                          (not (eq (cadr letarg) 'quote)))
@@ -1207,7 +1148,7 @@ have been replaced by constants."
             ;; the let-bindings' values so that those values are
             ;; correct when we resume evaluation of this form.
             (when deferred
-              (eshell-manipulate "rebinding let args after `eshell-defer'"
+              (eshell-manipulate form "rebinding let args after `eshell-defer'"
                 (let ((bindings (car args)))
                   (while bindings
                     (let ((binding (if (consp (car bindings))
@@ -1232,7 +1173,7 @@ have been replaced by constants."
        (unless (eq (car form) 'unwind-protect)
          (setq args (cdr args)))
        (unless (eq (caar args) 'eshell-do-eval)
-         (eshell-manipulate "handling special form"
+          (eshell-manipulate form "handling special form"
            (setcar args `(eshell-do-eval ',(car args) ,synchronous-p))))
        (eval form))
        ((eq (car form) 'setq)
@@ -1242,7 +1183,7 @@ have been replaced by constants."
        (list 'quote (eval form)))
        (t
        (if (and args (not (memq (car form) '(run-hooks))))
-           (eshell-manipulate
+            (eshell-manipulate form
                (format-message "evaluating arguments to `%s'"
                                (symbol-name (car form)))
              (while args
@@ -1283,7 +1224,7 @@ have been replaced by constants."
                      (setq result (eval form))))))
            (if new-form
                (progn
-                 (eshell-manipulate "substituting replacement form"
+                  (eshell-manipulate form "substituting replacement form"
                    (setcar form (car new-form))
                    (setcdr form (cdr new-form)))
                  (eshell-do-eval form synchronous-p))
@@ -1292,7 +1233,7 @@ have been replaced by constants."
                        (procs (eshell-make-process-pair result)))
                   (if synchronous-p
                      (eshell/wait (cdr procs))
-                   (eshell-manipulate "inserting ignore form"
+                    (eshell-manipulate form "inserting ignore form"
                      (setcar form 'ignore)
                      (setcdr form nil))
                    (throw 'eshell-defer procs))
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el
index 87cd1f5dcb2..8be4536cff7 100644
--- a/lisp/eshell/esh-util.el
+++ b/lisp/eshell/esh-util.el
@@ -102,6 +102,15 @@ argument matches `eshell-number-regexp'."
                                     (string :tag "Username")
                                     (repeat :tag "UIDs" string))))))
 
+(defcustom eshell-debug-command nil
+  "A list of debug features to enable when running Eshell commands.
+Possible entries are `form', to log the manipulation of Eshell
+command forms.
+
+If nil, don't debug commands at all."
+  :version "30.1"
+  :type '(set (const :tag "Form manipulation" form)))
+
 ;;; Internal Variables:
 
 (defvar eshell-number-regexp
@@ -145,6 +154,9 @@ function `string-to-number'.")
                             ,#'eshell--mark-yanked-as-output))
   "A list of text properties to apply to command output.")
 
+(defvar eshell-debug-command-buffer "*eshell last cmd*"
+  "The name of the buffer to log debug messages about command invocation.")
+
 ;;; Obsolete variables:
 
 (define-obsolete-variable-alias 'eshell-host-names
@@ -164,11 +176,33 @@ function `string-to-number'.")
   "If `eshell-handle-errors' is non-nil, this is `condition-case'.
 Otherwise, evaluates FORM with no error handling."
   (declare (indent 2) (debug (sexp form &rest form)))
-  (if eshell-handle-errors
-      `(condition-case-unless-debug ,tag
-          ,form
-        ,@handlers)
-    form))
+  `(if eshell-handle-errors
+       (condition-case-unless-debug ,tag
+           ,form
+         ,@handlers)
+     ,form))
+
+(defun eshell-debug-command-start (command)
+  "Start debugging output for the command string COMMAND.
+If debugging is enabled (see `eshell-debug-command'), this will
+start logging to `*eshell last cmd*'."
+  (when eshell-debug-command
+    (with-current-buffer (get-buffer-create eshell-debug-command-buffer)
+      (erase-buffer)
+      (insert "command: \"" command "\"\n"))))
+
+(defmacro eshell-debug-command (kind message &optional form always)
+  "Output a debugging message to `*eshell last cmd*' if debugging is enabled.
+KIND is the kind of message to log (either `form' or `io').  If
+present in `eshell-debug-command' (or if ALWAYS is non-nil),
+output this message; otherwise, ignore it."
+  (let ((kind-sym (make-symbol "kind")))
+    `(let ((,kind-sym ,kind))
+       (when ,(or always `(memq ,kind-sym eshell-debug-command))
+         (with-current-buffer (get-buffer-create eshell-debug-command-buffer)
+           (insert "\n\C-l\n[" (symbol-name ,kind-sym) "] " ,message)
+           (when-let ((form ,form))
+             (insert "\n\n" (eshell-stringify form))))))))
 
 (defun eshell--mark-as-output (start end &optional object)
   "Mark the text from START to END as Eshell output.
diff --git a/lisp/eshell/eshell.el b/lisp/eshell/eshell.el
index 15fc2ae6310..cbd0de3c093 100644
--- a/lisp/eshell/eshell.el
+++ b/lisp/eshell/eshell.el
@@ -301,7 +301,8 @@ argument), then insert output into the current buffer at 
point."
                     `(let ((eshell-current-handles
                             (eshell-create-handles ,stdout 'insert))
                            (eshell-current-subjob-p))
-                      ,(eshell-parse-command command))))
+                      ,(eshell-parse-command command))
+                    command))
             intr
             (bufname (if (eq (car-safe proc) :eshell-background)
                          "*Eshell Async Command Output*"



reply via email to

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