]> git.cworth.org Git - notmuch/blobdiff - emacs/notmuch-show.el
emacs: Optionally retain the state of the buffer during `notmuch-show-refresh-view'.
[notmuch] / emacs / notmuch-show.el
index c8371e7539f1e19054fecc395509b97b5fa3b8f0..33845d3972cc62f58849813add8f850d517b1be1 100644 (file)
@@ -146,6 +146,10 @@ indentation."
 (make-variable-buffer-local 'notmuch-show-elide-non-matching-messages)
 (put 'notmuch-show-elide-non-matching-messages 'permanent-local t)
 
+(defvar notmuch-show-indent-content t)
+(make-variable-buffer-local 'notmuch-show-indent-content)
+(put 'notmuch-show-indent-content 'permanent-local t)
+
 (defmacro with-current-notmuch-show-message (&rest body)
   "Evaluate body with current buffer set to the text of current message"
   `(save-excursion
@@ -256,10 +260,12 @@ operation on the contents of the current buffer."
         (all (buffer-substring (notmuch-show-message-top)
                                (notmuch-show-message-bottom)))
 
-        (props (notmuch-show-get-message-properties)))
+        (props (notmuch-show-get-message-properties))
+        (indenting notmuch-show-indent-content))
     (with-temp-buffer
       (insert all)
-      (indent-rigidly (point-min) (point-max) (- depth))
+      (if indenting
+         (indent-rigidly (point-min) (point-max) (- depth)))
       ;; Remove the original header.
       (goto-char (point-min))
       (re-search-forward "^$" (point-max) nil)
@@ -900,7 +906,8 @@ current buffer, if possible."
     (setq body-start (point-marker))
     ;; A blank line between the headers and the body.
     (insert "\n")
-    (notmuch-show-insert-body msg (plist-get msg :body) depth)
+    (notmuch-show-insert-body msg (plist-get msg :body)
+                             (if notmuch-show-indent-content depth 0))
     ;; Ensure that the body ends with a newline.
     (unless (bolp)
       (insert "\n"))
@@ -908,7 +915,8 @@ current buffer, if possible."
     (setq content-end (point-marker))
 
     ;; Indent according to the depth in the thread.
-    (indent-rigidly content-start content-end (* notmuch-show-indent-messages-width depth))
+    (if notmuch-show-indent-content
+       (indent-rigidly content-start content-end (* notmuch-show-indent-messages-width depth)))
 
     (setq message-end (point-max-marker))
 
@@ -944,7 +952,7 @@ current buffer, if possible."
   (message (if notmuch-show-process-crypto
               "Processing cryptographic MIME parts."
             "Not processing cryptographic MIME parts."))
-  (notmuch-show-refresh-view))
+  (notmuch-show-refresh-view t))
 
 (defun notmuch-show-toggle-elide-non-matching ()
   "Toggle the display of non-matching messages."
@@ -953,7 +961,16 @@ current buffer, if possible."
   (message (if notmuch-show-elide-non-matching-messages
               "Showing matching messages only."
             "Showing all messages."))
-  (notmuch-show-refresh-view))
+  (notmuch-show-refresh-view t))
+
+(defun notmuch-show-toggle-thread-indentation ()
+  "Toggle the indentation of threads."
+  (interactive)
+  (setq notmuch-show-indent-content (not notmuch-show-indent-content))
+  (message (if notmuch-show-indent-content
+              "Content is indented."
+            "Content is not indented."))
+  (notmuch-show-refresh-view t))
 
 (defun notmuch-show-insert-tree (tree depth)
   "Insert the message tree TREE at depth DEPTH in the current thread."
@@ -1057,14 +1074,54 @@ function is used."
 
     (notmuch-show-mark-read)))
 
-(defun notmuch-show-refresh-view ()
+(defun notmuch-show-capture-state ()
+  "Capture the state of the current buffer.
+
+This includes:
+ - the list of open messages,
+ - the current message."
+  (list (notmuch-show-get-message-id) (notmuch-show-get-message-ids-for-open-messages)))
+
+(defun notmuch-show-apply-state (state)
+  "Apply STATE to the current buffer.
+
+This includes:
+ - opening the messages previously opened,
+ - closing all other messages,
+ - moving to the correct current message."
+  (let ((current (car state))
+       (open (cadr state)))
+
+    ;; Open those that were open.
+    (goto-char (point-min))
+    (loop do (notmuch-show-message-visible (notmuch-show-get-message-properties)
+                                          (member (notmuch-show-get-message-id) open))
+         until (not (notmuch-show-goto-message-next)))
+
+    ;; Go to the previously open message.
+    (goto-char (point-min))
+    (unless (loop if (string= current (notmuch-show-get-message-id))
+                 return t
+                 until (not (notmuch-show-goto-message-next)))
+      (goto-char (point-min))
+      (message "Previously current message not found."))
+    (notmuch-show-message-adjust)))
+
+(defun notmuch-show-refresh-view (&optional retain-state)
   "Refresh the current view.
 
-Refreshes the current view, observing changes in cryptographic preferences."
+Refreshes the current view, observing changes in display
+preferences. If RETAIN-STATE is non-nil then the state of the
+buffer is stored and re-applied after the refresh."
   (interactive)
-  (let ((inhibit-read-only t))
-    (erase-buffer))
-  (notmuch-show-worker))
+  (let ((inhibit-read-only t)
+       state)
+    (if retain-state
+       (setq state (notmuch-show-capture-state)))
+    (erase-buffer)
+    (notmuch-show-worker)
+    (if state
+       (notmuch-show-apply-state state))))
 
 (defvar notmuch-show-stash-map
   (let ((map (make-sparse-keymap)))
@@ -1119,6 +1176,8 @@ Refreshes the current view, observing changes in cryptographic preferences."
        (define-key map "#" 'notmuch-show-print-message)
        (define-key map "!" 'notmuch-show-toggle-elide-non-matching)
        (define-key map "$" 'notmuch-show-toggle-process-crypto)
+       (define-key map "<" 'notmuch-show-toggle-thread-indentation)
+       (define-key map "t" 'toggle-truncate-lines)
        map)
       "Keymap for \"notmuch show\" buffers.")
 (fset 'notmuch-show-mode-map notmuch-show-mode-map)