Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 84CB9431FBC for ; Wed, 20 Jan 2010 13:58:15 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: -3.999 X-Spam-Level: X-Spam-Status: No, score=-3.999 tagged_above=-999 required=5 tests=[BAYES_50=0.001, RCVD_IN_DNSWL_MED=-4] autolearn=ham Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id YxTNh47KGfg8 for ; Wed, 20 Jan 2010 13:58:14 -0800 (PST) X-Greylist: delayed 3603 seconds by postgrey-1.32 at olra; Wed, 20 Jan 2010 13:58:14 PST Received: from ipex1.johnshopkins.edu (ipex1.johnshopkins.edu [162.129.8.141]) by olra.theworths.org (Postfix) with ESMTP id 631CE431FAE for ; Wed, 20 Jan 2010 13:58:14 -0800 (PST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AsoEAG39VkuA3DZF/2dsb2JhbACQGwG9UIVJhnaCLoIIBA X-IronPort-AV: E=Sophos;i="4.49,312,1262581200"; d="scan'208";a="288755396" Received: from watt.gilman.jhu.edu ([128.220.54.69]) by ipex1.johnshopkins.edu with ESMTP/TLS/ADH-AES256-SHA; 20 Jan 2010 15:58:11 -0500 Received: by watt.gilman.jhu.edu (Postfix, from userid 502) id B6C6A3E39C9; Wed, 20 Jan 2010 15:58:10 -0500 (EST) From: Jesse Rosenthal To: notmuch@notmuchmail.org Date: Wed, 20 Jan 2010 15:58:10 -0500 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailman-Approved-At: Thu, 21 Jan 2010 01:01:16 -0800 Cc: jrosenthal@jhu.edu Subject: [notmuch] [PATCH] notmuch.el: add functionality to add or remove tags by region. X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 20 Jan 2010 21:58:15 -0000 This patch adds `-region' versions of the `notmuch-search-' commands to find properties. It also splits up `notmuch-add/remove-tags' into both a `-thread' and a `-region' version. (This makes us modify `notmuch-search-archive-thread' to use the `notmuch-search-remove-tag-thread' function, instead of `notmuch-search-remove-tag', for consistency.) The add/remove-tag command called by pressing `+' or `-' will then choose accordingly, based on whether region is active. --- notmuch.el | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 84 insertions(+), 11 deletions(-) diff --git a/notmuch.el b/notmuch.el index 97914f2..e333f24 100644 --- a/notmuch.el +++ b/notmuch.el @@ -1117,18 +1117,41 @@ Complete list of currently available key bindings: (set (make-local-variable 'font-lock-defaults) '(notmuch-search-font-lock-keywords t))) +(defun notmuch-search-properties-in-region (property beg end) + (save-excursion + (let ((output nil) + (last-line (line-number-at-pos end))) + (goto-char beg) + (beginning-of-line) + (while (<= (line-number-at-pos) last-line) + (setq output (cons (get-text-property (point) property) output)) + (forward-line 1)) + output))) + (defun notmuch-search-find-thread-id () "Return the thread for the current thread" (get-text-property (point) 'notmuch-search-thread-id)) +(defun notmuch-search-find-thread-id-region (beg end) + "Return a list of threads for the current region" + (notmuch-search-properties-in-region 'notmuch-search-thread-id beg end)) + (defun notmuch-search-find-authors () "Return the authors for the current thread" (get-text-property (point) 'notmuch-search-authors)) +(defun notmuch-search-find-authors-region (beg end) + "Return a list of authors for the current region" + (notmuch-search-properties-in-region notmuch-search-authors beg end)) + (defun notmuch-search-find-subject () "Return the subject for the current thread" (get-text-property (point) 'notmuch-search-subject)) +(defun notmuch-search-find-subject-region (beg end) + "Return a list of authors for the current region" + (notmuch-search-properties-in-region notmuch-search-subject beg end)) + (defun notmuch-search-show-thread () "Display the currently selected thread." (interactive) @@ -1173,6 +1196,14 @@ and will also appear in a buffer named \"*Notmuch errors*\"." (delete-region beg end) (insert (mapconcat 'identity tags " ")))))) +(defun notmuch-search-set-tags-region (tags beg end) + (save-excursion + (let ((last-line (line-number-at-pos end))) + (goto-char beg) + (while (<= (line-number-at-pos) last-line) + (notmuch-search-set-tags tags) + (forward-line))))) + (defun notmuch-search-get-tags () (save-excursion (end-of-line) @@ -1182,32 +1213,74 @@ and will also appear in a buffer named \"*Notmuch errors*\"." (let ((end (- (point) 1))) (split-string (buffer-substring beg end)))))) +(defun notmuch-search-get-tags-region (beg end) + (save-excursion + (let ((output nil) + (last-line (line-number-at-pos end))) + (goto-char beg) + (while (<= (line-number-at-pos) last-line) + (setq output (append output (notmuch-search-get-tags))) + (forward-line 1)) + output))) + +(defun notmuch-search-add-tag-thread (tag) + (notmuch-call-notmuch-process "tag" (concat "+" tag) (notmuch-search-find-thread-id)) + (notmuch-search-set-tags (delete-dups (sort (cons tag (notmuch-search-get-tags)) 'string<)))) + +(defun notmuch-search-add-tag-region (tag beg end) + (let ((search-id-string (mapconcat 'identity (notmuch-search-find-thread-id-region beg end) " or "))) + (notmuch-call-notmuch-process "tag" (concat "+" tag) search-id-string) + (notmuch-search-set-tags-region (delete-dups (sort (cons tag (notmuch-search-get-tags-region beg end)) 'string<)) beg end))) + +(defun notmuch-search-remove-tag-thread (tag) + (notmuch-call-notmuch-process "tag" (concat "-" tag) (notmuch-search-find-thread-id)) + (notmuch-search-set-tags (delete tag (notmuch-search-get-tags)))) + +(defun notmuch-search-remove-tag-region (tag beg end) + (let ((search-id-string (mapconcat 'identity (notmuch-search-find-thread-id-region beg end) " or "))) + (notmuch-call-notmuch-process "tag" (concat "-" tag) search-id-string) + (notmuch-search-set-tags-region (delete tag (notmuch-search-get-tags-region beg end)) beg end))) + (defun notmuch-search-add-tag (tag) - "Add a tag to the currently selected thread. + "Add a tag to the currently selected thread or region. -The tag is added to messages in the currently selected thread -which match the current search terms." +The tag is added to messages in the currently selected thread or +region which match the current search terms." (interactive (list (notmuch-select-tag-with-completion "Tag to add: "))) - (notmuch-call-notmuch-process "tag" (concat "+" tag) (notmuch-search-find-thread-id)) - (notmuch-search-set-tags (delete-dups (sort (cons tag (notmuch-search-get-tags)) 'string<)))) + (save-excursion + (if (region-active-p) + (let* ((beg (region-beginning)) + (end (region-end))) + (notmuch-search-add-tag-region tag beg end)) + (notmuch-search-add-tag-thread tag)))) (defun notmuch-search-remove-tag (tag) - "Remove a tag from the currently selected thread. + "Remove a tag from the currently selected thread or region. The tag is removed from messages in the currently selected thread -which match the current search terms." +or region which match the current search terms." (interactive - (list (notmuch-select-tag-with-completion "Tag to remove: " (notmuch-search-find-thread-id)))) - (notmuch-call-notmuch-process "tag" (concat "-" tag) (notmuch-search-find-thread-id)) - (notmuch-search-set-tags (delete tag (notmuch-search-get-tags)))) + (list (notmuch-select-tag-with-completion + "Tag to remove: " + (if (region-active-p) + (mapconcat 'identity + (notmuch-search-find-thread-id-region (region-beginning) (region-end)) + " ") + (notmuch-search-find-thread-id))))) + (save-excursion + (if (region-active-p) + (let* ((beg (region-beginning)) + (end (region-end))) + (notmuch-search-remove-tag-region tag beg end)) + (notmuch-search-remove-tag-thread tag)))) (defun notmuch-search-archive-thread () "Archive the currently selected thread (remove its \"inbox\" tag). This function advances the next thread when finished." (interactive) - (notmuch-search-remove-tag "inbox") + (notmuch-search-remove-tag-thread "inbox") (forward-line)) (defun notmuch-search-process-sentinel (proc msg) -- 1.6.5.3