;;; Code:
+(eval-when-compile (require 'cl-lib))
+
(require 'mail-parse)
(require 'notmuch-lib)
(require 'notmuch-tag)
(require 'notmuch-parser)
-(eval-when-compile (require 'cl))
(declare-function notmuch-search "notmuch" (&optional query oldest-first target-thread target-line))
(declare-function notmuch-call-notmuch-process "notmuch" (&rest args))
(declare-function notmuch-read-query "notmuch" (prompt))
;; The main tree view bindings
(define-key map (kbd "RET") 'notmuch-tree-show-message)
(define-key map [mouse-1] 'notmuch-tree-show-message)
- (define-key map "x" 'notmuch-tree-quit)
+ (define-key map "x" 'notmuch-tree-archive-message-then-next-or-exit)
+ (define-key map "X" 'notmuch-tree-archive-thread-then-exit)
(define-key map "A" 'notmuch-tree-archive-thread)
(define-key map "a" 'notmuch-tree-archive-message-then-next)
(define-key map "z" 'notmuch-tree-to-tree)
(when (notmuch-tree-scroll-message-window)
(notmuch-tree-next-matching-message)))
-(defun notmuch-tree-quit ()
+(defun notmuch-tree-quit (&optional kill-both)
"Close the split view or exit tree."
- (interactive)
- (unless (notmuch-tree-close-message-window)
+ (interactive "P")
+ (when (or (not (notmuch-tree-close-message-window)) kill-both)
(kill-buffer (current-buffer))))
(defun notmuch-tree-close-message-window ()
(notmuch-tree-archive-message unarchive)
(notmuch-tree-next-matching-message))
+(defun notmuch-tree-archive-thread-then-exit ()
+ "Archive all messages in the current buffer, then exit notmuch-tree."
+ (interactive)
+ (notmuch-tree-archive-thread)
+ (notmuch-tree-quit t))
+
+(defun notmuch-tree-archive-message-then-next-or-exit ()
+ "Archive current message, then show next open message in current thread.
+
+If at the last open message in the current thread, then exit back
+to search results."
+ (interactive)
+ (notmuch-tree-archive-message)
+ (notmuch-tree-next-matching-message t))
+
(defun notmuch-tree-next-message ()
"Move to next message."
(interactive)
(when (window-live-p notmuch-tree-message-window)
(notmuch-tree-show-message-in)))
-(defun notmuch-tree-prev-matching-message ()
+(defun notmuch-tree-goto-matching-message (&optional prev)
+ "Move to the next or previous matching message.
+
+Returns t if there was a next matching message in the thread to show,
+nil otherwise."
+ (let ((dir (if prev -1 nil))
+ (eobfn (if prev #'bobp #'eobp)))
+ (while (and (not (funcall eobfn))
+ (not (notmuch-tree-get-match)))
+ (forward-line dir))
+ (not (funcall eobfn))))
+
+(defun notmuch-tree-matching-message (&optional prev pop-at-end)
+ "Move to the next or previous matching message"
+ (interactive "P")
+ (forward-line (if prev -1 nil))
+ (if (and (not (notmuch-tree-goto-matching-message prev)) pop-at-end)
+ (notmuch-tree-quit pop-at-end)
+ (when (window-live-p notmuch-tree-message-window)
+ (notmuch-tree-show-message-in))))
+
+(defun notmuch-tree-prev-matching-message (&optional pop-at-end)
"Move to previous matching message."
- (interactive)
- (forward-line -1)
- (while (and (not (bobp)) (not (notmuch-tree-get-match)))
- (forward-line -1))
- (when (window-live-p notmuch-tree-message-window)
- (notmuch-tree-show-message-in)))
+ (interactive "P")
+ (notmuch-tree-matching-message t pop-at-end))
-(defun notmuch-tree-next-matching-message ()
+(defun notmuch-tree-next-matching-message (&optional pop-at-end)
"Move to next matching message."
- (interactive)
- (forward-line)
- (while (and (not (eobp)) (not (notmuch-tree-get-match)))
- (forward-line))
- (when (window-live-p notmuch-tree-message-window)
- (notmuch-tree-show-message-in)))
+ (interactive "P")
+ (notmuch-tree-matching-message nil pop-at-end))
(defun notmuch-tree-refresh-view (&optional view)
"Refresh view."
and call FUNCTION for side effects."
(save-excursion
(notmuch-tree-thread-top)
- (loop collect (funcall function)
- do (forward-line)
- while (and (notmuch-tree-get-message-properties)
- (not (notmuch-tree-get-prop :first))))))
+ (cl-loop collect (funcall function)
+ do (forward-line)
+ while (and (notmuch-tree-get-message-properties)
+ (not (notmuch-tree-get-prop :first))))))
(defun notmuch-tree-get-messages-ids-thread-search ()
"Return a search string for all message ids of messages in the current thread."
(defun notmuch-tree-insert-thread (thread depth tree-status)
"Insert the collection of sibling sub-threads THREAD at depth DEPTH in the current forest."
(let ((n (length thread)))
- (loop for tree in thread
- for count from 1 to n
-
- do (notmuch-tree-insert-tree tree depth tree-status (eq count 1) (eq count n)))))
+ (cl-loop for tree in thread
+ for count from 1 to n
+ do (notmuch-tree-insert-tree tree depth tree-status
+ (eq count 1)
+ (eq count n)))))
(defun notmuch-tree-insert-forest-thread (forest-thread)
"Insert a single complete thread."