From bc13c49736f867efe8af40ce8ddcd25d4c2cbd14 Mon Sep 17 00:00:00 2001 From: djcb Date: Mon, 16 Apr 2012 18:31:48 +0300 Subject: [PATCH] * improved debugging/logging support - add mu4e-toggle-logging to enable/disable logging - add mu4e-show-log to view the log buffer, and bind it to '$' in the main/header/view buffers - add a note about it to the doc (mu4e.texi) - make mu4e-log the the new logging function, use colors to distinguish incoming/outgoing data - only keep last 1200 lines of log in the log buffer --- emacs/mu4e-hdrs.el | 1 + emacs/mu4e-main.el | 1 + emacs/mu4e-proc.el | 20 ++++------------ emacs/mu4e-utils.el | 58 +++++++++++++++++++++++++++++++++++++++++++++ emacs/mu4e-vars.el | 8 +++++++ emacs/mu4e-view.el | 3 +++ emacs/mu4e.texi | 21 +++++++++++++++- 7 files changed, 95 insertions(+), 17 deletions(-) diff --git a/emacs/mu4e-hdrs.el b/emacs/mu4e-hdrs.el index aa8a3607..50602807 100644 --- a/emacs/mu4e-hdrs.el +++ b/emacs/mu4e-hdrs.el @@ -287,6 +287,7 @@ after the end of the search results." (define-key map (kbd "RET") 'mu4e-view-message) (define-key map [mouse-2] 'mu4e-view-message) + (define-key map "$" 'mu4e-show-log) (define-key map "H" 'mu4e-display-manual) ;; menu diff --git a/emacs/mu4e-main.el b/emacs/mu4e-main.el index b14c8d71..add1a894 100644 --- a/emacs/mu4e-main.el +++ b/emacs/mu4e-main.el @@ -44,6 +44,7 @@ (define-key map "f" 'smtpmail-send-queued-mail) (define-key map "U" 'mu4e-update-mail-show-window) + (define-key map "$" 'mu4e-show-log) (define-key map "H" 'mu4e-display-manual) map) diff --git a/emacs/mu4e-proc.el b/emacs/mu4e-proc.el index cdd69825..ee7ac5c2 100644 --- a/emacs/mu4e-proc.el +++ b/emacs/mu4e-proc.el @@ -1,4 +1,4 @@ -;;; mu4e-proc.el -- part of mu4e, the mu mail user agent +;; mu4e-proc.el -- part of mu4e, the mu mail user agent ;; ;; Copyright (C) 2011-2012 Dirk-Jan C. Binnema @@ -162,11 +162,11 @@ updated as well, with all processed sexp data removed." 6. a compose looks like: (:compose [:original] [:include ]) `mu4e-compose-func'." - (mu4e-proc-log "* Received %d byte(s)" (length str)) + (mu4e-log 'misc "* Received %d byte(s)" (length str)) (setq mu4e-buf (concat mu4e-buf str)) ;; update our buffer (let ((sexp (mu4e-proc-eat-sexp-from-buf))) (while sexp - (mu4e-proc-log "<- %S" sexp) + (mu4e-log 'from-server "%S" sexp) (cond ;; a header plist can be recognized by the existence of a :date field ((plist-get sexp :date) @@ -260,24 +260,12 @@ terminates." (t (message "Something bad happened to the mu server process"))))) - -(defconst mu4e-proc-log-buffer-name "*mu4e-log*" - "*internal* Name of the logging buffer.") - -(defun mu4e-proc-log (frm &rest args) - "Write something in the *mu4e-log* buffer - mainly useful for debugging." - (when mu4e-debug - (with-current-buffer (get-buffer-create mu4e-proc-log-buffer-name) - (goto-char (point-max)) - (insert (apply 'format (concat (format-time-string "%Y-%m-%d %T " - (current-time)) frm "\n") args))))) - (defun mu4e-proc-send-command (frm &rest args) "Send as command to the mu server process; start the process if needed." (unless (mu4e-proc-is-running) (mu4e-start-proc)) (let ((cmd (apply 'format frm args))) - (mu4e-proc-log (concat "-> " cmd)) + (mu4e-log 'to-server "%s" cmd) (process-send-string mu4e-mu-proc (concat cmd "\n")))) diff --git a/emacs/mu4e-utils.el b/emacs/mu4e-utils.el index e1961197..b464803e 100644 --- a/emacs/mu4e-utils.el +++ b/emacs/mu4e-utils.el @@ -472,5 +472,63 @@ server has the expected values." (mu4e-kill-proc) (kill-buffer))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; logging / debugging +(defun mu4e-log (type frm &rest args) + "Write a message of TYPE with format-string FRM and ARGS in +*mu4e-log* buffer, if the variable mu4e-debug is non-nil. Type is +either 'to-server, 'from-server or 'misc. This function is meant for debugging." + (when mu4e-debug + (with-current-buffer (get-buffer-create mu4e-log-buffer-name) + (view-mode) + (setq buffer-undo-list t) + (let* ((inhibit-read-only t) + (tstamp (propertize (format-time-string "%Y-%m-%d %T" (current-time)) + 'face 'font-lock-string-face)) + (msg-face + (case type + (from-server 'font-lock-type-face) + (to-server 'font-lock-function-name-face) + (misc 'font-lock-variable-name-face) + (otherwise (error "Unsupported log type")))) + (msg (propertize (apply 'format frm args) 'face msg-face))) + (goto-char (point-max)) + (insert tstamp + (case type + (from-server " <- ") + (to-server " -> " ) + (otherwise " ")) + msg "\n") + + ;; if `mu4e-log-max-lines is specified and exceeded, clearest the oldest + ;; lines + (when (numberp mu4e-log-max-lines) + (let ((lines (count-lines (point-min) (point-max)))) + (when (> lines mu4e-log-max-lines) + (goto-char (point-max)) + (forward-line (- mu4e-log-max-lines lines)) + (beginning-of-line) + (delete-region (point-min) (point))))))))) + +(defun mu4e-toggle-logging () + "Toggle between enabling/disabling debug-mode (in debug-mode, +mu4e logs some of its internal workings to a log-buffer. See +`mu4e-visit-log'." + (interactive) + (setq mu4e-debug (not mu4e-debug)) + (message "mu4e debug logging has been %s" + (if mu4e-debug "enabled" "disabled"))) + +(defun mu4e-show-log () + "Visit the mu4e debug log." + (interactive) + (let ((buf (get-buffer mu4e-log-buffer-name))) + (unless (buffer-live-p buf) + (error "No debug log available")) + (switch-to-buffer buf))) + + (provide 'mu4e-utils) ;;; End of mu4e-utils.el diff --git a/emacs/mu4e-vars.el b/emacs/mu4e-vars.el index 3a815971..987f8ba3 100644 --- a/emacs/mu4e-vars.el +++ b/emacs/mu4e-vars.el @@ -465,6 +465,14 @@ in which case it will be equal to `:to'.)") (defvar mu4e-captured-message nil "*internal* the last-captured message (the s-expression).") +(defvar mu4e-log-max-lines 1200 + "*internal* Last number of lines to keep around in the buffer.") + +(defconst mu4e-log-buffer-name "*mu4e-log*" + "*internal* Name of the logging buffer.") + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; our handlers funcs diff --git a/emacs/mu4e-view.el b/emacs/mu4e-view.el index b0e18d6d..2c49f63a 100644 --- a/emacs/mu4e-view.el +++ b/emacs/mu4e-view.el @@ -288,6 +288,7 @@ is nil, and otherwise open it." (define-key map "U" 'mu4e-view-unmark-all) (define-key map "x" 'mu4e-view-marked-execute) + (define-key map "$" 'mu4e-show-log) (define-key map "H" 'mu4e-display-manual) ;; menu @@ -359,6 +360,8 @@ is nil, and otherwise open it." (make-local-variable 'mu4e-lines-wrapped) (make-local-variable 'mu4e-cited-hidden) + (setq buffer-undo-list t) ;; don't record undo info + ;; filladapt is much better than the built-in filling ;; esp. with '>' cited parts (when (fboundp 'filladapt-mode) diff --git a/emacs/mu4e.texi b/emacs/mu4e.texi index 4cbb0638..455d1562 100644 --- a/emacs/mu4e.texi +++ b/emacs/mu4e.texi @@ -43,6 +43,7 @@ describes how to set up and use @t{mu4e}. Appendices * How it works:: Some notes about the implementation of mu4e +* Logging and debugging:: How to debug problems in @t{mu4e} * GNU Free Documentation License:: The license of this manual. @end menu @@ -1395,10 +1396,10 @@ menu assumes the default key-bindings, as do the clicks-on-bookmarks. @item @emph{Attachments are not accessible in draft/sent messages}. Currently, attachments in saved messages are special strings, which are transformed into the actual attachments when sending. However, you cannot access them afterwards. - @end itemize + @node How it works @appendix How it works @@ -1549,6 +1550,24 @@ we registered will be called, and it check the version we got from the @t{pong} with the version we expected, and raises an error, if they differ. +@node Logging and debugging +@appendix Logging and debugging + +As explained in @ref{How it works}, @t{mu4e} communicates with its backend +(@t{mu server}) by sending commands and receiving responses (s-expressions). + +For debugging purposes, it can be very useful to see this data. For this +reason, @t{mu4e} can log all these messages. Note that the 'protocol' is +documented to some extent in the @t{mu-server} manpage. + +You can enable (and disable) logging with @t{M-x mu4e-toggle-logging}. The +log-buffer is called @t{*mu4e-log-buffer*}, and in the @ref{Main view}, +@ref{Headers view} and @t{Message view}, there's a keybinding @key{$} that +will take you there. You can quit it by pressing @key{q}. + +Note that logging can be a bit resource-intensive, so you may not want to +leave it on all the time. By default, the log only maintains the most recent +1200 lines. @node GNU Free Documentation License @appendix GNU Free Documentation License