From 06bffb1158259f53a99962254e597671a9ec5886 Mon Sep 17 00:00:00 2001 From: jao Date: Wed, 18 Aug 2021 03:54:45 +0100 Subject: notmuch: show/hide trees --- lib/net/jao-notmuch.el | 116 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 86 insertions(+), 30 deletions(-) (limited to 'lib/net') diff --git a/lib/net/jao-notmuch.el b/lib/net/jao-notmuch.el index cedd2cf..1bcdaef 100644 --- a/lib/net/jao-notmuch.el +++ b/lib/net/jao-notmuch.el @@ -154,7 +154,7 @@ (let ((pos (point))) (while (setq pos (next-single-property-change pos 'w3m-href-anchor)) (when-let ((url (get-text-property pos 'w3m-href-anchor))) - (add-to-list 'res url t))) + (cl-pushnew 'res url))) res))) (defun jao-notmuch-browse-urls (&optional external) @@ -167,25 +167,6 @@ (funcall fn (completing-read "Browse URL: " urls)) (message "No URLs in this message"))))) - -;; Outline mode for tree view - -(defun jao-notmuch--setup-outline () - (setq-local outline-regexp ".+ [┬─] ") - (outline-minor-mode 1)) - -(add-hook 'notmuch-tree-mode-hook #'jao-notmuch--setup-outline) - -(defun jao-notmuch--tree-toggle (&rest _args) - (when outline-minor-mode - (outline-toggle-children))) - -(advice-add 'notmuch-tree-matching-message :before #'jao-notmuch--tree-toggle) -(advice-add 'notmuch-tree-matching-message :after #'jao-notmuch--tree-toggle) - -(define-key notmuch-tree-mode-map (kbd "T TAB") 'outline-cycle) -(define-key notmuch-tree-mode-map (kbd "T t") 'outline-cycle) - ;; Toggling mime parts and images @@ -285,8 +266,7 @@ (when (and (eq status 'exit) (buffer-live-p buffer)) (with-current-buffer buffer (jao-notmuch--tree-update-buffer-name) - (outline-hide-body) - (outline-toggle-children))))) + (jao-notmuch-tree-hide-all))))) (advice-add 'notmuch-tree-process-sentinel :after #'jao-notmuch--tree-sentinel) @@ -297,16 +277,92 @@ (jao-notmuch--tree-update-buffer-name n) (message n))) + +;; Show/hide threads + +(defun jao-notmuch--tree-top () (notmuch-tree-get-prop :first)) + +(defun jao-notmuch-tree-hide-thread () + (interactive) + (notmuch-tree-thread-top) + (save-excursion + (forward-line 1) + (when (not (jao-notmuch--tree-top)) + (let ((line-move-ignore-invisible nil) + (inhibit-read-only t) + (p (point))) + (unless (notmuch-tree-next-thread-in-tree) + (forward-line -1)) + (add-text-properties p (point) '(invisible t)))))) + +(defun jao-notmuch-tree-show-thread () + (interactive) + (when (or (jao-notmuch--tree-top) (invisible-p (point))) + (let ((line-move-ignore-invisible nil)) + (notmuch-tree-thread-top) + (let ((inhibit-read-only t) + (p (point))) + (notmuch-tree-next-thread-in-tree) + (remove-text-properties p (point) '(invisible nil)) + (goto-char p))))) + +(defun jao-notmuch-tree-show-all () + (interactive) + (let ((inhibit-read-only t)) + (put-text-property (point-min) (point-max) 'invisible nil))) + +(defun jao-notmuch-tree-hide-all () + (interactive) + (goto-char (point-min)) + (let ((inhibit-read-only t) + (line-move-ignore-invisible nil)) + (while (not (eobp)) + (forward-line) + (unless (jao-notmuch--tree-top) + (put-text-property (point) + (min (1+ (line-end-position)) (point-max)) + 'invisible t)))) + (goto-char (point-min))) + +(defun jao-notmuch-tree-toggle-thread () + (interactive) + (let ((line-move-ignore-invisible nil)) + (forward-line 1) + (when (jao-notmuch--tree-top) + (forward-line -1)) + (if (invisible-p (point)) + (jao-notmuch-tree-show-thread) + (jao-notmuch-tree-hide-thread)))) + +(defvar notmuch-tree-thread-map + (let ((m (make-keymap "Thread operations"))) + (define-key m (kbd "TAB") #'jao-notmuch-tree-toggle-thread) + (define-key m (kbd "t") #'jao-notmuch-tree-toggle-thread) + (define-key m (kbd "s") #'jao-notmuch-tree-show-thread) + (define-key m (kbd "S") #'jao-notmuch-tree-show-all) + (define-key m (kbd "h") #'jao-notmuch-tree-hide-thread) + (define-key m (kbd "H") #'jao-notmuch-tree-hide-all) + m)) + +(defun jao-notmuch--tree-next (prev thread no-exit) + (save-excursion (jao-notmuch-tree-hide-thread)) + (let ((line-move-ignore-invisible nil)) + (when thread (notmuch-tree-next-thread prev)) + (unless (jao-notmuch--looking-at-new-p) + (notmuch-tree-matching-message prev (not no-exit)))) + (save-excursion (jao-notmuch-tree-show-thread)) + (notmuch-tree-show-message nil) + (jao-notmuch--tree-update-buffer-name)) + (defun jao-notmuch-tree-next (thread &optional no-exit) - "Next message or thread in forest or exit if none." + "Next message or thread in forest, taking care of thread visibility." (interactive "P") - (if thread - (progn (notmuch-tree-next-thread) - (unless (jao-notmuch--looking-at-new-p) - (notmuch-tree-next-matching-message (not no-exit))) - (notmuch-tree-show-message nil)) - (notmuch-tree-next-matching-message (not no-exit))) - (jao-notmuch--tree-update-buffer-name)) + (jao-notmuch--tree-next nil thread no-exit)) + +(defun jao-notmuch-tree-previous (thread) + "Previous message or thread in forest, taking care of thread visibility.." + (interactive "P") + (jao-notmuch--tree-next t thread t)) ;; Tagging -- cgit v1.2.3