From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Andrea Monaco Newsgroups: gmane.emacs.devel Subject: [PATCH] Summary by thread in rmail Date: Wed, 05 Oct 2022 23:57:49 +0200 Message-ID: <87o7uq6ihu.fsf@autistici.org> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="10238"; mail-complaints-to="usenet@ciao.gmane.io" To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Wed Oct 05 23:59:02 2022 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ogCPt-0002Uj-8Q for ged-emacs-devel@m.gmane-mx.org; Wed, 05 Oct 2022 23:59:01 +0200 Original-Received: from localhost ([::1]:37488 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ogCPs-0003i8-Bw for ged-emacs-devel@m.gmane-mx.org; Wed, 05 Oct 2022 17:59:00 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:35148) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ogCOs-0002k0-Vi for emacs-devel@gnu.org; Wed, 05 Oct 2022 17:57:59 -0400 Original-Received: from confino.investici.org ([93.190.126.19]:59153) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ogCOo-0002XH-Av for emacs-devel@gnu.org; Wed, 05 Oct 2022 17:57:58 -0400 Original-Received: from mx1.investici.org (unknown [127.0.0.1]) by confino.investici.org (Postfix) with ESMTP id 4MjT2k5nfNz11CH for ; Wed, 5 Oct 2022 21:57:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=autistici.org; s=stigmate; t=1665007070; bh=On4ywCLyDQ0/+rG9rcO0GbAroPMWhRDFd8d7KC/Dntw=; h=From:To:Subject:Date:From; b=SjbHS/hxTvpETAuHCiSz0UZQXNPT8BIMUKn16L8f48TTu9aPAvBbuBLOSpNfbFu/F zdxqwVDkO8HpuuqyQ5JIlQQqkHVdtYjFQkAL6gqsIdLJ3rN/VPDClX/QY+zyAAxcjz qevrlF0Qq3p3666LWL9sY/0C1kSIoiOQCbZDuW6c= Original-Received: from [93.190.126.19] (mx1.investici.org [93.190.126.19]) (Authenticated sender: andrea.monaco@autistici.org) by localhost (Postfix) with ESMTPSA id 4MjT2k52dvz11CG for ; Wed, 5 Oct 2022 21:57:50 +0000 (UTC) Received-SPF: pass client-ip=93.190.126.19; envelope-from=andrea.monaco@autistici.org; helo=confino.investici.org X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:297016 Archived-At: I had some code ready. This only looks at the Subject field. You can invoke it with rmail-thread-summary and it creates a buffer called e.g. RMAIL-thread-summary that is independent of RMAIL-summary. There's still no code to update the summary after getting new mail. It's basic, but it works. Let me know, Andrea Monaco diff --git a/lisp/mail/rmailthread.el b/lisp/mail/rmailthread.el new file mode 100644 index 0000000000..a06d0ab144 --- /dev/null +++ b/lisp/mail/rmailthread.el @@ -0,0 +1,147 @@ + +(defvar rmail-thread-summary-buffer nil) +(put 'rmail-thread-summary-buffer 'permanent-local t) + + + + +(defun rmail-get-create-thread-summary-buffer () + "Return the Rmail thread summary buffer. +If necessary, it is created and undo is disabled." + (if (and rmail-thread-summary-buffer (buffer-name rmail-thread-summary-buffer)) + rmail-thread-summary-buffer + (let ((buff (generate-new-buffer (concat (buffer-name) "-thread-summary")))) + (with-current-buffer buff + (setq buffer-undo-list t)) + buff))) + + + +(defun rmail-new-thread-summary (desc redo function &rest args) + "Create a summary of selected messages by thread." + (message "Computing thread summary lines...") + (unless rmail-buffer + (error "No RMAIL buffer found")) + (let (mesg was-in-summary sumbuf) + (if (derived-mode-p 'rmail-summary-mode) + (setq was-in-summary t)) + (with-current-buffer rmail-buffer + (setq rmail-thread-summary-buffer (rmail-new-thread-summary-1 desc redo function args) + ;; r-s-b is buffer-local. + sumbuf rmail-thread-summary-buffer + mesg rmail-current-message)) + ;; Now display the summary buffer and go to the right place in it. + (unless was-in-summary + (if (and (one-window-p) + pop-up-windows + (not pop-up-frames)) + ;; If there is just one window, put the summary on the top. + (progn + (split-window (selected-window) rmail-summary-window-size) + (select-window (next-window (frame-first-window))) + (rmail-pop-to-buffer sumbuf) + ;; If pop-to-buffer did not use that window, delete that + ;; window. (This can happen if it uses another frame.) + (if (not (eq sumbuf (window-buffer (frame-first-window)))) + (delete-other-windows))) + (rmail-pop-to-buffer sumbuf)) + (set-buffer rmail-buffer)) + ;; This is how rmail makes the summary buffer reappear. + ;; We do this here to make the window the proper size. + ;(rmail-select-summary nil) + ;(set-buffer sumbuf)) + (switch-to-buffer sumbuf) + ;(rmail-summary-goto-msg mesg t t) + ;(rmail-summary-construct-io-menu) + (message "Computing thread summary lines... done"))) + + + +(defun rmail-new-thread-summary-1 (description redo function args) + (let ((summary-msgs ()) + (rmail-new-thread-summary-line-count 0) + ordered-threads + (threadbuf (rmail-get-create-thread-summary-buffer))) + ;; Scan the messages, getting their summary strings + ;; and putting the list of them in SUMMARY-MSGS. + (let* ((msgnum 1) + (main-buffer (current-buffer)) + (total rmail-total-messages) + (rmail-thread-hash-table (make-hash-table :test 'equal :size 1024)) + (inhibit-read-only t)) + (save-excursion + ;; Go where the mbox text is. + (if (rmail-buffers-swapped-p) + (set-buffer rmail-view-buffer)) + (let ((old-min (point-min-marker)) + (old-max (point-max-marker))) + (unwind-protect + ;; Can't use save-restriction here; that doesn't work if we + ;; plan to modify text outside the original restriction. + (save-excursion + (widen) + (goto-char (point-min)) + (while (>= total msgnum) + (with-current-buffer main-buffer + ;; First test whether to include this message. + (if (or (null function) + (apply function msgnum args)) + (let* ((subject (rmail-simplified-subject msgnum)) + (cell (gethash subject rmail-thread-hash-table)) + (th cell) + thread) + (while (and (not thread) th) + (if (equal (caar th) subject) + (setq thread (car th))) + (setq th (cdr th))) + (if thread + (setcdr thread + (cons (cons msgnum (rmail-get-summary msgnum)) (cdr thread))) + (progn + (let* ((newthread (list subject (cons msgnum (rmail-get-summary msgnum)))) + (newcell (cons newthread cell))) + (setq cell newcell) + (puthash subject newcell rmail-thread-hash-table) + (setq ordered-threads (cons newthread ordered-threads))))) + (setq msgnum (1+ msgnum)) + (if (and (not (zerop msgnum)) + (zerop (% msgnum 10))) + (message "Computing thread summary lines... %d" + msgnum)))))) + (setq ordered-threads (nreverse ordered-threads)))) + (narrow-to-region old-min old-max)))) + (setq rmail-thread-summary-buffer nil) + (save-excursion + (let ((rbuf (current-buffer)) + (total rmail-total-messages)) + (set-buffer threadbuf) + ;; Set up the summary buffer's contents. + (let ((buffer-read-only nil)) + (erase-buffer) + (while ordered-threads + (let ((thread-message (cdar ordered-threads))) + (setq thread-message (nreverse thread-message)) + (princ (cdar thread-message) threadbuf) + (setq thread-message (cdr thread-message)) + (while thread-message + (let* ((suml (cdar thread-message)) + (newsuml (concat (substring suml 0 42) " " (substring suml 42)))) + (princ newsuml threadbuf)) + (setq thread-message (cdr thread-message)))) + (setq ordered-threads (cdr ordered-threads))) + (goto-char (point-min))) + ;; Set up the rest of its state and local variables. + (setq buffer-read-only t) + (rmail-summary-mode) + (setq-local minor-mode-alist (list (list t (concat ": " description)))) + (setq rmail-buffer rbuf + rmail-summary-redo redo + rmail-total-messages total))) + threadbuf)) + + + +(defun rmail-thread-summary () + "Display a summary of all messages by thread, one line per message." + (interactive) + (rmail-new-thread-summary "All" '(rmail-thread-summary) nil))