* another attempt to add delete functionality in emacs @ 2012-01-07 22:28 Jameson Graef Rollins 2012-01-07 22:28 ` [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search Jameson Graef Rollins 2012-01-10 7:47 ` another attempt to add delete functionality in emacs David Edmondson 0 siblings, 2 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-07 22:28 UTC (permalink / raw) To: Notmuch Mail So, after many stabs at adding the ability to "delete" messages in emacs [0], and the corresponding heated discussions, I'm throwing another attempt into the fray. I try to address the concerns that have come up in previous attempts. In particular, I include a patch that creates a new customization variable, notmuch-search-exclude-deleted, that will exclude any messages with the "deleted" tag from searches. This actually makes "deleted" messages appear effectively deleted, which is one of the things cworth wanted to see, and one of the reasons he kept pushing back on previous attempts at this functionality. Also, no tags other than "deleted" are modified. All tags should be orthogonal, and should be handled so. Note: this is all about handling the "deleted" tag. No actual deletion of message is involved in this functionality at all. Actual deletion of messages should always be left entirely up to the user to handle as they see fit. jamie. [0] id:"1266408746-28549-1-git-send-email-Sebastian@SSpaeth.de" id:"87sk8qwjlt.fsf@yoom.home.cworth.org" id:"1271891763-10757-1-git-send-email-hohndel@infradead.org" id:"1310841600-28281-1-git-send-email-anarcat@koumbit.org" ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search 2012-01-07 22:28 another attempt to add delete functionality in emacs Jameson Graef Rollins @ 2012-01-07 22:28 ` Jameson Graef Rollins 2012-01-07 22:28 ` [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging Jameson Graef Rollins 2012-01-09 1:14 ` [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search Aaron Ecay 2012-01-10 7:47 ` another attempt to add delete functionality in emacs David Edmondson 1 sibling, 2 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-07 22:28 UTC (permalink / raw) To: Notmuch Mail The new customization variable, notmuch-search-exclude-deleted, when set to t, will exclude any messages with the "deleted" tag from searches. Additionally, specifying "tag:deleted" in the search directly will override the exclusion and will included deleted messages in the search results. --- emacs/notmuch.el | 8 ++++ test/emacs | 42 ++++++++++++++++++++ .../notmuch-search-tag-inbox-deleted-excluded | 24 +++++++++++ 3 files changed, 74 insertions(+), 0 deletions(-) create mode 100644 test/emacs.expected-output/notmuch-search-tag-inbox-deleted-excluded diff --git a/emacs/notmuch.el b/emacs/notmuch.el index fde2377..c519687 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -905,6 +905,11 @@ PROMPT is the string to prompt with." (read-from-minibuffer prompt nil keymap nil 'notmuch-query-history nil nil)))) +(defcustom notmuch-search-exclude-deleted nil + "Exclude deleted messages (with \"deleted\" tag) from search results." + :group 'notmuch + :type 'boolean) + ;;;###autoload (defun notmuch-search (query &optional oldest-first target-thread target-line continuation) "Run \"notmuch search\" with the given query string and display results. @@ -927,6 +932,9 @@ The optional parameters are used as follows: (set 'notmuch-search-target-thread target-thread) (set 'notmuch-search-target-line target-line) (set 'notmuch-search-continuation continuation) + (when (and notmuch-search-exclude-deleted + (not (string-match "tag:deleted[ )]*" query))) + (setq query (concat query " and not tag:deleted"))) (let ((proc (get-buffer-process (current-buffer))) (inhibit-read-only t)) (if proc diff --git a/test/emacs b/test/emacs index a06c223..1d78fbe 100755 --- a/test/emacs +++ b/test/emacs @@ -35,6 +35,48 @@ test_emacs '(notmuch-search "tag:inbox") (test-output)' test_expect_equal_file OUTPUT $EXPECTED/notmuch-search-tag-inbox +test_begin_subtest "Exclude \"deleted\" messages from search" +notmuch tag +deleted id:1258506353-20352-1-git-send-email-stewart@flamingspork.com +# we "delete" a second message that's part of a multi-message thread +# to make sure the rest of the thread is still returned +notmuch tag +deleted id:1258471718-6781-1-git-send-email-dottedmag@dottedmag.net +test_emacs '(let ((notmuch-search-exclude-deleted t)) + (notmuch-search "tag:inbox") + (notmuch-test-wait) + (test-output))' +notmuch tag -deleted id:1258506353-20352-1-git-send-email-stewart@flamingspork.com +notmuch tag -deleted id:1258471718-6781-1-git-send-email-dottedmag@dottedmag.net +test_expect_equal_file OUTPUT $EXPECTED/notmuch-search-tag-inbox-deleted-excluded + +test_begin_subtest "Exclude \"deleted\" messages from search, manual override" +notmuch tag +deleted id:1258506353-20352-1-git-send-email-stewart@flamingspork.com +notmuch tag +deleted id:1258471718-6781-1-git-send-email-dottedmag@dottedmag.net +cat <<EOF >EXPECTED + 2009-11-18 [1/1] Stewart Smith [notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (deleted inbox unread) + 2009-11-17 [1/5] Mikhail Gusarov, Carl Worth, Keith Packard [notmuch] [PATCH 1/2] Close message file after parsing message headers (deleted inbox unread) +End of search results. +EOF +test_emacs '(let ((notmuch-search-exclude-deleted t)) + (notmuch-search "tag:inbox and tag:deleted") + (notmuch-test-wait) + (test-output))' +notmuch tag -deleted id:1258506353-20352-1-git-send-email-stewart@flamingspork.com +notmuch tag -deleted id:1258471718-6781-1-git-send-email-dottedmag@dottedmag.net +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Exclude \"deleted\" messages from search, but not \"deleted*\"" +notmuch tag +deleted-patch id:1258506353-20352-1-git-send-email-stewart@flamingspork.com +cat <<EOF >EXPECTED + 2009-11-18 [1/1] Stewart Smith [notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (deleted-patch inbox unread) +End of search results. +EOF +test_emacs '(let ((notmuch-search-exclude-deleted t)) + (notmuch-search "tag:inbox and tag:deleted-patch") + (notmuch-test-wait) + (test-output))' +notmuch tag -deleted-patch id:1258506353-20352-1-git-send-email-stewart@flamingspork.com +test_expect_equal_file OUTPUT EXPECTED + test_begin_subtest "Navigation of notmuch-hello to search results" test_emacs '(notmuch-hello) (goto-char (point-min)) diff --git a/test/emacs.expected-output/notmuch-search-tag-inbox-deleted-excluded b/test/emacs.expected-output/notmuch-search-tag-inbox-deleted-excluded new file mode 100644 index 0000000..39b4c51 --- /dev/null +++ b/test/emacs.expected-output/notmuch-search-tag-inbox-deleted-excluded @@ -0,0 +1,24 @@ + 2010-12-29 [1/1] François Boulogne [aur-general] Guidelines: cp, mkdir vs install (inbox unread) + 2010-12-16 [1/1] Olivier Berger Essai accentué (inbox unread) + 2009-11-18 [1/1] Chris Wilson [notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once (inbox unread) + 2009-11-18 [2/2] Alex Botero-Lowry, Carl Worth [notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment inbox unread) + 2009-11-18 [2/2] Ingmar Vanhassel, Carl Worth [notmuch] [PATCH] Typsos (inbox unread) + 2009-11-18 [3/3] Adrian Perez de Castro, Keith Packard, Carl Worth [notmuch] Introducing myself (inbox signed unread) + 2009-11-18 [3/3] Israel Herraiz, Keith Packard, Carl Worth [notmuch] New to the list (inbox unread) + 2009-11-18 [3/3] Jan Janak, Carl Worth [notmuch] What a great idea! (inbox unread) + 2009-11-18 [2/2] Jan Janak, Carl Worth [notmuch] [PATCH] Older versions of install do not support -C. (inbox unread) + 2009-11-18 [3/3] Aron Griffis, Keith Packard, Carl Worth [notmuch] archive (inbox unread) + 2009-11-18 [2/2] Keith Packard, Carl Worth [notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread) + 2009-11-18 [7/7] Lars Kellogg-Stedman, Mikhail Gusarov, Keith Packard, Carl Worth [notmuch] Working with Maildir storage? (inbox signed unread) + 2009-11-18 [4/5] Mikhail Gusarov, Carl Worth, Keith Packard [notmuch] [PATCH 1/2] Close message file after parsing message headers (deleted inbox unread) + 2009-11-18 [2/2] Keith Packard, Alexander Botero-Lowry [notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox unread) + 2009-11-18 [1/1] Alexander Botero-Lowry [notmuch] request for pull (inbox unread) + 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry [notmuch] Mac OS X/Darwin compatibility issues (inbox unread) + 2009-11-18 [1/1] Rolland Santimano [notmuch] Link to mailing list archives ? (inbox unread) + 2009-11-18 [1/1] Jan Janak [notmuch] [PATCH] notmuch new: Support for conversion of spool subdirectories into tags (inbox unread) + 2009-11-18 [1/1] Stewart Smith [notmuch] [PATCH] count_files: sort directory in inode order before statting (inbox unread) + 2009-11-18 [1/1] Stewart Smith [notmuch] [PATCH 2/2] Read mail directory in inode number order (inbox unread) + 2009-11-18 [2/2] Lars Kellogg-Stedman [notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread) + 2009-11-17 [1/1] Mikhail Gusarov [notmuch] [PATCH] Handle rename of message file (inbox unread) + 2009-11-17 [2/2] Alex Botero-Lowry, Carl Worth [notmuch] preliminary FreeBSD support (attachment inbox unread) +End of search results. -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging 2012-01-07 22:28 ` [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search Jameson Graef Rollins @ 2012-01-07 22:28 ` Jameson Graef Rollins 2012-01-07 22:28 ` [PATCH 3/4] emacs: add ability to "delete" messages and threads Jameson Graef Rollins 2012-01-09 1:08 ` [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging Aaron Ecay 2012-01-09 1:14 ` [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search Aaron Ecay 1 sibling, 2 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-07 22:28 UTC (permalink / raw) To: Notmuch Mail Instead of having a function that is only used for archiving a thread, we instead make it useful for any tagging operation. The new function, notmuch-show-tag-thread-internal, now takes two more arguments, for the "sign" of the tagging operation ("-" or "+"), and the tag to be added or removed. This will allow this function to be used for any generic thread tagging operation. The higher level functions that call this function are modified accordingly. --- emacs/notmuch-show.el | 34 ++++++++++++++++++++-------------- 1 files changed, 20 insertions(+), 14 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 5502efd..1e16f05 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1414,20 +1414,26 @@ argument, hide all of the messages." (interactive) (backward-button 1)) -(defun notmuch-show-archive-thread-internal (show-next) +(defun notmuch-show-tag-thread-internal (sign tag show-next) ;; Remove the tag from the current set of messages. (goto-char (point-min)) - (loop do (notmuch-show-remove-tag "inbox") - until (not (notmuch-show-goto-message-next))) - ;; Move to the next item in the search results, if any. - (let ((parent-buffer notmuch-show-parent-buffer)) - (notmuch-kill-this-buffer) - (if parent-buffer - (progn - (switch-to-buffer parent-buffer) - (forward-line) - (if show-next - (notmuch-search-show-thread)))))) + (let ((tag-function)) + (cond + ((string= sign "-") + (setq tag-function 'notmuch-show-remove-tag)) + ((string= sign "+") + (setq tag-function 'notmuch-show-add-tag))) + (loop do (funcall tag-function tag) + until (not (notmuch-show-goto-message-next))) + ;; Move to the next item in the search results, if any. + (let ((parent-buffer notmuch-show-parent-buffer)) + (notmuch-kill-this-buffer) + (if parent-buffer + (progn + (switch-to-buffer parent-buffer) + (forward-line) + (if show-next + (notmuch-search-show-thread))))))) (defun notmuch-show-archive-thread () "Archive each message in thread, then show next thread from search. @@ -1441,12 +1447,12 @@ being delivered to the same thread. It does not archive the entire thread, but only the messages shown in the current buffer." (interactive) - (notmuch-show-archive-thread-internal t)) + (notmuch-show-tag-thread-internal "-" "inbox" t)) (defun notmuch-show-archive-thread-then-exit () "Archive each message in thread, then exit back to search results." (interactive) - (notmuch-show-archive-thread-internal nil)) + (notmuch-show-tag-thread-internal "-" "inbox" nil)) (defun notmuch-show-stash-cc () "Copy CC field of current message to kill-ring." -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH 3/4] emacs: add ability to "delete" messages and threads 2012-01-07 22:28 ` [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging Jameson Graef Rollins @ 2012-01-07 22:28 ` Jameson Graef Rollins 2012-01-07 22:28 ` [PATCH 4/4] emacs: modify help message for notmuch-search-line-faces to reflect preferred "deleted" tag name Jameson Graef Rollins 2012-01-08 1:26 ` change to default archive/delete key bindings Jameson Graef Rollins 2012-01-09 1:08 ` [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging Aaron Ecay 1 sibling, 2 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-07 22:28 UTC (permalink / raw) To: Notmuch Mail This completely mimics the behavior of archiving, but instead of remove the inbox tag it add the "deleted" tag. The functionality is bound to the 'd' key in both search and show mode. Note: this does *not* actually delete any messages. That is still left entirely up to the user to figure out how they want to handle that. This *just* adds the "deleted" tag to messages, no more. If the notmuch-search-exclude-deleted config variable is set, though, "deleted" messages will be excluded from search results. --- emacs/notmuch-show.el | 15 +++++++++++++++ emacs/notmuch.el | 12 ++++++++++++ 2 files changed, 27 insertions(+), 0 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 1e16f05..e1d15f4 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -944,6 +944,7 @@ thread id. If a prefix is given, crypto processing is toggled." (define-key map "+" 'notmuch-show-add-tag) (define-key map "x" 'notmuch-show-archive-thread-then-exit) (define-key map "a" 'notmuch-show-archive-thread) + (define-key map "d" 'notmuch-show-delete-thread) (define-key map "N" 'notmuch-show-next-message) (define-key map "P" 'notmuch-show-previous-message) (define-key map "n" 'notmuch-show-next-open-message) @@ -1454,6 +1455,20 @@ buffer." (interactive) (notmuch-show-tag-thread-internal "-" "inbox" nil)) +(defun notmuch-show-delete-thread () + "Delete each message in thread, then show next thread from search. + +Delete each message currently shown by adding the \"deleted\" +tag to each. Then kill this buffer and show the next thread +from the search from which this thread was originally shown. + +Note: This command is safe from any race condition of new messages +being delivered to the same thread. It does not archive the +entire thread, but only the messages shown in the current +buffer." + (interactive) + (notmuch-show-tag-thread-internal "+" "deleted" t)) + (defun notmuch-show-stash-cc () "Copy CC field of current message to kill-ring." (interactive) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index c519687..2b860f4 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -218,6 +218,7 @@ For a mouse binding, return nil." (define-key map [mouse-1] 'notmuch-search-show-thread) (define-key map "*" 'notmuch-search-operate-all) (define-key map "a" 'notmuch-search-archive-thread) + (define-key map "d" 'notmuch-search-delete-thread) (define-key map "-" 'notmuch-search-remove-tag) (define-key map "+" 'notmuch-search-add-tag) (define-key map (kbd "RET") 'notmuch-search-show-thread) @@ -605,6 +606,17 @@ This function advances the next thread when finished." (notmuch-search-remove-tag-thread "inbox") (forward-line)) +(defun notmuch-search-delete-thread () + "Delete the currently selected thread (add the \"deleted\" tag). + +This function advances the next thread when finished. + +If notmuch-search-exclude-deleted is set, \"deleted\" messages +will be excluded from searches." + (interactive) + (notmuch-search-add-tag "deleted") + (forward-line)) + (defvar notmuch-search-process-filter-data nil "Data that has not yet been processed.") (make-variable-buffer-local 'notmuch-search-process-filter-data) -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH 4/4] emacs: modify help message for notmuch-search-line-faces to reflect preferred "deleted" tag name. 2012-01-07 22:28 ` [PATCH 3/4] emacs: add ability to "delete" messages and threads Jameson Graef Rollins @ 2012-01-07 22:28 ` Jameson Graef Rollins 2012-01-08 1:26 ` change to default archive/delete key bindings Jameson Graef Rollins 1 sibling, 0 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-07 22:28 UTC (permalink / raw) To: Notmuch Mail No functional change here. The help message previously referred to the "delete" tag, but "deleted" is now preferred, so hopefully this will reduce any potential confusion. --- emacs/notmuch.el | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 2b860f4..ebdc7d1 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -658,12 +658,12 @@ will be excluded from searches." Here is an example of how to color search results based on tags. (the following text would be placed in your ~/.emacs file): - (setq notmuch-search-line-faces '((\"delete\" . (:foreground \"red\" + (setq notmuch-search-line-faces '((\"deleted\" . (:foreground \"red\" :background \"blue\")) (\"unread\" . (:foreground \"green\")))) The attributes defined for matching tags are merged, with later -attributes overriding earlier. A message having both \"delete\" +attributes overriding earlier. A message having both \"deleted\" and \"unread\" tags with the above settings would have a green foreground and blue background." :type '(alist :key-type (string) :value-type (custom-face-edit)) -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* change to default archive/delete key bindings 2012-01-07 22:28 ` [PATCH 3/4] emacs: add ability to "delete" messages and threads Jameson Graef Rollins 2012-01-07 22:28 ` [PATCH 4/4] emacs: modify help message for notmuch-search-line-faces to reflect preferred "deleted" tag name Jameson Graef Rollins @ 2012-01-08 1:26 ` Jameson Graef Rollins 2012-01-08 1:26 ` [PATCH 1/4] emacs: add show-mode functions to archive/delete only current message Jameson Graef Rollins 2012-01-10 7:48 ` change to default archive/delete key bindings David Edmondson 1 sibling, 2 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-08 1:26 UTC (permalink / raw) To: Notmuch Mail While working on the delete message handling patches, I was reminded how much I really dislike the default show-mode key bindings. Why can't I just archive/delete the current message, without archiving the entire thread? It doesn't make any sense. Here we add two new functions to archive and delete just the single message, and then move to the next open message. We also add an option to the -next-open-message function so that it will pop back out to the parent search buffer when reaching the end of the thread. This should make message processing flow much smoother. Patches 1,2 and 4 can be applied even if the consensus is to not change the default key bindings, to make it easier for users to achieve the desired functionality without having to write their own functions. jamie. ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 1/4] emacs: add show-mode functions to archive/delete only current message 2012-01-08 1:26 ` change to default archive/delete key bindings Jameson Graef Rollins @ 2012-01-08 1:26 ` Jameson Graef Rollins 2012-01-08 1:26 ` [PATCH 2/4] emacs: add option to notmuch-show-next-open-message to pop out to parent buffer if at end Jameson Graef Rollins 2012-01-08 19:09 ` [PATCH 1/4 v2] emacs: add show-mode functions to archive/delete only current message Jameson Graef Rollins 2012-01-10 7:48 ` change to default archive/delete key bindings David Edmondson 1 sibling, 2 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-08 1:26 UTC (permalink / raw) To: Notmuch Mail This adds two new function, notmuch-show-{archive,delete}-message, that archive/delete the current message, and then move to the next open one. --- emacs/notmuch-show.el | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+), 0 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index e1d15f4..8bb052e 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1436,6 +1436,18 @@ argument, hide all of the messages." (if show-next (notmuch-search-show-thread))))))) +(defun notmuch-show-archive-message () + "Archive the current message and advance. + +After the last message is reached, either the buffer will be +closed and the cursor will move to the search result if +available, or the cursor will move to the end of the current +thread. +" + (interactive) + (notmuch-show-remove-tag "inbox") + (notmuch-show-next-open-message))) + (defun notmuch-show-archive-thread () "Archive each message in thread, then show next thread from search. @@ -1455,6 +1467,18 @@ buffer." (interactive) (notmuch-show-tag-thread-internal "-" "inbox" nil)) +(defun notmuch-show-delete-message () + "Delete the current message and advance. + +After the last message is reached, either the buffer will be +closed and the cursor will move to the search result if +available, or the cursor will move to the end of the current +thread. +" + (interactive) + (notmuch-show-add-tag "deleted") + (notmuch-show-next-open-message))) + (defun notmuch-show-delete-thread () "Delete each message in thread, then show next thread from search. -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH 2/4] emacs: add option to notmuch-show-next-open-message to pop out to parent buffer if at end 2012-01-08 1:26 ` [PATCH 1/4] emacs: add show-mode functions to archive/delete only current message Jameson Graef Rollins @ 2012-01-08 1:26 ` Jameson Graef Rollins 2012-01-08 1:26 ` [PATCH 3/4] emacs: modify the default show-mode key bindings for archiving/deleting Jameson Graef Rollins 2012-01-09 1:12 ` [PATCH 2/4] emacs: add option to notmuch-show-next-open-message to pop out to parent buffer if at end Aaron Ecay 2012-01-08 19:09 ` [PATCH 1/4 v2] emacs: add show-mode functions to archive/delete only current message Jameson Graef Rollins 1 sibling, 2 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-08 1:26 UTC (permalink / raw) To: Notmuch Mail This will allow for keybindings that achieve a smoother message processing flow by reducing the number of key presses needed for most common operations. --- emacs/notmuch-show.el | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 8bb052e..e7bb958 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1264,17 +1264,23 @@ any effects from previous calls to (notmuch-show-mark-read) (notmuch-show-message-adjust)) -(defun notmuch-show-next-open-message () +(defun notmuch-show-next-open-message (&optional pop-at-end) "Show the next message." (interactive) - (let (r) + (let ((r) + (parent-buffer notmuch-show-parent-buffer)) (while (and (setq r (notmuch-show-goto-message-next)) (not (notmuch-show-message-visible-p)))) (if r (progn (notmuch-show-mark-read) (notmuch-show-message-adjust)) - (goto-char (point-max))))) + (if (and parent-buffer pop-at-end) + (progn + (kill-this-buffer) + (switch-to-buffer parent-buffer) + (forward-line 1)) + (goto-char (point-max)))))) (defun notmuch-show-previous-open-message () "Show the previous message." -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH 3/4] emacs: modify the default show-mode key bindings for archiving/deleting 2012-01-08 1:26 ` [PATCH 2/4] emacs: add option to notmuch-show-next-open-message to pop out to parent buffer if at end Jameson Graef Rollins @ 2012-01-08 1:26 ` Jameson Graef Rollins 2012-01-08 1:26 ` [PATCH 4/4] emacs: use pop-at-end functionality in archive/delete-message functions Jameson Graef Rollins 2012-01-09 1:12 ` [PATCH 2/4] emacs: add option to notmuch-show-next-open-message to pop out to parent buffer if at end Aaron Ecay 1 sibling, 1 reply; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-08 1:26 UTC (permalink / raw) To: Notmuch Mail This changes the default key bindings for the 'a' and 'd' keys in notmuch-show mode. Instead of archiving/deleting the entire thread, they now just archive/delete the current message, and then advance to the next open message. 'A' and 'D' are rebound to the previous archive/delete-thread functions. --- emacs/notmuch-show.el | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index e7bb958..4c2b507 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -943,8 +943,10 @@ thread id. If a prefix is given, crypto processing is toggled." (define-key map "-" 'notmuch-show-remove-tag) (define-key map "+" 'notmuch-show-add-tag) (define-key map "x" 'notmuch-show-archive-thread-then-exit) - (define-key map "a" 'notmuch-show-archive-thread) - (define-key map "d" 'notmuch-show-delete-thread) + (define-key map "a" 'notmuch-show-archive-message) + (define-key map "A" 'notmuch-show-archive-thread) + (define-key map "d" 'notmuch-show-delete-message) + (define-key map "D" 'notmuch-show-delete-thread) (define-key map "N" 'notmuch-show-next-message) (define-key map "P" 'notmuch-show-previous-message) (define-key map "n" 'notmuch-show-next-open-message) -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH 4/4] emacs: use pop-at-end functionality in archive/delete-message functions 2012-01-08 1:26 ` [PATCH 3/4] emacs: modify the default show-mode key bindings for archiving/deleting Jameson Graef Rollins @ 2012-01-08 1:26 ` Jameson Graef Rollins 2012-01-08 18:56 ` [PATCH 4/4 v2] " Jameson Graef Rollins 0 siblings, 1 reply; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-08 1:26 UTC (permalink / raw) To: Notmuch Mail This provides a smoother message processing flow by reducing the number of key presses needed for these common operations. --- emacs/notmuch-show.el | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 4c2b507..7103c23 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1454,7 +1454,7 @@ thread. " (interactive) (notmuch-show-remove-tag "inbox") - (notmuch-show-next-open-message))) + (notmuch-show-next-open-message t))) (defun notmuch-show-archive-thread () "Archive each message in thread, then show next thread from search. @@ -1485,7 +1485,7 @@ thread. " (interactive) (notmuch-show-add-tag "deleted") - (notmuch-show-next-open-message))) + (notmuch-show-next-open-message t))) (defun notmuch-show-delete-thread () "Delete each message in thread, then show next thread from search. -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH 4/4 v2] emacs: use pop-at-end functionality in archive/delete-message functions 2012-01-08 1:26 ` [PATCH 4/4] emacs: use pop-at-end functionality in archive/delete-message functions Jameson Graef Rollins @ 2012-01-08 18:56 ` Jameson Graef Rollins 2012-01-08 19:28 ` [PATCH 4/4 v3] " Jameson Graef Rollins 0 siblings, 1 reply; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-08 18:56 UTC (permalink / raw) To: Notmuch Mail This provides a smoother message processing flow by reducing the number of key presses needed for these common operations. --- Sorry, there were some errant extra parens at the end of these function definitions. emacs/notmuch-show.el | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 4c2b507..a706637 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1454,7 +1454,7 @@ thread. " (interactive) (notmuch-show-remove-tag "inbox") - (notmuch-show-next-open-message))) + (notmuch-show-next-open-message t)) (defun notmuch-show-archive-thread () "Archive each message in thread, then show next thread from search. @@ -1485,7 +1485,7 @@ thread. " (interactive) (notmuch-show-add-tag "deleted") - (notmuch-show-next-open-message))) + (notmuch-show-next-open-message t)) (defun notmuch-show-delete-thread () "Delete each message in thread, then show next thread from search. -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH 4/4 v3] emacs: use pop-at-end functionality in archive/delete-message functions 2012-01-08 18:56 ` [PATCH 4/4 v2] " Jameson Graef Rollins @ 2012-01-08 19:28 ` Jameson Graef Rollins 0 siblings, 0 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-08 19:28 UTC (permalink / raw) To: Notmuch Mail This provides a smoother message processing flow by reducing the number of key presses needed for these common operations. --- Sorry sorry. I originally missed the problem in patch 1/4, so I had to modify this patch again to apply against the new version of the previous. So sorry for the noise, and thanks to amdragon for pointing all of this out. emacs/notmuch-show.el | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index b9ec584..a706637 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1454,7 +1454,7 @@ thread. " (interactive) (notmuch-show-remove-tag "inbox") - (notmuch-show-next-open-message)) + (notmuch-show-next-open-message t)) (defun notmuch-show-archive-thread () "Archive each message in thread, then show next thread from search. @@ -1485,7 +1485,7 @@ thread. " (interactive) (notmuch-show-add-tag "deleted") - (notmuch-show-next-open-message)) + (notmuch-show-next-open-message t)) (defun notmuch-show-delete-thread () "Delete each message in thread, then show next thread from search. -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH 2/4] emacs: add option to notmuch-show-next-open-message to pop out to parent buffer if at end 2012-01-08 1:26 ` [PATCH 2/4] emacs: add option to notmuch-show-next-open-message to pop out to parent buffer if at end Jameson Graef Rollins 2012-01-08 1:26 ` [PATCH 3/4] emacs: modify the default show-mode key bindings for archiving/deleting Jameson Graef Rollins @ 2012-01-09 1:12 ` Aaron Ecay 1 sibling, 0 replies; 176+ messages in thread From: Aaron Ecay @ 2012-01-09 1:12 UTC (permalink / raw) To: Jameson Graef Rollins, Notmuch Mail Jameson, One small, stylistic/nitpicky comment :) On Sat, 7 Jan 2012 17:26:53 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > This will allow for keybindings that achieve a smoother message > processing flow by reducing the number of key presses needed for most > common operations. > --- > emacs/notmuch-show.el | 12 +++++++++--- > 1 files changed, 9 insertions(+), 3 deletions(-) > > diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el > index 8bb052e..e7bb958 100644 > --- a/emacs/notmuch-show.el > +++ b/emacs/notmuch-show.el > @@ -1264,17 +1264,23 @@ any effects from previous calls to > (notmuch-show-mark-read) > (notmuch-show-message-adjust)) > > -(defun notmuch-show-next-open-message () > +(defun notmuch-show-next-open-message (&optional pop-at-end) > "Show the next message." > (interactive) > - (let (r) > + (let ((r) > + (parent-buffer notmuch-show-parent-buffer)) No second set of parentheses is needed around r. Also, it is more idiomatic to put the initialized variable (i.e. parent-buffer) before the uninitialized one (r). > (while (and (setq r (notmuch-show-goto-message-next)) > (not (notmuch-show-message-visible-p)))) > (if r > (progn > (notmuch-show-mark-read) > (notmuch-show-message-adjust)) > - (goto-char (point-max))))) > + (if (and parent-buffer pop-at-end) > + (progn > + (kill-this-buffer) > + (switch-to-buffer parent-buffer) > + (forward-line 1)) > + (goto-char (point-max)))))) > > (defun notmuch-show-previous-open-message () > "Show the previous message." > -- > 1.7.7.3 > > _______________________________________________ > notmuch mailing list > notmuch@notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch -- Aaron Ecay ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 1/4 v2] emacs: add show-mode functions to archive/delete only current message 2012-01-08 1:26 ` [PATCH 1/4] emacs: add show-mode functions to archive/delete only current message Jameson Graef Rollins 2012-01-08 1:26 ` [PATCH 2/4] emacs: add option to notmuch-show-next-open-message to pop out to parent buffer if at end Jameson Graef Rollins @ 2012-01-08 19:09 ` Jameson Graef Rollins 2012-01-10 7:43 ` David Edmondson 1 sibling, 1 reply; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-08 19:09 UTC (permalink / raw) To: Notmuch Mail This adds two new function, notmuch-show-{archive,delete}-message, that archive/delete the current message, and then move to the next open one. --- Sorry, there were some errant extra parens at the end of these function definitions. emacs/notmuch-show.el | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+), 0 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index e1d15f4..b2e7829 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1436,6 +1436,18 @@ argument, hide all of the messages." (if show-next (notmuch-search-show-thread))))))) +(defun notmuch-show-archive-message () + "Archive the current message and advance. + +After the last message is reached, either the buffer will be +closed and the cursor will move to the search result if +available, or the cursor will move to the end of the current +thread. +" + (interactive) + (notmuch-show-remove-tag "inbox") + (notmuch-show-next-open-message)) + (defun notmuch-show-archive-thread () "Archive each message in thread, then show next thread from search. @@ -1455,6 +1467,18 @@ buffer." (interactive) (notmuch-show-tag-thread-internal "-" "inbox" nil)) +(defun notmuch-show-delete-message () + "Delete the current message and advance. + +After the last message is reached, either the buffer will be +closed and the cursor will move to the search result if +available, or the cursor will move to the end of the current +thread. +" + (interactive) + (notmuch-show-add-tag "deleted") + (notmuch-show-next-open-message)) + (defun notmuch-show-delete-thread () "Delete each message in thread, then show next thread from search. -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH 1/4 v2] emacs: add show-mode functions to archive/delete only current message 2012-01-08 19:09 ` [PATCH 1/4 v2] emacs: add show-mode functions to archive/delete only current message Jameson Graef Rollins @ 2012-01-10 7:43 ` David Edmondson 0 siblings, 0 replies; 176+ messages in thread From: David Edmondson @ 2012-01-10 7:43 UTC (permalink / raw) To: Jameson Graef Rollins, Notmuch Mail [-- Attachment #1: Type: text/plain, Size: 257 bytes --] On Sun, 8 Jan 2012 11:09:09 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > This adds two new function, notmuch-show-{archive,delete}-message, > that archive/delete the current message, and then move to the next > open one. Looks fine. [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: change to default archive/delete key bindings 2012-01-08 1:26 ` change to default archive/delete key bindings Jameson Graef Rollins 2012-01-08 1:26 ` [PATCH 1/4] emacs: add show-mode functions to archive/delete only current message Jameson Graef Rollins @ 2012-01-10 7:48 ` David Edmondson 1 sibling, 0 replies; 176+ messages in thread From: David Edmondson @ 2012-01-10 7:48 UTC (permalink / raw) To: Jameson Graef Rollins, Notmuch Mail [-- Attachment #1: Type: text/plain, Size: 793 bytes --] On Sat, 7 Jan 2012 17:26:51 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > While working on the delete message handling patches, I was reminded > how much I really dislike the default show-mode key bindings. Why > can't I just archive/delete the current message, without archiving the > entire thread? It doesn't make any sense. > > Here we add two new functions to archive and delete just the single > message, and then move to the next open message. We also add an > option to the -next-open-message function so that it will pop back out > to the parent search buffer when reaching the end of the thread. This > should make message processing flow much smoother. This seems good to me, though it will confuse me for a while when first introduced :-/ [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging 2012-01-07 22:28 ` [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging Jameson Graef Rollins 2012-01-07 22:28 ` [PATCH 3/4] emacs: add ability to "delete" messages and threads Jameson Graef Rollins @ 2012-01-09 1:08 ` Aaron Ecay 2012-01-09 2:49 ` Jameson Graef Rollins 1 sibling, 1 reply; 176+ messages in thread From: Aaron Ecay @ 2012-01-09 1:08 UTC (permalink / raw) To: Jameson Graef Rollins, Notmuch Mail Jameson, Some comments below: On Sat, 7 Jan 2012 14:28:12 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > Instead of having a function that is only used for archiving a thread, > we instead make it useful for any tagging operation. The new > function, notmuch-show-tag-thread-internal, now takes two more > arguments, for the "sign" of the tagging operation ("-" or "+"), and > the tag to be added or removed. This will allow this function to be > used for any generic thread tagging operation. > > The higher level functions that call this function are modified > accordingly. > --- > emacs/notmuch-show.el | 34 ++++++++++++++++++++-------------- > 1 files changed, 20 insertions(+), 14 deletions(-) > > diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el > index 5502efd..1e16f05 100644 > --- a/emacs/notmuch-show.el > +++ b/emacs/notmuch-show.el > @@ -1414,20 +1414,26 @@ argument, hide all of the messages." > (interactive) > (backward-button 1)) > > -(defun notmuch-show-archive-thread-internal (show-next) > +(defun notmuch-show-tag-thread-internal (sign tag show-next) A couple of comments on the arguments: - It would be good to make show-next &optional. This will enable code to call the fn with only two arguments, and not showing next will be the default behavior. - A more lispy way of specifying the sign would be to use a boolean. Perhaps you could call this “remove”; a value of ‘t’ would remove the tag; ‘nil’ would add it. Moving this argument after ‘tag’ and also making it &optional woudl allow this fn to be called with one arg to add a tag. (Maybe this is too minimalist and API, however.) > ;; Remove the tag from the current set of messages. > (goto-char (point-min)) > - (loop do (notmuch-show-remove-tag "inbox") > - until (not (notmuch-show-goto-message-next))) > - ;; Move to the next item in the search results, if any. > - (let ((parent-buffer notmuch-show-parent-buffer)) > - (notmuch-kill-this-buffer) > - (if parent-buffer > - (progn > - (switch-to-buffer parent-buffer) > - (forward-line) > - (if show-next > - (notmuch-search-show-thread)))))) > + (let ((tag-function)) No second set of parens is needed around tag-function. > + (cond > + ((string= sign "-") > + (setq tag-function 'notmuch-show-remove-tag)) > + ((string= sign "+") > + (setq tag-function 'notmuch-show-add-tag))) > + (loop do (funcall tag-function tag) > + until (not (notmuch-show-goto-message-next))) > + ;; Move to the next item in the search results, if any. Does it make sense to separate the tagging and the movement? It seems plausible that some code somewhere might want to add/remove a tag from all messages in the thread w/o changing the display. > + (let ((parent-buffer notmuch-show-parent-buffer)) > + (notmuch-kill-this-buffer) > + (if parent-buffer > + (progn > + (switch-to-buffer parent-buffer) > + (forward-line) > + (if show-next > + (notmuch-search-show-thread))))))) -- Aaron Ecay ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging 2012-01-09 1:08 ` [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging Aaron Ecay @ 2012-01-09 2:49 ` Jameson Graef Rollins 2012-01-09 5:02 ` Aaron Ecay 0 siblings, 1 reply; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-09 2:49 UTC (permalink / raw) To: Aaron Ecay, Notmuch Mail [-- Attachment #1: Type: text/plain, Size: 1466 bytes --] Thanks so much for the review, Aaron. On Sun, 08 Jan 2012 20:08:59 -0500, Aaron Ecay <aaronecay@gmail.com> wrote: > A couple of comments on the arguments: > - It would be good to make show-next &optional. This will enable code > to call the fn with only two arguments, and not showing next will be > the default behavior. That's a nice idea. Probably better for a separate patch, though. > - A more lispy way of specifying the sign would be to use a > boolean. Perhaps you could call this “remove”; a value of ‘t’ would > remove the tag; ‘nil’ would add it. Moving this argument after ‘tag’ > and also making it &optional woudl allow this fn to be called with one > arg to add a tag. (Maybe this is too minimalist and API, however.) That might be more lispy, but it seems a lot less clear to me. It might save a few keystrokes when coding, but it would definitely make the code a lot harder to read ("remove" to add a tag?). I think I would prefer people to give the sign explicitly. > No second set of parens is needed around tag-function. Yeah, I've seen this either way. I guess it's just a stylistic choice. I think it might make sense, but again I think that's out of the scope of this patch series. The point was to make a minimal set of modifications here. If we want to separate out the functionality, we should do that in a separate patch. Thanks again for the review. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging 2012-01-09 2:49 ` Jameson Graef Rollins @ 2012-01-09 5:02 ` Aaron Ecay 2012-01-11 2:56 ` Jameson Graef Rollins 0 siblings, 1 reply; 176+ messages in thread From: Aaron Ecay @ 2012-01-09 5:02 UTC (permalink / raw) To: Jameson Graef Rollins, Notmuch Mail On Sun, 08 Jan 2012 18:49:56 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > Thanks so much for the review, Aaron. > > On Sun, 08 Jan 2012 20:08:59 -0500, Aaron Ecay <aaronecay@gmail.com> wrote: > > A couple of comments on the arguments: > > - It would be good to make show-next &optional. This will enable code > > to call the fn with only two arguments, and not showing next will be > > the default behavior. > > That's a nice idea. Probably better for a separate patch, though. This patch introduces show-next as a new argument to the function. So it can and should make it &optional, if that is the appropriate semantics for it to have. > > > - A more lispy way of specifying the sign would be to use a > > boolean. Perhaps you could call this “remove”; a value of ‘t’ would > > remove the tag; ‘nil’ would add it. Moving this argument after ‘tag’ > > and also making it &optional woudl allow this fn to be called with one > > arg to add a tag. (Maybe this is too minimalist and API, however.) > > That might be more lispy, but it seems a lot less clear to me. It might > save a few keystrokes when coding, but it would definitely make the code > a lot harder to read ("remove" to add a tag?). I think I would prefer > people to give the sign explicitly. Using a string value makes it harder to interface with other code. For example, the prefix argument (C-u) is delivered to emacs commands as a boolean value (nil if no arg, something truthy if the arg is given). A plausible custom end user function/keybinding would be one to add a tag to the open messages, or remove that tag if the prefix arg is given to the same command. (So that ‘d’ deletes and ‘C-u d’ undeletes, for example.) In order to do that, the user’s code has to convert the prefix arg into a string. Making something “lispy” isn’t just about code readability/saving keystrokes, but also refers to how well the code interfaces with the conventions used by the rest of the emacs environment. That said, here’s an alternate proposal: provide two functions as the “external” API, namely ‘notmuch-show-{add,remove}-tag-thread’ (by parallelism with ‘notmuch-show-{add,remove}-tag’). These could be thin wrappers around ‘notmuch-show-tag-thread-internal’, which would then not be intended to be called by user code. > > > No second set of parens is needed around tag-function. > > Yeah, I've seen this either way. I guess it's just a stylistic > choice. Using double parens is semantically correct, but makes the code less idiomatic and harder to read (IMO). To test my intuition, I looked at ‘let’ invocations in the Emacs source that have a non-initialized variable (because the multiple variable case is hard to grep for). Double parens are used only 3% of the time (44 double vs 1468 single). Make of this data what you will. -- Aaron Ecay ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging 2012-01-09 5:02 ` Aaron Ecay @ 2012-01-11 2:56 ` Jameson Graef Rollins 2012-01-11 5:53 ` Aaron Ecay 0 siblings, 1 reply; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-11 2:56 UTC (permalink / raw) To: Aaron Ecay, Notmuch Mail [-- Attachment #1: Type: text/plain, Size: 1376 bytes --] On Mon, 09 Jan 2012 00:02:20 -0500, Aaron Ecay <aaronecay@gmail.com> wrote: > On Sun, 08 Jan 2012 18:49:56 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > > On Sun, 08 Jan 2012 20:08:59 -0500, Aaron Ecay <aaronecay@gmail.com> wrote: > > > > > > - It would be good to make show-next &optional. This will enable code > > > to call the fn with only two arguments, and not showing next will be > > > the default behavior. > > > > That's a nice idea. Probably better for a separate patch, though. > > This patch introduces show-next as a new argument to the function. So it > can and should make it &optional, if that is the appropriate semantics > for it to have. Actually, the show-next argument was already part of the function. I did not introduce it. And it wasn't optional originally, so if we want to change that behavior we should probably do so in a separate patch. > That said, here’s an alternate proposal: provide two functions as the > “external” API, namely ‘notmuch-show-{add,remove}-tag-thread’ (by > parallelism with ‘notmuch-show-{add,remove}-tag’). These could be > thin wrappers around ‘notmuch-show-tag-thread-internal’, which would > then not be intended to be called by user code. I think that's a better idea. In the next version I'll add something like this instead. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging 2012-01-11 2:56 ` Jameson Graef Rollins @ 2012-01-11 5:53 ` Aaron Ecay 2012-01-11 7:07 ` Jameson Graef Rollins 0 siblings, 1 reply; 176+ messages in thread From: Aaron Ecay @ 2012-01-11 5:53 UTC (permalink / raw) To: Jameson Graef Rollins, Notmuch Mail On Tue, 10 Jan 2012 18:56:29 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > Actually, the show-next argument was already part of the function. I > did not introduce it. And it wasn't optional originally, so if we want > to change that behavior we should probably do so in a separate patch. Hrm. I didn’t communicate as clearly as I could have – you are correct that the show-next argument to the notmuch-show-archive-internal function was pre-existing. But notmuch-show-tag-thread-internal is a new function, with potentially expanded usefulness to third-party code. Thus I think I’m in the clear to bikeshed about its calling convention. :) It’s your patch, though, so it’s your call if you feel that the &optional goes best in a new change. -- Aaron Ecay ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging 2012-01-11 5:53 ` Aaron Ecay @ 2012-01-11 7:07 ` Jameson Graef Rollins 0 siblings, 0 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-11 7:07 UTC (permalink / raw) To: Aaron Ecay, Notmuch Mail [-- Attachment #1: Type: text/plain, Size: 1026 bytes --] On Wed, 11 Jan 2012 00:53:35 -0500, Aaron Ecay <aaronecay@gmail.com> wrote: > On Tue, 10 Jan 2012 18:56:29 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > > Actually, the show-next argument was already part of the function. I > > did not introduce it. And it wasn't optional originally, so if we want > > to change that behavior we should probably do so in a separate patch. > > Hrm. I didn’t communicate as clearly as I could have – you are correct > that the show-next argument to the notmuch-show-archive-internal function > was pre-existing. But notmuch-show-tag-thread-internal is a new function, > with potentially expanded usefulness to third-party code. Thus I think > I’m in the clear to bikeshed about its calling convention. :) It’s your > patch, though, so it’s your call if you feel that the &optional goes best > in a new change. No, I see your point, Aaron. I'll rework it to make it a little clean and more flexible when I resend. Thanks again. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search 2012-01-07 22:28 ` [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search Jameson Graef Rollins 2012-01-07 22:28 ` [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging Jameson Graef Rollins @ 2012-01-09 1:14 ` Aaron Ecay 2012-01-09 1:49 ` Austin Clements 1 sibling, 1 reply; 176+ messages in thread From: Aaron Ecay @ 2012-01-09 1:14 UTC (permalink / raw) To: Jameson Graef Rollins, Notmuch Mail Jameson, One comment On Sat, 7 Jan 2012 14:28:11 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > The new customization variable, notmuch-search-exclude-deleted, when > set to t, will exclude any messages with the "deleted" tag from > searches. > > Additionally, specifying "tag:deleted" in the search directly will > override the exclusion and will included deleted messages in the > search results. > --- > emacs/notmuch.el | 8 ++++ > test/emacs | 42 ++++++++++++++++++++ > .../notmuch-search-tag-inbox-deleted-excluded | 24 +++++++++++ > 3 files changed, 74 insertions(+), 0 deletions(-) > create mode 100644 test/emacs.expected-output/notmuch-search-tag-inbox-deleted-excluded > > diff --git a/emacs/notmuch.el b/emacs/notmuch.el > index fde2377..c519687 100644 > --- a/emacs/notmuch.el > +++ b/emacs/notmuch.el > @@ -905,6 +905,11 @@ PROMPT is the string to prompt with." > (read-from-minibuffer prompt nil keymap nil > 'notmuch-query-history nil nil)))) > > +(defcustom notmuch-search-exclude-deleted nil > + "Exclude deleted messages (with \"deleted\" tag) from search results." > + :group 'notmuch > + :type 'boolean) > + > ;;;###autoload > (defun notmuch-search (query &optional oldest-first target-thread target-line continuation) > "Run \"notmuch search\" with the given query string and display results. > @@ -927,6 +932,9 @@ The optional parameters are used as follows: > (set 'notmuch-search-target-thread target-thread) > (set 'notmuch-search-target-line target-line) > (set 'notmuch-search-continuation continuation) > + (when (and notmuch-search-exclude-deleted > + (not (string-match "tag:deleted[ )]*" query))) “is:” is a synonym for “tag:” in searches – so this section of the code should look for it too. -- Aaron Ecay ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search 2012-01-09 1:14 ` [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search Aaron Ecay @ 2012-01-09 1:49 ` Austin Clements 2012-01-09 2:34 ` Jameson Graef Rollins 2012-01-09 4:31 ` Austin Clements 0 siblings, 2 replies; 176+ messages in thread From: Austin Clements @ 2012-01-09 1:49 UTC (permalink / raw) To: Aaron Ecay; +Cc: Notmuch Mail > > @@ -927,6 +932,9 @@ The optional parameters are used as follows: > > (set 'notmuch-search-target-thread target-thread) > > (set 'notmuch-search-target-line target-line) > > (set 'notmuch-search-continuation continuation) > > + (when (and notmuch-search-exclude-deleted > > + (not (string-match "tag:deleted[ )]*" query))) > > “is:” is a synonym for “tag:” in searches – so this section of the code > should look for it too. There are several other things that could also trip up this regexp. xtag:deletedx would be falsely matched, as would a quoted phrase containing "tag:deleted", while tag:"deleted" and tag:(deleted) would incorrectly not be matched. Getting this right is hard, though I'd be happy with "\\<\\(tag\\|is\\):deleted\\>" or maybe "\\<\\(tag\\|is\\):\\(\"?\\)deleted\\>\\2" Implicit exclusions like this were actually one of my target features for the custom query parser, but I think hacking around that by inspecting the query string is a fine interim solution. (One of these months I'll dust off the query parser, really!) ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search 2012-01-09 1:49 ` Austin Clements @ 2012-01-09 2:34 ` Jameson Graef Rollins 2012-01-09 2:46 ` Austin Clements 2012-01-09 4:31 ` Austin Clements 1 sibling, 1 reply; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-09 2:34 UTC (permalink / raw) To: Austin Clements, Aaron Ecay; +Cc: Notmuch Mail [-- Attachment #1: Type: text/plain, Size: 2163 bytes --] On Sun, 8 Jan 2012 20:49:38 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > > @@ -927,6 +932,9 @@ The optional parameters are used as follows: > > > (set 'notmuch-search-target-thread target-thread) > > > (set 'notmuch-search-target-line target-line) > > > (set 'notmuch-search-continuation continuation) > > > + (when (and notmuch-search-exclude-deleted > > > + (not (string-match "tag:deleted[ )]*" query))) > > > > “is:” is a synonym for “tag:” in searches – so this section of the code > > should look for it too. > > There are several other things that could also trip up this regexp. > xtag:deletedx would be falsely matched, as would a quoted phrase > containing "tag:deleted", while tag:"deleted" and tag:(deleted) would > incorrectly not be matched. Thanks so much for the review, guys. I should have mentioned in this patch that the my regex skills are very weak, and that it was surely incomplete. I always forget about the is: prefix as well. > Getting this right is hard, though I'd be happy with > > "\\<\\(tag\\|is\\):deleted\\>" Every time I think I start to understand regex I am reminded that it's black magic and I really know nothing. For instance, I am not familiar with "<" or ">", although they appear to be a "word" boundaries (although I'm not sure how "word" is defined). Also, why is all the \\ (double?) escaping needed? I'll certainly take your word for it, though. > or maybe > > "\\<\\(tag\\|is\\):\\(\"?\\)deleted\\>\\2" After staring at this for 10 minutes I think I'm getting the extra bits here. It matches an initial \", and then a second at the end if the first matched. That's clever. Why \\>\\2 instead of \\2\\> ? I'm definitely confused by why so much apparent escaping is needed, though. > Implicit exclusions like this were actually one of my target features > for the custom query parser, but I think hacking around that by > inspecting the query string is a fine interim solution. (One of these > months I'll dust off the query parser, really!) Very much looking forward to it! jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search 2012-01-09 2:34 ` Jameson Graef Rollins @ 2012-01-09 2:46 ` Austin Clements 0 siblings, 0 replies; 176+ messages in thread From: Austin Clements @ 2012-01-09 2:46 UTC (permalink / raw) To: Jameson Graef Rollins; +Cc: Notmuch Mail Quoth Jameson Graef Rollins on Jan 08 at 6:34 pm: > On Sun, 8 Jan 2012 20:49:38 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > > > @@ -927,6 +932,9 @@ The optional parameters are used as follows: > > > > (set 'notmuch-search-target-thread target-thread) > > > > (set 'notmuch-search-target-line target-line) > > > > (set 'notmuch-search-continuation continuation) > > > > + (when (and notmuch-search-exclude-deleted > > > > + (not (string-match "tag:deleted[ )]*" query))) > > > > > > “is:” is a synonym for “tag:” in searches – so this section of the code > > > should look for it too. > > > > There are several other things that could also trip up this regexp. > > xtag:deletedx would be falsely matched, as would a quoted phrase > > containing "tag:deleted", while tag:"deleted" and tag:(deleted) would > > incorrectly not be matched. > > Thanks so much for the review, guys. I should have mentioned in this > patch that the my regex skills are very weak, and that it was surely > incomplete. I always forget about the is: prefix as well. > > > Getting this right is hard, though I'd be happy with > > > > "\\<\\(tag\\|is\\):deleted\\>" > > Every time I think I start to understand regex I am reminded that it's > black magic and I really know nothing. For instance, I am not familiar > with "<" or ">", although they appear to be a "word" boundaries > (although I'm not sure how "word" is defined). Also, why is all the \\ > (double?) escaping needed? I'll certainly take your word for it, > though. I'm not positive, but I think \> matches on the transition from a "word-constituent" character to a non-word-constituent character, as defined by Emacs' active syntax table. The slashes are all doubled because I was writing it as an Emacs string for easy pasting (sorry, I should have been explicit about that). The regexp itself is \<\(tag\|is\):deleted\> > > or maybe > > > > "\\<\\(tag\\|is\\):\\(\"?\\)deleted\\>\\2" > > After staring at this for 10 minutes I think I'm getting the extra bits > here. It matches an initial \", and then a second at the end if the > first matched. That's clever. Why Exactly. > \\>\\2 > > instead of > > \\2\\> > > ? Okay, that can qualify as black magic. The problem is that a " will mess up the word-boundary matching because " isn't a word constituent character. So, if it is looking for a quote at the end, the \2 in \2\> would match and consume the ", but then the \> wouldn't match. ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search 2012-01-09 1:49 ` Austin Clements 2012-01-09 2:34 ` Jameson Graef Rollins @ 2012-01-09 4:31 ` Austin Clements 2012-01-11 5:02 ` [PATCH 0/3] Automatic tag-based exclusion Austin Clements 1 sibling, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-09 4:31 UTC (permalink / raw) To: Jameson Graef Rollins, Aaron Ecay; +Cc: Notmuch Mail Quoth myself on Jan 08 at 8:49 pm: > > > @@ -927,6 +932,9 @@ The optional parameters are used as follows: > > > (set 'notmuch-search-target-thread target-thread) > > > (set 'notmuch-search-target-line target-line) > > > (set 'notmuch-search-continuation continuation) > > > + (when (and notmuch-search-exclude-deleted > > > + (not (string-match "tag:deleted[ )]*" query))) > > > > “is:” is a synonym for “tag:” in searches – so this section of the code > > should look for it too. > > There are several other things that could also trip up this regexp. > xtag:deletedx would be falsely matched, as would a quoted phrase > containing "tag:deleted", while tag:"deleted" and tag:(deleted) would > incorrectly not be matched. Getting this right is hard, though I'd be > happy with > > "\\<\\(tag\\|is\\):deleted\\>" > > or maybe > > "\\<\\(tag\\|is\\):\\(\"?\\)deleted\\>\\2" For the record, here's a More Correct (TM) version "\\(^\\|[-+ ()]\\)\\(tag\\|is\\):\\(\"?\\)deleted\\3\\($\\|[ ()]\\)" However, as we discussed on IRC, it's probably better to fix this in the CLI/library by adding a config option for auto-excluded tags, an API to register these with the library (probably part of the query API), and to iterate over the terms in the parsed query to determine which tag exclusions should be automatically added. ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 0/3] Automatic tag-based exclusion 2012-01-09 4:31 ` Austin Clements @ 2012-01-11 5:02 ` Austin Clements 2012-01-11 5:02 ` [PATCH 1/3] count: Convert to new-style argument parsing Austin Clements ` (4 more replies) 0 siblings, 5 replies; 176+ messages in thread From: Austin Clements @ 2012-01-11 5:02 UTC (permalink / raw) To: notmuch This implements essentially the same idea as Jamie's patch, but does it in the library/CLI and operates on the parsed query rather than using an ad hoc regexp. Which tags are automatically excluded is set in the config file and defaults to "deleted" and "spam". My comment for the config file is clunky. I'd love suggestions for improvements. The first patch can be applied without the other two. ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 1/3] count: Convert to new-style argument parsing 2012-01-11 5:02 ` [PATCH 0/3] Automatic tag-based exclusion Austin Clements @ 2012-01-11 5:02 ` Austin Clements 2012-01-11 8:17 ` Jani Nikula 2012-01-11 5:02 ` [PATCH 2/3] lib: Add support for automatically excluding tags from queries Austin Clements ` (3 subsequent siblings) 4 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-11 5:02 UTC (permalink / raw) To: notmuch --- notmuch-count.c | 53 +++++++++++++++++++++++++---------------------------- 1 files changed, 25 insertions(+), 28 deletions(-) diff --git a/notmuch-count.c b/notmuch-count.c index 20ce334..fb7401b 100644 --- a/notmuch-count.c +++ b/notmuch-count.c @@ -21,6 +21,11 @@ #include "notmuch-client.h" +typedef enum { + OUTPUT_THREADS, + OUTPUT_MESSAGES, +} output_t; + int notmuch_count_command (void *ctx, int argc, char *argv[]) { @@ -28,35 +33,23 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) notmuch_database_t *notmuch; notmuch_query_t *query; char *query_str; - int i; - notmuch_bool_t output_messages = TRUE; + int opt_index; + output_t output = OUTPUT_MESSAGES; - argc--; argv++; /* skip subcommand argument */ + notmuch_opt_desc_t options[] = { + { NOTMUCH_OPT_KEYWORD, &output, "output", 'o', + (notmuch_keyword_t []){ { "threads", OUTPUT_THREADS }, + { "messages", OUTPUT_MESSAGES }, + { 0, 0 } } }, + { 0, 0, 0, 0, 0 } + }; - for (i = 0; i < argc && argv[i][0] == '-'; i++) { - if (strcmp (argv[i], "--") == 0) { - i++; - break; - } - if (STRNCMP_LITERAL (argv[i], "--output=") == 0) { - const char *opt = argv[i] + sizeof ("--output=") - 1; - if (strcmp (opt, "threads") == 0) { - output_messages = FALSE; - } else if (strcmp (opt, "messages") == 0) { - output_messages = TRUE; - } else { - fprintf (stderr, "Invalid value for --output: %s\n", opt); - return 1; - } - } else { - fprintf (stderr, "Unrecognized option: %s\n", argv[i]); - return 1; - } + opt_index = parse_arguments (argc, argv, options, 1); + + if (opt_index < 0) { + return 1; } - argc -= i; - argv += i; - config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) return 1; @@ -66,7 +59,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) if (notmuch == NULL) return 1; - query_str = query_string_from_args (ctx, argc, argv); + query_str = query_string_from_args (ctx, argc-opt_index, argv+opt_index); if (query_str == NULL) { fprintf (stderr, "Out of memory.\n"); return 1; @@ -82,10 +75,14 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) return 1; } - if (output_messages) + switch (output) { + case OUTPUT_MESSAGES: printf ("%u\n", notmuch_query_count_messages (query)); - else + break; + case OUTPUT_THREADS: printf ("%u\n", notmuch_query_count_threads (query)); + break; + } notmuch_query_destroy (query); notmuch_database_close (notmuch); -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH 1/3] count: Convert to new-style argument parsing 2012-01-11 5:02 ` [PATCH 1/3] count: Convert to new-style argument parsing Austin Clements @ 2012-01-11 8:17 ` Jani Nikula 2012-01-11 18:26 ` Austin Clements 2012-01-11 18:27 ` Jani Nikula 0 siblings, 2 replies; 176+ messages in thread From: Jani Nikula @ 2012-01-11 8:17 UTC (permalink / raw) To: Austin Clements, notmuch On Wed, 11 Jan 2012 00:02:51 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > --- > notmuch-count.c | 53 +++++++++++++++++++++++++---------------------------- > 1 files changed, 25 insertions(+), 28 deletions(-) > > diff --git a/notmuch-count.c b/notmuch-count.c > index 20ce334..fb7401b 100644 > --- a/notmuch-count.c > +++ b/notmuch-count.c > @@ -21,6 +21,11 @@ > > #include "notmuch-client.h" > > +typedef enum { > + OUTPUT_THREADS, > + OUTPUT_MESSAGES, > +} output_t; > + > int > notmuch_count_command (void *ctx, int argc, char *argv[]) > { > @@ -28,35 +33,23 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) > notmuch_database_t *notmuch; > notmuch_query_t *query; > char *query_str; > - int i; > - notmuch_bool_t output_messages = TRUE; > + int opt_index; > + output_t output = OUTPUT_MESSAGES; > > - argc--; argv++; /* skip subcommand argument */ > + notmuch_opt_desc_t options[] = { > + { NOTMUCH_OPT_KEYWORD, &output, "output", 'o', > + (notmuch_keyword_t []){ { "threads", OUTPUT_THREADS }, > + { "messages", OUTPUT_MESSAGES }, > + { 0, 0 } } }, To be pedantic, parse_arguments() expects 'output_var' to be a pointer to int for NOTMUCH_OPT_KEYWORD. sizeof(enum) is implementation dependent. I would forget about output_t typedef, use plain enum, and int type for 'output'. In fact, this is exactly what I did in commits e6d89ad723f775952d89d4f81b6072617c5caf18 and be5619cca32452f1a398add85908d78d6e72f469. In the latter I could have used notmuch_bool_t because it's a typedeffed int, but then I would've depended on some external typedef not changing (it probably won't, but this is defensive programming). Otherwise, looks good. BR, Jani. > + { 0, 0, 0, 0, 0 } > + }; > > - for (i = 0; i < argc && argv[i][0] == '-'; i++) { > - if (strcmp (argv[i], "--") == 0) { > - i++; > - break; > - } > - if (STRNCMP_LITERAL (argv[i], "--output=") == 0) { > - const char *opt = argv[i] + sizeof ("--output=") - 1; > - if (strcmp (opt, "threads") == 0) { > - output_messages = FALSE; > - } else if (strcmp (opt, "messages") == 0) { > - output_messages = TRUE; > - } else { > - fprintf (stderr, "Invalid value for --output: %s\n", opt); > - return 1; > - } > - } else { > - fprintf (stderr, "Unrecognized option: %s\n", argv[i]); > - return 1; > - } > + opt_index = parse_arguments (argc, argv, options, 1); > + > + if (opt_index < 0) { > + return 1; > } > > - argc -= i; > - argv += i; > - > config = notmuch_config_open (ctx, NULL, NULL); > if (config == NULL) > return 1; > @@ -66,7 +59,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) > if (notmuch == NULL) > return 1; > > - query_str = query_string_from_args (ctx, argc, argv); > + query_str = query_string_from_args (ctx, argc-opt_index, argv+opt_index); > if (query_str == NULL) { > fprintf (stderr, "Out of memory.\n"); > return 1; > @@ -82,10 +75,14 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) > return 1; > } > > - if (output_messages) > + switch (output) { > + case OUTPUT_MESSAGES: > printf ("%u\n", notmuch_query_count_messages (query)); > - else > + break; > + case OUTPUT_THREADS: > printf ("%u\n", notmuch_query_count_threads (query)); > + break; > + } > > notmuch_query_destroy (query); > notmuch_database_close (notmuch); > -- > 1.7.7.3 > > _______________________________________________ > notmuch mailing list > notmuch@notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 1/3] count: Convert to new-style argument parsing 2012-01-11 8:17 ` Jani Nikula @ 2012-01-11 18:26 ` Austin Clements 2012-01-11 18:27 ` Jani Nikula 1 sibling, 0 replies; 176+ messages in thread From: Austin Clements @ 2012-01-11 18:26 UTC (permalink / raw) To: Jani Nikula; +Cc: notmuch Quoth Jani Nikula on Jan 11 at 8:17 am: > On Wed, 11 Jan 2012 00:02:51 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > --- > > notmuch-count.c | 53 +++++++++++++++++++++++++---------------------------- > > 1 files changed, 25 insertions(+), 28 deletions(-) > > > > diff --git a/notmuch-count.c b/notmuch-count.c > > index 20ce334..fb7401b 100644 > > --- a/notmuch-count.c > > +++ b/notmuch-count.c > > @@ -21,6 +21,11 @@ > > > > #include "notmuch-client.h" > > > > +typedef enum { > > + OUTPUT_THREADS, > > + OUTPUT_MESSAGES, > > +} output_t; > > + > > int > > notmuch_count_command (void *ctx, int argc, char *argv[]) > > { > > @@ -28,35 +33,23 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) > > notmuch_database_t *notmuch; > > notmuch_query_t *query; > > char *query_str; > > - int i; > > - notmuch_bool_t output_messages = TRUE; > > + int opt_index; > > + output_t output = OUTPUT_MESSAGES; > > > > - argc--; argv++; /* skip subcommand argument */ > > + notmuch_opt_desc_t options[] = { > > + { NOTMUCH_OPT_KEYWORD, &output, "output", 'o', > > + (notmuch_keyword_t []){ { "threads", OUTPUT_THREADS }, > > + { "messages", OUTPUT_MESSAGES }, > > + { 0, 0 } } }, > > To be pedantic, parse_arguments() expects 'output_var' to be a pointer > to int for NOTMUCH_OPT_KEYWORD. sizeof(enum) is implementation > dependent. I would forget about output_t typedef, use plain enum, and > int type for 'output'. Pedantic or not, that's a good point. We should fix this in notmuch-search.c, too (which is where I shamelessly copied this from). Or make the argument parser more type-safe. ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 1/3] count: Convert to new-style argument parsing 2012-01-11 8:17 ` Jani Nikula 2012-01-11 18:26 ` Austin Clements @ 2012-01-11 18:27 ` Jani Nikula 1 sibling, 0 replies; 176+ messages in thread From: Jani Nikula @ 2012-01-11 18:27 UTC (permalink / raw) To: Austin Clements, notmuch On Wed, 11 Jan 2012 08:17:05 +0000, Jani Nikula <jani@nikula.org> wrote: > In fact, this is exactly what I did in commits > e6d89ad723f775952d89d4f81b6072617c5caf18 and > be5619cca32452f1a398add85908d78d6e72f469. In the latter I could have > used notmuch_bool_t because it's a typedeffed int, but then I would've > depended on some external typedef not changing (it probably won't, but > this is defensive programming). Please disregard the commit ids above. The correct references are 2d1385e141b1799b4b3942a3fe2dcbcdbf92dc38 and id:"d32e63c8115b1f2868acf96c83b30697be88ff10.1326224339.git.jani@nikula.org". Sorry for the confusion. BR, Jani. ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 2/3] lib: Add support for automatically excluding tags from queries 2012-01-11 5:02 ` [PATCH 0/3] Automatic tag-based exclusion Austin Clements 2012-01-11 5:02 ` [PATCH 1/3] count: Convert to new-style argument parsing Austin Clements @ 2012-01-11 5:02 ` Austin Clements 2012-01-11 10:11 ` Jani Nikula 2012-01-11 5:02 ` [PATCH 3/3] search: Support automatic tag exclusions Austin Clements ` (2 subsequent siblings) 4 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-11 5:02 UTC (permalink / raw) To: notmuch This is useful for tags like "deleted" and "spam" that people generally want to exclude from query results. These exclusions will be overridden if a tag is explicitly mentioned in a query. --- lib/notmuch.h | 6 ++++++ lib/query.cc | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 0 deletions(-) diff --git a/lib/notmuch.h b/lib/notmuch.h index 9f23a10..0a3ae2b 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -457,6 +457,12 @@ notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort); notmuch_sort_t notmuch_query_get_sort (notmuch_query_t *query); +/* Add a tag that will be excluded by default from the query results. + * This exclusion will be overridden if this tag appears explicitly in + * the query. */ +void +notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag); + /* Execute a query for threads, returning a notmuch_threads_t object * which can be used to iterate over the results. The returned threads * object is owned by the query and as such, will only be valid until diff --git a/lib/query.cc b/lib/query.cc index b6c0f12..716db1c 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -27,6 +27,7 @@ struct _notmuch_query { notmuch_database_t *notmuch; const char *query_string; notmuch_sort_t sort; + notmuch_string_list_t *exclude_terms; }; typedef struct _notmuch_mset_messages { @@ -76,6 +77,8 @@ notmuch_query_create (notmuch_database_t *notmuch, query->sort = NOTMUCH_SORT_NEWEST_FIRST; + query->exclude_terms = _notmuch_string_list_create (query); + return query; } @@ -97,6 +100,13 @@ notmuch_query_get_sort (notmuch_query_t *query) return query->sort; } +void +notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag) +{ + char *term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag); + _notmuch_string_list_append (query->exclude_terms, term); +} + /* We end up having to call the destructors explicitly because we had * to use "placement new" in order to initialize C++ objects within a * block that we allocated with talloc. So C++ is making talloc @@ -112,6 +122,25 @@ _notmuch_messages_destructor (notmuch_mset_messages_t *messages) return 0; } +static Xapian::Query +_notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery) +{ + Xapian::TermIterator end = xquery.get_terms_end (); + + for (notmuch_string_node_t *term = query->exclude_terms->head; term; + term = term->next) { + Xapian::TermIterator it = xquery.get_terms_begin (); + for (; it != end; it++) { + if (*it == term->string) + break; + } + if (it == end) + xquery = Xapian::Query (Xapian::Query::OP_AND_NOT, + xquery, Xapian::Query (term->string)); + } + return xquery; +} + notmuch_messages_t * notmuch_query_search_messages (notmuch_query_t *query) { @@ -157,6 +186,8 @@ notmuch_query_search_messages (notmuch_query_t *query) mail_query, string_query); } + final_query = _notmuch_exclude_tags (query, final_query); + enquire.set_weighting_scheme (Xapian::BoolWeight()); switch (query->sort) { @@ -436,6 +467,8 @@ notmuch_query_count_messages (notmuch_query_t *query) mail_query, string_query); } + final_query = _notmuch_exclude_tags (query, final_query); + enquire.set_weighting_scheme(Xapian::BoolWeight()); enquire.set_docid_order(Xapian::Enquire::ASCENDING); -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH 2/3] lib: Add support for automatically excluding tags from queries 2012-01-11 5:02 ` [PATCH 2/3] lib: Add support for automatically excluding tags from queries Austin Clements @ 2012-01-11 10:11 ` Jani Nikula 2012-01-11 18:48 ` Austin Clements 0 siblings, 1 reply; 176+ messages in thread From: Jani Nikula @ 2012-01-11 10:11 UTC (permalink / raw) To: Austin Clements, notmuch On Wed, 11 Jan 2012 00:02:52 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > This is useful for tags like "deleted" and "spam" that people > generally want to exclude from query results. These exclusions will > be overridden if a tag is explicitly mentioned in a query. > --- > lib/notmuch.h | 6 ++++++ > lib/query.cc | 33 +++++++++++++++++++++++++++++++++ > 2 files changed, 39 insertions(+), 0 deletions(-) > > diff --git a/lib/notmuch.h b/lib/notmuch.h > index 9f23a10..0a3ae2b 100644 > --- a/lib/notmuch.h > +++ b/lib/notmuch.h > @@ -457,6 +457,12 @@ notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort); > notmuch_sort_t > notmuch_query_get_sort (notmuch_query_t *query); > > +/* Add a tag that will be excluded by default from the query results. > + * This exclusion will be overridden if this tag appears explicitly in > + * the query. */ > +void > +notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag); > + > /* Execute a query for threads, returning a notmuch_threads_t object > * which can be used to iterate over the results. The returned threads > * object is owned by the query and as such, will only be valid until > diff --git a/lib/query.cc b/lib/query.cc > index b6c0f12..716db1c 100644 > --- a/lib/query.cc > +++ b/lib/query.cc > @@ -27,6 +27,7 @@ struct _notmuch_query { > notmuch_database_t *notmuch; > const char *query_string; > notmuch_sort_t sort; > + notmuch_string_list_t *exclude_terms; > }; > > typedef struct _notmuch_mset_messages { > @@ -76,6 +77,8 @@ notmuch_query_create (notmuch_database_t *notmuch, > > query->sort = NOTMUCH_SORT_NEWEST_FIRST; > > + query->exclude_terms = _notmuch_string_list_create (query); > + > return query; > } > > @@ -97,6 +100,13 @@ notmuch_query_get_sort (notmuch_query_t *query) > return query->sort; > } > > +void > +notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag) > +{ > + char *term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag); > + _notmuch_string_list_append (query->exclude_terms, term); > +} > + > /* We end up having to call the destructors explicitly because we had > * to use "placement new" in order to initialize C++ objects within a > * block that we allocated with talloc. So C++ is making talloc > @@ -112,6 +122,25 @@ _notmuch_messages_destructor (notmuch_mset_messages_t *messages) > return 0; > } > I'd like to have a comment here, or inline in the code, explaining the following function a little bit. > +static Xapian::Query > +_notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery) > +{ > + Xapian::TermIterator end = xquery.get_terms_end (); > + > + for (notmuch_string_node_t *term = query->exclude_terms->head; term; > + term = term->next) { > + Xapian::TermIterator it = xquery.get_terms_begin (); > + for (; it != end; it++) { > + if (*it == term->string) [This is a double reminder to me why I'm not that enthusiastic about operator overloading in C++.] > + break; > + } > + if (it == end) > + xquery = Xapian::Query (Xapian::Query::OP_AND_NOT, > + xquery, Xapian::Query (term->string)); I briefly dug into Xapian documentation and source code, and became none the wiser whether this copies the queries passed to it or not, i.e. does this leak memory or not. I just presume you know what you're doing. ;) I think the function fails if someone is stupid enough to exclude the same tag twice. I'm not sure if you should care. If you think so, you could just check double add in notmuch_query_add_tag_exclude(). Otherwise, looks good. > + } > + return xquery; > +} > + > notmuch_messages_t * > notmuch_query_search_messages (notmuch_query_t *query) > { > @@ -157,6 +186,8 @@ notmuch_query_search_messages (notmuch_query_t *query) > mail_query, string_query); > } > > + final_query = _notmuch_exclude_tags (query, final_query); > + > enquire.set_weighting_scheme (Xapian::BoolWeight()); > > switch (query->sort) { > @@ -436,6 +467,8 @@ notmuch_query_count_messages (notmuch_query_t *query) > mail_query, string_query); > } > > + final_query = _notmuch_exclude_tags (query, final_query); > + > enquire.set_weighting_scheme(Xapian::BoolWeight()); > enquire.set_docid_order(Xapian::Enquire::ASCENDING); > > -- > 1.7.7.3 > > _______________________________________________ > notmuch mailing list > notmuch@notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 2/3] lib: Add support for automatically excluding tags from queries 2012-01-11 10:11 ` Jani Nikula @ 2012-01-11 18:48 ` Austin Clements 0 siblings, 0 replies; 176+ messages in thread From: Austin Clements @ 2012-01-11 18:48 UTC (permalink / raw) To: Jani Nikula; +Cc: notmuch Quoth Jani Nikula on Jan 11 at 10:11 am: > On Wed, 11 Jan 2012 00:02:52 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > This is useful for tags like "deleted" and "spam" that people > > generally want to exclude from query results. These exclusions will > > be overridden if a tag is explicitly mentioned in a query. > > --- > > lib/notmuch.h | 6 ++++++ > > lib/query.cc | 33 +++++++++++++++++++++++++++++++++ > > 2 files changed, 39 insertions(+), 0 deletions(-) > > > > diff --git a/lib/notmuch.h b/lib/notmuch.h > > index 9f23a10..0a3ae2b 100644 > > --- a/lib/notmuch.h > > +++ b/lib/notmuch.h > > @@ -457,6 +457,12 @@ notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort); > > notmuch_sort_t > > notmuch_query_get_sort (notmuch_query_t *query); > > > > +/* Add a tag that will be excluded by default from the query results. > > + * This exclusion will be overridden if this tag appears explicitly in > > + * the query. */ > > +void > > +notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag); > > + > > /* Execute a query for threads, returning a notmuch_threads_t object > > * which can be used to iterate over the results. The returned threads > > * object is owned by the query and as such, will only be valid until > > diff --git a/lib/query.cc b/lib/query.cc > > index b6c0f12..716db1c 100644 > > --- a/lib/query.cc > > +++ b/lib/query.cc > > @@ -27,6 +27,7 @@ struct _notmuch_query { > > notmuch_database_t *notmuch; > > const char *query_string; > > notmuch_sort_t sort; > > + notmuch_string_list_t *exclude_terms; > > }; > > > > typedef struct _notmuch_mset_messages { > > @@ -76,6 +77,8 @@ notmuch_query_create (notmuch_database_t *notmuch, > > > > query->sort = NOTMUCH_SORT_NEWEST_FIRST; > > > > + query->exclude_terms = _notmuch_string_list_create (query); > > + > > return query; > > } > > > > @@ -97,6 +100,13 @@ notmuch_query_get_sort (notmuch_query_t *query) > > return query->sort; > > } > > > > +void > > +notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag) > > +{ > > + char *term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag); > > + _notmuch_string_list_append (query->exclude_terms, term); > > +} > > + > > /* We end up having to call the destructors explicitly because we had > > * to use "placement new" in order to initialize C++ objects within a > > * block that we allocated with talloc. So C++ is making talloc > > @@ -112,6 +122,25 @@ _notmuch_messages_destructor (notmuch_mset_messages_t *messages) > > return 0; > > } > > > > I'd like to have a comment here, or inline in the code, explaining the > following function a little bit. Done. > > +static Xapian::Query > > +_notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery) > > +{ > > + Xapian::TermIterator end = xquery.get_terms_end (); > > + > > + for (notmuch_string_node_t *term = query->exclude_terms->head; term; > > + term = term->next) { > > + Xapian::TermIterator it = xquery.get_terms_begin (); > > + for (; it != end; it++) { > > + if (*it == term->string) > > [This is a double reminder to me why I'm not that enthusiastic about > operator overloading in C++.] Actually, that's a good point. I had originally done this to prevent std::string from performing any internal allocation or copying (which calling c_str could do), but since it took me some digging to figure out if I had *actually* avoided this (turns out there's an overloaded string==char*, so I had), I've switched to using string.compare, which I think makes the behavior and performance more obvious. > > + break; > > + } > > + if (it == end) > > + xquery = Xapian::Query (Xapian::Query::OP_AND_NOT, > > + xquery, Xapian::Query (term->string)); > > I briefly dug into Xapian documentation and source code, and became none > the wiser whether this copies the queries passed to it or not, i.e. does > this leak memory or not. I just presume you know what you're doing. ;) Since my code isn't doing any memory allocation, it can't leak memory. It could do a lot of copying, but it turns out that isn't a problem either because Xapian objects are internally reference-counted handles. So, in other words, if you write the obvious thing, it will do the right thing, which is totally contrary to what C++ has conditioned us to expect. ]:--8) > I think the function fails if someone is stupid enough to exclude the > same tag twice. I'm not sure if you should care. If you think so, you > could just check double add in notmuch_query_add_tag_exclude(). It handles this correctly for two reasons. Suppose tag x is excluded twice. At worst, if tag:x doesn't appear in the query, the returned query will get two AND NOT tag:x's, but that doesn't affect the results. It turns out it doesn't even get doubled up for a slightly subtle reason: when the loop reaches the second x in the exclude list, it will iterate over the new query, which already has the AND NOT tag:x in it, so it will see the tag:x as if it were in the original query and not further modify the query. However, this did point out a bug. I was using the end iterator from the original query even when I started iterating over the modified query. I'll send out an updated series after someone looks at the third patch. > Otherwise, looks good. > > > + } > > + return xquery; > > +} > > + > > notmuch_messages_t * > > notmuch_query_search_messages (notmuch_query_t *query) > > { > > @@ -157,6 +186,8 @@ notmuch_query_search_messages (notmuch_query_t *query) > > mail_query, string_query); > > } > > > > + final_query = _notmuch_exclude_tags (query, final_query); > > + > > enquire.set_weighting_scheme (Xapian::BoolWeight()); > > > > switch (query->sort) { > > @@ -436,6 +467,8 @@ notmuch_query_count_messages (notmuch_query_t *query) > > mail_query, string_query); > > } > > > > + final_query = _notmuch_exclude_tags (query, final_query); > > + > > enquire.set_weighting_scheme(Xapian::BoolWeight()); > > enquire.set_docid_order(Xapian::Enquire::ASCENDING); > > > ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 3/3] search: Support automatic tag exclusions 2012-01-11 5:02 ` [PATCH 0/3] Automatic tag-based exclusion Austin Clements 2012-01-11 5:02 ` [PATCH 1/3] count: Convert to new-style argument parsing Austin Clements 2012-01-11 5:02 ` [PATCH 2/3] lib: Add support for automatically excluding tags from queries Austin Clements @ 2012-01-11 5:02 ` Austin Clements 2012-01-11 19:27 ` Jani Nikula 2012-01-11 7:05 ` [PATCH 0/3] Automatic tag-based exclusion Jameson Graef Rollins 2012-01-13 23:07 ` [PATCH v2 0/3] Austin Clements 4 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-11 5:02 UTC (permalink / raw) To: notmuch This adds a "search" section to the config file and an "auto_tag_exclusions" setting in that section. The search and count commands pass tag tags from the configuration to the library. --- notmuch-client.h | 8 ++++++++ notmuch-config.c | 42 ++++++++++++++++++++++++++++++++++++++++++ notmuch-count.c | 8 ++++++++ notmuch-search.c | 8 ++++++++ test/search | 18 ++++++++++++++++++ 5 files changed, 84 insertions(+), 0 deletions(-) diff --git a/notmuch-client.h b/notmuch-client.h index 517c010..62ede28 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -235,6 +235,14 @@ void notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config, notmuch_bool_t synchronize_flags); +const char ** +notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t *length); + +void +notmuch_config_set_auto_exclude_tags (notmuch_config_t *config, + const char *list[], + size_t length); + int notmuch_run_hook (const char *db_path, const char *hook); diff --git a/notmuch-config.c b/notmuch-config.c index d697138..6c3123b 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -84,6 +84,15 @@ static const char maildir_config_comment[] = "\tand update tags, while the \"notmuch tag\" and \"notmuch restore\"\n" "\tcommands will notice tag changes and update flags in filenames\n"; +static const char search_config_comment[] = + " Search configuration\n" + "\n" + " The following option is supported here:\n" + "\n" + "\tauto_exclude_tags A ;-separated list of tags that will be\n" + "\t excluded from queries by default. This can be overridden by including\n" + "\t these tags in a query.\n"; + struct _notmuch_config { char *filename; GKeyFile *key_file; @@ -96,6 +105,8 @@ struct _notmuch_config { const char **new_tags; size_t new_tags_length; notmuch_bool_t maildir_synchronize_flags; + const char **auto_exclude_tags; + size_t auto_exclude_tags_length; }; static int @@ -221,6 +232,7 @@ notmuch_config_open (void *ctx, int file_had_new_group; int file_had_user_group; int file_had_maildir_group; + int file_had_search_group; if (is_new_ret) *is_new_ret = 0; @@ -252,6 +264,8 @@ notmuch_config_open (void *ctx, config->new_tags = NULL; config->new_tags_length = 0; config->maildir_synchronize_flags = TRUE; + config->auto_exclude_tags = NULL; + config->auto_exclude_tags_length = 0; if (! g_key_file_load_from_file (config->key_file, config->filename, @@ -295,6 +309,7 @@ notmuch_config_open (void *ctx, file_had_new_group = g_key_file_has_group (config->key_file, "new"); file_had_user_group = g_key_file_has_group (config->key_file, "user"); file_had_maildir_group = g_key_file_has_group (config->key_file, "maildir"); + file_had_search_group = g_key_file_has_group (config->key_file, "search"); if (notmuch_config_get_database_path (config) == NULL) { @@ -345,6 +360,11 @@ notmuch_config_open (void *ctx, notmuch_config_set_new_tags (config, tags, 2); } + if (notmuch_config_get_auto_exclude_tags (config, &tmp) == NULL) { + const char *tags[] = { "deleted", "spam" }; + notmuch_config_set_auto_exclude_tags (config, tags, 2); + } + error = NULL; config->maildir_synchronize_flags = g_key_file_get_boolean (config->key_file, @@ -387,6 +407,11 @@ notmuch_config_open (void *ctx, maildir_config_comment, NULL); } + if (! file_had_search_group) { + g_key_file_set_comment (config->key_file, "search", NULL, + search_config_comment, NULL); + } + if (is_new_ret) *is_new_ret = is_new; @@ -597,6 +622,23 @@ notmuch_config_set_new_tags (notmuch_config_t *config, &(config->new_tags)); } +const char ** +notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t *length) +{ + return _config_get_list (config, "search", "auto_exclude_tags", + &(config->auto_exclude_tags), + &(config->auto_exclude_tags_length), length); +} + +void +notmuch_config_set_auto_exclude_tags (notmuch_config_t *config, + const char *list[], + size_t length) +{ + _config_set_list (config, "search", "auto_exclude_tags", list, length, + &(config->auto_exclude_tags)); +} + /* Given a configuration item of the form <group>.<key> return the * component group and key. If any error occurs, print a message on * stderr and return 1. Otherwise, return 0. diff --git a/notmuch-count.c b/notmuch-count.c index fb7401b..494619f 100644 --- a/notmuch-count.c +++ b/notmuch-count.c @@ -35,6 +35,9 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) char *query_str; int opt_index; output_t output = OUTPUT_MESSAGES; + const char **auto_exclude_tags; + size_t auto_exclude_tags_length; + unsigned int i; notmuch_opt_desc_t options[] = { { NOTMUCH_OPT_KEYWORD, &output, "output", 'o', @@ -75,6 +78,11 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) return 1; } + auto_exclude_tags = notmuch_config_get_auto_exclude_tags + (config, &auto_exclude_tags_length); + for (i = 0; i < auto_exclude_tags_length; i++) + notmuch_query_add_tag_exclude (query, auto_exclude_tags[i]); + switch (output) { case OUTPUT_MESSAGES: printf ("%u\n", notmuch_query_count_messages (query)); diff --git a/notmuch-search.c b/notmuch-search.c index 4baab56..8867aab 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -423,6 +423,9 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) output_t output = OUTPUT_SUMMARY; int offset = 0; int limit = -1; /* unlimited */ + const char **auto_exclude_tags; + size_t auto_exclude_tags_length; + unsigned int i; enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT } format_sel = NOTMUCH_FORMAT_TEXT; @@ -490,6 +493,11 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) notmuch_query_set_sort (query, sort); + auto_exclude_tags = notmuch_config_get_auto_exclude_tags + (config, &auto_exclude_tags_length); + for (i = 0; i < auto_exclude_tags_length; i++) + notmuch_query_add_tag_exclude (query, auto_exclude_tags[i]); + switch (output) { default: case OUTPUT_SUMMARY: diff --git a/test/search b/test/search index a7a0b18..f421ae3 100755 --- a/test/search +++ b/test/search @@ -129,4 +129,22 @@ add_message '[subject]="utf8-message-body-subject"' '[date]="Sat, 01 Jan 2000 12 output=$(notmuch search "bödý" | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread)" +test_begin_subtest "Search hides deleted" +generate_message '[subject]="Not deleted"' +generate_message '[subject]="Deleted"' +notmuch new > /dev/null +notmuch tag +deleted id:$gen_msg_id +output=$(notmuch search subject:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread)" + +test_begin_subtest "Search shows deleted if requested" +output=$(notmuch search subject:deleted and tag:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Deleted (deleted inbox unread)" + +test_begin_subtest "Search hides deleted in threads" +add_message '[subject]="Not deleted reply"' '[in-reply-to]="<$gen_msg_id>"' +output=$(notmuch search subject:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) +thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted inbox unread)" + test_done -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH 3/3] search: Support automatic tag exclusions 2012-01-11 5:02 ` [PATCH 3/3] search: Support automatic tag exclusions Austin Clements @ 2012-01-11 19:27 ` Jani Nikula 0 siblings, 0 replies; 176+ messages in thread From: Jani Nikula @ 2012-01-11 19:27 UTC (permalink / raw) To: Austin Clements, notmuch On Wed, 11 Jan 2012 00:02:53 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > This adds a "search" section to the config file and an > "auto_tag_exclusions" setting in that section. The search and count > commands pass tag tags from the configuration to the library. Looks good. Perhaps a few subtests like this in test/count on a corpus with some "deleted" or "spam" tags would be in order: test_begin_subtest "message count with --output=messages" test_expect_equal \ "`notmuch search --output=messages ${SEARCH} | wc -l`" \ "`notmuch count --output=messages ${SEARCH}`" test_begin_subtest "thread count with --output=threads" test_expect_equal \ "`notmuch search --output=threads ${SEARCH} | wc -l`" \ "`notmuch count --output=threads ${SEARCH}`" That's copy-paste from test/count; doing the same after some exclude tagging (and making sure it actually affects count) should be enough. BR, Jani. > --- > notmuch-client.h | 8 ++++++++ > notmuch-config.c | 42 ++++++++++++++++++++++++++++++++++++++++++ > notmuch-count.c | 8 ++++++++ > notmuch-search.c | 8 ++++++++ > test/search | 18 ++++++++++++++++++ > 5 files changed, 84 insertions(+), 0 deletions(-) > > diff --git a/notmuch-client.h b/notmuch-client.h > index 517c010..62ede28 100644 > --- a/notmuch-client.h > +++ b/notmuch-client.h > @@ -235,6 +235,14 @@ void > notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config, > notmuch_bool_t synchronize_flags); > > +const char ** > +notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t *length); > + > +void > +notmuch_config_set_auto_exclude_tags (notmuch_config_t *config, > + const char *list[], > + size_t length); > + > int > notmuch_run_hook (const char *db_path, const char *hook); > > diff --git a/notmuch-config.c b/notmuch-config.c > index d697138..6c3123b 100644 > --- a/notmuch-config.c > +++ b/notmuch-config.c > @@ -84,6 +84,15 @@ static const char maildir_config_comment[] = > "\tand update tags, while the \"notmuch tag\" and \"notmuch restore\"\n" > "\tcommands will notice tag changes and update flags in filenames\n"; > > +static const char search_config_comment[] = > + " Search configuration\n" > + "\n" > + " The following option is supported here:\n" > + "\n" > + "\tauto_exclude_tags A ;-separated list of tags that will be\n" > + "\t excluded from queries by default. This can be overridden by including\n" > + "\t these tags in a query.\n"; > + > struct _notmuch_config { > char *filename; > GKeyFile *key_file; > @@ -96,6 +105,8 @@ struct _notmuch_config { > const char **new_tags; > size_t new_tags_length; > notmuch_bool_t maildir_synchronize_flags; > + const char **auto_exclude_tags; > + size_t auto_exclude_tags_length; > }; > > static int > @@ -221,6 +232,7 @@ notmuch_config_open (void *ctx, > int file_had_new_group; > int file_had_user_group; > int file_had_maildir_group; > + int file_had_search_group; > > if (is_new_ret) > *is_new_ret = 0; > @@ -252,6 +264,8 @@ notmuch_config_open (void *ctx, > config->new_tags = NULL; > config->new_tags_length = 0; > config->maildir_synchronize_flags = TRUE; > + config->auto_exclude_tags = NULL; > + config->auto_exclude_tags_length = 0; > > if (! g_key_file_load_from_file (config->key_file, > config->filename, > @@ -295,6 +309,7 @@ notmuch_config_open (void *ctx, > file_had_new_group = g_key_file_has_group (config->key_file, "new"); > file_had_user_group = g_key_file_has_group (config->key_file, "user"); > file_had_maildir_group = g_key_file_has_group (config->key_file, "maildir"); > + file_had_search_group = g_key_file_has_group (config->key_file, "search"); > > > if (notmuch_config_get_database_path (config) == NULL) { > @@ -345,6 +360,11 @@ notmuch_config_open (void *ctx, > notmuch_config_set_new_tags (config, tags, 2); > } > > + if (notmuch_config_get_auto_exclude_tags (config, &tmp) == NULL) { > + const char *tags[] = { "deleted", "spam" }; > + notmuch_config_set_auto_exclude_tags (config, tags, 2); > + } > + > error = NULL; > config->maildir_synchronize_flags = > g_key_file_get_boolean (config->key_file, > @@ -387,6 +407,11 @@ notmuch_config_open (void *ctx, > maildir_config_comment, NULL); > } > > + if (! file_had_search_group) { > + g_key_file_set_comment (config->key_file, "search", NULL, > + search_config_comment, NULL); > + } > + > if (is_new_ret) > *is_new_ret = is_new; > > @@ -597,6 +622,23 @@ notmuch_config_set_new_tags (notmuch_config_t *config, > &(config->new_tags)); > } > > +const char ** > +notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t *length) > +{ > + return _config_get_list (config, "search", "auto_exclude_tags", > + &(config->auto_exclude_tags), > + &(config->auto_exclude_tags_length), length); > +} > + > +void > +notmuch_config_set_auto_exclude_tags (notmuch_config_t *config, > + const char *list[], > + size_t length) > +{ > + _config_set_list (config, "search", "auto_exclude_tags", list, length, > + &(config->auto_exclude_tags)); > +} > + > /* Given a configuration item of the form <group>.<key> return the > * component group and key. If any error occurs, print a message on > * stderr and return 1. Otherwise, return 0. > diff --git a/notmuch-count.c b/notmuch-count.c > index fb7401b..494619f 100644 > --- a/notmuch-count.c > +++ b/notmuch-count.c > @@ -35,6 +35,9 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) > char *query_str; > int opt_index; > output_t output = OUTPUT_MESSAGES; > + const char **auto_exclude_tags; > + size_t auto_exclude_tags_length; > + unsigned int i; > > notmuch_opt_desc_t options[] = { > { NOTMUCH_OPT_KEYWORD, &output, "output", 'o', > @@ -75,6 +78,11 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) > return 1; > } > > + auto_exclude_tags = notmuch_config_get_auto_exclude_tags > + (config, &auto_exclude_tags_length); > + for (i = 0; i < auto_exclude_tags_length; i++) > + notmuch_query_add_tag_exclude (query, auto_exclude_tags[i]); > + > switch (output) { > case OUTPUT_MESSAGES: > printf ("%u\n", notmuch_query_count_messages (query)); > diff --git a/notmuch-search.c b/notmuch-search.c > index 4baab56..8867aab 100644 > --- a/notmuch-search.c > +++ b/notmuch-search.c > @@ -423,6 +423,9 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) > output_t output = OUTPUT_SUMMARY; > int offset = 0; > int limit = -1; /* unlimited */ > + const char **auto_exclude_tags; > + size_t auto_exclude_tags_length; > + unsigned int i; > > enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT } > format_sel = NOTMUCH_FORMAT_TEXT; > @@ -490,6 +493,11 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) > > notmuch_query_set_sort (query, sort); > > + auto_exclude_tags = notmuch_config_get_auto_exclude_tags > + (config, &auto_exclude_tags_length); > + for (i = 0; i < auto_exclude_tags_length; i++) > + notmuch_query_add_tag_exclude (query, auto_exclude_tags[i]); > + > switch (output) { > default: > case OUTPUT_SUMMARY: > diff --git a/test/search b/test/search > index a7a0b18..f421ae3 100755 > --- a/test/search > +++ b/test/search > @@ -129,4 +129,22 @@ add_message '[subject]="utf8-message-body-subject"' '[date]="Sat, 01 Jan 2000 12 > output=$(notmuch search "bödý" | notmuch_search_sanitize) > test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread)" > > +test_begin_subtest "Search hides deleted" > +generate_message '[subject]="Not deleted"' > +generate_message '[subject]="Deleted"' > +notmuch new > /dev/null > +notmuch tag +deleted id:$gen_msg_id > +output=$(notmuch search subject:deleted | notmuch_search_sanitize) > +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread)" > + > +test_begin_subtest "Search shows deleted if requested" > +output=$(notmuch search subject:deleted and tag:deleted | notmuch_search_sanitize) > +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Deleted (deleted inbox unread)" > + > +test_begin_subtest "Search hides deleted in threads" > +add_message '[subject]="Not deleted reply"' '[in-reply-to]="<$gen_msg_id>"' > +output=$(notmuch search subject:deleted | notmuch_search_sanitize) > +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) > +thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted inbox unread)" > + > test_done > -- > 1.7.7.3 > > _______________________________________________ > notmuch mailing list > notmuch@notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 0/3] Automatic tag-based exclusion 2012-01-11 5:02 ` [PATCH 0/3] Automatic tag-based exclusion Austin Clements ` (2 preceding siblings ...) 2012-01-11 5:02 ` [PATCH 3/3] search: Support automatic tag exclusions Austin Clements @ 2012-01-11 7:05 ` Jameson Graef Rollins 2012-01-13 23:07 ` [PATCH v2 0/3] Austin Clements 4 siblings, 0 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-11 7:05 UTC (permalink / raw) To: Austin Clements, notmuch [-- Attachment #1: Type: text/plain, Size: 513 bytes --] On Wed, 11 Jan 2012 00:02:50 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > This implements essentially the same idea as Jamie's patch, but does > it in the library/CLI and operates on the parsed query rather than > using an ad hoc regexp. Which tags are automatically excluded is set > in the config file and defaults to "deleted" and "spam". Yay Austin! Nice fast work! That's really great. Don't have time to review right now, but asap. I'll resend my emacs patches as soon as I can as well. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH v2 0/3] 2012-01-11 5:02 ` [PATCH 0/3] Automatic tag-based exclusion Austin Clements ` (3 preceding siblings ...) 2012-01-11 7:05 ` [PATCH 0/3] Automatic tag-based exclusion Jameson Graef Rollins @ 2012-01-13 23:07 ` Austin Clements 2012-01-13 23:07 ` [PATCH v2 1/3] count: Convert to new-style argument parsing Austin Clements ` (4 more replies) 4 siblings, 5 replies; 176+ messages in thread From: Austin Clements @ 2012-01-13 23:07 UTC (permalink / raw) To: notmuch This addresses Jani's comments and improves some of the text and code comments. ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH v2 1/3] count: Convert to new-style argument parsing 2012-01-13 23:07 ` [PATCH v2 0/3] Austin Clements @ 2012-01-13 23:07 ` Austin Clements 2012-01-14 1:49 ` David Bremner 2012-01-13 23:07 ` [PATCH v2 2/3] lib: Add support for automatically excluding tags from queries Austin Clements ` (3 subsequent siblings) 4 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-13 23:07 UTC (permalink / raw) To: notmuch --- notmuch-count.c | 53 +++++++++++++++++++++++++---------------------------- 1 files changed, 25 insertions(+), 28 deletions(-) diff --git a/notmuch-count.c b/notmuch-count.c index 20ce334..0982f99 100644 --- a/notmuch-count.c +++ b/notmuch-count.c @@ -21,6 +21,11 @@ #include "notmuch-client.h" +enum { + OUTPUT_THREADS, + OUTPUT_MESSAGES, +}; + int notmuch_count_command (void *ctx, int argc, char *argv[]) { @@ -28,35 +33,23 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) notmuch_database_t *notmuch; notmuch_query_t *query; char *query_str; - int i; - notmuch_bool_t output_messages = TRUE; + int opt_index; + int output = OUTPUT_MESSAGES; - argc--; argv++; /* skip subcommand argument */ + notmuch_opt_desc_t options[] = { + { NOTMUCH_OPT_KEYWORD, &output, "output", 'o', + (notmuch_keyword_t []){ { "threads", OUTPUT_THREADS }, + { "messages", OUTPUT_MESSAGES }, + { 0, 0 } } }, + { 0, 0, 0, 0, 0 } + }; - for (i = 0; i < argc && argv[i][0] == '-'; i++) { - if (strcmp (argv[i], "--") == 0) { - i++; - break; - } - if (STRNCMP_LITERAL (argv[i], "--output=") == 0) { - const char *opt = argv[i] + sizeof ("--output=") - 1; - if (strcmp (opt, "threads") == 0) { - output_messages = FALSE; - } else if (strcmp (opt, "messages") == 0) { - output_messages = TRUE; - } else { - fprintf (stderr, "Invalid value for --output: %s\n", opt); - return 1; - } - } else { - fprintf (stderr, "Unrecognized option: %s\n", argv[i]); - return 1; - } + opt_index = parse_arguments (argc, argv, options, 1); + + if (opt_index < 0) { + return 1; } - argc -= i; - argv += i; - config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) return 1; @@ -66,7 +59,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) if (notmuch == NULL) return 1; - query_str = query_string_from_args (ctx, argc, argv); + query_str = query_string_from_args (ctx, argc-opt_index, argv+opt_index); if (query_str == NULL) { fprintf (stderr, "Out of memory.\n"); return 1; @@ -82,10 +75,14 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) return 1; } - if (output_messages) + switch (output) { + case OUTPUT_MESSAGES: printf ("%u\n", notmuch_query_count_messages (query)); - else + break; + case OUTPUT_THREADS: printf ("%u\n", notmuch_query_count_threads (query)); + break; + } notmuch_query_destroy (query); notmuch_database_close (notmuch); -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH v2 1/3] count: Convert to new-style argument parsing 2012-01-13 23:07 ` [PATCH v2 1/3] count: Convert to new-style argument parsing Austin Clements @ 2012-01-14 1:49 ` David Bremner 0 siblings, 0 replies; 176+ messages in thread From: David Bremner @ 2012-01-14 1:49 UTC (permalink / raw) To: Austin Clements, notmuch On Fri, 13 Jan 2012 18:07:02 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > --- > notmuch-count.c | 53 +++++++++++++++++++++++++---------------------------- > 1 files changed, 25 insertions(+), 28 deletions(-) This seems independent of the rest of the series, and kindof obvious by this point, so I pushed it. d ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH v2 2/3] lib: Add support for automatically excluding tags from queries 2012-01-13 23:07 ` [PATCH v2 0/3] Austin Clements 2012-01-13 23:07 ` [PATCH v2 1/3] count: Convert to new-style argument parsing Austin Clements @ 2012-01-13 23:07 ` Austin Clements 2012-01-14 23:38 ` Jameson Graef Rollins 2012-01-13 23:07 ` [PATCH v2 3/3] search: Support automatic tag exclusions Austin Clements ` (2 subsequent siblings) 4 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-13 23:07 UTC (permalink / raw) To: notmuch This is useful for tags like "deleted" and "spam" that people generally want to exclude from query results. These exclusions will be overridden if a tag is explicitly mentioned in a query. --- lib/notmuch.h | 6 ++++++ lib/query.cc | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 0 deletions(-) diff --git a/lib/notmuch.h b/lib/notmuch.h index 9f23a10..7929fe7 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -457,6 +457,12 @@ notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort); notmuch_sort_t notmuch_query_get_sort (notmuch_query_t *query); +/* Add a tag that will be excluded from the query results by default. + * This exclusion will be overridden if this tag appears explicitly in + * the query. */ +void +notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag); + /* Execute a query for threads, returning a notmuch_threads_t object * which can be used to iterate over the results. The returned threads * object is owned by the query and as such, will only be valid until diff --git a/lib/query.cc b/lib/query.cc index b6c0f12..0b36602 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -27,6 +27,7 @@ struct _notmuch_query { notmuch_database_t *notmuch; const char *query_string; notmuch_sort_t sort; + notmuch_string_list_t *exclude_terms; }; typedef struct _notmuch_mset_messages { @@ -76,6 +77,8 @@ notmuch_query_create (notmuch_database_t *notmuch, query->sort = NOTMUCH_SORT_NEWEST_FIRST; + query->exclude_terms = _notmuch_string_list_create (query); + return query; } @@ -97,6 +100,13 @@ notmuch_query_get_sort (notmuch_query_t *query) return query->sort; } +void +notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag) +{ + char *term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag); + _notmuch_string_list_append (query->exclude_terms, term); +} + /* We end up having to call the destructors explicitly because we had * to use "placement new" in order to initialize C++ objects within a * block that we allocated with talloc. So C++ is making talloc @@ -112,6 +122,27 @@ _notmuch_messages_destructor (notmuch_mset_messages_t *messages) return 0; } +/* Return a query that does not match messages with the excluded tags + * registered with the query. Any tags that explicitly appear in + * xquery will not be excluded. */ +static Xapian::Query +_notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery) +{ + for (notmuch_string_node_t *term = query->exclude_terms->head; term; + term = term->next) { + Xapian::TermIterator it = xquery.get_terms_begin (); + Xapian::TermIterator end = xquery.get_terms_end (); + for (; it != end; it++) { + if ((*it).compare (term->string) == 0) + break; + } + if (it == end) + xquery = Xapian::Query (Xapian::Query::OP_AND_NOT, + xquery, Xapian::Query (term->string)); + } + return xquery; +} + notmuch_messages_t * notmuch_query_search_messages (notmuch_query_t *query) { @@ -157,6 +188,8 @@ notmuch_query_search_messages (notmuch_query_t *query) mail_query, string_query); } + final_query = _notmuch_exclude_tags (query, final_query); + enquire.set_weighting_scheme (Xapian::BoolWeight()); switch (query->sort) { @@ -436,6 +469,8 @@ notmuch_query_count_messages (notmuch_query_t *query) mail_query, string_query); } + final_query = _notmuch_exclude_tags (query, final_query); + enquire.set_weighting_scheme(Xapian::BoolWeight()); enquire.set_docid_order(Xapian::Enquire::ASCENDING); -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH v2 2/3] lib: Add support for automatically excluding tags from queries 2012-01-13 23:07 ` [PATCH v2 2/3] lib: Add support for automatically excluding tags from queries Austin Clements @ 2012-01-14 23:38 ` Jameson Graef Rollins 2012-01-15 0:05 ` Austin Clements 0 siblings, 1 reply; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-14 23:38 UTC (permalink / raw) To: Austin Clements, notmuch [-- Attachment #1: Type: text/plain, Size: 1391 bytes --] It looks like something in this patch is causing the following build warning: CXX -O2 lib/query.o lib/query.cc:26:8: warning: ‘_notmuch_query’ declared with greater visibility than the type of its field ‘_notmuch_query::exclude_terms’ [-Wattributes] However, I can't quite figure out what's causing it. > +void > +notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag) > +{ > + char *term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag); > + _notmuch_string_list_append (query->exclude_terms, term); > +} This is really not an issue with this patch at all, and it should NOT prevent it from being applied, but this came up briefly on IRC and I'm curious, so I'll ask about it here. Are terms ALWAYS lower cased? If not, it seems to me it's possible to have an indexed term 'Kspam' that would get confused with the term 'spam' prefixed with the keyword prefix 'K' (which we use for tags). Maybe this degeneracy is broken by the query parser somehow (or maybe by the fact that tags are boolean terms?), but I wonder if it's not safer to use the built-in xapian prefix separator ':', ie: ... talloc_asprintf (query, "%s:%s", _find_prefix ("tag"), tag); I guess fixing that globally would require a database rebuild... Ok, that's totally just an aside, and should not be a blocker for this patch. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v2 2/3] lib: Add support for automatically excluding tags from queries 2012-01-14 23:38 ` Jameson Graef Rollins @ 2012-01-15 0:05 ` Austin Clements 0 siblings, 0 replies; 176+ messages in thread From: Austin Clements @ 2012-01-15 0:05 UTC (permalink / raw) To: Jameson Graef Rollins; +Cc: notmuch Quoth Jameson Graef Rollins on Jan 14 at 3:38 pm: > It looks like something in this patch is causing the following build > warning: > > CXX -O2 lib/query.o > lib/query.cc:26:8: warning: ‘_notmuch_query’ declared with greater visibility than the type of its field > ‘_notmuch_query::exclude_terms’ [-Wattributes] > > However, I can't quite figure out what's causing it. The problem is that notmuch_query_t is a "visible" symbol because the type is declared (though not defined) in lib/notmuch.h. The actual definition is tucked away in lib/query.cc, but GCC doesn't seem to care. I added a field of type notmuch_string_list_t to the struct's definition, but notmuch_string_list_t is declared between the "hidden" pragmas in lib/notmuch-private.h because the type is private to the library. This field with a hidden type in a visible type is what GCC is complaining about. I'm rather confused by the whole type visibility thing since type symbols aren't linkable anyway. However, while puzzling over how you could possibly use hidden types if they can only be used in other hidden types, I discovered that Carl had solved this exact problem last May in d5523ead by adding a visibility("default") attribute to the offending hidden type. > > +void > > +notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag) > > +{ > > + char *term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag); > > + _notmuch_string_list_append (query->exclude_terms, term); > > +} > > This is really not an issue with this patch at all, and it should NOT > prevent it from being applied, but this came up briefly on IRC and I'm > curious, so I'll ask about it here. > > Are terms ALWAYS lower cased? If not, it seems to me it's possible to > have an indexed term 'Kspam' that would get confused with the term > 'spam' prefixed with the keyword prefix 'K' (which we use for tags). > Maybe this degeneracy is broken by the query parser somehow (or maybe by > the fact that tags are boolean terms?), but I wonder if it's not safer > to use the built-in xapian prefix separator ':', ie: > > ... talloc_asprintf (query, "%s:%s", _find_prefix ("tag"), tag); > > I guess fixing that globally would require a database rebuild... We discussed this on IRC, but to summarize for the list, the tag prefix is a single character, so Xapian's ':' rule doesn't apply. There are several places where we *do* get this wrong and use a multi-character term prefix with a term that may start with a capital letter but they're all terms you can't search anyway and, unless I'm mistaken, we're completely consistent about where we violate or do not violate the ':' rule. > Ok, that's totally just an aside, and should not be a blocker for this > patch. > > jamie. ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH v2 3/3] search: Support automatic tag exclusions 2012-01-13 23:07 ` [PATCH v2 0/3] Austin Clements 2012-01-13 23:07 ` [PATCH v2 1/3] count: Convert to new-style argument parsing Austin Clements 2012-01-13 23:07 ` [PATCH v2 2/3] lib: Add support for automatically excluding tags from queries Austin Clements @ 2012-01-13 23:07 ` Austin Clements 2012-01-14 23:40 ` Jameson Graef Rollins 2012-01-14 23:38 ` [PATCH v2 0/3] Jameson Graef Rollins 2012-01-15 0:17 ` [PATCH v3 0/2] Automatic tag-based exclusion Austin Clements 4 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-13 23:07 UTC (permalink / raw) To: notmuch This adds a "search" section to the config file and an "auto_tag_exclusions" setting in that section. The search and count commands pass tag tags from the configuration to the library. --- notmuch-client.h | 8 ++++++++ notmuch-config.c | 42 ++++++++++++++++++++++++++++++++++++++++++ notmuch-count.c | 8 ++++++++ notmuch-search.c | 8 ++++++++ test/search | 18 ++++++++++++++++++ 5 files changed, 84 insertions(+), 0 deletions(-) diff --git a/notmuch-client.h b/notmuch-client.h index 517c010..62ede28 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -235,6 +235,14 @@ void notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config, notmuch_bool_t synchronize_flags); +const char ** +notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t *length); + +void +notmuch_config_set_auto_exclude_tags (notmuch_config_t *config, + const char *list[], + size_t length); + int notmuch_run_hook (const char *db_path, const char *hook); diff --git a/notmuch-config.c b/notmuch-config.c index d697138..3d4d5b9 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -84,6 +84,15 @@ static const char maildir_config_comment[] = "\tand update tags, while the \"notmuch tag\" and \"notmuch restore\"\n" "\tcommands will notice tag changes and update flags in filenames\n"; +static const char search_config_comment[] = + " Search configuration\n" + "\n" + " The following option is supported here:\n" + "\n" + "\tauto_exclude_tags A ;-separated list of tags that will be\n" + "\t excluded from search results by default. Using an excluded tag\n" + "\t in a query will override that exclusion.\n"; + struct _notmuch_config { char *filename; GKeyFile *key_file; @@ -96,6 +105,8 @@ struct _notmuch_config { const char **new_tags; size_t new_tags_length; notmuch_bool_t maildir_synchronize_flags; + const char **auto_exclude_tags; + size_t auto_exclude_tags_length; }; static int @@ -221,6 +232,7 @@ notmuch_config_open (void *ctx, int file_had_new_group; int file_had_user_group; int file_had_maildir_group; + int file_had_search_group; if (is_new_ret) *is_new_ret = 0; @@ -252,6 +264,8 @@ notmuch_config_open (void *ctx, config->new_tags = NULL; config->new_tags_length = 0; config->maildir_synchronize_flags = TRUE; + config->auto_exclude_tags = NULL; + config->auto_exclude_tags_length = 0; if (! g_key_file_load_from_file (config->key_file, config->filename, @@ -295,6 +309,7 @@ notmuch_config_open (void *ctx, file_had_new_group = g_key_file_has_group (config->key_file, "new"); file_had_user_group = g_key_file_has_group (config->key_file, "user"); file_had_maildir_group = g_key_file_has_group (config->key_file, "maildir"); + file_had_search_group = g_key_file_has_group (config->key_file, "search"); if (notmuch_config_get_database_path (config) == NULL) { @@ -345,6 +360,11 @@ notmuch_config_open (void *ctx, notmuch_config_set_new_tags (config, tags, 2); } + if (notmuch_config_get_auto_exclude_tags (config, &tmp) == NULL) { + const char *tags[] = { "deleted", "spam" }; + notmuch_config_set_auto_exclude_tags (config, tags, 2); + } + error = NULL; config->maildir_synchronize_flags = g_key_file_get_boolean (config->key_file, @@ -387,6 +407,11 @@ notmuch_config_open (void *ctx, maildir_config_comment, NULL); } + if (! file_had_search_group) { + g_key_file_set_comment (config->key_file, "search", NULL, + search_config_comment, NULL); + } + if (is_new_ret) *is_new_ret = is_new; @@ -597,6 +622,23 @@ notmuch_config_set_new_tags (notmuch_config_t *config, &(config->new_tags)); } +const char ** +notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t *length) +{ + return _config_get_list (config, "search", "auto_exclude_tags", + &(config->auto_exclude_tags), + &(config->auto_exclude_tags_length), length); +} + +void +notmuch_config_set_auto_exclude_tags (notmuch_config_t *config, + const char *list[], + size_t length) +{ + _config_set_list (config, "search", "auto_exclude_tags", list, length, + &(config->auto_exclude_tags)); +} + /* Given a configuration item of the form <group>.<key> return the * component group and key. If any error occurs, print a message on * stderr and return 1. Otherwise, return 0. diff --git a/notmuch-count.c b/notmuch-count.c index 0982f99..f77861e 100644 --- a/notmuch-count.c +++ b/notmuch-count.c @@ -35,6 +35,9 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) char *query_str; int opt_index; int output = OUTPUT_MESSAGES; + const char **auto_exclude_tags; + size_t auto_exclude_tags_length; + unsigned int i; notmuch_opt_desc_t options[] = { { NOTMUCH_OPT_KEYWORD, &output, "output", 'o', @@ -75,6 +78,11 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) return 1; } + auto_exclude_tags = notmuch_config_get_auto_exclude_tags + (config, &auto_exclude_tags_length); + for (i = 0; i < auto_exclude_tags_length; i++) + notmuch_query_add_tag_exclude (query, auto_exclude_tags[i]); + switch (output) { case OUTPUT_MESSAGES: printf ("%u\n", notmuch_query_count_messages (query)); diff --git a/notmuch-search.c b/notmuch-search.c index 4baab56..8867aab 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -423,6 +423,9 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) output_t output = OUTPUT_SUMMARY; int offset = 0; int limit = -1; /* unlimited */ + const char **auto_exclude_tags; + size_t auto_exclude_tags_length; + unsigned int i; enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT } format_sel = NOTMUCH_FORMAT_TEXT; @@ -490,6 +493,11 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) notmuch_query_set_sort (query, sort); + auto_exclude_tags = notmuch_config_get_auto_exclude_tags + (config, &auto_exclude_tags_length); + for (i = 0; i < auto_exclude_tags_length; i++) + notmuch_query_add_tag_exclude (query, auto_exclude_tags[i]); + switch (output) { default: case OUTPUT_SUMMARY: diff --git a/test/search b/test/search index a7a0b18..bf965e7 100755 --- a/test/search +++ b/test/search @@ -129,4 +129,22 @@ add_message '[subject]="utf8-message-body-subject"' '[date]="Sat, 01 Jan 2000 12 output=$(notmuch search "bödý" | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread)" +test_begin_subtest "Exclude \"deleted\" messages from search" +generate_message '[subject]="Not deleted"' +generate_message '[subject]="Deleted"' +notmuch new > /dev/null +notmuch tag +deleted id:$gen_msg_id +output=$(notmuch search subject:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread)" + +test_begin_subtest "Exclude \"deleted\" messages from search, overridden" +output=$(notmuch search subject:deleted and tag:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Deleted (deleted inbox unread)" + +test_begin_subtest "Exclude \"deleted\" messages from threads" +add_message '[subject]="Not deleted reply"' '[in-reply-to]="<$gen_msg_id>"' +output=$(notmuch search subject:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) +thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted inbox unread)" + test_done -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH v2 3/3] search: Support automatic tag exclusions 2012-01-13 23:07 ` [PATCH v2 3/3] search: Support automatic tag exclusions Austin Clements @ 2012-01-14 23:40 ` Jameson Graef Rollins 2012-01-15 0:14 ` Austin Clements 2012-01-16 9:12 ` David Edmondson 0 siblings, 2 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-14 23:40 UTC (permalink / raw) To: Austin Clements, notmuch [-- Attachment #1: Type: text/plain, Size: 1142 bytes --] This patch looks fine. Philosophical UI discussion to follow: On Fri, 13 Jan 2012 18:07:04 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > + if (notmuch_config_get_auto_exclude_tags (config, &tmp) == NULL) { > + const char *tags[] = { "deleted", "spam" }; > + notmuch_config_set_auto_exclude_tags (config, tags, 2); > + } This creates the config section with the exclude list pre-set to "deleted;spam". I personally have no problem with this, since I was going to be setting exactly that anyway. However, assuming we decide to have this be the default in the CLI, should we therefore add support for it in the emacs UI? I've been going back and forth on this (as readers are well aware), and have most recently rejected the idea that we should add delete support to the emacs UI. However, if we are excluding "deleted" tags by default, then I'm going to go back and say that we should include the keybindings to "delete" messages. Comments? If people think we should exclude "deleted;spam" by default, and agree that we should also add delete support in the emacs UI, I'll go ahead and rework my keybinding patches. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v2 3/3] search: Support automatic tag exclusions 2012-01-14 23:40 ` Jameson Graef Rollins @ 2012-01-15 0:14 ` Austin Clements 2012-01-16 9:12 ` David Edmondson 1 sibling, 0 replies; 176+ messages in thread From: Austin Clements @ 2012-01-15 0:14 UTC (permalink / raw) To: Jameson Graef Rollins; +Cc: notmuch Quoth Jameson Graef Rollins on Jan 14 at 3:40 pm: > This patch looks fine. Philosophical UI discussion to follow: > > On Fri, 13 Jan 2012 18:07:04 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > + if (notmuch_config_get_auto_exclude_tags (config, &tmp) == NULL) { > > + const char *tags[] = { "deleted", "spam" }; > > + notmuch_config_set_auto_exclude_tags (config, tags, 2); > > + } > > This creates the config section with the exclude list pre-set to > "deleted;spam". I personally have no problem with this, since I was > going to be setting exactly that anyway. However, assuming we decide to > have this be the default in the CLI, should we therefore add support for > it in the emacs UI? I've been going back and forth on this (as readers > are well aware), and have most recently rejected the idea that we should > add delete support to the emacs UI. However, if we are excluding > "deleted" tags by default, then I'm going to go back and say that we > should include the keybindings to "delete" messages. Comments? It's not that Emacs doesn't support the deleted tag. You can always +deleted<RET>, and this even seems like a pretty natural thing to do. To me, the question is whether there should be a shortcut to do this. I'm probably not one to answer this, since I don't plan to use the deleted tag and hence using this binding would only ever be an accident (though I will use the spam tag and I don't think I need a binding for that; perhaps I would feel differently if my spam filters were less effective). > If people think we should exclude "deleted;spam" by default, and agree > that we should also add delete support in the emacs UI, I'll go ahead > and rework my keybinding patches. > > jamie. ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v2 3/3] search: Support automatic tag exclusions 2012-01-14 23:40 ` Jameson Graef Rollins 2012-01-15 0:14 ` Austin Clements @ 2012-01-16 9:12 ` David Edmondson 2012-01-16 19:28 ` Austin Clements 2012-01-16 19:34 ` Jameson Graef Rollins 1 sibling, 2 replies; 176+ messages in thread From: David Edmondson @ 2012-01-16 9:12 UTC (permalink / raw) To: Jameson Graef Rollins, Austin Clements, notmuch [-- Attachment #1: Type: text/plain, Size: 793 bytes --] On Sat, 14 Jan 2012 15:40:26 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > This patch looks fine. Philosophical UI discussion to follow: > > On Fri, 13 Jan 2012 18:07:04 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > + if (notmuch_config_get_auto_exclude_tags (config, &tmp) == NULL) { > > + const char *tags[] = { "deleted", "spam" }; > > + notmuch_config_set_auto_exclude_tags (config, tags, 2); > > + } > > This creates the config section with the exclude list pre-set to > "deleted;spam". I don't think that anything should be excluded from the search results by default, at least not as a default behaviour of the 'notmuch' binary. Having "deleted" and "spam" as default settings in the configuration file might be more reasonable. [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v2 3/3] search: Support automatic tag exclusions 2012-01-16 9:12 ` David Edmondson @ 2012-01-16 19:28 ` Austin Clements 2012-01-16 22:18 ` Jeremy Nickurak [not found] ` <CA+eQo_3xxuhgUUXWXWyVD1LFhvhkw2psbA3ZnFnZk=BjjHXy8w@mail.gmail.com> 2012-01-16 19:34 ` Jameson Graef Rollins 1 sibling, 2 replies; 176+ messages in thread From: Austin Clements @ 2012-01-16 19:28 UTC (permalink / raw) To: David Edmondson; +Cc: notmuch Quoth David Edmondson on Jan 16 at 9:12 am: > On Sat, 14 Jan 2012 15:40:26 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > > This patch looks fine. Philosophical UI discussion to follow: > > > > On Fri, 13 Jan 2012 18:07:04 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > > + if (notmuch_config_get_auto_exclude_tags (config, &tmp) == NULL) { > > > + const char *tags[] = { "deleted", "spam" }; > > > + notmuch_config_set_auto_exclude_tags (config, tags, 2); > > > + } > > > > This creates the config section with the exclude list pre-set to > > "deleted;spam". > > I don't think that anything should be excluded from the search results > by default, at least not as a default behaviour of the 'notmuch' > binary. > > Having "deleted" and "spam" as default settings in the configuration > file might be more reasonable. Sorry, I'm confused. Are you saying deleted;spam should or should not be the default? ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v2 3/3] search: Support automatic tag exclusions 2012-01-16 19:28 ` Austin Clements @ 2012-01-16 22:18 ` Jeremy Nickurak 2012-01-16 22:25 ` Jameson Graef Rollins [not found] ` <CA+eQo_3xxuhgUUXWXWyVD1LFhvhkw2psbA3ZnFnZk=BjjHXy8w@mail.gmail.com> 1 sibling, 1 reply; 176+ messages in thread From: Jeremy Nickurak @ 2012-01-16 22:18 UTC (permalink / raw) To: notmuch On Mon, Jan 16, 2012 at 12:28, Austin Clements <amdragon@mit.edu> wrote: > Quoth David Edmondson on Jan 16 at 9:12 am: >> Having "deleted" and "spam" as default settings in the configuration >> file might be more reasonable. > > Sorry, I'm confused. Are you saying deleted;spam should or should not > be the default? If I read correctly: 1) If no exclude options are in the config file, none should be used. 2) On notmuch setup, "deleted" and "spam" should be added to .notmuch-config ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v2 3/3] search: Support automatic tag exclusions 2012-01-16 22:18 ` Jeremy Nickurak @ 2012-01-16 22:25 ` Jameson Graef Rollins 0 siblings, 0 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-16 22:25 UTC (permalink / raw) To: Jeremy Nickurak, notmuch [-- Attachment #1: Type: text/plain, Size: 262 bytes --] On Mon, 16 Jan 2012 15:18:18 -0700, Jeremy Nickurak <not-much@trk.nickurak.ca> wrote: > 1) If no exclude options are in the config file, none should be used. > 2) On notmuch setup, "deleted" and "spam" should be added to .notmuch-config That's correct. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
[parent not found: <CA+eQo_3xxuhgUUXWXWyVD1LFhvhkw2psbA3ZnFnZk=BjjHXy8w@mail.gmail.com>]
* Re: [PATCH v2 3/3] search: Support automatic tag exclusions [not found] ` <CA+eQo_3xxuhgUUXWXWyVD1LFhvhkw2psbA3ZnFnZk=BjjHXy8w@mail.gmail.com> @ 2012-01-17 9:08 ` David Edmondson 2012-01-17 20:32 ` Austin Clements 0 siblings, 1 reply; 176+ messages in thread From: David Edmondson @ 2012-01-17 9:08 UTC (permalink / raw) To: Jeremy Nickurak, Austin Clements; +Cc: notmuch [-- Attachment #1: Type: text/plain, Size: 537 bytes --] On Mon, 16 Jan 2012 15:16:24 -0700, Jeremy Nickurak <jeremy@nickurak.ca> wrote: > On Mon, Jan 16, 2012 at 12:28, Austin Clements <amdragon@mit.edu> wrote: > >> Having "deleted" and "spam" as default settings in the configuration > >> file might be more reasonable. > > If I read correctly: > > 1) If no exclude options are in the config file, none should be used. Yes. > 2) On notmuch setup, "deleted" and "spam" should be added to .notmuch-config I might argue between 'should' and 'could', but the sense is correct. [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v2 3/3] search: Support automatic tag exclusions 2012-01-17 9:08 ` David Edmondson @ 2012-01-17 20:32 ` Austin Clements 2012-01-18 8:38 ` David Edmondson 0 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-17 20:32 UTC (permalink / raw) To: David Edmondson; +Cc: notmuch, Jeremy Nickurak Quoth David Edmondson on Jan 17 at 9:08 am: > On Mon, 16 Jan 2012 15:16:24 -0700, Jeremy Nickurak <jeremy@nickurak.ca> wrote: > > On Mon, Jan 16, 2012 at 12:28, Austin Clements <amdragon@mit.edu> wrote: > > >> Having "deleted" and "spam" as default settings in the configuration > > >> file might be more reasonable. > > > > If I read correctly: > > > > 1) If no exclude options are in the config file, none should be used. > > Yes. > > > 2) On notmuch setup, "deleted" and "spam" should be added to .notmuch-config > > I might argue between 'should' and 'could', but the sense is correct. Oh, I think I see. I don't know if I can do precisely that, since the config code doesn't know if it's being called from setup, but is something like this essentially what you're suggesting? if (notmuch_config_get_auto_exclude_tags (config, &tmp) == NULL) { if (is_new) { const char *tags[] = { "deleted", "spam" }; notmuch_config_set_auto_exclude_tags (config, tags, 2); } else { notmuch_config_set_auto_exclude_tags (config, NULL, 0); } } (where is_new is TRUE if this is a brand-new config file) ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v2 3/3] search: Support automatic tag exclusions 2012-01-17 20:32 ` Austin Clements @ 2012-01-18 8:38 ` David Edmondson 2012-01-18 8:52 ` Jameson Graef Rollins 0 siblings, 1 reply; 176+ messages in thread From: David Edmondson @ 2012-01-18 8:38 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch, Jeremy Nickurak [-- Attachment #1: Type: text/plain, Size: 1987 bytes --] On Tue, 17 Jan 2012 15:32:11 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > Quoth David Edmondson on Jan 17 at 9:08 am: > > On Mon, 16 Jan 2012 15:16:24 -0700, Jeremy Nickurak <jeremy@nickurak.ca> wrote: > > > On Mon, Jan 16, 2012 at 12:28, Austin Clements <amdragon@mit.edu> wrote: > > > >> Having "deleted" and "spam" as default settings in the configuration > > > >> file might be more reasonable. > > > > > > If I read correctly: > > > > > > 1) If no exclude options are in the config file, none should be used. > > > > Yes. > > > > > 2) On notmuch setup, "deleted" and "spam" should be added to .notmuch-config > > > > I might argue between 'should' and 'could', but the sense is correct. > > Oh, I think I see. I don't know if I can do precisely that, since the > config code doesn't know if it's being called from setup, but is > something like this essentially what you're suggesting? > > if (notmuch_config_get_auto_exclude_tags (config, &tmp) == NULL) { > if (is_new) { > const char *tags[] = { "deleted", "spam" }; > notmuch_config_set_auto_exclude_tags (config, tags, 2); > } else { > notmuch_config_set_auto_exclude_tags (config, NULL, 0); > } > } > > (where is_new is TRUE if this is a brand-new config file) I'm not sure, as I haven't looked at the configuration code at all, sorry. Something must create the initial configuration file if none exists. I'd be okay with that code adding 'deleted' and 'spam' to the excluded list. This would mean that an existing user would see no change without taking some action (adding the tags to the configuration file) and a new user would see the new behaviour (automatic exclusion). I'm not completely sure that automatically adding the exclusion of the specified tags via the configuration file for new users is a great idea. It seems as though it will lead to confusion for someone at some point. [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v2 3/3] search: Support automatic tag exclusions 2012-01-18 8:38 ` David Edmondson @ 2012-01-18 8:52 ` Jameson Graef Rollins 2012-01-18 9:52 ` David Edmondson 0 siblings, 1 reply; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-18 8:52 UTC (permalink / raw) To: David Edmondson, Austin Clements; +Cc: notmuch, Jeremy Nickurak [-- Attachment #1: Type: text/plain, Size: 1125 bytes --] On Wed, 18 Jan 2012 08:38:23 +0000, David Edmondson <dme@dme.org> wrote: > Something must create the initial configuration file if none exists. I'd > be okay with that code adding 'deleted' and 'spam' to the excluded list. > > This would mean that an existing user would see no change without taking > some action (adding the tags to the configuration file) and a new user > would see the new behaviour (automatic exclusion). What you describe is indeed how it currently works. For new users or old users who rerun setup, the config file will automatically include the exclusions. Otherwise, users will see no change. > I'm not completely sure that automatically adding the exclusion of the > specified tags via the configuration file for new users is a great > idea. It seems as though it will lead to confusion for someone at some > point. Without any keys pre-bound to add "deleted" or "spam" tags, it probably won't make much difference for new users. And as long as it's documented, users will be warned of the behavior. Reading the config file would also make it clear how the variable changes behavior. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v2 3/3] search: Support automatic tag exclusions 2012-01-18 8:52 ` Jameson Graef Rollins @ 2012-01-18 9:52 ` David Edmondson 2012-01-18 18:51 ` Jameson Graef Rollins 0 siblings, 1 reply; 176+ messages in thread From: David Edmondson @ 2012-01-18 9:52 UTC (permalink / raw) To: Jameson Graef Rollins, Austin Clements; +Cc: notmuch, Jeremy Nickurak [-- Attachment #1: Type: text/plain, Size: 1568 bytes --] On Wed, 18 Jan 2012 00:52:09 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > On Wed, 18 Jan 2012 08:38:23 +0000, David Edmondson <dme@dme.org> wrote: > > Something must create the initial configuration file if none exists. I'd > > be okay with that code adding 'deleted' and 'spam' to the excluded list. > > > > This would mean that an existing user would see no change without taking > > some action (adding the tags to the configuration file) and a new user > > would see the new behaviour (automatic exclusion). > > What you describe is indeed how it currently works. For new users or > old users who rerun setup, the config file will automatically include > the exclusions. Otherwise, users will see no change. Good, thanks. > > I'm not completely sure that automatically adding the exclusion of the > > specified tags via the configuration file for new users is a great > > idea. It seems as though it will lead to confusion for someone at some > > point. > > Without any keys pre-bound to add "deleted" or "spam" tags, it probably > won't make much difference for new users. And as long as it's > documented, users will be warned of the behavior. Reading the config > file would also make it clear how the variable changes behavior. I agree that as long as no keys are pre-bound it will make little difference. That just transfers the discussion to the thread about adding the bindings, which seems silly. Anyway, I'm not too worried - I just won't answer any of the questions about it on the list :-) [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v2 3/3] search: Support automatic tag exclusions 2012-01-18 9:52 ` David Edmondson @ 2012-01-18 18:51 ` Jameson Graef Rollins 0 siblings, 0 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-18 18:51 UTC (permalink / raw) To: David Edmondson, Austin Clements; +Cc: notmuch, Jeremy Nickurak [-- Attachment #1: Type: text/plain, Size: 551 bytes --] On Wed, 18 Jan 2012 09:52:52 +0000, David Edmondson <dme@dme.org> wrote: > I agree that as long as no keys are pre-bound it will make little > difference. That just transfers the discussion to the thread about > adding the bindings, which seems silly. I think that's ok. The tag exclusion is in, which is great. The next question, of whether we should setup excludes by default, is intimately related to whether or not we support key bindings to add those tags. So I think it's fine to transfer the rest of this discussion to that thread. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v2 3/3] search: Support automatic tag exclusions 2012-01-16 9:12 ` David Edmondson 2012-01-16 19:28 ` Austin Clements @ 2012-01-16 19:34 ` Jameson Graef Rollins 1 sibling, 0 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-16 19:34 UTC (permalink / raw) To: David Edmondson, Austin Clements, notmuch [-- Attachment #1: Type: text/plain, Size: 536 bytes --] On Mon, 16 Jan 2012 09:12:38 +0000, David Edmondson <dme@dme.org> wrote: > I don't think that anything should be excluded from the search results > by default, at least not as a default behaviour of the 'notmuch' > binary. > > Having "deleted" and "spam" as default settings in the configuration > file might be more reasonable. Yes, I agree completely. The CLI does not, and should not, exclude anything by default. I only meant that the patch adds the configuration variable by default, which seems ok to me. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v2 0/3] 2012-01-13 23:07 ` [PATCH v2 0/3] Austin Clements ` (2 preceding siblings ...) 2012-01-13 23:07 ` [PATCH v2 3/3] search: Support automatic tag exclusions Austin Clements @ 2012-01-14 23:38 ` Jameson Graef Rollins 2012-01-15 0:17 ` [PATCH v3 0/2] Automatic tag-based exclusion Austin Clements 4 siblings, 0 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-14 23:38 UTC (permalink / raw) To: Austin Clements, notmuch [-- Attachment #1: Type: text/plain, Size: 292 bytes --] On Fri, 13 Jan 2012 18:07:01 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > This addresses Jani's comments and improves some of the text and code > comments. This is a really nice feature addition, Austin. And it works like a charm. ++1. A couple of small comments to follow. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH v3 0/2] Automatic tag-based exclusion 2012-01-13 23:07 ` [PATCH v2 0/3] Austin Clements ` (3 preceding siblings ...) 2012-01-14 23:38 ` [PATCH v2 0/3] Jameson Graef Rollins @ 2012-01-15 0:17 ` Austin Clements 2012-01-15 0:17 ` [PATCH v3 1/2] lib: Add support for automatically excluding tags from queries Austin Clements ` (4 more replies) 4 siblings, 5 replies; 176+ messages in thread From: Austin Clements @ 2012-01-15 0:17 UTC (permalink / raw) To: notmuch This fixes the symbol visibility warning Jamie pointed out. ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH v3 1/2] lib: Add support for automatically excluding tags from queries 2012-01-15 0:17 ` [PATCH v3 0/2] Automatic tag-based exclusion Austin Clements @ 2012-01-15 0:17 ` Austin Clements 2012-01-15 0:17 ` [PATCH v3 2/2] search: Support automatic tag exclusions Austin Clements ` (3 subsequent siblings) 4 siblings, 0 replies; 176+ messages in thread From: Austin Clements @ 2012-01-15 0:17 UTC (permalink / raw) To: notmuch This is useful for tags like "deleted" and "spam" that people generally want to exclude from query results. These exclusions will be overridden if a tag is explicitly mentioned in a query. --- lib/notmuch-private.h | 2 +- lib/notmuch.h | 6 ++++++ lib/query.cc | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletions(-) diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h index 60a932f..7bf153e 100644 --- a/lib/notmuch-private.h +++ b/lib/notmuch-private.h @@ -458,7 +458,7 @@ typedef struct _notmuch_string_node { struct _notmuch_string_node *next; } notmuch_string_node_t; -typedef struct _notmuch_string_list { +typedef struct visible _notmuch_string_list { int length; notmuch_string_node_t *head; notmuch_string_node_t **tail; diff --git a/lib/notmuch.h b/lib/notmuch.h index 9f23a10..7929fe7 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -457,6 +457,12 @@ notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort); notmuch_sort_t notmuch_query_get_sort (notmuch_query_t *query); +/* Add a tag that will be excluded from the query results by default. + * This exclusion will be overridden if this tag appears explicitly in + * the query. */ +void +notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag); + /* Execute a query for threads, returning a notmuch_threads_t object * which can be used to iterate over the results. The returned threads * object is owned by the query and as such, will only be valid until diff --git a/lib/query.cc b/lib/query.cc index b6c0f12..0b36602 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -27,6 +27,7 @@ struct _notmuch_query { notmuch_database_t *notmuch; const char *query_string; notmuch_sort_t sort; + notmuch_string_list_t *exclude_terms; }; typedef struct _notmuch_mset_messages { @@ -76,6 +77,8 @@ notmuch_query_create (notmuch_database_t *notmuch, query->sort = NOTMUCH_SORT_NEWEST_FIRST; + query->exclude_terms = _notmuch_string_list_create (query); + return query; } @@ -97,6 +100,13 @@ notmuch_query_get_sort (notmuch_query_t *query) return query->sort; } +void +notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag) +{ + char *term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag); + _notmuch_string_list_append (query->exclude_terms, term); +} + /* We end up having to call the destructors explicitly because we had * to use "placement new" in order to initialize C++ objects within a * block that we allocated with talloc. So C++ is making talloc @@ -112,6 +122,27 @@ _notmuch_messages_destructor (notmuch_mset_messages_t *messages) return 0; } +/* Return a query that does not match messages with the excluded tags + * registered with the query. Any tags that explicitly appear in + * xquery will not be excluded. */ +static Xapian::Query +_notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery) +{ + for (notmuch_string_node_t *term = query->exclude_terms->head; term; + term = term->next) { + Xapian::TermIterator it = xquery.get_terms_begin (); + Xapian::TermIterator end = xquery.get_terms_end (); + for (; it != end; it++) { + if ((*it).compare (term->string) == 0) + break; + } + if (it == end) + xquery = Xapian::Query (Xapian::Query::OP_AND_NOT, + xquery, Xapian::Query (term->string)); + } + return xquery; +} + notmuch_messages_t * notmuch_query_search_messages (notmuch_query_t *query) { @@ -157,6 +188,8 @@ notmuch_query_search_messages (notmuch_query_t *query) mail_query, string_query); } + final_query = _notmuch_exclude_tags (query, final_query); + enquire.set_weighting_scheme (Xapian::BoolWeight()); switch (query->sort) { @@ -436,6 +469,8 @@ notmuch_query_count_messages (notmuch_query_t *query) mail_query, string_query); } + final_query = _notmuch_exclude_tags (query, final_query); + enquire.set_weighting_scheme(Xapian::BoolWeight()); enquire.set_docid_order(Xapian::Enquire::ASCENDING); -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH v3 2/2] search: Support automatic tag exclusions 2012-01-15 0:17 ` [PATCH v3 0/2] Automatic tag-based exclusion Austin Clements 2012-01-15 0:17 ` [PATCH v3 1/2] lib: Add support for automatically excluding tags from queries Austin Clements @ 2012-01-15 0:17 ` Austin Clements 2012-01-19 19:19 ` Pieter Praet 2012-01-16 19:35 ` [PATCH v3 0/2] Automatic tag-based exclusion Jameson Graef Rollins ` (2 subsequent siblings) 4 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-15 0:17 UTC (permalink / raw) To: notmuch This adds a "search" section to the config file and an "auto_tag_exclusions" setting in that section. The search and count commands pass tag tags from the configuration to the library. --- notmuch-client.h | 8 ++++++++ notmuch-config.c | 42 ++++++++++++++++++++++++++++++++++++++++++ notmuch-count.c | 8 ++++++++ notmuch-search.c | 8 ++++++++ test/search | 18 ++++++++++++++++++ 5 files changed, 84 insertions(+), 0 deletions(-) diff --git a/notmuch-client.h b/notmuch-client.h index 517c010..62ede28 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -235,6 +235,14 @@ void notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config, notmuch_bool_t synchronize_flags); +const char ** +notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t *length); + +void +notmuch_config_set_auto_exclude_tags (notmuch_config_t *config, + const char *list[], + size_t length); + int notmuch_run_hook (const char *db_path, const char *hook); diff --git a/notmuch-config.c b/notmuch-config.c index d697138..3d4d5b9 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -84,6 +84,15 @@ static const char maildir_config_comment[] = "\tand update tags, while the \"notmuch tag\" and \"notmuch restore\"\n" "\tcommands will notice tag changes and update flags in filenames\n"; +static const char search_config_comment[] = + " Search configuration\n" + "\n" + " The following option is supported here:\n" + "\n" + "\tauto_exclude_tags A ;-separated list of tags that will be\n" + "\t excluded from search results by default. Using an excluded tag\n" + "\t in a query will override that exclusion.\n"; + struct _notmuch_config { char *filename; GKeyFile *key_file; @@ -96,6 +105,8 @@ struct _notmuch_config { const char **new_tags; size_t new_tags_length; notmuch_bool_t maildir_synchronize_flags; + const char **auto_exclude_tags; + size_t auto_exclude_tags_length; }; static int @@ -221,6 +232,7 @@ notmuch_config_open (void *ctx, int file_had_new_group; int file_had_user_group; int file_had_maildir_group; + int file_had_search_group; if (is_new_ret) *is_new_ret = 0; @@ -252,6 +264,8 @@ notmuch_config_open (void *ctx, config->new_tags = NULL; config->new_tags_length = 0; config->maildir_synchronize_flags = TRUE; + config->auto_exclude_tags = NULL; + config->auto_exclude_tags_length = 0; if (! g_key_file_load_from_file (config->key_file, config->filename, @@ -295,6 +309,7 @@ notmuch_config_open (void *ctx, file_had_new_group = g_key_file_has_group (config->key_file, "new"); file_had_user_group = g_key_file_has_group (config->key_file, "user"); file_had_maildir_group = g_key_file_has_group (config->key_file, "maildir"); + file_had_search_group = g_key_file_has_group (config->key_file, "search"); if (notmuch_config_get_database_path (config) == NULL) { @@ -345,6 +360,11 @@ notmuch_config_open (void *ctx, notmuch_config_set_new_tags (config, tags, 2); } + if (notmuch_config_get_auto_exclude_tags (config, &tmp) == NULL) { + const char *tags[] = { "deleted", "spam" }; + notmuch_config_set_auto_exclude_tags (config, tags, 2); + } + error = NULL; config->maildir_synchronize_flags = g_key_file_get_boolean (config->key_file, @@ -387,6 +407,11 @@ notmuch_config_open (void *ctx, maildir_config_comment, NULL); } + if (! file_had_search_group) { + g_key_file_set_comment (config->key_file, "search", NULL, + search_config_comment, NULL); + } + if (is_new_ret) *is_new_ret = is_new; @@ -597,6 +622,23 @@ notmuch_config_set_new_tags (notmuch_config_t *config, &(config->new_tags)); } +const char ** +notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t *length) +{ + return _config_get_list (config, "search", "auto_exclude_tags", + &(config->auto_exclude_tags), + &(config->auto_exclude_tags_length), length); +} + +void +notmuch_config_set_auto_exclude_tags (notmuch_config_t *config, + const char *list[], + size_t length) +{ + _config_set_list (config, "search", "auto_exclude_tags", list, length, + &(config->auto_exclude_tags)); +} + /* Given a configuration item of the form <group>.<key> return the * component group and key. If any error occurs, print a message on * stderr and return 1. Otherwise, return 0. diff --git a/notmuch-count.c b/notmuch-count.c index 0982f99..f77861e 100644 --- a/notmuch-count.c +++ b/notmuch-count.c @@ -35,6 +35,9 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) char *query_str; int opt_index; int output = OUTPUT_MESSAGES; + const char **auto_exclude_tags; + size_t auto_exclude_tags_length; + unsigned int i; notmuch_opt_desc_t options[] = { { NOTMUCH_OPT_KEYWORD, &output, "output", 'o', @@ -75,6 +78,11 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) return 1; } + auto_exclude_tags = notmuch_config_get_auto_exclude_tags + (config, &auto_exclude_tags_length); + for (i = 0; i < auto_exclude_tags_length; i++) + notmuch_query_add_tag_exclude (query, auto_exclude_tags[i]); + switch (output) { case OUTPUT_MESSAGES: printf ("%u\n", notmuch_query_count_messages (query)); diff --git a/notmuch-search.c b/notmuch-search.c index 4baab56..8867aab 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -423,6 +423,9 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) output_t output = OUTPUT_SUMMARY; int offset = 0; int limit = -1; /* unlimited */ + const char **auto_exclude_tags; + size_t auto_exclude_tags_length; + unsigned int i; enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT } format_sel = NOTMUCH_FORMAT_TEXT; @@ -490,6 +493,11 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) notmuch_query_set_sort (query, sort); + auto_exclude_tags = notmuch_config_get_auto_exclude_tags + (config, &auto_exclude_tags_length); + for (i = 0; i < auto_exclude_tags_length; i++) + notmuch_query_add_tag_exclude (query, auto_exclude_tags[i]); + switch (output) { default: case OUTPUT_SUMMARY: diff --git a/test/search b/test/search index a7a0b18..bf965e7 100755 --- a/test/search +++ b/test/search @@ -129,4 +129,22 @@ add_message '[subject]="utf8-message-body-subject"' '[date]="Sat, 01 Jan 2000 12 output=$(notmuch search "bödý" | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread)" +test_begin_subtest "Exclude \"deleted\" messages from search" +generate_message '[subject]="Not deleted"' +generate_message '[subject]="Deleted"' +notmuch new > /dev/null +notmuch tag +deleted id:$gen_msg_id +output=$(notmuch search subject:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread)" + +test_begin_subtest "Exclude \"deleted\" messages from search, overridden" +output=$(notmuch search subject:deleted and tag:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Deleted (deleted inbox unread)" + +test_begin_subtest "Exclude \"deleted\" messages from threads" +add_message '[subject]="Not deleted reply"' '[in-reply-to]="<$gen_msg_id>"' +output=$(notmuch search subject:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) +thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted inbox unread)" + test_done -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH v3 2/2] search: Support automatic tag exclusions 2012-01-15 0:17 ` [PATCH v3 2/2] search: Support automatic tag exclusions Austin Clements @ 2012-01-19 19:19 ` Pieter Praet 2012-01-19 19:19 ` [PATCH 1/4] search: rename auto_exclude_tags to {search, }exclude_tags Pieter Praet ` (5 more replies) 0 siblings, 6 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-19 19:19 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail Nice feature! I won't be using it myself, but I can imagine it being *very* useful for those who still feel the need to "delete" email :). Nitpicking: - All other config-related functions and args include the section title in their name [1], so for the sake of consistency, we might want to mirror that. Also, the "auto"matic part is pretty much a given. So I'd like to suggest replacing all occurences of "auto_exclude_tags" with "search_exclude_tags" (and simply "exclude_tags" in the args to `_config_get_list' and `_config_set_list', of course). Unfortunately, this would also partially invalidate your recent NEWS submission [2]. - If the 'search.exclude_tags' option is missing from the config file, its value is automatically set to "deleted;spam;", which probably isn't a sane default. Luckily, you've already provided the solution [3]. - To make new users aware of the config option's existence, we should prompt them to configure it during setup. Patches follow. Peace [1] Eg. `notmuch_config_get_user_name', `notmuch_config_get_new_tags', `notmuch_config_get_maildir_synchronize_flags', ... [2] id:"1326920330-31496-1-git-send-email-amdragon@mit.edu" [3] id:"20120117203211.GQ16740@mit.edu" ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 1/4] search: rename auto_exclude_tags to {search, }exclude_tags 2012-01-19 19:19 ` Pieter Praet @ 2012-01-19 19:19 ` Pieter Praet 2012-01-19 19:41 ` [PATCH 1/4] search: rename auto_exclude_tags to {search,}exclude_tags Austin Clements 2012-01-19 19:19 ` [PATCH 2/4] test: only exclude "deleted" messages from search if explicitly configured Pieter Praet ` (4 subsequent siblings) 5 siblings, 1 reply; 176+ messages in thread From: Pieter Praet @ 2012-01-19 19:19 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail All other config-related functions and args include the section title in their name, so for the sake of consistency, mirror that. Also, the "auto"matic part is a given, so that was dropped. --- notmuch-client.h | 4 ++-- notmuch-config.c | 32 ++++++++++++++++---------------- notmuch-count.c | 12 ++++++------ notmuch-search.c | 12 ++++++------ 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/notmuch-client.h b/notmuch-client.h index 62ede28..4bc7320 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -236,10 +236,10 @@ notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config, notmuch_bool_t synchronize_flags); const char ** -notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t *length); +notmuch_config_get_search_exclude_tags (notmuch_config_t *config, size_t *length); void -notmuch_config_set_auto_exclude_tags (notmuch_config_t *config, +notmuch_config_set_search_exclude_tags (notmuch_config_t *config, const char *list[], size_t length); diff --git a/notmuch-config.c b/notmuch-config.c index 3d4d5b9..687bd76 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -89,9 +89,9 @@ static const char search_config_comment[] = "\n" " The following option is supported here:\n" "\n" - "\tauto_exclude_tags A ;-separated list of tags that will be\n" - "\t excluded from search results by default. Using an excluded tag\n" - "\t in a query will override that exclusion.\n"; + "\texclude_tags A list (separated by ';') of the tags that will be\n" + "\t\texcluded from search results by default. Using an excluded tag in a\n" + "\t\tquery will override that exclusion.\n"; struct _notmuch_config { char *filename; @@ -105,8 +105,8 @@ struct _notmuch_config { const char **new_tags; size_t new_tags_length; notmuch_bool_t maildir_synchronize_flags; - const char **auto_exclude_tags; - size_t auto_exclude_tags_length; + const char **search_exclude_tags; + size_t search_exclude_tags_length; }; static int @@ -264,8 +264,8 @@ notmuch_config_open (void *ctx, config->new_tags = NULL; config->new_tags_length = 0; config->maildir_synchronize_flags = TRUE; - config->auto_exclude_tags = NULL; - config->auto_exclude_tags_length = 0; + config->search_exclude_tags = NULL; + config->search_exclude_tags_length = 0; if (! g_key_file_load_from_file (config->key_file, config->filename, @@ -360,9 +360,9 @@ notmuch_config_open (void *ctx, notmuch_config_set_new_tags (config, tags, 2); } - if (notmuch_config_get_auto_exclude_tags (config, &tmp) == NULL) { + if (notmuch_config_get_search_exclude_tags (config, &tmp) == NULL) { const char *tags[] = { "deleted", "spam" }; - notmuch_config_set_auto_exclude_tags (config, tags, 2); + notmuch_config_set_search_exclude_tags (config, tags, 2); } error = NULL; @@ -623,20 +623,20 @@ notmuch_config_set_new_tags (notmuch_config_t *config, } const char ** -notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t *length) +notmuch_config_get_search_exclude_tags (notmuch_config_t *config, size_t *length) { - return _config_get_list (config, "search", "auto_exclude_tags", - &(config->auto_exclude_tags), - &(config->auto_exclude_tags_length), length); + return _config_get_list (config, "search", "exclude_tags", + &(config->search_exclude_tags), + &(config->search_exclude_tags_length), length); } void -notmuch_config_set_auto_exclude_tags (notmuch_config_t *config, +notmuch_config_set_search_exclude_tags (notmuch_config_t *config, const char *list[], size_t length) { - _config_set_list (config, "search", "auto_exclude_tags", list, length, - &(config->auto_exclude_tags)); + _config_set_list (config, "search", "exclude_tags", list, length, + &(config->search_exclude_tags)); } /* Given a configuration item of the form <group>.<key> return the diff --git a/notmuch-count.c b/notmuch-count.c index f77861e..63459fb 100644 --- a/notmuch-count.c +++ b/notmuch-count.c @@ -35,8 +35,8 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) char *query_str; int opt_index; int output = OUTPUT_MESSAGES; - const char **auto_exclude_tags; - size_t auto_exclude_tags_length; + const char **search_exclude_tags; + size_t search_exclude_tags_length; unsigned int i; notmuch_opt_desc_t options[] = { @@ -78,10 +78,10 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) return 1; } - auto_exclude_tags = notmuch_config_get_auto_exclude_tags - (config, &auto_exclude_tags_length); - for (i = 0; i < auto_exclude_tags_length; i++) - notmuch_query_add_tag_exclude (query, auto_exclude_tags[i]); + search_exclude_tags = notmuch_config_get_search_exclude_tags + (config, &search_exclude_tags_length); + for (i = 0; i < search_exclude_tags_length; i++) + notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); switch (output) { case OUTPUT_MESSAGES: diff --git a/notmuch-search.c b/notmuch-search.c index 8867aab..d504051 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -423,8 +423,8 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) output_t output = OUTPUT_SUMMARY; int offset = 0; int limit = -1; /* unlimited */ - const char **auto_exclude_tags; - size_t auto_exclude_tags_length; + const char **search_exclude_tags; + size_t search_exclude_tags_length; unsigned int i; enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT } @@ -493,10 +493,10 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) notmuch_query_set_sort (query, sort); - auto_exclude_tags = notmuch_config_get_auto_exclude_tags - (config, &auto_exclude_tags_length); - for (i = 0; i < auto_exclude_tags_length; i++) - notmuch_query_add_tag_exclude (query, auto_exclude_tags[i]); + search_exclude_tags = notmuch_config_get_search_exclude_tags + (config, &search_exclude_tags_length); + for (i = 0; i < search_exclude_tags_length; i++) + notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); switch (output) { default: -- 1.7.8.1 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH 1/4] search: rename auto_exclude_tags to {search,}exclude_tags 2012-01-19 19:19 ` [PATCH 1/4] search: rename auto_exclude_tags to {search, }exclude_tags Pieter Praet @ 2012-01-19 19:41 ` Austin Clements 2012-01-19 21:14 ` [PATCH 1/4] search: rename auto_exclude_tags to {search, }exclude_tags Pieter Praet 0 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-19 19:41 UTC (permalink / raw) To: Pieter Praet; +Cc: Notmuch Mail Quoth Pieter Praet on Jan 19 at 8:19 pm: > All other config-related functions and args include the section > title in their name, so for the sake of consistency, mirror that. > > Also, the "auto"matic part is a given, so that was dropped. LGTM other than one nit, below. > --- a/notmuch-config.c > +++ b/notmuch-config.c > @@ -89,9 +89,9 @@ static const char search_config_comment[] = > "\n" > " The following option is supported here:\n" > "\n" > - "\tauto_exclude_tags A ;-separated list of tags that will be\n" > - "\t excluded from search results by default. Using an excluded tag\n" > - "\t in a query will override that exclusion.\n"; > + "\texclude_tags A list (separated by ';') of the tags that will be\n" > + "\t\texcluded from search results by default. Using an excluded tag in a\n" > + "\t\tquery will override that exclusion.\n"; I'd propose that any tag whose name is more than seven characters long should have its description start under it, indented by a tab, like I did in id:"1326920205-31296-1-git-send-email-amdragon@mit.edu". That looks nice and keeps the description indented consistently without ridiculous amounts of negative space and narrow wrapping. ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 1/4] search: rename auto_exclude_tags to {search, }exclude_tags 2012-01-19 19:41 ` [PATCH 1/4] search: rename auto_exclude_tags to {search,}exclude_tags Austin Clements @ 2012-01-19 21:14 ` Pieter Praet 0 siblings, 0 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-19 21:14 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail On Thu, 19 Jan 2012 14:41:15 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > Quoth Pieter Praet on Jan 19 at 8:19 pm: > > All other config-related functions and args include the section > > title in their name, so for the sake of consistency, mirror that. > > > > Also, the "auto"matic part is a given, so that was dropped. > > LGTM other than one nit, below. > > > --- a/notmuch-config.c > > +++ b/notmuch-config.c > > @@ -89,9 +89,9 @@ static const char search_config_comment[] = > > "\n" > > " The following option is supported here:\n" > > "\n" > > - "\tauto_exclude_tags A ;-separated list of tags that will be\n" > > - "\t excluded from search results by default. Using an excluded tag\n" > > - "\t in a query will override that exclusion.\n"; > > + "\texclude_tags A list (separated by ';') of the tags that will be\n" > > + "\t\texcluded from search results by default. Using an excluded tag in a\n" > > + "\t\tquery will override that exclusion.\n"; > > I'd propose that any tag whose name is more than seven characters long > should have its description start under it, indented by a tab, like I > did in id:"1326920205-31296-1-git-send-email-amdragon@mit.edu". That > looks nice and keeps the description indented consistently without > ridiculous amounts of negative space and narrow wrapping. Oh, nice. Looks like I should first work down to inbox zero (still got a looong way to go :/...) before submitting patches. I'll wait for yours to be pushed before resubmitting this series. Peace -- Pieter ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 2/4] test: only exclude "deleted" messages from search if explicitly configured 2012-01-19 19:19 ` Pieter Praet 2012-01-19 19:19 ` [PATCH 1/4] search: rename auto_exclude_tags to {search, }exclude_tags Pieter Praet @ 2012-01-19 19:19 ` Pieter Praet 2012-01-19 19:19 ` [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup Pieter Praet ` (3 subsequent siblings) 5 siblings, 0 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-19 19:19 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail If the 'search.exclude_tags' option is missing from the config file, its value is automatically set to "deleted;spam;". Taking PoLS/DWIM into account, this should probably only happen during setup. --- test/search | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/test/search b/test/search index bf965e7..99d94bd 100755 --- a/test/search +++ b/test/search @@ -130,6 +130,7 @@ output=$(notmuch search "bödý" | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread)" test_begin_subtest "Exclude \"deleted\" messages from search" +notmuch config set search.exclude_tags = deleted generate_message '[subject]="Not deleted"' generate_message '[subject]="Deleted"' notmuch new > /dev/null @@ -147,4 +148,11 @@ output=$(notmuch search subject:deleted | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted inbox unread)" +test_begin_subtest "Don't exclude \"deleted\" messages from search if not configured" +test_subtest_known_broken +notmuch config set search.exclude_tags +output=$(notmuch search subject:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) +thread:XXX 2001-01-05 [2/2] Notmuch Test Suite; Deleted (deleted inbox unread)" + test_done -- 1.7.8.1 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup 2012-01-19 19:19 ` Pieter Praet 2012-01-19 19:19 ` [PATCH 1/4] search: rename auto_exclude_tags to {search, }exclude_tags Pieter Praet 2012-01-19 19:19 ` [PATCH 2/4] test: only exclude "deleted" messages from search if explicitly configured Pieter Praet @ 2012-01-19 19:19 ` Pieter Praet 2012-01-22 22:14 ` Xavier Maillard 2012-01-19 19:19 ` [PATCH 4/4] setup: prompt user for search.exclude_tags value Pieter Praet ` (2 subsequent siblings) 5 siblings, 1 reply; 176+ messages in thread From: Pieter Praet @ 2012-01-19 19:19 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail If the 'search.exclude_tags' option is missing from the config file, its value is automatically set to "deleted;spam;". Taking PoLS/DWIM into account, this should probably only happen during setup. This patch is actually Austin Clements' work: id:"20120117203211.GQ16740@mit.edu" --- notmuch-config.c | 8 ++++++-- test/search | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/notmuch-config.c b/notmuch-config.c index 687bd76..1d9e842 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -361,8 +361,12 @@ notmuch_config_open (void *ctx, } if (notmuch_config_get_search_exclude_tags (config, &tmp) == NULL) { - const char *tags[] = { "deleted", "spam" }; - notmuch_config_set_search_exclude_tags (config, tags, 2); + if (is_new) { + const char *tags[] = { "deleted", "spam" }; + notmuch_config_set_search_exclude_tags (config, tags, 2); + } else { + notmuch_config_set_search_exclude_tags (config, NULL, 0); + } } error = NULL; diff --git a/test/search b/test/search index 99d94bd..414be35 100755 --- a/test/search +++ b/test/search @@ -149,7 +149,6 @@ test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; N thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted inbox unread)" test_begin_subtest "Don't exclude \"deleted\" messages from search if not configured" -test_subtest_known_broken notmuch config set search.exclude_tags output=$(notmuch search subject:deleted | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) -- 1.7.8.1 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup 2012-01-19 19:19 ` [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup Pieter Praet @ 2012-01-22 22:14 ` Xavier Maillard 2012-01-22 22:53 ` Jameson Graef Rollins 2012-01-23 4:16 ` Pieter Praet 0 siblings, 2 replies; 176+ messages in thread From: Xavier Maillard @ 2012-01-22 22:14 UTC (permalink / raw) To: Pieter Praet, Austin Clements; +Cc: Notmuch Mail On Thu, 19 Jan 2012 20:19:03 +0100, Pieter Praet <pieter@praet.org> wrote: > If the 'search.exclude_tags' option is missing from the config file, > its value is automatically set to "deleted;spam;". Taking PoLS/DWIM > into account, this should probably only happen during setup. > > This patch is actually Austin Clements' work: > id:"20120117203211.GQ16740@mit.edu" I do not think this is a sane default. As I told it in another post. I do not expect notmuch to skew my search queries not that I specifically asked. /Xavier ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup 2012-01-22 22:14 ` Xavier Maillard @ 2012-01-22 22:53 ` Jameson Graef Rollins 2012-01-23 5:05 ` Pieter Praet 2012-01-23 4:16 ` Pieter Praet 1 sibling, 1 reply; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-22 22:53 UTC (permalink / raw) To: Xavier Maillard, Pieter Praet, Austin Clements; +Cc: Notmuch Mail [-- Attachment #1: Type: text/plain, Size: 1300 bytes --] On Sun, 22 Jan 2012 23:14:13 +0100, Xavier Maillard <xavier@maillard.im> wrote: > > On Thu, 19 Jan 2012 20:19:03 +0100, Pieter Praet <pieter@praet.org> wrote: > > If the 'search.exclude_tags' option is missing from the config file, > > its value is automatically set to "deleted;spam;". Taking PoLS/DWIM > > into account, this should probably only happen during setup. > > > > This patch is actually Austin Clements' work: > > id:"20120117203211.GQ16740@mit.edu" > > I do not think this is a sane default. As I told it in another post. I > do not expect notmuch to skew my search queries not that I specifically > asked. Hi, Xavier. Do you currently mark things as "deleted" or "spam"? If not, this would have no affect on your search results. If you do, do you currently expect those messages to show up in searches? If so, why did you mark them as "deleted" or "spam" to begin with? I agree with your point in principle (ie. I don't generally want my searches tampered with behind the scenes) but the issue here is about messages that have been explicitly tagged as a form of "trash". Trash is by it's nature something you're trying to get rid of. If you wanted to find something in the future, why would you put it in the trash in the first place? jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup 2012-01-22 22:53 ` Jameson Graef Rollins @ 2012-01-23 5:05 ` Pieter Praet 2012-01-23 5:34 ` Jameson Graef Rollins 2012-01-23 7:22 ` Jani Nikula 0 siblings, 2 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-23 5:05 UTC (permalink / raw) To: Jameson Graef Rollins, Xavier Maillard, Austin Clements; +Cc: Notmuch Mail On Sun, 22 Jan 2012 14:53:41 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > On Sun, 22 Jan 2012 23:14:13 +0100, Xavier Maillard <xavier@maillard.im> wrote: > > > > On Thu, 19 Jan 2012 20:19:03 +0100, Pieter Praet <pieter@praet.org> wrote: > > > If the 'search.exclude_tags' option is missing from the config file, > > > its value is automatically set to "deleted;spam;". Taking PoLS/DWIM > > > into account, this should probably only happen during setup. > > > > > > This patch is actually Austin Clements' work: > > > id:"20120117203211.GQ16740@mit.edu" > > > > I do not think this is a sane default. As I told it in another post. I > > do not expect notmuch to skew my search queries not that I specifically > > asked. > > Hi, Xavier. Do you currently mark things as "deleted" or "spam"? If > not, this would have no affect on your search results. If you do, do > you currently expect those messages to show up in searches? If so, why > did you mark them as "deleted" or "spam" to begin with? > > I agree with your point in principle (ie. I don't generally want my > searches tampered with behind the scenes) but the issue here is about > messages that have been explicitly tagged as a form of "trash". Trash > is by it's nature something you're trying to get rid of. If you wanted > to find something in the future, why would you put it in the trash in > the first place? > You definitely have a point, but then again, who are we to assume that the terms "deleted" and "spam" have the *exact* same meaning for everyone? (also see id:"8739bbo0br.fsf@praet.org") IMHO, this is one of those options that should remain disabled until *explicitly* set by the user. > jamie. Peace -- Pieter ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup 2012-01-23 5:05 ` Pieter Praet @ 2012-01-23 5:34 ` Jameson Graef Rollins 2012-01-23 7:35 ` Pieter Praet 2012-01-23 7:22 ` Jani Nikula 1 sibling, 1 reply; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-23 5:34 UTC (permalink / raw) To: Pieter Praet, Xavier Maillard, Austin Clements; +Cc: Notmuch Mail [-- Attachment #1: Type: text/plain, Size: 1995 bytes --] On Mon, 23 Jan 2012 06:05:27 +0100, Pieter Praet <pieter@praet.org> wrote: > You definitely have a point, but then again, who are we to assume that > the terms "deleted" and "spam" have the *exact* same meaning for > everyone? (also see id:"8739bbo0br.fsf@praet.org") Hrm. I'm not sure I buy this. Words already have meanings. If we're going to start down a rabbit hole where we have to assume that users are making up crazy alternate meanings for words, we're going to run into a lot of problems. Notmuch, or at least the emacs interface, already assumes a specific meaning for certain terms, like most notably "inbox". Given that we're dealing with english here, I think we have to assume common usage meanings for any of the words we're using to describe anything. This argument breaks a little in regards to "delete" since we're not actually deleting anything in the sense of rm'ing it form the filesystem, so we're already changing the meaning a bit. But see below. > IMHO, this is one of those options that should remain disabled until > *explicitly* set by the user. Ok, but then we're back to the incredibly prolonged discussion we've been having about adding "delete" keys. If we disable this by default, but add "delete" keys, the user might be in for a different surprise if "deleted" messages keep showing up in searches. Basically we have two options as I see it: - add keys bindings to add "deleted" tags, and then *also* exclude "tag:deleted" by default. - don't exclude anything by default, but then don't add any special keys to handle "deleted" tags. There seemed to be a consensus forming that we in fact did want to add the "deleted" key bindings. If we do that, then I think we should generate the config file to exclude "deleted" tags by default. jamie. PS: when I say "exclude tags by default" I actually mean that the setting should be added to the config file upon (re)generation. Nothing should be excluded if nothing is set in the config file. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup 2012-01-23 5:34 ` Jameson Graef Rollins @ 2012-01-23 7:35 ` Pieter Praet 0 siblings, 0 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-23 7:35 UTC (permalink / raw) To: Jameson Graef Rollins, Xavier Maillard, Austin Clements; +Cc: Notmuch Mail On Sun, 22 Jan 2012 21:34:00 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > On Mon, 23 Jan 2012 06:05:27 +0100, Pieter Praet <pieter@praet.org> wrote: > > You definitely have a point, but then again, who are we to assume that > > the terms "deleted" and "spam" have the *exact* same meaning for > > everyone? (also see id:"8739bbo0br.fsf@praet.org") > > Hrm. I'm not sure I buy this. Words already have meanings. If we're > going to start down a rabbit hole where we have to assume that users are > making up crazy alternate meanings for words, we're going to run into a > lot of problems. > True, but we're talking about tags here. Flexibility is their raison d'être. If we're going to impose semi-arbitrary limitations, we do away with alot of the benefits we were looking for in the first place. > Notmuch, or at least the emacs interface, already assumes a specific > meaning for certain terms, like most notably "inbox". Given that we're > dealing with english here, I think we have to assume common usage > meanings for any of the words we're using to describe anything. > Actually, we're only a small step away from being free to use whatever tag(s) we want for this. The term "inbox" is hardcoded in only 4 places, all of which are trivial to fix: - @ binary - `notmuch_config_open', where it's only used as a fallback when 'new.tags' isn't set (and reused to suggest a default value for 'new.tags' when running setup). - @ Emacs UI - `notmuch-saved-searches' (the function), where it's only used as a fallback when `notmuch-saved-searches' (the var) isn't set. - `notmuch-search-archive-thread' - `notmuch-show-archive-thread-internal' > This argument breaks a little in regards to "delete" since we're not > actually deleting anything in the sense of rm'ing it form the > filesystem, so we're already changing the meaning a bit. But see below. > [...] > > IMHO, this is one of those options that should remain disabled until > > *explicitly* set by the user. > > Ok, but then we're back to the incredibly prolonged discussion we've > been having about adding "delete" keys. If we disable this by default, > but add "delete" keys, the user might be in for a different surprise if > "deleted" messages keep showing up in searches. > > Basically we have two options as I see it: > > - add keys bindings to add "deleted" tags, and then *also* exclude > "tag:deleted" by default. > > - don't exclude anything by default, but then don't add any special keys > to handle "deleted" tags. > Adding a key to "delete" messages doesn't necessarily have to mean that the tag it adds should be hardcoded to "deleted". For example, our config file could contain something like this: #+begin_src conf [new] tags=unread;inbox; [tag] deleted=deleted;-inbox; archive=-inbox; [search] exclude_tags=deleted;spam; #+end_src (where all entries under the [tag] section could be used as aliases for "complex" tagging operations) ... and then we could "delete" messages using something like: #+begin_src emacs-lisp (define-key notmuch-show-mode-map "d" (lambda() (interactive) (notmuch-show-mod-tags (split-string (notmuch-config-get "tag.deleted") "\n")) (notmuch-show-next-open-message))) #+end_src (`notmuch-show-mod-tags' doesn't exist, of course, but see `notmuch-message-mark-replied' for a good example of how it could be work...) > There seemed to be a consensus forming that we in fact did want to add > the "deleted" key bindings. [...] +1. > [...] If we do that, then I think we should > generate the config file to exclude "deleted" tags by default. > > jamie. > > PS: when I say "exclude tags by default" I actually mean that the > setting should be added to the config file upon (re)generation. Nothing > should be excluded if nothing is set in the config file. Exactly! This is actually the *only* reason I involved myself with this whole conversation in the first place :) Peace -- Pieter ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup 2012-01-23 5:05 ` Pieter Praet 2012-01-23 5:34 ` Jameson Graef Rollins @ 2012-01-23 7:22 ` Jani Nikula 2012-01-23 7:38 ` Jameson Graef Rollins 2012-01-23 8:03 ` Pieter Praet 1 sibling, 2 replies; 176+ messages in thread From: Jani Nikula @ 2012-01-23 7:22 UTC (permalink / raw) To: Pieter Praet, Jameson Graef Rollins, Xavier Maillard, Austin Clements Cc: Notmuch Mail On Mon, 23 Jan 2012 06:05:27 +0100, Pieter Praet <pieter@praet.org> wrote: > On Sun, 22 Jan 2012 14:53:41 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > > On Sun, 22 Jan 2012 23:14:13 +0100, Xavier Maillard <xavier@maillard.im> wrote: > > > > > > On Thu, 19 Jan 2012 20:19:03 +0100, Pieter Praet <pieter@praet.org> wrote: > > > > If the 'search.exclude_tags' option is missing from the config file, > > > > its value is automatically set to "deleted;spam;". Taking PoLS/DWIM > > > > into account, this should probably only happen during setup. > > > > > > > > This patch is actually Austin Clements' work: > > > > id:"20120117203211.GQ16740@mit.edu" > > > > > > I do not think this is a sane default. As I told it in another post. I > > > do not expect notmuch to skew my search queries not that I specifically > > > asked. > > > > Hi, Xavier. Do you currently mark things as "deleted" or "spam"? If > > not, this would have no affect on your search results. If you do, do > > you currently expect those messages to show up in searches? If so, why > > did you mark them as "deleted" or "spam" to begin with? > > > > I agree with your point in principle (ie. I don't generally want my > > searches tampered with behind the scenes) but the issue here is about > > messages that have been explicitly tagged as a form of "trash". Trash > > is by it's nature something you're trying to get rid of. If you wanted > > to find something in the future, why would you put it in the trash in > > the first place? > > > > You definitely have a point, but then again, who are we to assume that > the terms "deleted" and "spam" have the *exact* same meaning for > everyone? (also see id:"8739bbo0br.fsf@praet.org") "deleted" used to be a tag recognized by notmuch, and it used to sync to the T (trashed) maildir flag. Even if notmuch won't delete any of your mails now, I don't think you should use "deleted" on messages you want to see again. Please let's not split hairs about this. There really should be a definitive list of tags that are special to lib/cli/emacs (like "inbox", "unread", "deleted", ...), or are recommended for specific purposes (like "new" as an intermediate tag before more sophisticated tagging), to avoid prolonged discussions like this. BR, Jani. ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup 2012-01-23 7:22 ` Jani Nikula @ 2012-01-23 7:38 ` Jameson Graef Rollins 2012-01-23 8:24 ` Jani Nikula 2012-01-23 8:03 ` Pieter Praet 1 sibling, 1 reply; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-23 7:38 UTC (permalink / raw) To: Jani Nikula, Pieter Praet, Xavier Maillard, Austin Clements; +Cc: Notmuch Mail [-- Attachment #1: Type: text/plain, Size: 682 bytes --] On Mon, 23 Jan 2012 07:22:25 +0000, Jani Nikula <jani@nikula.org> wrote: > There really should be a definitive list of tags that are special to > lib/cli/emacs (like "inbox", "unread", "deleted", ...), or are > recommended for specific purposes (like "new" as an intermediate tag > before more sophisticated tagging), to avoid prolonged discussions like > this. Just to be clear: the lib doesn't assign any special meaning to any tag (as it shouldn't). The cli does, but only in the sense that it creates config files that designate certain tags for certain operations by default. It's really in emacs where certain tags currently have unconfigurable meanings ("inbox"). jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup 2012-01-23 7:38 ` Jameson Graef Rollins @ 2012-01-23 8:24 ` Jani Nikula 2012-01-23 8:45 ` Jameson Graef Rollins 2012-01-25 0:43 ` Pieter Praet 0 siblings, 2 replies; 176+ messages in thread From: Jani Nikula @ 2012-01-23 8:24 UTC (permalink / raw) To: Jameson Graef Rollins, Pieter Praet, Xavier Maillard, Austin Clements Cc: Notmuch Mail On Sun, 22 Jan 2012 23:38:40 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > On Mon, 23 Jan 2012 07:22:25 +0000, Jani Nikula <jani@nikula.org> wrote: > > There really should be a definitive list of tags that are special to > > lib/cli/emacs (like "inbox", "unread", "deleted", ...), or are > > recommended for specific purposes (like "new" as an intermediate tag > > before more sophisticated tagging), to avoid prolonged discussions like > > this. > > Just to be clear: the lib doesn't assign any special meaning to any tag > (as it shouldn't). The cli does, but only in the sense that it creates > config files that designate certain tags for certain operations by > default. It's really in emacs where certain tags currently have > unconfigurable meanings ("inbox"). The lib *does* assign special meaning to the tags it syncs to maildir flags: draft, flagged, passed, replied, unread. (deleted used to be part of the list.) The cli does have to request the syncing, but the mapping is in the lib (flag2tag array in lib/message.cc). BR, Jani. ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup 2012-01-23 8:24 ` Jani Nikula @ 2012-01-23 8:45 ` Jameson Graef Rollins 2012-01-25 0:43 ` Pieter Praet 1 sibling, 0 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-23 8:45 UTC (permalink / raw) To: Jani Nikula, Pieter Praet, Xavier Maillard, Austin Clements; +Cc: Notmuch Mail [-- Attachment #1: Type: text/plain, Size: 393 bytes --] On Mon, 23 Jan 2012 08:24:44 +0000, Jani Nikula <jani@nikula.org> wrote: > The lib *does* assign special meaning to the tags it syncs to maildir > flags: draft, flagged, passed, replied, unread. (deleted used to be part > of the list.) The cli does have to request the syncing, but the mapping > is in the lib (flag2tag array in lib/message.cc). Ah, you're absolutely right. My bad. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup 2012-01-23 8:24 ` Jani Nikula 2012-01-23 8:45 ` Jameson Graef Rollins @ 2012-01-25 0:43 ` Pieter Praet 1 sibling, 0 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-25 0:43 UTC (permalink / raw) To: Jani Nikula, Jameson Graef Rollins, Xavier Maillard, Austin Clements Cc: Notmuch Mail On Mon, 23 Jan 2012 08:24:44 +0000, Jani Nikula <jani@nikula.org> wrote: > On Sun, 22 Jan 2012 23:38:40 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > > On Mon, 23 Jan 2012 07:22:25 +0000, Jani Nikula <jani@nikula.org> wrote: > > > There really should be a definitive list of tags that are special to > > > lib/cli/emacs (like "inbox", "unread", "deleted", ...), or are > > > recommended for specific purposes (like "new" as an intermediate tag > > > before more sophisticated tagging), to avoid prolonged discussions like > > > this. > > > > Just to be clear: the lib doesn't assign any special meaning to any tag > > (as it shouldn't). The cli does, but only in the sense that it creates > > config files that designate certain tags for certain operations by > > default. It's really in emacs where certain tags currently have > > unconfigurable meanings ("inbox"). > > The lib *does* assign special meaning to the tags it syncs to maildir > flags: draft, flagged, passed, replied, unread. (deleted used to be part > of the list.) The cli does have to request the syncing, but the mapping > is in the lib (flag2tag array in lib/message.cc). > Hmmm, right. And seeing as how we can't simply replace the hardcoded tag names in the flag2tag array with calls to the `notmuch_config_get_*' functions (or move the Maildir sync stuff out of the lib altogether), custom tag-to-concept mapping probably won't become a reality anytime soon. Too bad... > BR, > Jani. Peace -- Pieter ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup 2012-01-23 7:22 ` Jani Nikula 2012-01-23 7:38 ` Jameson Graef Rollins @ 2012-01-23 8:03 ` Pieter Praet 2012-01-23 8:31 ` Jani Nikula 1 sibling, 1 reply; 176+ messages in thread From: Pieter Praet @ 2012-01-23 8:03 UTC (permalink / raw) To: Jani Nikula, Jameson Graef Rollins, Xavier Maillard, Austin Clements Cc: Notmuch Mail On Mon, 23 Jan 2012 07:22:25 +0000, Jani Nikula <jani@nikula.org> wrote: > On Mon, 23 Jan 2012 06:05:27 +0100, Pieter Praet <pieter@praet.org> wrote: > > On Sun, 22 Jan 2012 14:53:41 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > > > On Sun, 22 Jan 2012 23:14:13 +0100, Xavier Maillard <xavier@maillard.im> wrote: > > > > > > > > On Thu, 19 Jan 2012 20:19:03 +0100, Pieter Praet <pieter@praet.org> wrote: > > > > > If the 'search.exclude_tags' option is missing from the config file, > > > > > its value is automatically set to "deleted;spam;". Taking PoLS/DWIM > > > > > into account, this should probably only happen during setup. > > > > > > > > > > This patch is actually Austin Clements' work: > > > > > id:"20120117203211.GQ16740@mit.edu" > > > > > > > > I do not think this is a sane default. As I told it in another post. I > > > > do not expect notmuch to skew my search queries not that I specifically > > > > asked. > > > > > > Hi, Xavier. Do you currently mark things as "deleted" or "spam"? If > > > not, this would have no affect on your search results. If you do, do > > > you currently expect those messages to show up in searches? If so, why > > > did you mark them as "deleted" or "spam" to begin with? > > > > > > I agree with your point in principle (ie. I don't generally want my > > > searches tampered with behind the scenes) but the issue here is about > > > messages that have been explicitly tagged as a form of "trash". Trash > > > is by it's nature something you're trying to get rid of. If you wanted > > > to find something in the future, why would you put it in the trash in > > > the first place? > > > > > > > You definitely have a point, but then again, who are we to assume that > > the terms "deleted" and "spam" have the *exact* same meaning for > > everyone? (also see id:"8739bbo0br.fsf@praet.org") > > "deleted" used to be a tag recognized by notmuch, and it used to sync to > the T (trashed) maildir flag. Even if notmuch won't delete any of your > mails now, I don't think you should use "deleted" on messages you want > to see again. Please let's not split hairs about this. > Agreed, but it might be nice to make a clear distinction between concepts and the actual tags mapped to them. I'm not suggestion we redefine the term "deleted", but from an internationalization standpoint, we shouldn't prevent users from mapping e.g. "verwijderd", "supprimé", "gelöscht", ... to the concept "deleted". > There really should be a definitive list of tags that are special to > lib/cli/emacs (like "inbox", "unread", "deleted", ...), or are > recommended for specific purposes (like "new" as an intermediate tag > before more sophisticated tagging), to avoid prolonged discussions like > this. > A list of recommended tags would definitely be nice, as long as they remain recommendations (as opposed to obligations), especially since there's really no reason to designate certain tags as being "special". > BR, > Jani. Peace -- Pieter ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup 2012-01-23 8:03 ` Pieter Praet @ 2012-01-23 8:31 ` Jani Nikula 2012-01-25 0:42 ` Pieter Praet 0 siblings, 1 reply; 176+ messages in thread From: Jani Nikula @ 2012-01-23 8:31 UTC (permalink / raw) To: Pieter Praet, Jameson Graef Rollins, Xavier Maillard, Austin Clements Cc: Notmuch Mail On Mon, 23 Jan 2012 09:03:42 +0100, Pieter Praet <pieter@praet.org> wrote: > On Mon, 23 Jan 2012 07:22:25 +0000, Jani Nikula <jani@nikula.org> wrote: > > On Mon, 23 Jan 2012 06:05:27 +0100, Pieter Praet <pieter@praet.org> wrote: > > > On Sun, 22 Jan 2012 14:53:41 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > > > > On Sun, 22 Jan 2012 23:14:13 +0100, Xavier Maillard <xavier@maillard.im> wrote: > > > > > > > > > > On Thu, 19 Jan 2012 20:19:03 +0100, Pieter Praet <pieter@praet.org> wrote: > > > > > > If the 'search.exclude_tags' option is missing from the config file, > > > > > > its value is automatically set to "deleted;spam;". Taking PoLS/DWIM > > > > > > into account, this should probably only happen during setup. > > > > > > > > > > > > This patch is actually Austin Clements' work: > > > > > > id:"20120117203211.GQ16740@mit.edu" > > > > > > > > > > I do not think this is a sane default. As I told it in another post. I > > > > > do not expect notmuch to skew my search queries not that I specifically > > > > > asked. > > > > > > > > Hi, Xavier. Do you currently mark things as "deleted" or "spam"? If > > > > not, this would have no affect on your search results. If you do, do > > > > you currently expect those messages to show up in searches? If so, why > > > > did you mark them as "deleted" or "spam" to begin with? > > > > > > > > I agree with your point in principle (ie. I don't generally want my > > > > searches tampered with behind the scenes) but the issue here is about > > > > messages that have been explicitly tagged as a form of "trash". Trash > > > > is by it's nature something you're trying to get rid of. If you wanted > > > > to find something in the future, why would you put it in the trash in > > > > the first place? > > > > > > > > > > You definitely have a point, but then again, who are we to assume that > > > the terms "deleted" and "spam" have the *exact* same meaning for > > > everyone? (also see id:"8739bbo0br.fsf@praet.org") > > > > "deleted" used to be a tag recognized by notmuch, and it used to sync to > > the T (trashed) maildir flag. Even if notmuch won't delete any of your > > mails now, I don't think you should use "deleted" on messages you want > > to see again. Please let's not split hairs about this. > > > > Agreed, but it might be nice to make a clear distinction between > concepts and the actual tags mapped to them. I'm not suggestion we > redefine the term "deleted", but from an internationalization > standpoint, we shouldn't prevent users from mapping e.g. "verwijderd", > "supprimé", "gelöscht", ... to the concept "deleted". > > > There really should be a definitive list of tags that are special to > > lib/cli/emacs (like "inbox", "unread", "deleted", ...), or are > > recommended for specific purposes (like "new" as an intermediate tag > > before more sophisticated tagging), to avoid prolonged discussions like > > this. > > > > A list of recommended tags would definitely be nice, as long as they > remain recommendations (as opposed to obligations), especially since > there's really no reason to designate certain tags as being "special". Whether there's reason or not, certain tags are special, for a fact, and they are not just recommendations. Perhaps one day someone will contribute patches to make them configurable, and separate the concepts from the actual tags, but in the mean time it will be easier to just document them for what they are. BR, Jani. ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup 2012-01-23 8:31 ` Jani Nikula @ 2012-01-25 0:42 ` Pieter Praet 0 siblings, 0 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-25 0:42 UTC (permalink / raw) To: Jani Nikula, Jameson Graef Rollins, Xavier Maillard, Austin Clements Cc: Notmuch Mail On Mon, 23 Jan 2012 08:31:23 +0000, Jani Nikula <jani@nikula.org> wrote: > On Mon, 23 Jan 2012 09:03:42 +0100, Pieter Praet <pieter@praet.org> wrote: > > On Mon, 23 Jan 2012 07:22:25 +0000, Jani Nikula <jani@nikula.org> wrote: > > > On Mon, 23 Jan 2012 06:05:27 +0100, Pieter Praet <pieter@praet.org> wrote: > > > > On Sun, 22 Jan 2012 14:53:41 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > > > > > On Sun, 22 Jan 2012 23:14:13 +0100, Xavier Maillard <xavier@maillard.im> wrote: > > > > > > > > > > > > On Thu, 19 Jan 2012 20:19:03 +0100, Pieter Praet <pieter@praet.org> wrote: > > > > > > > If the 'search.exclude_tags' option is missing from the config file, > > > > > > > its value is automatically set to "deleted;spam;". Taking PoLS/DWIM > > > > > > > into account, this should probably only happen during setup. > > > > > > > > > > > > > > This patch is actually Austin Clements' work: > > > > > > > id:"20120117203211.GQ16740@mit.edu" > > > > > > > > > > > > I do not think this is a sane default. As I told it in another post. I > > > > > > do not expect notmuch to skew my search queries not that I specifically > > > > > > asked. > > > > > > > > > > Hi, Xavier. Do you currently mark things as "deleted" or "spam"? If > > > > > not, this would have no affect on your search results. If you do, do > > > > > you currently expect those messages to show up in searches? If so, why > > > > > did you mark them as "deleted" or "spam" to begin with? > > > > > > > > > > I agree with your point in principle (ie. I don't generally want my > > > > > searches tampered with behind the scenes) but the issue here is about > > > > > messages that have been explicitly tagged as a form of "trash". Trash > > > > > is by it's nature something you're trying to get rid of. If you wanted > > > > > to find something in the future, why would you put it in the trash in > > > > > the first place? > > > > > > > > > > > > > You definitely have a point, but then again, who are we to assume that > > > > the terms "deleted" and "spam" have the *exact* same meaning for > > > > everyone? (also see id:"8739bbo0br.fsf@praet.org") > > > > > > "deleted" used to be a tag recognized by notmuch, and it used to sync to > > > the T (trashed) maildir flag. Even if notmuch won't delete any of your > > > mails now, I don't think you should use "deleted" on messages you want > > > to see again. Please let's not split hairs about this. > > > > > > > Agreed, but it might be nice to make a clear distinction between > > concepts and the actual tags mapped to them. I'm not suggestion we > > redefine the term "deleted", but from an internationalization > > standpoint, we shouldn't prevent users from mapping e.g. "verwijderd", > > "supprimé", "gelöscht", ... to the concept "deleted". > > > > > There really should be a definitive list of tags that are special to > > > lib/cli/emacs (like "inbox", "unread", "deleted", ...), or are > > > recommended for specific purposes (like "new" as an intermediate tag > > > before more sophisticated tagging), to avoid prolonged discussions like > > > this. > > > > > > > A list of recommended tags would definitely be nice, as long as they > > remain recommendations (as opposed to obligations), especially since > > there's really no reason to designate certain tags as being "special". > > Whether there's reason or not, certain tags are special, for a fact, and > they are not just recommendations. [...] My mistake. Thanks for the correction! > [...] Perhaps one day someone will > contribute patches to make them configurable, and separate the concepts > from the actual tags, but in the mean time it will be easier to just > document them for what they are. > Agreed. > BR, > Jani. Peace -- Pieter ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup 2012-01-22 22:14 ` Xavier Maillard 2012-01-22 22:53 ` Jameson Graef Rollins @ 2012-01-23 4:16 ` Pieter Praet 1 sibling, 0 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-23 4:16 UTC (permalink / raw) To: Xavier Maillard, Austin Clements; +Cc: Notmuch Mail On Sun, 22 Jan 2012 23:14:13 +0100, Xavier Maillard <xavier@maillard.im> wrote: > > On Thu, 19 Jan 2012 20:19:03 +0100, Pieter Praet <pieter@praet.org> wrote: > > If the 'search.exclude_tags' option is missing from the config file, > > its value is automatically set to "deleted;spam;". Taking PoLS/DWIM > > into account, this should probably only happen during setup. > > > > This patch is actually Austin Clements' work: > > id:"20120117203211.GQ16740@mit.edu" > > I do not think this is a sane default. As I told it in another post. I > do not expect notmuch to skew my search queries not that I specifically > asked. > I agree 100%. I've responded in more detail @ your previous reply: id:"87ty3nawbt.fsf@praet.org" > /Xavier Peace -- Pieter ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 4/4] setup: prompt user for search.exclude_tags value 2012-01-19 19:19 ` Pieter Praet ` (2 preceding siblings ...) 2012-01-19 19:19 ` [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup Pieter Praet @ 2012-01-19 19:19 ` Pieter Praet 2012-01-19 19:44 ` Austin Clements 2012-01-19 19:36 ` [PATCH v3 2/2] search: Support automatic tag exclusions Austin Clements 2012-01-22 22:09 ` Xavier Maillard 5 siblings, 1 reply; 176+ messages in thread From: Pieter Praet @ 2012-01-19 19:19 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail Allow users to customize the search.exclude_tags option during setup. --- notmuch-setup.c | 36 ++++++++++++++++++++++++++++++++++++ 1 files changed, 36 insertions(+), 0 deletions(-) diff --git a/notmuch-setup.c b/notmuch-setup.c index c3ea937..44d4aaa 100644 --- a/notmuch-setup.c +++ b/notmuch-setup.c @@ -101,6 +101,8 @@ notmuch_setup_command (unused (void *ctx), int is_new; const char **new_tags; size_t new_tags_len; + const char **search_exclude_tags; + size_t search_exclude_tags_len; #define prompt(format, ...) \ do { \ @@ -195,6 +197,40 @@ notmuch_setup_command (unused (void *ctx), g_ptr_array_free (tags, TRUE); } + search_exclude_tags = notmuch_config_get_search_exclude_tags (config, &search_exclude_tags_len); + + printf ("Tags to exclude when searching messages (separated by spaces) ["); + + for (i = 0; i < search_exclude_tags_len; i++) { + if (i != 0) + printf (" "); + printf ("%s", search_exclude_tags[i]); + } + + prompt ("]: "); + + if (strlen (response)) { + GPtrArray *tags = g_ptr_array_new (); + char *tag = response; + char *space; + + while (tag && *tag) { + space = strchr (tag, ' '); + if (space) + g_ptr_array_add (tags, talloc_strndup (ctx, tag, space - tag)); + else + g_ptr_array_add (tags, talloc_strdup (ctx, tag)); + tag = space; + while (tag && *tag == ' ') + tag++; + } + + notmuch_config_set_search_exclude_tags (config, (const char **) tags->pdata, + tags->len); + + g_ptr_array_free (tags, TRUE); + } + if (! notmuch_config_save (config)) { if (is_new) welcome_message_post_setup (); -- 1.7.8.1 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH 4/4] setup: prompt user for search.exclude_tags value 2012-01-19 19:19 ` [PATCH 4/4] setup: prompt user for search.exclude_tags value Pieter Praet @ 2012-01-19 19:44 ` Austin Clements 2012-01-19 21:16 ` Pieter Praet 0 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-19 19:44 UTC (permalink / raw) To: Pieter Praet; +Cc: Notmuch Mail Quoth Pieter Praet on Jan 19 at 8:19 pm: > Allow users to customize the search.exclude_tags option during setup. > > --- > notmuch-setup.c | 36 ++++++++++++++++++++++++++++++++++++ > 1 files changed, 36 insertions(+), 0 deletions(-) > > diff --git a/notmuch-setup.c b/notmuch-setup.c > index c3ea937..44d4aaa 100644 > --- a/notmuch-setup.c > +++ b/notmuch-setup.c > @@ -101,6 +101,8 @@ notmuch_setup_command (unused (void *ctx), > int is_new; > const char **new_tags; > size_t new_tags_len; > + const char **search_exclude_tags; > + size_t search_exclude_tags_len; > > #define prompt(format, ...) \ > do { \ > @@ -195,6 +197,40 @@ notmuch_setup_command (unused (void *ctx), > g_ptr_array_free (tags, TRUE); > } > > + search_exclude_tags = notmuch_config_get_search_exclude_tags (config, &search_exclude_tags_len); > + > + printf ("Tags to exclude when searching messages (separated by spaces) ["); > + > + for (i = 0; i < search_exclude_tags_len; i++) { > + if (i != 0) > + printf (" "); > + printf ("%s", search_exclude_tags[i]); > + } > + > + prompt ("]: "); > + > + if (strlen (response)) { > + GPtrArray *tags = g_ptr_array_new (); > + char *tag = response; > + char *space; > + > + while (tag && *tag) { > + space = strchr (tag, ' '); > + if (space) > + g_ptr_array_add (tags, talloc_strndup (ctx, tag, space - tag)); > + else > + g_ptr_array_add (tags, talloc_strdup (ctx, tag)); > + tag = space; > + while (tag && *tag == ' ') > + tag++; > + } > + > + notmuch_config_set_search_exclude_tags (config, (const char **) tags->pdata, > + tags->len); > + > + g_ptr_array_free (tags, TRUE); > + } > + Holy code duplication. Can we move most of this (at least the response parsing part and maybe the prompt printing) into a function and use it for both new tags and exclude tags? > if (! notmuch_config_save (config)) { > if (is_new) > welcome_message_post_setup (); ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 4/4] setup: prompt user for search.exclude_tags value 2012-01-19 19:44 ` Austin Clements @ 2012-01-19 21:16 ` Pieter Praet 2012-01-20 4:19 ` Austin Clements 0 siblings, 1 reply; 176+ messages in thread From: Pieter Praet @ 2012-01-19 21:16 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail On Thu, 19 Jan 2012 14:44:37 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > Quoth Pieter Praet on Jan 19 at 8:19 pm: > > Allow users to customize the search.exclude_tags option during setup. > > > > --- > > notmuch-setup.c | 36 ++++++++++++++++++++++++++++++++++++ > > 1 files changed, 36 insertions(+), 0 deletions(-) > > > > diff --git a/notmuch-setup.c b/notmuch-setup.c > > index c3ea937..44d4aaa 100644 > > --- a/notmuch-setup.c > > +++ b/notmuch-setup.c > > @@ -101,6 +101,8 @@ notmuch_setup_command (unused (void *ctx), > > int is_new; > > const char **new_tags; > > size_t new_tags_len; > > + const char **search_exclude_tags; > > + size_t search_exclude_tags_len; > > > > #define prompt(format, ...) \ > > do { \ > > @@ -195,6 +197,40 @@ notmuch_setup_command (unused (void *ctx), > > g_ptr_array_free (tags, TRUE); > > } > > > > + search_exclude_tags = notmuch_config_get_search_exclude_tags (config, &search_exclude_tags_len); > > + > > + printf ("Tags to exclude when searching messages (separated by spaces) ["); > > + > > + for (i = 0; i < search_exclude_tags_len; i++) { > > + if (i != 0) > > + printf (" "); > > + printf ("%s", search_exclude_tags[i]); > > + } > > + > > + prompt ("]: "); > > + > > + if (strlen (response)) { > > + GPtrArray *tags = g_ptr_array_new (); > > + char *tag = response; > > + char *space; > > + > > + while (tag && *tag) { > > + space = strchr (tag, ' '); > > + if (space) > > + g_ptr_array_add (tags, talloc_strndup (ctx, tag, space - tag)); > > + else > > + g_ptr_array_add (tags, talloc_strdup (ctx, tag)); > > + tag = space; > > + while (tag && *tag == ' ') > > + tag++; > > + } > > + > > + notmuch_config_set_search_exclude_tags (config, (const char **) tags->pdata, > > + tags->len); > > + > > + g_ptr_array_free (tags, TRUE); > > + } > > + > > Holy code duplication. Can we move most of this (at least the > response parsing part and maybe the prompt printing) into a function > and use it for both new tags and exclude tags? > Depends on who "we" is... :) I would gladly do it if I could, but I think this uber1337 copy-paste coding job serves as *very* convincing proof that I'm pretty much in the dark (with a single wet match) when it comes to C :) > > if (! notmuch_config_save (config)) { > > if (is_new) > > welcome_message_post_setup (); Peace -- Pieter ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 4/4] setup: prompt user for search.exclude_tags value 2012-01-19 21:16 ` Pieter Praet @ 2012-01-20 4:19 ` Austin Clements 2012-01-22 6:55 ` Pieter Praet 0 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-20 4:19 UTC (permalink / raw) To: Pieter Praet; +Cc: Notmuch Mail Quoth Pieter Praet on Jan 19 at 10:16 pm: > On Thu, 19 Jan 2012 14:44:37 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > Quoth Pieter Praet on Jan 19 at 8:19 pm: > > > Allow users to customize the search.exclude_tags option during setup. > > > > > > --- > > > notmuch-setup.c | 36 ++++++++++++++++++++++++++++++++++++ > > > 1 files changed, 36 insertions(+), 0 deletions(-) > > > > > > diff --git a/notmuch-setup.c b/notmuch-setup.c > > > index c3ea937..44d4aaa 100644 > > > --- a/notmuch-setup.c > > > +++ b/notmuch-setup.c > > > @@ -101,6 +101,8 @@ notmuch_setup_command (unused (void *ctx), > > > int is_new; > > > const char **new_tags; > > > size_t new_tags_len; > > > + const char **search_exclude_tags; > > > + size_t search_exclude_tags_len; > > > > > > #define prompt(format, ...) \ > > > do { \ > > > @@ -195,6 +197,40 @@ notmuch_setup_command (unused (void *ctx), > > > g_ptr_array_free (tags, TRUE); > > > } > > > > > > + search_exclude_tags = notmuch_config_get_search_exclude_tags (config, &search_exclude_tags_len); > > > + > > > + printf ("Tags to exclude when searching messages (separated by spaces) ["); > > > + > > > + for (i = 0; i < search_exclude_tags_len; i++) { > > > + if (i != 0) > > > + printf (" "); > > > + printf ("%s", search_exclude_tags[i]); > > > + } > > > + > > > + prompt ("]: "); > > > + > > > + if (strlen (response)) { > > > + GPtrArray *tags = g_ptr_array_new (); > > > + char *tag = response; > > > + char *space; > > > + > > > + while (tag && *tag) { > > > + space = strchr (tag, ' '); > > > + if (space) > > > + g_ptr_array_add (tags, talloc_strndup (ctx, tag, space - tag)); > > > + else > > > + g_ptr_array_add (tags, talloc_strdup (ctx, tag)); > > > + tag = space; > > > + while (tag && *tag == ' ') > > > + tag++; > > > + } > > > + > > > + notmuch_config_set_search_exclude_tags (config, (const char **) tags->pdata, > > > + tags->len); > > > + > > > + g_ptr_array_free (tags, TRUE); > > > + } > > > + > > > > Holy code duplication. Can we move most of this (at least the > > response parsing part and maybe the prompt printing) into a function > > and use it for both new tags and exclude tags? > > > > Depends on who "we" is... :) I would gladly do it if I could, but I > think this uber1337 copy-paste coding job serves as *very* convincing > proof that I'm pretty much in the dark (with a single wet match) when it > comes to C :) Hah, okay. How about this as an initial minor refactoring of the code for new.tags? diff --git a/notmuch-setup.c b/notmuch-setup.c index c3ea937..dcfa607 100644 --- a/notmuch-setup.c +++ b/notmuch-setup.c @@ -87,6 +87,38 @@ welcome_message_post_setup (void) "have sufficient storage space available now.\n\n"); } +static void +print_tag_list (const char **tags, size_t tags_len) +{ + unsigned int i; + for (i = 0; i < tags_len; i++) { + if (i != 0) + printf (" "); + printf ("%s", tags[i]); + } +} + +static GPtrArray * +parse_tag_list (void *ctx, char *response) +{ + GPtrArray *tags = g_ptr_array_new (); + char *tag = response; + char *space; + + while (tag && *tag) { + space = strchr (tag, ' '); + if (space) + g_ptr_array_add (tags, talloc_strndup (ctx, tag, space - tag)); + else + g_ptr_array_add (tags, talloc_strdup (ctx, tag)); + tag = space; + while (tag && *tag == ' ') + tag++; + } + + return tags; +} + int notmuch_setup_command (unused (void *ctx), unused (int argc), unused (char *argv[])) @@ -164,30 +196,11 @@ notmuch_setup_command (unused (void *ctx), new_tags = notmuch_config_get_new_tags (config, &new_tags_len); printf ("Tags to apply to all new messages (separated by spaces) ["); - - for (i = 0; i < new_tags_len; i++) { - if (i != 0) - printf (" "); - printf ("%s", new_tags[i]); - } - + print_tag_list(new_tags, new_tags_len); prompt ("]: "); if (strlen (response)) { - GPtrArray *tags = g_ptr_array_new (); - char *tag = response; - char *space; - - while (tag && *tag) { - space = strchr (tag, ' '); - if (space) - g_ptr_array_add (tags, talloc_strndup (ctx, tag, space - tag)); - else - g_ptr_array_add (tags, talloc_strdup (ctx, tag)); - tag = space; - while (tag && *tag == ' ') - tag++; - } + GPtrArray *tags = parse_tag_list (ctx, response); notmuch_config_set_new_tags (config, (const char **) tags->pdata, tags->len); ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH 4/4] setup: prompt user for search.exclude_tags value 2012-01-20 4:19 ` Austin Clements @ 2012-01-22 6:55 ` Pieter Praet 2012-01-22 17:08 ` Austin Clements 0 siblings, 1 reply; 176+ messages in thread From: Pieter Praet @ 2012-01-22 6:55 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail On Thu, 19 Jan 2012 23:19:02 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > [...] > Hah, okay. How about this as an initial minor refactoring of the code > for new.tags? > [...] Great, thanks! Would the following commit message be satisfactory? : #+begin_quote setup: move tag printing and parsing into separate functions * notmuch-setup.c (notmuch_setup_command): Break tag printing and response parsing out into separate functions called `print_tag_list' respectively `parse_tag_list', for reuse with the 'search.exclude_tags' option. #+end_quote (if not, please suggest an alternative; it'll be your name at the top) Thanks again! Peace -- Pieter ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 4/4] setup: prompt user for search.exclude_tags value 2012-01-22 6:55 ` Pieter Praet @ 2012-01-22 17:08 ` Austin Clements 2012-01-23 4:17 ` Pieter Praet 0 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-22 17:08 UTC (permalink / raw) To: Pieter Praet; +Cc: Notmuch Mail Quoth Pieter Praet on Jan 22 at 7:55 am: > On Thu, 19 Jan 2012 23:19:02 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > [...] > > Hah, okay. How about this as an initial minor refactoring of the code > > for new.tags? > > [...] > > Great, thanks! > > > Would the following commit message be satisfactory? : > > #+begin_quote > setup: move tag printing and parsing into separate functions > > * notmuch-setup.c (notmuch_setup_command): > Break tag printing and response parsing out into separate functions > called `print_tag_list' respectively `parse_tag_list', for reuse > with the 'search.exclude_tags' option. > #+end_quote > > (if not, please suggest an alternative; it'll be your name at the top) Sure. ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 4/4] setup: prompt user for search.exclude_tags value 2012-01-22 17:08 ` Austin Clements @ 2012-01-23 4:17 ` Pieter Praet 2012-01-23 4:22 ` [PATCH v2 1/6] search: rename auto_exclude_tags to {search, }exclude_tags Pieter Praet ` (5 more replies) 0 siblings, 6 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-23 4:17 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail On Sun, 22 Jan 2012 12:08:15 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > Quoth Pieter Praet on Jan 22 at 7:55 am: > > On Thu, 19 Jan 2012 23:19:02 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > > [...] > > > Hah, okay. How about this as an initial minor refactoring of the code > > > for new.tags? > > > [...] > > > > Great, thanks! > > > > > > Would the following commit message be satisfactory? : > > > > #+begin_quote > > setup: move tag printing and parsing into separate functions > > > > * notmuch-setup.c (notmuch_setup_command): > > Break tag printing and response parsing out into separate functions > > called `print_tag_list' respectively `parse_tag_list', for reuse > > with the 'search.exclude_tags' option. > > #+end_quote > > > > (if not, please suggest an alternative; it'll be your name at the top) > > Sure. Great! Updated patch series follows. Peace -- Pieter ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH v2 1/6] search: rename auto_exclude_tags to {search, }exclude_tags 2012-01-23 4:17 ` Pieter Praet @ 2012-01-23 4:22 ` Pieter Praet 2012-01-23 23:28 ` David Bremner 2012-01-23 4:22 ` [PATCH v2 2/6] test: only exclude "deleted" messages from search if explicitly configured Pieter Praet ` (4 subsequent siblings) 5 siblings, 1 reply; 176+ messages in thread From: Pieter Praet @ 2012-01-23 4:22 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail All other config-related functions and args include the section title in their name, so for the sake of consistency, mirror that. Also, the "auto"matic part is a given, so that was dropped. --- notmuch-client.h | 4 ++-- notmuch-config.c | 28 ++++++++++++++-------------- notmuch-count.c | 12 ++++++------ notmuch-search.c | 12 ++++++------ 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/notmuch-client.h b/notmuch-client.h index 9c1d383..f5414f6 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -252,10 +252,10 @@ notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config, notmuch_bool_t synchronize_flags); const char ** -notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t *length); +notmuch_config_get_search_exclude_tags (notmuch_config_t *config, size_t *length); void -notmuch_config_set_auto_exclude_tags (notmuch_config_t *config, +notmuch_config_set_search_exclude_tags (notmuch_config_t *config, const char *list[], size_t length); diff --git a/notmuch-config.c b/notmuch-config.c index 8dcfe86..39da888 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -89,7 +89,7 @@ static const char search_config_comment[] = "\n" " The following option is supported here:\n" "\n" - "\tauto_exclude_tags\n" + "\texclude_tags\n" "\t\tA ;-separated list of tags that will be excluded from\n" "\t\tsearch results by default. Using an excluded tag in a\n" "\t\tquery will override that exclusion.\n"; @@ -106,8 +106,8 @@ struct _notmuch_config { const char **new_tags; size_t new_tags_length; notmuch_bool_t maildir_synchronize_flags; - const char **auto_exclude_tags; - size_t auto_exclude_tags_length; + const char **search_exclude_tags; + size_t search_exclude_tags_length; }; static int @@ -265,8 +265,8 @@ notmuch_config_open (void *ctx, config->new_tags = NULL; config->new_tags_length = 0; config->maildir_synchronize_flags = TRUE; - config->auto_exclude_tags = NULL; - config->auto_exclude_tags_length = 0; + config->search_exclude_tags = NULL; + config->search_exclude_tags_length = 0; if (! g_key_file_load_from_file (config->key_file, config->filename, @@ -361,9 +361,9 @@ notmuch_config_open (void *ctx, notmuch_config_set_new_tags (config, tags, 2); } - if (notmuch_config_get_auto_exclude_tags (config, &tmp) == NULL) { + if (notmuch_config_get_search_exclude_tags (config, &tmp) == NULL) { const char *tags[] = { "deleted", "spam" }; - notmuch_config_set_auto_exclude_tags (config, tags, 2); + notmuch_config_set_search_exclude_tags (config, tags, 2); } error = NULL; @@ -624,20 +624,20 @@ notmuch_config_set_new_tags (notmuch_config_t *config, } const char ** -notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t *length) +notmuch_config_get_search_exclude_tags (notmuch_config_t *config, size_t *length) { - return _config_get_list (config, "search", "auto_exclude_tags", - &(config->auto_exclude_tags), - &(config->auto_exclude_tags_length), length); + return _config_get_list (config, "search", "exclude_tags", + &(config->search_exclude_tags), + &(config->search_exclude_tags_length), length); } void -notmuch_config_set_auto_exclude_tags (notmuch_config_t *config, +notmuch_config_set_search_exclude_tags (notmuch_config_t *config, const char *list[], size_t length) { - _config_set_list (config, "search", "auto_exclude_tags", list, length, - &(config->auto_exclude_tags)); + _config_set_list (config, "search", "exclude_tags", list, length, + &(config->search_exclude_tags)); } /* Given a configuration item of the form <group>.<key> return the diff --git a/notmuch-count.c b/notmuch-count.c index f77861e..63459fb 100644 --- a/notmuch-count.c +++ b/notmuch-count.c @@ -35,8 +35,8 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) char *query_str; int opt_index; int output = OUTPUT_MESSAGES; - const char **auto_exclude_tags; - size_t auto_exclude_tags_length; + const char **search_exclude_tags; + size_t search_exclude_tags_length; unsigned int i; notmuch_opt_desc_t options[] = { @@ -78,10 +78,10 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) return 1; } - auto_exclude_tags = notmuch_config_get_auto_exclude_tags - (config, &auto_exclude_tags_length); - for (i = 0; i < auto_exclude_tags_length; i++) - notmuch_query_add_tag_exclude (query, auto_exclude_tags[i]); + search_exclude_tags = notmuch_config_get_search_exclude_tags + (config, &search_exclude_tags_length); + for (i = 0; i < search_exclude_tags_length; i++) + notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); switch (output) { case OUTPUT_MESSAGES: diff --git a/notmuch-search.c b/notmuch-search.c index 8867aab..d504051 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -423,8 +423,8 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) output_t output = OUTPUT_SUMMARY; int offset = 0; int limit = -1; /* unlimited */ - const char **auto_exclude_tags; - size_t auto_exclude_tags_length; + const char **search_exclude_tags; + size_t search_exclude_tags_length; unsigned int i; enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT } @@ -493,10 +493,10 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) notmuch_query_set_sort (query, sort); - auto_exclude_tags = notmuch_config_get_auto_exclude_tags - (config, &auto_exclude_tags_length); - for (i = 0; i < auto_exclude_tags_length; i++) - notmuch_query_add_tag_exclude (query, auto_exclude_tags[i]); + search_exclude_tags = notmuch_config_get_search_exclude_tags + (config, &search_exclude_tags_length); + for (i = 0; i < search_exclude_tags_length; i++) + notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); switch (output) { default: -- 1.7.8.1 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH v2 1/6] search: rename auto_exclude_tags to {search, }exclude_tags 2012-01-23 4:22 ` [PATCH v2 1/6] search: rename auto_exclude_tags to {search, }exclude_tags Pieter Praet @ 2012-01-23 23:28 ` David Bremner 0 siblings, 0 replies; 176+ messages in thread From: David Bremner @ 2012-01-23 23:28 UTC (permalink / raw) To: Pieter Praet, Austin Clements; +Cc: Notmuch Mail On Mon, 23 Jan 2012 05:22:32 +0100, Pieter Praet <pieter@praet.org> wrote: > All other config-related functions and args include the section > title in their name, so for the sake of consistency, mirror that. > All six pushed, d ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH v2 2/6] test: only exclude "deleted" messages from search if explicitly configured 2012-01-23 4:17 ` Pieter Praet 2012-01-23 4:22 ` [PATCH v2 1/6] search: rename auto_exclude_tags to {search, }exclude_tags Pieter Praet @ 2012-01-23 4:22 ` Pieter Praet 2012-01-23 4:22 ` [PATCH v2 3/6] config: only exclude messages if 'search.exclude_tags' is explicitly set Pieter Praet ` (3 subsequent siblings) 5 siblings, 0 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-23 4:22 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail Currently, the 'search.exclude_tags' option is automatically set to "deleted;spam;" if it's missing from the config file. This violates the Principle of Least Surprise, so update the tests to *only* expect the exclusion of messages which are tagged "deleted" if the 'search.exclude_tags' option is explicitly set *and* contains that tag. --- test/search | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/test/search b/test/search index bf965e7..99d94bd 100755 --- a/test/search +++ b/test/search @@ -130,6 +130,7 @@ output=$(notmuch search "bödý" | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread)" test_begin_subtest "Exclude \"deleted\" messages from search" +notmuch config set search.exclude_tags = deleted generate_message '[subject]="Not deleted"' generate_message '[subject]="Deleted"' notmuch new > /dev/null @@ -147,4 +148,11 @@ output=$(notmuch search subject:deleted | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted inbox unread)" +test_begin_subtest "Don't exclude \"deleted\" messages from search if not configured" +test_subtest_known_broken +notmuch config set search.exclude_tags +output=$(notmuch search subject:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) +thread:XXX 2001-01-05 [2/2] Notmuch Test Suite; Deleted (deleted inbox unread)" + test_done -- 1.7.8.1 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH v2 3/6] config: only exclude messages if 'search.exclude_tags' is explicitly set 2012-01-23 4:17 ` Pieter Praet 2012-01-23 4:22 ` [PATCH v2 1/6] search: rename auto_exclude_tags to {search, }exclude_tags Pieter Praet 2012-01-23 4:22 ` [PATCH v2 2/6] test: only exclude "deleted" messages from search if explicitly configured Pieter Praet @ 2012-01-23 4:22 ` Pieter Praet 2012-01-23 4:22 ` [PATCH v2 4/6] setup: move tag printing and parsing into separate functions Pieter Praet ` (2 subsequent siblings) 5 siblings, 0 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-23 4:22 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail Currently, the 'search.exclude_tags' option is automatically set to "deleted;spam;" if it's missing from the config file. This violates the Principle of Least Surprise, so *only* set 'search.exclude_tags' to "deleted;spam;" if we didn't find a configuration file at all. This patch is actually Austin Clements' work: id:"20120117203211.GQ16740@mit.edu" --- notmuch-config.c | 8 ++++++-- test/search | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/notmuch-config.c b/notmuch-config.c index 39da888..0ded6d7 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -362,8 +362,12 @@ notmuch_config_open (void *ctx, } if (notmuch_config_get_search_exclude_tags (config, &tmp) == NULL) { - const char *tags[] = { "deleted", "spam" }; - notmuch_config_set_search_exclude_tags (config, tags, 2); + if (is_new) { + const char *tags[] = { "deleted", "spam" }; + notmuch_config_set_search_exclude_tags (config, tags, 2); + } else { + notmuch_config_set_search_exclude_tags (config, NULL, 0); + } } error = NULL; diff --git a/test/search b/test/search index 99d94bd..414be35 100755 --- a/test/search +++ b/test/search @@ -149,7 +149,6 @@ test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; N thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted inbox unread)" test_begin_subtest "Don't exclude \"deleted\" messages from search if not configured" -test_subtest_known_broken notmuch config set search.exclude_tags output=$(notmuch search subject:deleted | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) -- 1.7.8.1 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH v2 4/6] setup: move tag printing and parsing into separate functions 2012-01-23 4:17 ` Pieter Praet ` (2 preceding siblings ...) 2012-01-23 4:22 ` [PATCH v2 3/6] config: only exclude messages if 'search.exclude_tags' is explicitly set Pieter Praet @ 2012-01-23 4:22 ` Pieter Praet 2012-01-23 5:07 ` Austin Clements 2012-01-23 4:22 ` [PATCH v2 5/6] setup: prompt user for search.exclude_tags value Pieter Praet 2012-01-23 4:22 ` [PATCH v2 6/6] NEWS: update "Tag exclusion" section Pieter Praet 5 siblings, 1 reply; 176+ messages in thread From: Pieter Praet @ 2012-01-23 4:22 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail From: Austin Clements <amdragon@MIT.EDU> * notmuch-setup.c (notmuch_setup_command): Break tag printing and response parsing out into separate functions called `print_tag_list' respectively `parse_tag_list', for reuse with the 'search.exclude_tags' option. --- notmuch-setup.c | 55 ++++++++++++++++++++++++++++++++++--------------------- 1 files changed, 34 insertions(+), 21 deletions(-) diff --git a/notmuch-setup.c b/notmuch-setup.c index c3ea937..dcfa607 100644 --- a/notmuch-setup.c +++ b/notmuch-setup.c @@ -87,6 +87,38 @@ welcome_message_post_setup (void) "have sufficient storage space available now.\n\n"); } +static void +print_tag_list (const char **tags, size_t tags_len) +{ + unsigned int i; + for (i = 0; i < tags_len; i++) { + if (i != 0) + printf (" "); + printf ("%s", tags[i]); + } +} + +static GPtrArray * +parse_tag_list (void *ctx, char *response) +{ + GPtrArray *tags = g_ptr_array_new (); + char *tag = response; + char *space; + + while (tag && *tag) { + space = strchr (tag, ' '); + if (space) + g_ptr_array_add (tags, talloc_strndup (ctx, tag, space - tag)); + else + g_ptr_array_add (tags, talloc_strdup (ctx, tag)); + tag = space; + while (tag && *tag == ' ') + tag++; + } + + return tags; +} + int notmuch_setup_command (unused (void *ctx), unused (int argc), unused (char *argv[])) @@ -164,30 +196,11 @@ notmuch_setup_command (unused (void *ctx), new_tags = notmuch_config_get_new_tags (config, &new_tags_len); printf ("Tags to apply to all new messages (separated by spaces) ["); - - for (i = 0; i < new_tags_len; i++) { - if (i != 0) - printf (" "); - printf ("%s", new_tags[i]); - } - + print_tag_list(new_tags, new_tags_len); prompt ("]: "); if (strlen (response)) { - GPtrArray *tags = g_ptr_array_new (); - char *tag = response; - char *space; - - while (tag && *tag) { - space = strchr (tag, ' '); - if (space) - g_ptr_array_add (tags, talloc_strndup (ctx, tag, space - tag)); - else - g_ptr_array_add (tags, talloc_strdup (ctx, tag)); - tag = space; - while (tag && *tag == ' ') - tag++; - } + GPtrArray *tags = parse_tag_list (ctx, response); notmuch_config_set_new_tags (config, (const char **) tags->pdata, tags->len); -- 1.7.8.1 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH v2 4/6] setup: move tag printing and parsing into separate functions 2012-01-23 4:22 ` [PATCH v2 4/6] setup: move tag printing and parsing into separate functions Pieter Praet @ 2012-01-23 5:07 ` Austin Clements 2012-01-23 5:50 ` [PATCH v3 4/6] setup: Create functions for tag list printing and parsing Pieter Praet 0 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-23 5:07 UTC (permalink / raw) To: Pieter Praet; +Cc: Notmuch Mail Quoth Pieter Praet on Jan 23 at 5:22 am: > From: Austin Clements <amdragon@MIT.EDU> > > * notmuch-setup.c (notmuch_setup_command): > Break tag printing and response parsing out into separate functions > called `print_tag_list' respectively `parse_tag_list', for reuse > with the 'search.exclude_tags' option. Since I'm revising this patch a little bit anyway, how about setup: Create functions for tag list printing and parsing This refactors the tag list printing and parsing currently used for new.tags so that both can be reused for the new search.exclude_tags option. > > --- > notmuch-setup.c | 55 ++++++++++++++++++++++++++++++++++--------------------- > 1 files changed, 34 insertions(+), 21 deletions(-) > > diff --git a/notmuch-setup.c b/notmuch-setup.c > index c3ea937..dcfa607 100644 > --- a/notmuch-setup.c > +++ b/notmuch-setup.c > @@ -87,6 +87,38 @@ welcome_message_post_setup (void) > "have sufficient storage space available now.\n\n"); > } > > +static void > +print_tag_list (const char **tags, size_t tags_len) > +{ > + unsigned int i; > + for (i = 0; i < tags_len; i++) { > + if (i != 0) > + printf (" "); > + printf ("%s", tags[i]); > + } > +} > + > +static GPtrArray * > +parse_tag_list (void *ctx, char *response) > +{ > + GPtrArray *tags = g_ptr_array_new (); > + char *tag = response; > + char *space; > + > + while (tag && *tag) { > + space = strchr (tag, ' '); > + if (space) > + g_ptr_array_add (tags, talloc_strndup (ctx, tag, space - tag)); > + else > + g_ptr_array_add (tags, talloc_strdup (ctx, tag)); > + tag = space; > + while (tag && *tag == ' ') > + tag++; > + } > + > + return tags; > +} > + > int > notmuch_setup_command (unused (void *ctx), > unused (int argc), unused (char *argv[])) > @@ -164,30 +196,11 @@ notmuch_setup_command (unused (void *ctx), > new_tags = notmuch_config_get_new_tags (config, &new_tags_len); > > printf ("Tags to apply to all new messages (separated by spaces) ["); > - > - for (i = 0; i < new_tags_len; i++) { > - if (i != 0) > - printf (" "); > - printf ("%s", new_tags[i]); > - } > - > + print_tag_list(new_tags, new_tags_len); Missing space before paren. (Sorry, my fault.) > prompt ("]: "); > > if (strlen (response)) { > - GPtrArray *tags = g_ptr_array_new (); > - char *tag = response; > - char *space; > - > - while (tag && *tag) { > - space = strchr (tag, ' '); > - if (space) > - g_ptr_array_add (tags, talloc_strndup (ctx, tag, space - tag)); > - else > - g_ptr_array_add (tags, talloc_strdup (ctx, tag)); > - tag = space; > - while (tag && *tag == ' ') > - tag++; > - } > + GPtrArray *tags = parse_tag_list (ctx, response); > > notmuch_config_set_new_tags (config, (const char **) tags->pdata, > tags->len); ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH v3 4/6] setup: Create functions for tag list printing and parsing 2012-01-23 5:07 ` Austin Clements @ 2012-01-23 5:50 ` Pieter Praet 0 siblings, 0 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-23 5:50 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail From: Austin Clements <amdragon@MIT.EDU> This refactors the tag list printing and parsing currently used for new.tags so that both can be reused for the new search.exclude_tags option. --- notmuch-setup.c | 55 ++++++++++++++++++++++++++++++++++--------------------- 1 files changed, 34 insertions(+), 21 deletions(-) diff --git a/notmuch-setup.c b/notmuch-setup.c index c3ea937..f85e0eb 100644 --- a/notmuch-setup.c +++ b/notmuch-setup.c @@ -87,6 +87,38 @@ welcome_message_post_setup (void) "have sufficient storage space available now.\n\n"); } +static void +print_tag_list (const char **tags, size_t tags_len) +{ + unsigned int i; + for (i = 0; i < tags_len; i++) { + if (i != 0) + printf (" "); + printf ("%s", tags[i]); + } +} + +static GPtrArray * +parse_tag_list (void *ctx, char *response) +{ + GPtrArray *tags = g_ptr_array_new (); + char *tag = response; + char *space; + + while (tag && *tag) { + space = strchr (tag, ' '); + if (space) + g_ptr_array_add (tags, talloc_strndup (ctx, tag, space - tag)); + else + g_ptr_array_add (tags, talloc_strdup (ctx, tag)); + tag = space; + while (tag && *tag == ' ') + tag++; + } + + return tags; +} + int notmuch_setup_command (unused (void *ctx), unused (int argc), unused (char *argv[])) @@ -164,30 +196,11 @@ notmuch_setup_command (unused (void *ctx), new_tags = notmuch_config_get_new_tags (config, &new_tags_len); printf ("Tags to apply to all new messages (separated by spaces) ["); - - for (i = 0; i < new_tags_len; i++) { - if (i != 0) - printf (" "); - printf ("%s", new_tags[i]); - } - + print_tag_list (new_tags, new_tags_len); prompt ("]: "); if (strlen (response)) { - GPtrArray *tags = g_ptr_array_new (); - char *tag = response; - char *space; - - while (tag && *tag) { - space = strchr (tag, ' '); - if (space) - g_ptr_array_add (tags, talloc_strndup (ctx, tag, space - tag)); - else - g_ptr_array_add (tags, talloc_strdup (ctx, tag)); - tag = space; - while (tag && *tag == ' ') - tag++; - } + GPtrArray *tags = parse_tag_list (ctx, response); notmuch_config_set_new_tags (config, (const char **) tags->pdata, tags->len); -- 1.7.8.1 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH v2 5/6] setup: prompt user for search.exclude_tags value 2012-01-23 4:17 ` Pieter Praet ` (3 preceding siblings ...) 2012-01-23 4:22 ` [PATCH v2 4/6] setup: move tag printing and parsing into separate functions Pieter Praet @ 2012-01-23 4:22 ` Pieter Praet 2012-01-23 4:34 ` Austin Clements 2012-01-23 4:22 ` [PATCH v2 6/6] NEWS: update "Tag exclusion" section Pieter Praet 5 siblings, 1 reply; 176+ messages in thread From: Pieter Praet @ 2012-01-23 4:22 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail Allow users to customize the search.exclude_tags option during setup. --- notmuch-setup.c | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+), 0 deletions(-) diff --git a/notmuch-setup.c b/notmuch-setup.c index dcfa607..0d75adc 100644 --- a/notmuch-setup.c +++ b/notmuch-setup.c @@ -133,6 +133,8 @@ notmuch_setup_command (unused (void *ctx), int is_new; const char **new_tags; size_t new_tags_len; + const char **search_exclude_tags; + size_t search_exclude_tags_len; #define prompt(format, ...) \ do { \ @@ -208,6 +210,25 @@ notmuch_setup_command (unused (void *ctx), g_ptr_array_free (tags, TRUE); } + + search_exclude_tags = notmuch_config_get_search_exclude_tags (config, &search_exclude_tags_len); + + printf ("Tags to exclude when searching messages (separated by spaces) ["); + print_tag_list(search_exclude_tags, search_exclude_tags_len); + prompt ("]: "); + + if (strlen (response)) { + GPtrArray *tags = parse_tag_list (ctx, response); + + notmuch_config_set_search_exclude_tags (config, + (const char **) + tags->pdata, + tags->len); + + g_ptr_array_free (tags, TRUE); + } + + if (! notmuch_config_save (config)) { if (is_new) welcome_message_post_setup (); -- 1.7.8.1 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH v2 5/6] setup: prompt user for search.exclude_tags value 2012-01-23 4:22 ` [PATCH v2 5/6] setup: prompt user for search.exclude_tags value Pieter Praet @ 2012-01-23 4:34 ` Austin Clements 2012-01-23 5:40 ` [PATCH v3 " Pieter Praet 0 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-23 4:34 UTC (permalink / raw) To: Pieter Praet; +Cc: Notmuch Mail Quoth Pieter Praet on Jan 23 at 5:22 am: > Allow users to customize the search.exclude_tags option during setup. > --- > notmuch-setup.c | 21 +++++++++++++++++++++ > 1 files changed, 21 insertions(+), 0 deletions(-) > > diff --git a/notmuch-setup.c b/notmuch-setup.c > index dcfa607..0d75adc 100644 > --- a/notmuch-setup.c > +++ b/notmuch-setup.c > @@ -133,6 +133,8 @@ notmuch_setup_command (unused (void *ctx), > int is_new; > const char **new_tags; > size_t new_tags_len; > + const char **search_exclude_tags; > + size_t search_exclude_tags_len; > > #define prompt(format, ...) \ > do { \ > @@ -208,6 +210,25 @@ notmuch_setup_command (unused (void *ctx), > g_ptr_array_free (tags, TRUE); > } > > + > + search_exclude_tags = notmuch_config_get_search_exclude_tags (config, &search_exclude_tags_len); > + > + printf ("Tags to exclude when searching messages (separated by spaces) ["); > + print_tag_list(search_exclude_tags, search_exclude_tags_len); Missing space before paren. > + prompt ("]: "); > + > + if (strlen (response)) { > + GPtrArray *tags = parse_tag_list (ctx, response); > + > + notmuch_config_set_search_exclude_tags (config, > + (const char **) > + tags->pdata, No newline is needed between the case and the value. > + tags->len); > + > + g_ptr_array_free (tags, TRUE); > + } > + > + > if (! notmuch_config_save (config)) { > if (is_new) > welcome_message_post_setup (); ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH v3 5/6] setup: prompt user for search.exclude_tags value 2012-01-23 4:34 ` Austin Clements @ 2012-01-23 5:40 ` Pieter Praet 0 siblings, 0 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-23 5:40 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail Allow users to customize the search.exclude_tags option during setup. --- v2: - less copy-paste coding... :) v3: Austin's corrections [1] - @ `print_tag_list': add space before paren. - @ `notmuch_config_set_search_exclude_tags': remove \n between type cast and value. [1] id:"20120123043435.GR16740@mit.edu" notmuch-setup.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-) diff --git a/notmuch-setup.c b/notmuch-setup.c index dcfa607..2941c52 100644 --- a/notmuch-setup.c +++ b/notmuch-setup.c @@ -133,6 +133,8 @@ notmuch_setup_command (unused (void *ctx), int is_new; const char **new_tags; size_t new_tags_len; + const char **search_exclude_tags; + size_t search_exclude_tags_len; #define prompt(format, ...) \ do { \ @@ -208,6 +210,24 @@ notmuch_setup_command (unused (void *ctx), g_ptr_array_free (tags, TRUE); } + + search_exclude_tags = notmuch_config_get_search_exclude_tags (config, &search_exclude_tags_len); + + printf ("Tags to exclude when searching messages (separated by spaces) ["); + print_tag_list (search_exclude_tags, search_exclude_tags_len); + prompt ("]: "); + + if (strlen (response)) { + GPtrArray *tags = parse_tag_list (ctx, response); + + notmuch_config_set_search_exclude_tags (config, + (const char **) tags->pdata, + tags->len); + + g_ptr_array_free (tags, TRUE); + } + + if (! notmuch_config_save (config)) { if (is_new) welcome_message_post_setup (); -- 1.7.8.1 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH v2 6/6] NEWS: update "Tag exclusion" section 2012-01-23 4:17 ` Pieter Praet ` (4 preceding siblings ...) 2012-01-23 4:22 ` [PATCH v2 5/6] setup: prompt user for search.exclude_tags value Pieter Praet @ 2012-01-23 4:22 ` Pieter Praet 2012-01-23 4:41 ` Austin Clements 5 siblings, 1 reply; 176+ messages in thread From: Pieter Praet @ 2012-01-23 4:22 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail --- NEWS | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 2c2d9e9..a0b7929 100644 --- a/NEWS +++ b/NEWS @@ -13,10 +13,16 @@ Reply to sender Tag exclusion - Tags can be automatically excluded from search results unless they - appear explicitly in a query. By default, notmuch excludes the tags - deleted and spam. This can be changed using the new config setting - search.auto_exclude_tags. + Tags can be automatically excluded from search results by adding them + to the new 'search.exclude_tags' option in the Notmuch config file. + + This behaviour can be overridden by explicitly including an excluded + tag in your query, for example: + + notmuch search $your_query and tag:$excluded_tag + + Existing users will probably want to run "notmuch setup" again to add + the new well-commented [search] section to the configuration file. Emacs Interface --------------- -- 1.7.8.1 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH v2 6/6] NEWS: update "Tag exclusion" section 2012-01-23 4:22 ` [PATCH v2 6/6] NEWS: update "Tag exclusion" section Pieter Praet @ 2012-01-23 4:41 ` Austin Clements 2012-01-23 5:41 ` [PATCH v3 " Pieter Praet 0 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-23 4:41 UTC (permalink / raw) To: Pieter Praet; +Cc: Notmuch Mail Quoth Pieter Praet on Jan 23 at 5:22 am: > --- > NEWS | 14 ++++++++++---- > 1 files changed, 10 insertions(+), 4 deletions(-) > > diff --git a/NEWS b/NEWS > index 2c2d9e9..a0b7929 100644 > --- a/NEWS > +++ b/NEWS > @@ -13,10 +13,16 @@ Reply to sender > > Tag exclusion > > - Tags can be automatically excluded from search results unless they > - appear explicitly in a query. By default, notmuch excludes the tags > - deleted and spam. This can be changed using the new config setting > - search.auto_exclude_tags. > + Tags can be automatically excluded from search results by adding them > + to the new 'search.exclude_tags' option in the Notmuch config file. > + > + This behaviour can be overridden by explicitly including an excluded > + tag in your query, for example: > + > + notmuch search $your_query and tag:$excluded_tag > + > + Existing users will probably want to run "notmuch setup" again to add > + the new well-commented [search] section to the configuration file. Should probably add something about the default for new configurations. This also gives existing users an idea of what to set this to if they want to follow the conventions used by new configurations. Maybe just add In new configurations, this defaults to "deleted" and "spam". > > Emacs Interface > --------------- ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH v3 6/6] NEWS: update "Tag exclusion" section 2012-01-23 4:41 ` Austin Clements @ 2012-01-23 5:41 ` Pieter Praet 2012-01-23 14:49 ` Austin Clements 0 siblings, 1 reply; 176+ messages in thread From: Pieter Praet @ 2012-01-23 5:41 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail --- Added note re new configurations, as suggested by Austin: id:"20120123044108.GS16740@mit.edu" NEWS | 19 +++++++++++++++---- 1 files changed, 15 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 2c2d9e9..2acdce5 100644 --- a/NEWS +++ b/NEWS @@ -13,10 +13,21 @@ Reply to sender Tag exclusion - Tags can be automatically excluded from search results unless they - appear explicitly in a query. By default, notmuch excludes the tags - deleted and spam. This can be changed using the new config setting - search.auto_exclude_tags. + Tags can be automatically excluded from search results by adding them + to the new 'search.exclude_tags' option in the Notmuch config file. + + This behaviour can be overridden by explicitly including an excluded + tag in your query, for example: + + notmuch search $your_query and tag:$excluded_tag + + Existing users will probably want to run "notmuch setup" again to add + the new well-commented [search] section to the configuration file. + + For new configurations, accepting the default setting will cause the + tags "deleted" and "spam" to be excluded, equivalent to running: + + notmuch config set search.exclude_tags deleted spam Emacs Interface --------------- -- 1.7.8.1 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH v3 6/6] NEWS: update "Tag exclusion" section 2012-01-23 5:41 ` [PATCH v3 " Pieter Praet @ 2012-01-23 14:49 ` Austin Clements 0 siblings, 0 replies; 176+ messages in thread From: Austin Clements @ 2012-01-23 14:49 UTC (permalink / raw) To: Pieter Praet; +Cc: Notmuch Mail Series LGTM. Quoth Pieter Praet on Jan 23 at 6:41 am: > --- > > Added note re new configurations, as suggested by Austin: > id:"20120123044108.GS16740@mit.edu" > > NEWS | 19 +++++++++++++++---- > 1 files changed, 15 insertions(+), 4 deletions(-) > > diff --git a/NEWS b/NEWS > index 2c2d9e9..2acdce5 100644 > --- a/NEWS > +++ b/NEWS > @@ -13,10 +13,21 @@ Reply to sender > > Tag exclusion > > - Tags can be automatically excluded from search results unless they > - appear explicitly in a query. By default, notmuch excludes the tags > - deleted and spam. This can be changed using the new config setting > - search.auto_exclude_tags. > + Tags can be automatically excluded from search results by adding them > + to the new 'search.exclude_tags' option in the Notmuch config file. > + > + This behaviour can be overridden by explicitly including an excluded > + tag in your query, for example: > + > + notmuch search $your_query and tag:$excluded_tag > + > + Existing users will probably want to run "notmuch setup" again to add > + the new well-commented [search] section to the configuration file. > + > + For new configurations, accepting the default setting will cause the > + tags "deleted" and "spam" to be excluded, equivalent to running: > + > + notmuch config set search.exclude_tags deleted spam > > Emacs Interface > --------------- ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v3 2/2] search: Support automatic tag exclusions 2012-01-19 19:19 ` Pieter Praet ` (3 preceding siblings ...) 2012-01-19 19:19 ` [PATCH 4/4] setup: prompt user for search.exclude_tags value Pieter Praet @ 2012-01-19 19:36 ` Austin Clements 2012-01-19 20:06 ` markwalters1009 2012-01-19 21:21 ` Pieter Praet 2012-01-22 22:09 ` Xavier Maillard 5 siblings, 2 replies; 176+ messages in thread From: Austin Clements @ 2012-01-19 19:36 UTC (permalink / raw) To: Pieter Praet; +Cc: Notmuch Mail Quoth Pieter Praet on Jan 19 at 8:19 pm: > Nice feature! I won't be using it myself, but I can imagine it being > *very* useful for those who still feel the need to "delete" email :). Same here. I probably will use the spam tag, though. > Nitpicking: > > - All other config-related functions and args include the section title > in their name [1], so for the sake of consistency, we might want to > mirror that. Also, the "auto"matic part is pretty much a given. > > So I'd like to suggest replacing all occurences of "auto_exclude_tags" > with "search_exclude_tags" (and simply "exclude_tags" in the args to > `_config_get_list' and `_config_set_list', of course). You are technically correct, the best kind of correct. I'd completely missed this pattern. This should get fixed ASAP, while this feature still has limited adoption. > Unfortunately, this would also partially invalidate your recent NEWS > submission [2]. No worries, though maybe you want to tack an updated version of that patch on the end of your series? > - If the 'search.exclude_tags' option is missing from the config file, > its value is automatically set to "deleted;spam;", which probably isn't > a sane default. Luckily, you've already provided the solution [3]. I'm good either way. I got lost in the discussion of defaults but Jamie assured me everything was okay, so I took the path of least resistance and left things as they were. > - To make new users aware of the config option's existence, we should > prompt them to configure it during setup. Sure. > Patches follow. > > > Peace > > > [1] Eg. `notmuch_config_get_user_name', `notmuch_config_get_new_tags', > `notmuch_config_get_maildir_synchronize_flags', ... > > [2] id:"1326920330-31496-1-git-send-email-amdragon@mit.edu" > > [3] id:"20120117203211.GQ16740@mit.edu" > ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v3 2/2] search: Support automatic tag exclusions 2012-01-19 19:36 ` [PATCH v3 2/2] search: Support automatic tag exclusions Austin Clements @ 2012-01-19 20:06 ` markwalters1009 2012-01-19 20:16 ` Aaron Ecay 2012-01-19 21:21 ` Pieter Praet 1 sibling, 1 reply; 176+ messages in thread From: markwalters1009 @ 2012-01-19 20:06 UTC (permalink / raw) To: Austin Clements, Pieter Praet; +Cc: Notmuch Mail > > So I'd like to suggest replacing all occurences of "auto_exclude_tags" > > with "search_exclude_tags" (and simply "exclude_tags" in the args to > > `_config_get_list' and `_config_set_list', of course). > > You are technically correct, the best kind of correct. I'd completely > missed this pattern. This should get fixed ASAP, while this feature > still has limited adoption. I would actually like make a different suggestion: extend auto_exclude_tags to notmuch-show as well. I was quite surprised to see my deleted (ie hidden rather than actually deleted) messages return when viewing a thread. Best wishes Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v3 2/2] search: Support automatic tag exclusions 2012-01-19 20:06 ` markwalters1009 @ 2012-01-19 20:16 ` Aaron Ecay 2012-01-19 20:23 ` Mark Walters 0 siblings, 1 reply; 176+ messages in thread From: Aaron Ecay @ 2012-01-19 20:16 UTC (permalink / raw) To: markwalters1009, Austin Clements, Pieter Praet; +Cc: Notmuch Mail On Thu, 19 Jan 2012 20:06:27 +0000, markwalters1009@gmail.com wrote: > I would actually like make a different suggestion: extend > auto_exclude_tags to notmuch-show as well. I was quite surprised to see > my deleted (ie hidden rather than actually deleted) messages return when > viewing a thread. It might be best to show the messages in the thread – after all, you might want to “undelete” (or “unspam”) those messages in light of later replies to them. (And if you are sure you really want them gone, you should be deleting them or moving them out of your maildir periodically, rather than relying on notmuch to not show them to you ever.) (Perhaps another application of this functionality would be to “mute” certain threads on a mailing list. Then you could use a query for “word-i-am-interested-in AND tag:muted” to find out if something interesting pops up in a muted thread. Then in the show view, you will want to unmute the other thread messages.) Perhaps this could be an application of dme’s header-line collapsing functionality in id:"cun8vl5m610.fsf@hotblack-desiato.hh.sledj.net" (suitably cleaned up), such that you see only a single line in the show buffer that says: ----- 6 messages hidden ----- instead of the 6 (or however many) individual messages. -- Aaron Ecay ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v3 2/2] search: Support automatic tag exclusions 2012-01-19 20:16 ` Aaron Ecay @ 2012-01-19 20:23 ` Mark Walters 2012-01-19 20:28 ` Austin Clements 0 siblings, 1 reply; 176+ messages in thread From: Mark Walters @ 2012-01-19 20:23 UTC (permalink / raw) To: Aaron Ecay, Austin Clements, Pieter Praet; +Cc: Notmuch Mail > On Thu, 19 Jan 2012 20:06:27 +0000, markwalters1009@gmail.com wrote: > > I would actually like make a different suggestion: extend > > auto_exclude_tags to notmuch-show as well. I was quite surprised to see > > my deleted (ie hidden rather than actually deleted) messages return when > > viewing a thread. > > It might be best to show the messages in the thread – after all, you > might want to “undelete” (or “unspam”) those messages in light of later > replies to them. (And if you are sure you really want them gone, you > should be deleting them or moving them out of your maildir periodically, > rather than relying on notmuch to not show them to you ever.) I am happy with them appearing as a non matching message, but currently they appear as a full open message. (The patch to achieve this is trivial: essentially transpose part of Austin's patch of notmuch-search.c into notmuch-show.c) Best wishes Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v3 2/2] search: Support automatic tag exclusions 2012-01-19 20:23 ` Mark Walters @ 2012-01-19 20:28 ` Austin Clements 2012-01-19 22:01 ` Mark Walters 0 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-19 20:28 UTC (permalink / raw) To: Mark Walters; +Cc: Notmuch Mail, Pieter Praet, Aaron Ecay Quoth Mark Walters on Jan 19 at 8:23 pm: > > > On Thu, 19 Jan 2012 20:06:27 +0000, markwalters1009@gmail.com wrote: > > > I would actually like make a different suggestion: extend > > > auto_exclude_tags to notmuch-show as well. I was quite surprised to see > > > my deleted (ie hidden rather than actually deleted) messages return when > > > viewing a thread. > > > > It might be best to show the messages in the thread – after all, you > > might want to “undelete” (or “unspam”) those messages in light of later > > replies to them. (And if you are sure you really want them gone, you > > should be deleting them or moving them out of your maildir periodically, > > rather than relying on notmuch to not show them to you ever.) > > I am happy with them appearing as a non matching message, but currently > they appear as a full open message. (The patch to achieve this is > trivial: essentially transpose part of Austin's patch of > notmuch-search.c into notmuch-show.c) This definitely sounds like the right thing to do. We can argue about more sophisticated UIs, but it should do this at a minimum. ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v3 2/2] search: Support automatic tag exclusions 2012-01-19 20:28 ` Austin Clements @ 2012-01-19 22:01 ` Mark Walters 2012-01-19 22:03 ` [PATCH] Automatically exclude tags in notmuch-show Mark Walters 2012-01-19 22:44 ` [PATCH v3 2/2] search: Support automatic tag exclusions Pieter Praet 0 siblings, 2 replies; 176+ messages in thread From: Mark Walters @ 2012-01-19 22:01 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail, Pieter Praet, Aaron Ecay > > I am happy with them appearing as a non matching message, but currently > > they appear as a full open message. (The patch to achieve this is > > trivial: essentially transpose part of Austin's patch of > > notmuch-search.c into notmuch-show.c) > > This definitely sounds like the right thing to do. We can argue about > more sophisticated UIs, but it should do this at a minimum. I will post the trivial patch in a moment (trivial but I could easily have done something stupid). I haven't written a test yet: should it have one, and if so, could someone point me to the appropriate place to put it? Best wishes Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH] Automatically exclude tags in notmuch-show 2012-01-19 22:01 ` Mark Walters @ 2012-01-19 22:03 ` Mark Walters 2012-01-19 22:59 ` Austin Clements 2012-01-19 22:44 ` [PATCH v3 2/2] search: Support automatic tag exclusions Pieter Praet 1 sibling, 1 reply; 176+ messages in thread From: Mark Walters @ 2012-01-19 22:03 UTC (permalink / raw) To: notmuch Add the use of auto_exclude_tags in notmuch-show.c. As with Austin's patch (commit 42a907992823030f070fc395a174f779998ca6f5) it just adds the excluded tags to the query so the excluded messages will still appear in the emacs interface, but as a single header line rather than as a matching message. --- notmuch-show.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/notmuch-show.c b/notmuch-show.c index d14dac9..925dfd6 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -948,9 +948,12 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) char *opt; const notmuch_show_format_t *format = &format_text; notmuch_show_params_t params; + const char **auto_exclude_tags; + size_t auto_exclude_tags_length; int mbox = 0; int format_specified = 0; int i; + unsigned int j; params.entire_thread = 0; params.raw = 0; @@ -1040,6 +1043,11 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) return 1; } + auto_exclude_tags = notmuch_config_get_auto_exclude_tags + (config, &auto_exclude_tags_length); + for (j = 0; j < auto_exclude_tags_length; j++) + notmuch_query_add_tag_exclude (query, auto_exclude_tags[j]); + /* if part was requested and format was not specified, use format=raw */ if (params.part >= 0 && !format_specified) format = &format_raw; -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH] Automatically exclude tags in notmuch-show 2012-01-19 22:03 ` [PATCH] Automatically exclude tags in notmuch-show Mark Walters @ 2012-01-19 22:59 ` Austin Clements 2012-01-19 23:54 ` Pieter Praet 2012-01-20 0:10 ` Mark Walters 0 siblings, 2 replies; 176+ messages in thread From: Austin Clements @ 2012-01-19 22:59 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch LGTM, but should definitely come with a test. Also, this won't commute with Pieter's patch (id:"1327000744-25463-2-git-send-email-pieter@praet.org"), so one or the other will have to get updated. Quoth Mark Walters on Jan 19 at 10:03 pm: > Add the use of auto_exclude_tags in notmuch-show.c. As with Austin's > patch (commit 42a907992823030f070fc395a174f779998ca6f5) it just adds > the excluded tags to the query so the excluded messages will still > appear in the emacs interface, but as a single header line rather than > as a matching message. > --- > notmuch-show.c | 8 ++++++++ > 1 files changed, 8 insertions(+), 0 deletions(-) > > diff --git a/notmuch-show.c b/notmuch-show.c > index d14dac9..925dfd6 100644 > --- a/notmuch-show.c > +++ b/notmuch-show.c > @@ -948,9 +948,12 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) > char *opt; > const notmuch_show_format_t *format = &format_text; > notmuch_show_params_t params; > + const char **auto_exclude_tags; > + size_t auto_exclude_tags_length; > int mbox = 0; > int format_specified = 0; > int i; > + unsigned int j; Hah. The original patch series updated 'count' to use the new argument parsing solely so I could steal 'i' for the tag exclude code. > > params.entire_thread = 0; > params.raw = 0; > @@ -1040,6 +1043,11 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) > return 1; > } > > + auto_exclude_tags = notmuch_config_get_auto_exclude_tags > + (config, &auto_exclude_tags_length); > + for (j = 0; j < auto_exclude_tags_length; j++) > + notmuch_query_add_tag_exclude (query, auto_exclude_tags[j]); > + > /* if part was requested and format was not specified, use format=raw */ > if (params.part >= 0 && !format_specified) > format = &format_raw; ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH] Automatically exclude tags in notmuch-show 2012-01-19 22:59 ` Austin Clements @ 2012-01-19 23:54 ` Pieter Praet 2012-01-20 0:10 ` Mark Walters 1 sibling, 0 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-19 23:54 UTC (permalink / raw) To: Austin Clements, Mark Walters; +Cc: notmuch On Thu, 19 Jan 2012 17:59:10 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > LGTM, but should definitely come with a test. > [...] > Also, this won't commute with Pieter's patch > (id:"1327000744-25463-2-git-send-email-pieter@praet.org"), so one or > the other will have to get updated. > No problem, I'll have to resubmit my entire series anyway, so go right ahead. > Quoth Mark Walters on Jan 19 at 10:03 pm: > > Add the use of auto_exclude_tags in notmuch-show.c. As with Austin's > > patch (commit 42a907992823030f070fc395a174f779998ca6f5) it just adds > > the excluded tags to the query so the excluded messages will still > > appear in the emacs interface, but as a single header line rather than > > as a matching message. > > --- > > notmuch-show.c | 8 ++++++++ > > 1 files changed, 8 insertions(+), 0 deletions(-) > > > > diff --git a/notmuch-show.c b/notmuch-show.c > > index d14dac9..925dfd6 100644 > > --- a/notmuch-show.c > > +++ b/notmuch-show.c > > @@ -948,9 +948,12 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) > > char *opt; > > const notmuch_show_format_t *format = &format_text; > > notmuch_show_params_t params; > > + const char **auto_exclude_tags; > > + size_t auto_exclude_tags_length; > > int mbox = 0; > > int format_specified = 0; > > int i; > > + unsigned int j; > > Hah. The original patch series updated 'count' to use the new > argument parsing solely so I could steal 'i' for the tag exclude code. > > > > > params.entire_thread = 0; > > params.raw = 0; > > @@ -1040,6 +1043,11 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) > > return 1; > > } > > > > + auto_exclude_tags = notmuch_config_get_auto_exclude_tags > > + (config, &auto_exclude_tags_length); > > + for (j = 0; j < auto_exclude_tags_length; j++) > > + notmuch_query_add_tag_exclude (query, auto_exclude_tags[j]); > > + > > /* if part was requested and format was not specified, use format=raw */ > > if (params.part >= 0 && !format_specified) > > format = &format_raw; > _______________________________________________ > notmuch mailing list > notmuch@notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch Peace -- Pieter ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH] Automatically exclude tags in notmuch-show 2012-01-19 22:59 ` Austin Clements 2012-01-19 23:54 ` Pieter Praet @ 2012-01-20 0:10 ` Mark Walters 2012-01-20 17:18 ` Austin Clements 1 sibling, 1 reply; 176+ messages in thread From: Mark Walters @ 2012-01-20 0:10 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch Ok Having said this is trivial I have found a problem. What should notmuch do if you do something like notmuch show id:<some-id> and that message is marked with a deleted tag? To be consistent with the other cases (where a deleted message is in a matched thread) we might want to return the message with the not-matched flag set (eg in JSON). But my patch doesn't, as it never even sees the thread since it doesn't match. Looking at notmuch-show.c I think we should not apply the exclude tags to do_show_single, but usually should apply it to do_show. One solution which is simple and is at least close to right would be to get do_show to return the number of threads found. If this is zero then retry the query without the excludes (possible setting the match_flag to zero on each message since we know it does not match) This is not a completely correct solution as if you ask notmuch-show to show more than one thread it might threads which only contain deleted messages. I can't see other good possibilities without slowing down the normal path a lot (eg find all threads that match the original query and then apply the argument above). Any thoughts? Incidentally, is there something strange at the end of notmuch-show.c: I can't see how we could ever reach the last half dozen lines. Best wishes Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH] Automatically exclude tags in notmuch-show 2012-01-20 0:10 ` Mark Walters @ 2012-01-20 17:18 ` Austin Clements 2012-01-22 0:38 ` Mark Walters 2012-01-22 18:16 ` Austin Clements 0 siblings, 2 replies; 176+ messages in thread From: Austin Clements @ 2012-01-20 17:18 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch Quoth Mark Walters on Jan 20 at 12:10 am: > > Ok Having said this is trivial I have found a problem. What should > notmuch do if you do something like > > notmuch show id:<some-id> > and that message is marked with a deleted tag? To be consistent with the > other cases (where a deleted message is in a matched thread) we might > want to return the message with the not-matched flag set (eg in > JSON). But my patch doesn't, as it never even sees the thread since it > doesn't match. > > Looking at notmuch-show.c I think we should not apply the exclude tags > to do_show_single, but usually should apply it to do_show. One solution > which is simple and is at least close to right would be to get do_show > to return the number of threads found. If this is zero then retry the > query without the excludes (possible setting the match_flag to zero on > each message since we know it does not match) > > This is not a completely correct solution as if you ask notmuch-show to > show more than one thread it might threads which only contain deleted > messages. > > I can't see other good possibilities without slowing down the normal > path a lot (eg find all threads that match the original query and then > apply the argument above). > > Any thoughts? Oh dear. Well, here's one idea. Instead of doing a single thread query in show, do a thread query without the exclusions and then a message query with the exclusions. Output all of the messages from the first query, but use the results of the second query to determine which messages are "matched". The same could be accomplished in the library somewhat more efficiently, but it's not obvious to me what the API would be. > Incidentally, is there something strange at the end of notmuch-show.c: I > can't see how we could ever reach the last half dozen lines. Yes, I've wondered about that before, too. I think none of those technically matter since they're all cleaning up resources that the OS is about to clean up for us. It would be a problem if the database was open in write mode because Xapian's write lock hangs around for a split second after the process terminates if you don't close the database yourself, but in read mode it doesn't take any locks. Not that this excuses the code. ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH] Automatically exclude tags in notmuch-show 2012-01-20 17:18 ` Austin Clements @ 2012-01-22 0:38 ` Mark Walters 2012-01-22 17:31 ` Austin Clements 2012-01-22 18:16 ` Austin Clements 1 sibling, 1 reply; 176+ messages in thread From: Mark Walters @ 2012-01-22 0:38 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch On Fri, 20 Jan 2012 12:18:01 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > Oh dear. > > Well, here's one idea. Instead of doing a single thread query in > show, do a thread query without the exclusions and then a message > query with the exclusions. Output all of the messages from the first > query, but use the results of the second query to determine which > messages are "matched". The same could be accomplished in the library > somewhat more efficiently, but it's not obvious to me what the API > would be. I have been thinking about this and one question is what should the sort order be? If I understand it correctly notmuch sorts the threads by the oldest/newest matching message, so the "correct" behaviour if no message matches is unclear. Perhaps all threads with a matching non-excluded message sorted by the matching-non-excluded message followed by all threads that match only on excluded messages with sort based on the matching excluded message? Best wishes Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH] Automatically exclude tags in notmuch-show 2012-01-22 0:38 ` Mark Walters @ 2012-01-22 17:31 ` Austin Clements 0 siblings, 0 replies; 176+ messages in thread From: Austin Clements @ 2012-01-22 17:31 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch Quoth Mark Walters on Jan 22 at 12:38 am: > > On Fri, 20 Jan 2012 12:18:01 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > > > Oh dear. > > > > Well, here's one idea. Instead of doing a single thread query in > > show, do a thread query without the exclusions and then a message > > query with the exclusions. Output all of the messages from the first > > query, but use the results of the second query to determine which > > messages are "matched". The same could be accomplished in the library > > somewhat more efficiently, but it's not obvious to me what the API > > would be. > > I have been thinking about this and one question is what should the sort > order be? If I understand it correctly notmuch sorts the threads > by the oldest/newest matching message, so the "correct" behaviour if no > message matches is unclear. Perhaps all threads with a matching > non-excluded message sorted by the matching-non-excluded message > followed by all threads that match only on excluded messages with sort > based on the matching excluded message? I don't think show sorts in any particular way. Or are you saying that search also needs to know the difference between excluded and non-excluded matched messages? ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH] Automatically exclude tags in notmuch-show 2012-01-20 17:18 ` Austin Clements 2012-01-22 0:38 ` Mark Walters @ 2012-01-22 18:16 ` Austin Clements 2012-01-22 18:47 ` Mark Walters 2012-01-23 1:13 ` Mark Walters 1 sibling, 2 replies; 176+ messages in thread From: Austin Clements @ 2012-01-22 18:16 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch Quoth myself on Jan 20 at 12:18 pm: > Quoth Mark Walters on Jan 20 at 12:10 am: > > > > Ok Having said this is trivial I have found a problem. What should > > notmuch do if you do something like > > > > notmuch show id:<some-id> > > and that message is marked with a deleted tag? To be consistent with the > > other cases (where a deleted message is in a matched thread) we might > > want to return the message with the not-matched flag set (eg in > > JSON). But my patch doesn't, as it never even sees the thread since it > > doesn't match. > > > > Looking at notmuch-show.c I think we should not apply the exclude tags > > to do_show_single, but usually should apply it to do_show. One solution > > which is simple and is at least close to right would be to get do_show > > to return the number of threads found. If this is zero then retry the > > query without the excludes (possible setting the match_flag to zero on > > each message since we know it does not match) > > > > This is not a completely correct solution as if you ask notmuch-show to > > show more than one thread it might threads which only contain deleted > > messages. > > > > I can't see other good possibilities without slowing down the normal > > path a lot (eg find all threads that match the original query and then > > apply the argument above). > > > > Any thoughts? > > Oh dear. > > Well, here's one idea. Instead of doing a single thread query in > show, do a thread query without the exclusions and then a message > query with the exclusions. Output all of the messages from the first > query, but use the results of the second query to determine which > messages are "matched". The same could be accomplished in the library > somewhat more efficiently, but it's not obvious to me what the API > would be. Here's a slightly crazier idea that's more library-invasive than the original approach, but probably better in the long run. Have notmuch_query_search_* return everything and make exclusion a message flag like NOTMUCH_MESSAGE_FLAG_MATCH. Tweak the definition of "matched" to mean "matched and not excluded" (specifically, a message would have the match flag or the excluded flag or neither, but not both). Search would skip threads with zero matched messages and I think show would Just Work. I can think of two ways to implement this. notmuch_query_search_* could perform both the original query and the query with exclusions and use the docid set from the second to compute the "excluded" message flag. Alternatively, it could examine the tags of each message directly to compute the flag. The latter is probably easier to implement, but probably slower. Thoughts? ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH] Automatically exclude tags in notmuch-show 2012-01-22 18:16 ` Austin Clements @ 2012-01-22 18:47 ` Mark Walters 2012-01-23 1:13 ` Mark Walters 1 sibling, 0 replies; 176+ messages in thread From: Mark Walters @ 2012-01-22 18:47 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch On Sun, 22 Jan 2012 13:16:09 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > Quoth myself on Jan 20 at 12:18 pm: > > Quoth Mark Walters on Jan 20 at 12:10 am: > > > > > > Ok Having said this is trivial I have found a problem. What should > > > notmuch do if you do something like > > > > > > notmuch show id:<some-id> > > > and that message is marked with a deleted tag? To be consistent with the > > > other cases (where a deleted message is in a matched thread) we might > > > want to return the message with the not-matched flag set (eg in > > > JSON). But my patch doesn't, as it never even sees the thread since it > > > doesn't match. > > > > > > Looking at notmuch-show.c I think we should not apply the exclude tags > > > to do_show_single, but usually should apply it to do_show. One solution > > > which is simple and is at least close to right would be to get do_show > > > to return the number of threads found. If this is zero then retry the > > > query without the excludes (possible setting the match_flag to zero on > > > each message since we know it does not match) > > > > > > This is not a completely correct solution as if you ask notmuch-show to > > > show more than one thread it might threads which only contain deleted > > > messages. > > > > > > I can't see other good possibilities without slowing down the normal > > > path a lot (eg find all threads that match the original query and then > > > apply the argument above). > > > > > > Any thoughts? > > > > Oh dear. > > > > Well, here's one idea. Instead of doing a single thread query in > > show, do a thread query without the exclusions and then a message > > query with the exclusions. Output all of the messages from the first > > query, but use the results of the second query to determine which > > messages are "matched". The same could be accomplished in the library > > somewhat more efficiently, but it's not obvious to me what the API > > would be. > > Here's a slightly crazier idea that's more library-invasive than the > original approach, but probably better in the long run. > > Have notmuch_query_search_* return everything and make exclusion a > message flag like NOTMUCH_MESSAGE_FLAG_MATCH. Tweak the definition of > "matched" to mean "matched and not excluded" (specifically, a message > would have the match flag or the excluded flag or neither, but not > both). Search would skip threads with zero matched messages and I > think show would Just Work. > > I can think of two ways to implement this. notmuch_query_search_* > could perform both the original query and the query with exclusions > and use the docid set from the second to compute the "excluded" > message flag. Alternatively, it could examine the tags of each > message directly to compute the flag. The latter is probably easier > to implement, but probably slower. I really like the idea of returning two flags. I think your first suggestion works better for sorting reasons: we want to return a thread which has a match-not-excluded message and also a match-excluded message to be sorted based on the match-not-excluded message. Hence in notmuch_query_search_threads we can create the list of docids to iterate over as the list generated by query with exclusions followed by the list without exclusions. This list contains lots of messages twice but that doesn't matter since we have to check whether we have already output the message in an earlier thread anyway. Incidentally, it might not take very much more code to allow notmuch_query_search_threads to take two arbitrary queries and return all threads which match the first case but mark as matched those that match the second: i.e. a step on the way towards "thread based and". Best wishes Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH] Automatically exclude tags in notmuch-show 2012-01-22 18:16 ` Austin Clements 2012-01-22 18:47 ` Mark Walters @ 2012-01-23 1:13 ` Mark Walters 2012-01-23 1:52 ` Austin Clements 1 sibling, 1 reply; 176+ messages in thread From: Mark Walters @ 2012-01-23 1:13 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch On Sun, 22 Jan 2012 13:16:09 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > Quoth myself on Jan 20 at 12:18 pm: > > Quoth Mark Walters on Jan 20 at 12:10 am: > > > > > > Ok Having said this is trivial I have found a problem. What should > > > notmuch do if you do something like > > > > > > notmuch show id:<some-id> > > > and that message is marked with a deleted tag? To be consistent with the > > > other cases (where a deleted message is in a matched thread) we might > > > want to return the message with the not-matched flag set (eg in > > > JSON). But my patch doesn't, as it never even sees the thread since it > > > doesn't match. > > > > > > Looking at notmuch-show.c I think we should not apply the exclude tags > > > to do_show_single, but usually should apply it to do_show. One solution > > > which is simple and is at least close to right would be to get do_show > > > to return the number of threads found. If this is zero then retry the > > > query without the excludes (possible setting the match_flag to zero on > > > each message since we know it does not match) > > > > > > This is not a completely correct solution as if you ask notmuch-show to > > > show more than one thread it might threads which only contain deleted > > > messages. > > > > > > I can't see other good possibilities without slowing down the normal > > > path a lot (eg find all threads that match the original query and then > > > apply the argument above). > > > > > > Any thoughts? > > > > Oh dear. > > > > Well, here's one idea. Instead of doing a single thread query in > > show, do a thread query without the exclusions and then a message > > query with the exclusions. Output all of the messages from the first > > query, but use the results of the second query to determine which > > messages are "matched". The same could be accomplished in the library > > somewhat more efficiently, but it's not obvious to me what the API > > would be. > > Here's a slightly crazier idea that's more library-invasive than the > original approach, but probably better in the long run. > > Have notmuch_query_search_* return everything and make exclusion a > message flag like NOTMUCH_MESSAGE_FLAG_MATCH. Tweak the definition of > "matched" to mean "matched and not excluded" (specifically, a message > would have the match flag or the excluded flag or neither, but not > both). Search would skip threads with zero matched messages and I > think show would Just Work. > > I can think of two ways to implement this. notmuch_query_search_* > could perform both the original query and the query with exclusions > and use the docid set from the second to compute the "excluded" > message flag. Alternatively, it could examine the tags of each > message directly to compute the flag. The latter is probably easier > to implement, but probably slower. > > Thoughts? I have now thought about this some more and think I understand your idea (and how it would work) rather better now. I would suggest one small change: the flags for the messages returned should be "independent": so a message can match the query or not, and it can be excluded or not, with all 4 combinations being possible. (The consumer of notmuch_query_search_* would extract the information it wanted.) I have thought about some implementation ideas but I think sorting is going to be the deciding factor: what order should notmuch_query_search_* return messages/threads? For notmuch_query_search_messages either it returns them all together with the excluded messages marked, or returns all included ones, and then all excluded one. For notmuch_query_search_threads it is less clear. Currently it returns threads in order of first matching message. It is not clear what matching means now: is matching and included, or just matching? If the former then we will be returning some threads with no matching and included messages so we need to decide where to put them in the order. If we sort in both cases just on matching then we have the same output/sort as notmuch pre-excluded flags, just the frontends notmuch-search/show can decide to omit some lines/results. Note that after omitting "excluded" lines the thread sort would be different from the current notmuch-with-excluded implementation. Whereas if we sort based on matching and included, we keep the current sort order with some stuff appended. As regards implementation I think notmuch_query_search_messages is the crucial place: once that returns one of its two orders the rest sort of takes care of itself. Best wishes Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH] Automatically exclude tags in notmuch-show 2012-01-23 1:13 ` Mark Walters @ 2012-01-23 1:52 ` Austin Clements 2012-01-24 1:05 ` Mark Walters 0 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-23 1:52 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch Quoth Mark Walters on Jan 23 at 1:13 am: > On Sun, 22 Jan 2012 13:16:09 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > Quoth myself on Jan 20 at 12:18 pm: > > > Quoth Mark Walters on Jan 20 at 12:10 am: > > > > > > > > Ok Having said this is trivial I have found a problem. What should > > > > notmuch do if you do something like > > > > > > > > notmuch show id:<some-id> > > > > and that message is marked with a deleted tag? To be consistent with the > > > > other cases (where a deleted message is in a matched thread) we might > > > > want to return the message with the not-matched flag set (eg in > > > > JSON). But my patch doesn't, as it never even sees the thread since it > > > > doesn't match. > > > > > > > > Looking at notmuch-show.c I think we should not apply the exclude tags > > > > to do_show_single, but usually should apply it to do_show. One solution > > > > which is simple and is at least close to right would be to get do_show > > > > to return the number of threads found. If this is zero then retry the > > > > query without the excludes (possible setting the match_flag to zero on > > > > each message since we know it does not match) > > > > > > > > This is not a completely correct solution as if you ask notmuch-show to > > > > show more than one thread it might threads which only contain deleted > > > > messages. > > > > > > > > I can't see other good possibilities without slowing down the normal > > > > path a lot (eg find all threads that match the original query and then > > > > apply the argument above). > > > > > > > > Any thoughts? > > > > > > Oh dear. > > > > > > Well, here's one idea. Instead of doing a single thread query in > > > show, do a thread query without the exclusions and then a message > > > query with the exclusions. Output all of the messages from the first > > > query, but use the results of the second query to determine which > > > messages are "matched". The same could be accomplished in the library > > > somewhat more efficiently, but it's not obvious to me what the API > > > would be. > > > > Here's a slightly crazier idea that's more library-invasive than the > > original approach, but probably better in the long run. > > > > Have notmuch_query_search_* return everything and make exclusion a > > message flag like NOTMUCH_MESSAGE_FLAG_MATCH. Tweak the definition of > > "matched" to mean "matched and not excluded" (specifically, a message > > would have the match flag or the excluded flag or neither, but not > > both). Search would skip threads with zero matched messages and I > > think show would Just Work. > > > > I can think of two ways to implement this. notmuch_query_search_* > > could perform both the original query and the query with exclusions > > and use the docid set from the second to compute the "excluded" > > message flag. Alternatively, it could examine the tags of each > > message directly to compute the flag. The latter is probably easier > > to implement, but probably slower. > > > > Thoughts? > > I have now thought about this some more and think I understand your idea > (and how it would work) rather better now. > > I would suggest one small change: the flags for the messages returned > should be "independent": so a message can match the query or not, and it > can be excluded or not, with all 4 combinations being possible. (The > consumer of notmuch_query_search_* would extract the information it > wanted.) I'd initially approached it this way, but went with redefining a "matched" messages because it had much less impact on the API. For example, with the redefined "match", notmuch_thread_get_matched_messages still does the right thing for search and things like the thread subject can still be based on "matched" messages. If we orthongonalize these flags, then we at least need to count matched non-excluded messages and provide an API to access this (while I don't have a solid argument against such an API it just seems weirdly specific to me). My other concern is performance. In thread queries, marking non-matched messages as excluded would require either an extra query per thread or a single query to match all excluded messages (not filtered by the primary query). The former is prohibitive, though the latter might be acceptable (that might depend on how many things people mark as spam or deleted). If the cost is too high, this suggests that we shouldn't mark non-matched messages as excluded, but then we're back to effectively having three levels of matching: not matched, matched but not excluded, and matched but excluded. > I have thought about some implementation ideas but I think sorting is > going to be the deciding factor: what order should > notmuch_query_search_* return messages/threads? Yes. This is exactly what I've been puzzling over, too. > For notmuch_query_search_messages either it returns them all together > with the excluded messages marked, or returns all included ones, and > then all excluded one. I would prefer them intermingled. I feel like returning one and then the other is just exposing implementation details. Plus, it's unclear if the order of the two groups should depend on the sort order, be configurable, or what. Intermingling them seems like the obvious answer. > For notmuch_query_search_threads it is less clear. Currently it returns > threads in order of first matching message. It is not clear what > matching means now: is matching and included, or just matching? If the > former then we will be returning some threads with no matching and > included messages so we need to decide where to put them in the order. I would argue that, if the caller cares about the sort order of the results, it only makes sense for it to skip over threads consisting only of excluded messages, and if the caller doesn't care about the sort order, we can choose whatever's most convenient. > If we sort in both cases just on matching then we have the same > output/sort as notmuch pre-excluded flags, just the frontends > notmuch-search/show can decide to omit some lines/results. Note that > after omitting "excluded" lines the thread sort would be different from > the current notmuch-with-excluded implementation. > > Whereas if we sort based on matching and included, we keep the current > sort order with some stuff appended. > > As regards implementation I think notmuch_query_search_messages is the > crucial place: once that returns one of its two orders the rest sort of > takes care of itself. I think that comes down to exactly how we want to handle the message flags. > Best wishes > > Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH] Automatically exclude tags in notmuch-show 2012-01-23 1:52 ` Austin Clements @ 2012-01-24 1:05 ` Mark Walters 2012-01-24 1:16 ` Austin Clements 0 siblings, 1 reply; 176+ messages in thread From: Mark Walters @ 2012-01-24 1:05 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch On Sun, 22 Jan 2012 20:52:22 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > Quoth Mark Walters on Jan 23 at 1:13 am: > > On Sun, 22 Jan 2012 13:16:09 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > > Quoth myself on Jan 20 at 12:18 pm: > > > > Quoth Mark Walters on Jan 20 at 12:10 am: > > > > > > > > > > Ok Having said this is trivial I have found a problem. What should > > > > > notmuch do if you do something like > > > > > > > > > > notmuch show id:<some-id> > > > > > and that message is marked with a deleted tag? To be consistent with the > > > > > other cases (where a deleted message is in a matched thread) we might > > > > > want to return the message with the not-matched flag set (eg in > > > > > JSON). But my patch doesn't, as it never even sees the thread since it > > > > > doesn't match. > > > > > > > > > > Looking at notmuch-show.c I think we should not apply the exclude tags > > > > > to do_show_single, but usually should apply it to do_show. One solution > > > > > which is simple and is at least close to right would be to get do_show > > > > > to return the number of threads found. If this is zero then retry the > > > > > query without the excludes (possible setting the match_flag to zero on > > > > > each message since we know it does not match) > > > > > > > > > > This is not a completely correct solution as if you ask notmuch-show to > > > > > show more than one thread it might threads which only contain deleted > > > > > messages. > > > > > > > > > > I can't see other good possibilities without slowing down the normal > > > > > path a lot (eg find all threads that match the original query and then > > > > > apply the argument above). > > > > > > > > > > Any thoughts? > > > > > > > > Oh dear. > > > > > > > > Well, here's one idea. Instead of doing a single thread query in > > > > show, do a thread query without the exclusions and then a message > > > > query with the exclusions. Output all of the messages from the first > > > > query, but use the results of the second query to determine which > > > > messages are "matched". The same could be accomplished in the library > > > > somewhat more efficiently, but it's not obvious to me what the API > > > > would be. > > > > > > Here's a slightly crazier idea that's more library-invasive than the > > > original approach, but probably better in the long run. > > > > > > Have notmuch_query_search_* return everything and make exclusion a > > > message flag like NOTMUCH_MESSAGE_FLAG_MATCH. Tweak the definition of > > > "matched" to mean "matched and not excluded" (specifically, a message > > > would have the match flag or the excluded flag or neither, but not > > > both). Search would skip threads with zero matched messages and I > > > think show would Just Work. > > > > > > I can think of two ways to implement this. notmuch_query_search_* > > > could perform both the original query and the query with exclusions > > > and use the docid set from the second to compute the "excluded" > > > message flag. Alternatively, it could examine the tags of each > > > message directly to compute the flag. The latter is probably easier > > > to implement, but probably slower. > > > > > > Thoughts? > > > > I have now thought about this some more and think I understand your idea > > (and how it would work) rather better now. > > > > I would suggest one small change: the flags for the messages returned > > should be "independent": so a message can match the query or not, and it > > can be excluded or not, with all 4 combinations being possible. (The > > consumer of notmuch_query_search_* would extract the information it > > wanted.) > > I'd initially approached it this way, but went with redefining a > "matched" messages because it had much less impact on the API. For > example, with the redefined "match", > notmuch_thread_get_matched_messages still does the right thing for > search and things like the thread subject can still be based on > "matched" messages. If we orthongonalize these flags, then we at > least need to count matched non-excluded messages and provide an API > to access this (while I don't have a solid argument against such an > API it just seems weirdly specific to me). Ok I have an initial implementation of this which I will post as a reply to this thread: it does make the flags orthogonal but that would be easy to change. If we do want to keep match to mean match and not excluded then I would argue for a third flag so that the emacs frontend could see all 4 possibilities. Note that in your suggestion we still need to do something in notmuch_thread_get_matched_messages to set the subject etc in threads with no matching non-excluded messages. > My other concern is performance. In thread queries, marking > non-matched messages as excluded would require either an extra query > per thread or a single query to match all excluded messages (not > filtered by the primary query). The former is prohibitive, though the > latter might be acceptable (that might depend on how many things > people mark as spam or deleted). If the cost is too high, this > suggests that we shouldn't mark non-matched messages as excluded, but > then we're back to effectively having three levels of matching: not > matched, matched but not excluded, and matched but excluded. The implementation follows the second suggestion. I'll discuss performance below. > > I have thought about some implementation ideas but I think sorting is > > going to be the deciding factor: what order should > > notmuch_query_search_* return messages/threads? > > Yes. This is exactly what I've been puzzling over, too. > > > For notmuch_query_search_messages either it returns them all together > > with the excluded messages marked, or returns all included ones, and > > then all excluded one. > > I would prefer them intermingled. I feel like returning one and then > the other is just exposing implementation details. Plus, it's unclear > if the order of the two groups should depend on the sort order, be > configurable, or what. Intermingling them seems like the obvious > answer. > > > For notmuch_query_search_threads it is less clear. Currently it returns > > threads in order of first matching message. It is not clear what > > matching means now: is matching and included, or just matching? If the > > former then we will be returning some threads with no matching and > > included messages so we need to decide where to put them in the order. > > I would argue that, if the caller cares about the sort order of the > results, it only makes sense for it to skip over threads consisting > only of excluded messages, and if the caller doesn't care about the > sort order, we can choose whatever's most convenient. I have gone with this intermingled suggestion. One other implementation detail: the code uses the exclude query generated by your _notmuch_exclude_tags function; thus if the user over-rides the exclude with tag:deleted then these messages will not be marked excluded. I can't work out whether that is the right behaviour. The code as it stands should finish where we started, but have the infrastructure to show excluded messages. I think a nice interface would be for the emacs notmuch-search frontend to take all messages and hide all threads with 0 matching messages, but make them unhideable. (Possibly if there are no non-hidden threads it could offer to show them.) The notmuch-show frontend could take all messages but show only a header line for excluded messages (perhaps in a different colour). It would jump to the first matching non excluded message unless there aren't any, in which case it would go to the first matching (necessarily excluded) message instead. Performance: the code/notmuch is generally fast. On my computer/email archive of circa 70000 the time to constuct the list of excluded messages is of the order of 20 milliseconds. (Inherently it should not be much slower since the thread return already has to construct a complete list of all messages matching the query before it can return any threads.) However, in some case it will appear slower: if there are lots of threads that only match in excluded messages then this code will waste time constructing these "hidden threads". In other words the code will be comparable to the pre-exclude notmuch: since it is constructing the same threads. Finally, the code is obviously an early draft to see what people think. I know there are things that need freeing, and probably some error returns that should be checked. Best wishes Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH] Automatically exclude tags in notmuch-show 2012-01-24 1:05 ` Mark Walters @ 2012-01-24 1:16 ` Austin Clements 2012-01-24 1:18 ` [RFC PATCH 1/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters ` (3 more replies) 0 siblings, 4 replies; 176+ messages in thread From: Austin Clements @ 2012-01-24 1:16 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch Quoth Mark Walters on Jan 24 at 1:05 am: > > On Sun, 22 Jan 2012 20:52:22 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > Quoth Mark Walters on Jan 23 at 1:13 am: > > > On Sun, 22 Jan 2012 13:16:09 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > > > Quoth myself on Jan 20 at 12:18 pm: > > > > > Quoth Mark Walters on Jan 20 at 12:10 am: > > > > > > > > > > > > Ok Having said this is trivial I have found a problem. What should > > > > > > notmuch do if you do something like > > > > > > > > > > > > notmuch show id:<some-id> > > > > > > and that message is marked with a deleted tag? To be consistent with the > > > > > > other cases (where a deleted message is in a matched thread) we might > > > > > > want to return the message with the not-matched flag set (eg in > > > > > > JSON). But my patch doesn't, as it never even sees the thread since it > > > > > > doesn't match. > > > > > > > > > > > > Looking at notmuch-show.c I think we should not apply the exclude tags > > > > > > to do_show_single, but usually should apply it to do_show. One solution > > > > > > which is simple and is at least close to right would be to get do_show > > > > > > to return the number of threads found. If this is zero then retry the > > > > > > query without the excludes (possible setting the match_flag to zero on > > > > > > each message since we know it does not match) > > > > > > > > > > > > This is not a completely correct solution as if you ask notmuch-show to > > > > > > show more than one thread it might threads which only contain deleted > > > > > > messages. > > > > > > > > > > > > I can't see other good possibilities without slowing down the normal > > > > > > path a lot (eg find all threads that match the original query and then > > > > > > apply the argument above). > > > > > > > > > > > > Any thoughts? > > > > > > > > > > Oh dear. > > > > > > > > > > Well, here's one idea. Instead of doing a single thread query in > > > > > show, do a thread query without the exclusions and then a message > > > > > query with the exclusions. Output all of the messages from the first > > > > > query, but use the results of the second query to determine which > > > > > messages are "matched". The same could be accomplished in the library > > > > > somewhat more efficiently, but it's not obvious to me what the API > > > > > would be. > > > > > > > > Here's a slightly crazier idea that's more library-invasive than the > > > > original approach, but probably better in the long run. > > > > > > > > Have notmuch_query_search_* return everything and make exclusion a > > > > message flag like NOTMUCH_MESSAGE_FLAG_MATCH. Tweak the definition of > > > > "matched" to mean "matched and not excluded" (specifically, a message > > > > would have the match flag or the excluded flag or neither, but not > > > > both). Search would skip threads with zero matched messages and I > > > > think show would Just Work. > > > > > > > > I can think of two ways to implement this. notmuch_query_search_* > > > > could perform both the original query and the query with exclusions > > > > and use the docid set from the second to compute the "excluded" > > > > message flag. Alternatively, it could examine the tags of each > > > > message directly to compute the flag. The latter is probably easier > > > > to implement, but probably slower. > > > > > > > > Thoughts? > > > > > > I have now thought about this some more and think I understand your idea > > > (and how it would work) rather better now. > > > > > > I would suggest one small change: the flags for the messages returned > > > should be "independent": so a message can match the query or not, and it > > > can be excluded or not, with all 4 combinations being possible. (The > > > consumer of notmuch_query_search_* would extract the information it > > > wanted.) > > > > I'd initially approached it this way, but went with redefining a > > "matched" messages because it had much less impact on the API. For > > example, with the redefined "match", > > notmuch_thread_get_matched_messages still does the right thing for > > search and things like the thread subject can still be based on > > "matched" messages. If we orthongonalize these flags, then we at > > least need to count matched non-excluded messages and provide an API > > to access this (while I don't have a solid argument against such an > > API it just seems weirdly specific to me). > > Ok I have an initial implementation of this which I will post as a reply > to this thread: it does make the flags orthogonal but that would be easy > to change. If we do want to keep match to mean match and not excluded > then I would argue for a third flag so that the emacs frontend could see > all 4 possibilities. Note that in your suggestion we still need to do > something in notmuch_thread_get_matched_messages to set the subject etc > in threads with no matching non-excluded messages. Cool. I was starting to hack together an implementation too, but I'll put that on hold. Since notmuch_thread_get_matched_messages just counts matched messages, it doesn't need anything special for threads with no matched messages, but you're right that something has to be done about the subjects of threads containing only excluded messages. Could you CC me on the patch? The list has been stuck all day. > > My other concern is performance. In thread queries, marking > > non-matched messages as excluded would require either an extra query > > per thread or a single query to match all excluded messages (not > > filtered by the primary query). The former is prohibitive, though the > > latter might be acceptable (that might depend on how many things > > people mark as spam or deleted). If the cost is too high, this > > suggests that we shouldn't mark non-matched messages as excluded, but > > then we're back to effectively having three levels of matching: not > > matched, matched but not excluded, and matched but excluded. > > The implementation follows the second suggestion. I'll discuss > performance below. > > > > I have thought about some implementation ideas but I think sorting is > > > going to be the deciding factor: what order should > > > notmuch_query_search_* return messages/threads? > > > > Yes. This is exactly what I've been puzzling over, too. > > > > > For notmuch_query_search_messages either it returns them all together > > > with the excluded messages marked, or returns all included ones, and > > > then all excluded one. > > > > I would prefer them intermingled. I feel like returning one and then > > the other is just exposing implementation details. Plus, it's unclear > > if the order of the two groups should depend on the sort order, be > > configurable, or what. Intermingling them seems like the obvious > > answer. > > > > > For notmuch_query_search_threads it is less clear. Currently it returns > > > threads in order of first matching message. It is not clear what > > > matching means now: is matching and included, or just matching? If the > > > former then we will be returning some threads with no matching and > > > included messages so we need to decide where to put them in the order. > > > > I would argue that, if the caller cares about the sort order of the > > results, it only makes sense for it to skip over threads consisting > > only of excluded messages, and if the caller doesn't care about the > > sort order, we can choose whatever's most convenient. > > I have gone with this intermingled suggestion. > > One other implementation detail: the code uses the exclude query > generated by your _notmuch_exclude_tags function; thus if the user > over-rides the exclude with tag:deleted then these messages will not be > marked excluded. I can't work out whether that is the right behaviour. I think that's reasonable. Otherwise we need yet another state, matched-but-excluded-but-overridden. > The code as it stands should finish where we started, but have the > infrastructure to show excluded messages. > > I think a nice interface would be for the emacs notmuch-search frontend > to take all messages and hide all threads with 0 matching messages, but > make them unhideable. (Possibly if there are no non-hidden threads it > could offer to show them.) The notmuch-show frontend could take all That does sound nice, though where would they go in the list? Just at the end? > messages but show only a header line for excluded messages (perhaps in a > different colour). It would jump to the first matching non excluded > message unless there aren't any, in which case it would go to the first > matching (necessarily excluded) message instead. That sounds reasonable. Alternatively, show could parallel search and hide these messages, but point out that there are excluded messages and offer to show them. > Performance: the code/notmuch is generally fast. On my computer/email > archive of circa 70000 the time to constuct the list of excluded > messages is of the order of 20 milliseconds. (Inherently it should not > be much slower since the thread return already has to construct a > complete list of all messages matching the query before it can return > any threads.) I think this time will depend heavily on how many excluded messages you have. My performance concern is that it's not bounded by how many messages match the original query. > However, in some case it will appear slower: if there are lots of > threads that only match in excluded messages then this code will waste > time constructing these "hidden threads". In other words the code will > be comparable to the pre-exclude notmuch: since it is constructing the > same threads. > > Finally, the code is obviously an early draft to see what people > think. I know there are things that need freeing, and probably some > error returns that should be checked. > > Best wishes > > Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* [RFC PATCH 1/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag 2012-01-24 1:16 ` Austin Clements @ 2012-01-24 1:18 ` Mark Walters 2012-01-24 1:18 ` [RFC PATCH 2/4] " Mark Walters ` (2 subsequent siblings) 3 siblings, 0 replies; 176+ messages in thread From: Mark Walters @ 2012-01-24 1:18 UTC (permalink / raw) To: notmuch, Austin Clements Slightly refactor the exclude code to give the callers access to the exclude query itself. There should be no functional change. --- lib/query.cc | 29 +++++++++++++++++++---------- 1 files changed, 19 insertions(+), 10 deletions(-) diff --git a/lib/query.cc b/lib/query.cc index 0b36602..c25b301 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -122,12 +122,15 @@ _notmuch_messages_destructor (notmuch_mset_messages_t *messages) return 0; } -/* Return a query that does not match messages with the excluded tags - * registered with the query. Any tags that explicitly appear in - * xquery will not be excluded. */ +/* Return a query that matches messages with the excluded tags + * registered with query. Any tags that explicitly appear in xquery + * will not be excluded. The caller of this function has to combine + * the returned query appropriately.*/ static Xapian::Query _notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery) { + Xapian::Query exclude_query = Xapian::Query::MatchNothing; + for (notmuch_string_node_t *term = query->exclude_terms->head; term; term = term->next) { Xapian::TermIterator it = xquery.get_terms_begin (); @@ -137,10 +140,10 @@ _notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery) break; } if (it == end) - xquery = Xapian::Query (Xapian::Query::OP_AND_NOT, - xquery, Xapian::Query (term->string)); + exclude_query = Xapian::Query (Xapian::Query::OP_OR, + exclude_query, Xapian::Query (term->string)); } - return xquery; + return exclude_query; } notmuch_messages_t * @@ -168,7 +171,7 @@ notmuch_query_search_messages (notmuch_query_t *query) Xapian::Query mail_query (talloc_asprintf (query, "%s%s", _find_prefix ("type"), "mail")); - Xapian::Query string_query, final_query; + Xapian::Query string_query, final_query, exclude_query; Xapian::MSet mset; unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN | Xapian::QueryParser::FLAG_PHRASE | @@ -188,7 +191,10 @@ notmuch_query_search_messages (notmuch_query_t *query) mail_query, string_query); } - final_query = _notmuch_exclude_tags (query, final_query); + exclude_query = _notmuch_exclude_tags (query, final_query); + + final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, + final_query, exclude_query); enquire.set_weighting_scheme (Xapian::BoolWeight()); @@ -449,7 +455,7 @@ notmuch_query_count_messages (notmuch_query_t *query) Xapian::Query mail_query (talloc_asprintf (query, "%s%s", _find_prefix ("type"), "mail")); - Xapian::Query string_query, final_query; + Xapian::Query string_query, final_query, exclude_query; Xapian::MSet mset; unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN | Xapian::QueryParser::FLAG_PHRASE | @@ -469,7 +475,10 @@ notmuch_query_count_messages (notmuch_query_t *query) mail_query, string_query); } - final_query = _notmuch_exclude_tags (query, final_query); + exclude_query = _notmuch_exclude_tags (query, final_query); + + final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, + final_query, exclude_query); enquire.set_weighting_scheme(Xapian::BoolWeight()); enquire.set_docid_order(Xapian::Enquire::ASCENDING); -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag 2012-01-24 1:16 ` Austin Clements 2012-01-24 1:18 ` [RFC PATCH 1/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters @ 2012-01-24 1:18 ` Mark Walters 2012-01-24 2:45 ` Austin Clements 2012-01-24 1:18 ` [RFC PATCH 3/4] " Mark Walters 2012-01-24 1:18 ` [PATCH 4/4] " Mark Walters 3 siblings, 1 reply; 176+ messages in thread From: Mark Walters @ 2012-01-24 1:18 UTC (permalink / raw) To: notmuch, Austin Clements Form excluded doc_ids set and use that to exclude messages. Should be no functional change. --- lib/notmuch-private.h | 1 + lib/query.cc | 28 ++++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h index 7bf153e..e791bb0 100644 --- a/lib/notmuch-private.h +++ b/lib/notmuch-private.h @@ -401,6 +401,7 @@ typedef struct _notmuch_message_list { */ struct visible _notmuch_messages { notmuch_bool_t is_of_list_type; + notmuch_doc_id_set_t *excluded_doc_ids; notmuch_message_node_t *iterator; }; diff --git a/lib/query.cc b/lib/query.cc index c25b301..92fa834 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -57,6 +57,11 @@ struct visible _notmuch_threads { notmuch_doc_id_set_t match_set; }; +static notmuch_bool_t +_notmuch_doc_id_set_init (void *ctx, + notmuch_doc_id_set_t *doc_ids, + GArray *arr); + notmuch_query_t * notmuch_query_create (notmuch_database_t *notmuch, const char *query_string) @@ -173,6 +178,7 @@ notmuch_query_search_messages (notmuch_query_t *query) "mail")); Xapian::Query string_query, final_query, exclude_query; Xapian::MSet mset; + Xapian::MSetIterator iterator; unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN | Xapian::QueryParser::FLAG_PHRASE | Xapian::QueryParser::FLAG_LOVEHATE | @@ -193,8 +199,21 @@ notmuch_query_search_messages (notmuch_query_t *query) exclude_query = _notmuch_exclude_tags (query, final_query); - final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, - final_query, exclude_query); + enquire.set_weighting_scheme (Xapian::BoolWeight()); + enquire.set_query (exclude_query); + + mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ()); + + GArray *excluded_doc_ids = g_array_new (FALSE, FALSE, sizeof (unsigned int)); + + for (iterator = mset.begin (); iterator != mset.end (); iterator++) + { + unsigned int doc_id = *iterator; + g_array_append_val (excluded_doc_ids, doc_id); + } + messages->base.excluded_doc_ids = talloc (query, _notmuch_doc_id_set); + _notmuch_doc_id_set_init (query, messages->base.excluded_doc_ids, + excluded_doc_ids); enquire.set_weighting_scheme (Xapian::BoolWeight()); @@ -294,6 +313,11 @@ _notmuch_mset_messages_move_to_next (notmuch_messages_t *messages) mset_messages = (notmuch_mset_messages_t *) messages; mset_messages->iterator++; + + while ((mset_messages->iterator != mset_messages->iterator_end) && + (_notmuch_doc_id_set_contains (messages->excluded_doc_ids, + *mset_messages->iterator))) + mset_messages->iterator++; } static notmuch_bool_t -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag 2012-01-24 1:18 ` [RFC PATCH 2/4] " Mark Walters @ 2012-01-24 2:45 ` Austin Clements 2012-01-24 11:20 ` Mark Walters 2012-01-28 10:51 ` Mark Walters 0 siblings, 2 replies; 176+ messages in thread From: Austin Clements @ 2012-01-24 2:45 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch The overall structure of this series looks great. There's obviously a lot of clean up to do, but I'll reply with a few high-level comments. Quoth Mark Walters on Jan 24 at 1:18 am: > Form excluded doc_ids set and use that to exclude messages. > Should be no functional change. > > --- > lib/notmuch-private.h | 1 + > lib/query.cc | 28 ++++++++++++++++++++++++++-- > 2 files changed, 27 insertions(+), 2 deletions(-) > > diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h > index 7bf153e..e791bb0 100644 > --- a/lib/notmuch-private.h > +++ b/lib/notmuch-private.h > @@ -401,6 +401,7 @@ typedef struct _notmuch_message_list { > */ > struct visible _notmuch_messages { > notmuch_bool_t is_of_list_type; > + notmuch_doc_id_set_t *excluded_doc_ids; > notmuch_message_node_t *iterator; > }; > > diff --git a/lib/query.cc b/lib/query.cc > index c25b301..92fa834 100644 > --- a/lib/query.cc > +++ b/lib/query.cc > @@ -57,6 +57,11 @@ struct visible _notmuch_threads { > notmuch_doc_id_set_t match_set; > }; > > +static notmuch_bool_t > +_notmuch_doc_id_set_init (void *ctx, > + notmuch_doc_id_set_t *doc_ids, > + GArray *arr); > + > notmuch_query_t * > notmuch_query_create (notmuch_database_t *notmuch, > const char *query_string) > @@ -173,6 +178,7 @@ notmuch_query_search_messages (notmuch_query_t *query) > "mail")); > Xapian::Query string_query, final_query, exclude_query; > Xapian::MSet mset; > + Xapian::MSetIterator iterator; > unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN | > Xapian::QueryParser::FLAG_PHRASE | > Xapian::QueryParser::FLAG_LOVEHATE | > @@ -193,8 +199,21 @@ notmuch_query_search_messages (notmuch_query_t *query) > > exclude_query = _notmuch_exclude_tags (query, final_query); > > - final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, > - final_query, exclude_query); > + enquire.set_weighting_scheme (Xapian::BoolWeight()); > + enquire.set_query (exclude_query); > + > + mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ()); > + > + GArray *excluded_doc_ids = g_array_new (FALSE, FALSE, sizeof (unsigned int)); > + > + for (iterator = mset.begin (); iterator != mset.end (); iterator++) > + { > + unsigned int doc_id = *iterator; > + g_array_append_val (excluded_doc_ids, doc_id); > + } > + messages->base.excluded_doc_ids = talloc (query, _notmuch_doc_id_set); > + _notmuch_doc_id_set_init (query, messages->base.excluded_doc_ids, > + excluded_doc_ids); This might be inefficient for message-only queries, since it will fetch *all* excluded docids. This highlights a basic difference between message and thread search: thread search can return messages that don't match the original query and hence needs to know all potentially excluded messages, while message search can only return messages that match the original query. It's entirely possible this doesn't matter because Xapian probably still needs to fetch the full posting lists of the excluded terms, but it would be worth doing a quick/hacky benchmark to verify this, with enough excluded messages to make the cost non-trivial. If it does matter, you could pass in a flag indicating if the exclude query should be limited by the original query or not. Or you could do the limited exclude query in notmuch_query_search_messages and a separate open-ended exclude query in notmuch_query_search_threads. > > enquire.set_weighting_scheme (Xapian::BoolWeight()); > > @@ -294,6 +313,11 @@ _notmuch_mset_messages_move_to_next (notmuch_messages_t *messages) > mset_messages = (notmuch_mset_messages_t *) messages; > > mset_messages->iterator++; > + > + while ((mset_messages->iterator != mset_messages->iterator_end) && > + (_notmuch_doc_id_set_contains (messages->excluded_doc_ids, > + *mset_messages->iterator))) > + mset_messages->iterator++; This seemed a little weird, since you remove it in the next patch. Is this just to keep the tests happy? (If so, it would be worth mentioning in the commit message; other reviewers will definitely have the same question.) > } > > static notmuch_bool_t ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag 2012-01-24 2:45 ` Austin Clements @ 2012-01-24 11:20 ` Mark Walters 2012-01-28 10:51 ` Mark Walters 1 sibling, 0 replies; 176+ messages in thread From: Mark Walters @ 2012-01-24 11:20 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch On Mon, 23 Jan 2012 21:45:21 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > The overall structure of this series looks great. There's obviously a > lot of clean up to do, but I'll reply with a few high-level comments. > > Quoth Mark Walters on Jan 24 at 1:18 am: > > Form excluded doc_ids set and use that to exclude messages. > > Should be no functional change. > > > > --- > > lib/notmuch-private.h | 1 + > > lib/query.cc | 28 ++++++++++++++++++++++++++-- > > 2 files changed, 27 insertions(+), 2 deletions(-) > > > > diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h > > index 7bf153e..e791bb0 100644 > > --- a/lib/notmuch-private.h > > +++ b/lib/notmuch-private.h > > @@ -401,6 +401,7 @@ typedef struct _notmuch_message_list { > > */ > > struct visible _notmuch_messages { > > notmuch_bool_t is_of_list_type; > > + notmuch_doc_id_set_t *excluded_doc_ids; > > notmuch_message_node_t *iterator; > > }; > > > > diff --git a/lib/query.cc b/lib/query.cc > > index c25b301..92fa834 100644 > > --- a/lib/query.cc > > +++ b/lib/query.cc > > @@ -57,6 +57,11 @@ struct visible _notmuch_threads { > > notmuch_doc_id_set_t match_set; > > }; > > > > +static notmuch_bool_t > > +_notmuch_doc_id_set_init (void *ctx, > > + notmuch_doc_id_set_t *doc_ids, > > + GArray *arr); > > + > > notmuch_query_t * > > notmuch_query_create (notmuch_database_t *notmuch, > > const char *query_string) > > @@ -173,6 +178,7 @@ notmuch_query_search_messages (notmuch_query_t *query) > > "mail")); > > Xapian::Query string_query, final_query, exclude_query; > > Xapian::MSet mset; > > + Xapian::MSetIterator iterator; > > unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN | > > Xapian::QueryParser::FLAG_PHRASE | > > Xapian::QueryParser::FLAG_LOVEHATE | > > @@ -193,8 +199,21 @@ notmuch_query_search_messages (notmuch_query_t *query) > > > > exclude_query = _notmuch_exclude_tags (query, final_query); > > > > - final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, > > - final_query, exclude_query); > > + enquire.set_weighting_scheme (Xapian::BoolWeight()); > > + enquire.set_query (exclude_query); > > + > > + mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ()); > > + > > + GArray *excluded_doc_ids = g_array_new (FALSE, FALSE, sizeof (unsigned int)); > > + > > + for (iterator = mset.begin (); iterator != mset.end (); iterator++) > > + { > > + unsigned int doc_id = *iterator; > > + g_array_append_val (excluded_doc_ids, doc_id); > > + } > > + messages->base.excluded_doc_ids = talloc (query, _notmuch_doc_id_set); > > + _notmuch_doc_id_set_init (query, messages->base.excluded_doc_ids, > > + excluded_doc_ids); > > This might be inefficient for message-only queries, since it will > fetch *all* excluded docids. This highlights a basic difference > between message and thread search: thread search can return messages > that don't match the original query and hence needs to know all > potentially excluded messages, while message search can only return > messages that match the original query. > > It's entirely possible this doesn't matter because Xapian probably > still needs to fetch the full posting lists of the excluded terms, but > it would be worth doing a quick/hacky benchmark to verify this, with > enough excluded messages to make the cost non-trivial. > > If it does matter, you could pass in a flag indicating if the exclude > query should be limited by the original query or not. Or you could do > the limited exclude query in notmuch_query_search_messages and a > separate open-ended exclude query in notmuch_query_search_threads. Yes I will benchmark that: I am just importing a large archive into notmuch for testing. > > enquire.set_weighting_scheme (Xapian::BoolWeight()); > > > > @@ -294,6 +313,11 @@ _notmuch_mset_messages_move_to_next (notmuch_messages_t *messages) > > mset_messages = (notmuch_mset_messages_t *) messages; > > > > mset_messages->iterator++; > > + > > + while ((mset_messages->iterator != mset_messages->iterator_end) && > > + (_notmuch_doc_id_set_contains (messages->excluded_doc_ids, > > + *mset_messages->iterator))) > > + mset_messages->iterator++; > > This seemed a little weird, since you remove it in the next patch. Is > this just to keep the tests happy? (If so, it would be worth > mentioning in the commit message; other reviewers will definitely have > the same question.) Essentially just to keep tests happy: or rather to try and make it easy for a reviewer to see that the individual patch does not make any functional change. Best wishes Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag 2012-01-24 2:45 ` Austin Clements 2012-01-24 11:20 ` Mark Walters @ 2012-01-28 10:51 ` Mark Walters 2012-01-28 18:33 ` Austin Clements 1 sibling, 1 reply; 176+ messages in thread From: Mark Walters @ 2012-01-28 10:51 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch > > exclude_query = _notmuch_exclude_tags (query, final_query); > > > > - final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, > > - final_query, exclude_query); > > + enquire.set_weighting_scheme (Xapian::BoolWeight()); > > + enquire.set_query (exclude_query); > > + > > + mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ()); > > + > > + GArray *excluded_doc_ids = g_array_new (FALSE, FALSE, sizeof (unsigned int)); > > + > > + for (iterator = mset.begin (); iterator != mset.end (); iterator++) > > + { > > + unsigned int doc_id = *iterator; > > + g_array_append_val (excluded_doc_ids, doc_id); > > + } > > + messages->base.excluded_doc_ids = talloc (query, _notmuch_doc_id_set); > > + _notmuch_doc_id_set_init (query, messages->base.excluded_doc_ids, > > + excluded_doc_ids); > > This might be inefficient for message-only queries, since it will > fetch *all* excluded docids. This highlights a basic difference > between message and thread search: thread search can return messages > that don't match the original query and hence needs to know all > potentially excluded messages, while message search can only return > messages that match the original query. I now have some benchmarks (not run enough times to be hugely accurate so ignore minor differences). The full results are below. The summary is: Large-archive = 1 100 000 messages in 290 000 threads (about 10 years of lkml). I mark 1 000 000 deleted Small-archive = 70 000 messages in 35 000 threads. 10 000 marked deleted. Doing the initial exclude work on the big collection takes about 0.8s and on the small collection about 0.01s. So any query to the big collection takes at least 0.8s longer and this all occurs before any results appear. I then implemented the exclude doing it once for each thread query in _notmuch_create_thread. Roughly this made any query 50% slower. In normal front end use even the 0.8s is not totally unusable, but it is totally unacceptable in the backend where a user might do something like for i in ` notmuch search --output=threads from:xxx ` ; do notmuch search --output=messages $i; done to list all messages in all matching threads. So I think my conclusions are: (1) message only queries must be done without the full exclude. (2) thread queries which only match one message should not do the full exclude (3) it would be nice to switch between the two approaches depending on size but I don't see how to do that without extra(!) queries (4) One possible might be do something that say does thirty threads with the by thread method and then if not finished does the full exclude. (5) thread-by-thread might be best for Jani's limit-match id:"1327692900-22926-1-git-send-email-jani@nikula.org" Obviously, anything setting an exclude flag like this will be slower (since it is doing more work): the question is are either of these (or a combination like (4) above) acceptable? I now have a mostly working implementation from library to emacs frontend and I do like the overall outcome. The complete benchmarks are below Best wishes Mark LARGE COLLECTION is 1,100,000 messages 290,000 threads 1,000,000 deleted SMALL COLLECTION is 70,000 messages in 35,000 threads 10,000 deleted benchmarks: all times in seconds, x/y/z means a query which matches x threads with y matching messages and z messages in total. Ig or ignore means with the tag-exclude turned off (i.e. with a query matching the excluded tag). list all messages is the time for the for loop listed above giving all message-ids for all messages in any thread matching a query. Finally the three columns are master with exclude code disabled, thread-thread is doing excludes once per thread construction, and in-advance does all the exclude work in advance as in the patches I posted. In most cases the benchmark is the average of a lot of runs so the database should have been as cached as one could hope. master-(all) thread-thread in-advance LARGE COLLECTION show single message 0.016 0.018 0.78 search single message 0.015 0.016 0.78 search single with tag 0.015 0.015 0.009 945/2627/20000 query ignore 2.9 n/a 3 query 2.9 4.2 3.8 list all messages (ig) 13 n/a 13 list all messages 13 14 12mins 4754/13000/110000 query ignore 15.9 n/a 17 query 15.9 22 17.6 only messages 1.25 1.26 1.9 177/483/1752 query 0.3 0.42 1.1 search '*' 20mins 28mins 21.5mins SMALL COLLECTION 1500/2800/5600 query 1.8 2.7 2 list all messages 14.5 16.4 30 single message 0.008 0.008 0.018 search '*' 28 49 32 ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag 2012-01-28 10:51 ` Mark Walters @ 2012-01-28 18:33 ` Austin Clements 2012-01-28 23:57 ` Mark Walters 0 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-28 18:33 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch Quoth Mark Walters on Jan 28 at 10:51 am: > > > > exclude_query = _notmuch_exclude_tags (query, final_query); > > > > > > - final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, > > > - final_query, exclude_query); > > > + enquire.set_weighting_scheme (Xapian::BoolWeight()); > > > + enquire.set_query (exclude_query); > > > + > > > + mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ()); > > > + > > > + GArray *excluded_doc_ids = g_array_new (FALSE, FALSE, sizeof (unsigned int)); > > > + > > > + for (iterator = mset.begin (); iterator != mset.end (); iterator++) > > > + { > > > + unsigned int doc_id = *iterator; > > > + g_array_append_val (excluded_doc_ids, doc_id); > > > + } > > > + messages->base.excluded_doc_ids = talloc (query, _notmuch_doc_id_set); > > > + _notmuch_doc_id_set_init (query, messages->base.excluded_doc_ids, > > > + excluded_doc_ids); > > > > This might be inefficient for message-only queries, since it will > > fetch *all* excluded docids. This highlights a basic difference > > between message and thread search: thread search can return messages > > that don't match the original query and hence needs to know all > > potentially excluded messages, while message search can only return > > messages that match the original query. > > I now have some benchmarks (not run enough times to be hugely accurate > so ignore minor differences). The full results are below. The summary > is: > > Large-archive = 1 100 000 messages in 290 000 threads (about 10 years of > lkml). I mark 1 000 000 deleted > Small-archive = 70 000 messages in 35 000 threads. 10 000 marked > deleted. > > Doing the initial exclude work on the big collection takes about 0.8s > and on the small collection about 0.01s. So any query to the big > collection takes at least 0.8s longer and this all occurs before any > results appear. Interesting. Do you know where that time is spent? Also, it might be reasonable to assume that no more than, say, 10% of a person's mail store is excluded, but maybe that depends on how people use this feature. > I then implemented the exclude doing it once for each thread query in > _notmuch_create_thread. Roughly this made any query 50% slower. That's not terrible. > In normal front end use even the 0.8s is not totally unusable, but it is > totally unacceptable in the backend where a user might do something like > > for i in ` notmuch search --output=threads from:xxx ` ; > do > notmuch search --output=messages $i; > done > > to list all messages in all matching threads. > > So I think my conclusions are: > > (1) message only queries must be done without the full exclude. > (2) thread queries which only match one message should not do the full > exclude > (3) it would be nice to switch between the two approaches depending on > size but I don't see how to do that without extra(!) queries > (4) One possible might be do something that say does thirty threads with > the by thread method and then if not finished does the full exclude. > (5) thread-by-thread might be best for Jani's limit-match > id:"1327692900-22926-1-git-send-email-jani@nikula.org" > > Obviously, anything setting an exclude flag like this will be slower > (since it is doing more work): the question is are either of these (or a > combination like (4) above) acceptable? Or only mark matched messages as excluded. Here's another idea (actually, a rehash of an old idea). For message search do two queries, the original query and "<original> AND <exclude>", and use this to keep everything in order and mark excluded messages. For thread search, use message search results so it's easy to both sort by unexcluded messages and include fully-excluded threads, but compute the excluded flag (either just for unmatched messages or for all messages) by examining each message's tags directly (which thread_add_message already iterates over, so this is easy and won't add any overhead). If the excluded query is fast, which I think it will be, I think this should get the best of all worlds and be fairly straightforward to implement (no asymmetries between the queries used for message and thread search). It would be easy and worth it to run the excluded query by hand on your test corpus; I suspect it will be much faster than 0.8s because the query already uses "Tmail", which is huge and doesn't seem to slow things down. > I now have a mostly working implementation from library to > emacs frontend and I do like the overall outcome. Awesome. > The complete benchmarks are below > > Best wishes > > Mark > > LARGE COLLECTION is 1,100,000 messages 290,000 threads 1,000,000 deleted > SMALL COLLECTION is 70,000 messages in 35,000 threads 10,000 deleted > > benchmarks: all times in seconds, x/y/z means a query which matches x > threads with y matching messages and z messages in total. Ig or ignore > means with the tag-exclude turned off (i.e. with a query matching the > excluded tag). list all messages is the time for the for loop listed > above giving all message-ids for all messages in any thread matching a > query. > > Finally the three columns are master with exclude code disabled, > thread-thread is doing excludes once per thread construction, and > in-advance does all the exclude work in advance as in the patches I posted. > > In most cases the benchmark is the average of a lot of runs so the > database should have been as cached as one could hope. > > master-(all) thread-thread in-advance > LARGE COLLECTION > show single message 0.016 0.018 0.78 > search single message 0.015 0.016 0.78 > search single with tag 0.015 0.015 0.009 > 945/2627/20000 > query ignore 2.9 n/a 3 > query 2.9 4.2 3.8 > list all messages (ig) 13 n/a 13 > list all messages 13 14 12mins > 4754/13000/110000 > query ignore 15.9 n/a 17 > query 15.9 22 17.6 > only messages 1.25 1.26 1.9 > 177/483/1752 > query 0.3 0.42 1.1 > > search '*' 20mins 28mins 21.5mins > > SMALL COLLECTION > 1500/2800/5600 > query 1.8 2.7 2 > list all messages 14.5 16.4 30 > single message 0.008 0.008 0.018 > > search '*' 28 49 32 > ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag 2012-01-28 18:33 ` Austin Clements @ 2012-01-28 23:57 ` Mark Walters 2012-01-29 0:04 ` [PATCH 1/4] Add exclude flag Mark Walters ` (4 more replies) 0 siblings, 5 replies; 176+ messages in thread From: Mark Walters @ 2012-01-28 23:57 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch On Sat, 28 Jan 2012 13:33:40 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > Quoth Mark Walters on Jan 28 at 10:51 am: > > > > > > exclude_query = _notmuch_exclude_tags (query, final_query); > > > > > > > > - final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, > > > > - final_query, exclude_query); > > > > + enquire.set_weighting_scheme (Xapian::BoolWeight()); > > > > + enquire.set_query (exclude_query); > > > > + > > > > + mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ()); > > > > + > > > > + GArray *excluded_doc_ids = g_array_new (FALSE, FALSE, sizeof (unsigned int)); > > > > + > > > > + for (iterator = mset.begin (); iterator != mset.end (); iterator++) > > > > + { > > > > + unsigned int doc_id = *iterator; > > > > + g_array_append_val (excluded_doc_ids, doc_id); > > > > + } > > > > + messages->base.excluded_doc_ids = talloc (query, _notmuch_doc_id_set); > > > > + _notmuch_doc_id_set_init (query, messages->base.excluded_doc_ids, > > > > + excluded_doc_ids); > > > > > > This might be inefficient for message-only queries, since it will > > > fetch *all* excluded docids. This highlights a basic difference > > > between message and thread search: thread search can return messages > > > that don't match the original query and hence needs to know all > > > potentially excluded messages, while message search can only return > > > messages that match the original query. > > > > I now have some benchmarks (not run enough times to be hugely accurate > > so ignore minor differences). The full results are below. The summary > > is: > > > > Large-archive = 1 100 000 messages in 290 000 threads (about 10 years of > > lkml). I mark 1 000 000 deleted > > Small-archive = 70 000 messages in 35 000 threads. 10 000 marked > > deleted. > > > > Doing the initial exclude work on the big collection takes about 0.8s > > and on the small collection about 0.01s. So any query to the big > > collection takes at least 0.8s longer and this all occurs before any > > results appear. > > Interesting. Do you know where that time is spent? > > Also, it might be reasonable to assume that no more than, say, 10% of > a person's mail store is excluded, but maybe that depends on how > people use this feature. > > > I then implemented the exclude doing it once for each thread query in > > _notmuch_create_thread. Roughly this made any query 50% slower. > > That's not terrible. > > > In normal front end use even the 0.8s is not totally unusable, but it is > > totally unacceptable in the backend where a user might do something like > > > > for i in ` notmuch search --output=threads from:xxx ` ; > > do > > notmuch search --output=messages $i; > > done > > > > to list all messages in all matching threads. > > > > So I think my conclusions are: > > > > (1) message only queries must be done without the full exclude. > > (2) thread queries which only match one message should not do the full > > exclude > > (3) it would be nice to switch between the two approaches depending on > > size but I don't see how to do that without extra(!) queries > > (4) One possible might be do something that say does thirty threads with > > the by thread method and then if not finished does the full exclude. > > (5) thread-by-thread might be best for Jani's limit-match > > id:"1327692900-22926-1-git-send-email-jani@nikula.org" > > > > Obviously, anything setting an exclude flag like this will be slower > > (since it is doing more work): the question is are either of these (or a > > combination like (4) above) acceptable? > > Or only mark matched messages as excluded. > > Here's another idea (actually, a rehash of an old idea). For message > search do two queries, the original query and "<original> AND > <exclude>", and use this to keep everything in order and mark excluded > messages. For thread search, use message search results so it's easy > to both sort by unexcluded messages and include fully-excluded > threads, but compute the excluded flag (either just for unmatched > messages or for all messages) by examining each message's tags > directly (which thread_add_message already iterates over, so this is > easy and won't add any overhead). If the excluded query is fast, > which I think it will be, I think this should get the best of all > worlds and be fairly straightforward to implement (no asymmetries > between the queries used for message and thread search). It would be > easy and worth it to run the excluded query by hand on your test > corpus; I suspect it will be much faster than 0.8s because the query > already uses "Tmail", which is huge and doesn't seem to slow things > down. I have tried your suggestion (still marking all messages) and it does seem the way to go: the difference in speed is small from master is small: between 0 and 10% for most of the tests. The code seems to work and I will post it in reply to this thread. The library code is reasonable (although whether messages matching an exclude tag that has been specified in the query should be marked as excluded is unclear). The cli stuff needs thought (about what it should do rather than how to do it). I won't post the emacs stuff yet but I when I merge my various bits together I should get different colour headerlines for excluded messages and that they are initially shown collapsed. Best wishes Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 1/4] Add exclude flag 2012-01-28 23:57 ` Mark Walters @ 2012-01-29 0:04 ` Mark Walters 2012-01-29 0:04 ` [PATCH 2/4] " Mark Walters ` (3 subsequent siblings) 4 siblings, 0 replies; 176+ messages in thread From: Mark Walters @ 2012-01-29 0:04 UTC (permalink / raw) To: notmuch, amdragon Slightly refactor the exclude code to give the callers access to the exclude query itself. There should be no functional change. --- lib/query.cc | 29 +++++++++++++++++++---------- 1 files changed, 19 insertions(+), 10 deletions(-) diff --git a/lib/query.cc b/lib/query.cc index 0b36602..c25b301 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -122,12 +122,15 @@ _notmuch_messages_destructor (notmuch_mset_messages_t *messages) return 0; } -/* Return a query that does not match messages with the excluded tags - * registered with the query. Any tags that explicitly appear in - * xquery will not be excluded. */ +/* Return a query that matches messages with the excluded tags + * registered with query. Any tags that explicitly appear in xquery + * will not be excluded. The caller of this function has to combine + * the returned query appropriately.*/ static Xapian::Query _notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery) { + Xapian::Query exclude_query = Xapian::Query::MatchNothing; + for (notmuch_string_node_t *term = query->exclude_terms->head; term; term = term->next) { Xapian::TermIterator it = xquery.get_terms_begin (); @@ -137,10 +140,10 @@ _notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery) break; } if (it == end) - xquery = Xapian::Query (Xapian::Query::OP_AND_NOT, - xquery, Xapian::Query (term->string)); + exclude_query = Xapian::Query (Xapian::Query::OP_OR, + exclude_query, Xapian::Query (term->string)); } - return xquery; + return exclude_query; } notmuch_messages_t * @@ -168,7 +171,7 @@ notmuch_query_search_messages (notmuch_query_t *query) Xapian::Query mail_query (talloc_asprintf (query, "%s%s", _find_prefix ("type"), "mail")); - Xapian::Query string_query, final_query; + Xapian::Query string_query, final_query, exclude_query; Xapian::MSet mset; unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN | Xapian::QueryParser::FLAG_PHRASE | @@ -188,7 +191,10 @@ notmuch_query_search_messages (notmuch_query_t *query) mail_query, string_query); } - final_query = _notmuch_exclude_tags (query, final_query); + exclude_query = _notmuch_exclude_tags (query, final_query); + + final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, + final_query, exclude_query); enquire.set_weighting_scheme (Xapian::BoolWeight()); @@ -449,7 +455,7 @@ notmuch_query_count_messages (notmuch_query_t *query) Xapian::Query mail_query (talloc_asprintf (query, "%s%s", _find_prefix ("type"), "mail")); - Xapian::Query string_query, final_query; + Xapian::Query string_query, final_query, exclude_query; Xapian::MSet mset; unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN | Xapian::QueryParser::FLAG_PHRASE | @@ -469,7 +475,10 @@ notmuch_query_count_messages (notmuch_query_t *query) mail_query, string_query); } - final_query = _notmuch_exclude_tags (query, final_query); + exclude_query = _notmuch_exclude_tags (query, final_query); + + final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, + final_query, exclude_query); enquire.set_weighting_scheme(Xapian::BoolWeight()); enquire.set_docid_order(Xapian::Enquire::ASCENDING); -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH 2/4] Add exclude flag 2012-01-28 23:57 ` Mark Walters 2012-01-29 0:04 ` [PATCH 1/4] Add exclude flag Mark Walters @ 2012-01-29 0:04 ` Mark Walters 2012-01-29 0:04 ` [PATCH 3/4] " Mark Walters ` (2 subsequent siblings) 4 siblings, 0 replies; 176+ messages in thread From: Mark Walters @ 2012-01-29 0:04 UTC (permalink / raw) To: notmuch, amdragon Make notmuch_query_search_messages set the exclude flag Exclude flag will be added to notmuch_query_search threads later. --- lib/notmuch.h | 3 ++- lib/query.cc | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/lib/notmuch.h b/lib/notmuch.h index 7929fe7..cf0d45d 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -895,7 +895,8 @@ notmuch_message_get_filenames (notmuch_message_t *message); /* Message flags */ typedef enum _notmuch_message_flag { - NOTMUCH_MESSAGE_FLAG_MATCH + NOTMUCH_MESSAGE_FLAG_MATCH, + NOTMUCH_MESSAGE_FLAG_EXCLUDED } notmuch_message_flag_t; /* Get a value of a flag for the email corresponding to 'message'. */ diff --git a/lib/query.cc b/lib/query.cc index c25b301..8ffafe5 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -57,6 +57,12 @@ struct visible _notmuch_threads { notmuch_doc_id_set_t match_set; }; +/* we need this in the message functions so forward declare */ +static notmuch_bool_t +_notmuch_doc_id_set_init (void *ctx, + notmuch_doc_id_set_t *doc_ids, + GArray *arr); + notmuch_query_t * notmuch_query_create (notmuch_database_t *notmuch, const char *query_string) @@ -173,6 +179,7 @@ notmuch_query_search_messages (notmuch_query_t *query) "mail")); Xapian::Query string_query, final_query, exclude_query; Xapian::MSet mset; + Xapian::MSetIterator iterator; unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN | Xapian::QueryParser::FLAG_PHRASE | Xapian::QueryParser::FLAG_LOVEHATE | @@ -190,11 +197,28 @@ notmuch_query_search_messages (notmuch_query_t *query) final_query = Xapian::Query (Xapian::Query::OP_AND, mail_query, string_query); } + if (query->exclude_terms) { + exclude_query = _notmuch_exclude_tags (query, final_query); + exclude_query = Xapian::Query (Xapian::Query::OP_AND, + exclude_query, final_query); - exclude_query = _notmuch_exclude_tags (query, final_query); + enquire.set_weighting_scheme (Xapian::BoolWeight()); + enquire.set_query (exclude_query); - final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, - final_query, exclude_query); + mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ()); + + GArray *excluded_doc_ids = g_array_new (FALSE, FALSE, sizeof (unsigned int)); + + for (iterator = mset.begin (); iterator != mset.end (); iterator++) + { + unsigned int doc_id = *iterator; + g_array_append_val (excluded_doc_ids, doc_id); + } + messages->base.excluded_doc_ids = talloc (query, _notmuch_doc_id_set); + _notmuch_doc_id_set_init (query, messages->base.excluded_doc_ids, + excluded_doc_ids); + } else + messages->base.excluded_doc_ids = NULL; enquire.set_weighting_scheme (Xapian::BoolWeight()); @@ -283,6 +307,10 @@ _notmuch_mset_messages_get (notmuch_messages_t *messages) INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n"); } + if ((messages->excluded_doc_ids) && + (_notmuch_doc_id_set_contains (messages->excluded_doc_ids, doc_id))) + notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE); + return message; } -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH 3/4] Add exclude flag 2012-01-28 23:57 ` Mark Walters 2012-01-29 0:04 ` [PATCH 1/4] Add exclude flag Mark Walters 2012-01-29 0:04 ` [PATCH 2/4] " Mark Walters @ 2012-01-29 0:04 ` Mark Walters 2012-01-29 0:04 ` [PATCH 4/4] " Mark Walters 2012-01-29 10:37 ` [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters 4 siblings, 0 replies; 176+ messages in thread From: Mark Walters @ 2012-01-29 0:04 UTC (permalink / raw) To: notmuch, amdragon Add the exclude flag to notmuch_query_search_threads --- lib/notmuch-private.h | 17 +++++++++++------ lib/query.cc | 1 + lib/thread.cc | 18 +++++++++++++++--- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h index 7bf153e..56b87c6 100644 --- a/lib/notmuch-private.h +++ b/lib/notmuch-private.h @@ -211,12 +211,8 @@ _notmuch_directory_get_document_id (notmuch_directory_t *directory); /* thread.cc */ -notmuch_thread_t * -_notmuch_thread_create (void *ctx, - notmuch_database_t *notmuch, - unsigned int seed_doc_id, - notmuch_doc_id_set_t *match_set, - notmuch_sort_t sort); +/* Definition of _notmuch_thread_create moved later since now uses + * string_list_t */ /* message.cc */ @@ -401,6 +397,7 @@ typedef struct _notmuch_message_list { */ struct visible _notmuch_messages { notmuch_bool_t is_of_list_type; + notmuch_doc_id_set_t *excluded_doc_ids; notmuch_message_node_t *iterator; }; @@ -491,6 +488,14 @@ notmuch_filenames_t * _notmuch_filenames_create (const void *ctx, notmuch_string_list_t *list); +notmuch_thread_t * +_notmuch_thread_create (void *ctx, + notmuch_database_t *notmuch, + unsigned int seed_doc_id, + notmuch_doc_id_set_t *match_set, + notmuch_string_list_t *excluded_terms, + notmuch_sort_t sort); + #pragma GCC visibility pop NOTMUCH_END_DECLS diff --git a/lib/query.cc b/lib/query.cc index 8ffafe5..de95745 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -456,6 +456,7 @@ notmuch_threads_get (notmuch_threads_t *threads) threads->query->notmuch, doc_id, &threads->match_set, + threads->query->exclude_terms, threads->query->sort); } diff --git a/lib/thread.cc b/lib/thread.cc index 0435ee6..6d65d52 100644 --- a/lib/thread.cc +++ b/lib/thread.cc @@ -214,7 +214,8 @@ _thread_cleanup_author (notmuch_thread_t *thread, */ static void _thread_add_message (notmuch_thread_t *thread, - notmuch_message_t *message) + notmuch_message_t *message, + notmuch_string_list_t *exclude_terms) { notmuch_tags_t *tags; const char *tag; @@ -262,6 +263,15 @@ _thread_add_message (notmuch_thread_t *thread, notmuch_tags_move_to_next (tags)) { tag = notmuch_tags_get (tags); + /* mark excluded messages */ + for (notmuch_string_node_t *term = exclude_terms->head; term; + term = term->next) { + /* we ignore initial 'K' */ + if (strcmp(tag, (term->string + 1)) == 0) { + notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE); + break; + } + } g_hash_table_insert (thread->tags, xstrdup (tag), NULL); } } @@ -321,7 +331,8 @@ _thread_add_matched_message (notmuch_thread_t *thread, _thread_set_subject_from_message (thread, message); } - thread->matched_messages++; + if (!notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED)) + thread->matched_messages++; if (g_hash_table_lookup_extended (thread->message_hash, notmuch_message_get_message_id (message), NULL, @@ -392,6 +403,7 @@ _notmuch_thread_create (void *ctx, notmuch_database_t *notmuch, unsigned int seed_doc_id, notmuch_doc_id_set_t *match_set, + notmuch_string_list_t *exclude_terms, notmuch_sort_t sort) { notmuch_thread_t *thread; @@ -467,7 +479,7 @@ _notmuch_thread_create (void *ctx, if (doc_id == seed_doc_id) message = seed_message; - _thread_add_message (thread, message); + _thread_add_message (thread, message, exclude_terms); if ( _notmuch_doc_id_set_contains (match_set, doc_id)) { _notmuch_doc_id_set_remove (match_set, doc_id); -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH 4/4] Add exclude flag 2012-01-28 23:57 ` Mark Walters ` (2 preceding siblings ...) 2012-01-29 0:04 ` [PATCH 3/4] " Mark Walters @ 2012-01-29 0:04 ` Mark Walters 2012-01-29 10:37 ` [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters 4 siblings, 0 replies; 176+ messages in thread From: Mark Walters @ 2012-01-29 0:04 UTC (permalink / raw) To: notmuch, amdragon Make notmuch-show.c respect the EXCLUDE flag. --- notmuch-show.c | 20 +++++++++++++++++--- 1 files changed, 17 insertions(+), 3 deletions(-) diff --git a/notmuch-show.c b/notmuch-show.c index dec799c..b55d2ba 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -193,10 +193,12 @@ _get_one_line_summary (const void *ctx, notmuch_message_t *message) static void format_message_text (unused (const void *ctx), notmuch_message_t *message, int indent) { - printf ("id:%s depth:%d match:%d filename:%s\n", + /* Could changing this could break users ? */ + printf ("id:%s depth:%d match:%d excluded:%d filename:%s\n", notmuch_message_get_message_id (message), indent, notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH), + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED), notmuch_message_get_filename (message)); } @@ -212,9 +214,10 @@ format_message_json (const void *ctx, notmuch_message_t *message, unused (int in date = notmuch_message_get_date (message); relative_date = notmuch_time_relative_date (ctx, date); - printf ("\"id\": %s, \"match\": %s, \"filename\": %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [", + printf ("\"id\": %s, \"match\": %s, \"excluded\": %s, \"filename\": %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [", json_quote_str (ctx_quote, notmuch_message_get_message_id (message)), notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? "true" : "false", + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? "true" : "false", json_quote_str (ctx_quote, notmuch_message_get_filename (message)), date, relative_date); @@ -293,6 +296,7 @@ _is_from_line (const char *line) * * http://qmail.org/qmail-manual-html/man5/mbox.html */ +/* should this do something with the exclude flag? */ static void format_message_mbox (const void *ctx, notmuch_message_t *message, @@ -947,9 +951,11 @@ do_show_single (void *ctx, notmuch_messages_t *messages; notmuch_message_t *message; + /* we need to fix something in notmuch_query_count for now just + * comment this out*/ if (notmuch_query_count_messages (query) != 1) { fprintf (stderr, "Error: search term did not match precisely one message.\n"); - return 1; + /* return 1; */ } messages = notmuch_query_search_messages (query); @@ -1059,9 +1065,12 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) char *opt; const notmuch_show_format_t *format = &format_text; notmuch_show_params_t params; + const char **search_exclude_tags; + size_t search_exclude_tags_length; int mbox = 0; int format_specified = 0; int i; + unsigned int j; params.entire_thread = 0; params.raw = 0; @@ -1158,6 +1167,11 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) return 1; } + search_exclude_tags = notmuch_config_get_search_exclude_tags + (config, &search_exclude_tags_length); + for (j = 0; j < search_exclude_tags_length; j++) + notmuch_query_add_tag_exclude (query, search_exclude_tags[j]); + /* if part was requested and format was not specified, use format=raw */ if (params.part >= 0 && !format_specified) format = &format_raw; -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag 2012-01-28 23:57 ` Mark Walters ` (3 preceding siblings ...) 2012-01-29 0:04 ` [PATCH 4/4] " Mark Walters @ 2012-01-29 10:37 ` Mark Walters 2012-01-29 18:36 ` Mark Walters 4 siblings, 1 reply; 176+ messages in thread From: Mark Walters @ 2012-01-29 10:37 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch > The cli stuff needs thought (about what it should do rather than > how to do it). Ok I have thought about the cli interface. My thoughts are as follows: count/search/show should all have a --do-not-exclude option. notmuch count: messages: just output count of matching not-excluded threads: count threads matching in a non-excluded message notmuch search: default/summary should output line as in the current patch with number matching being number non-excluded matching (so some will be zero) messages/files/tags should be matching not-excluded threads: show thread ids of messages matching in a non-excluded message notmuch show: raw and part both deal with a single message so should output it regardless of exclude flags. text/json can give out the results including the exclude flag mbox only include matching not-excluded The rationale is that all formats which can return an exclude flag do; those that cannot omit the excluded results since the caller can just call without setting the excludes if they want the full results. Does that seem reasonable? Best wishes Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag 2012-01-29 10:37 ` [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters @ 2012-01-29 18:36 ` Mark Walters 2012-01-29 18:39 ` [PATCH 1/7] cli: add --do-not-exclude option to count and search Mark Walters ` (7 more replies) 0 siblings, 8 replies; 176+ messages in thread From: Mark Walters @ 2012-01-29 18:36 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch Ok I now have a patch set which might be complete enough to be worth reviewing. It is essentially complete and appears to work. Things that still need doing: updating the test suite. The series changes notmuch-show to output the exclude flag so several tests need updating. Of course, the new functionality needs some tests too. emacs/notmuch.el I think it would be nice to hide (make invisible) threads with no matching non-excluded messages (with a toggle for visibility) but that is definitely beyond my elisp skills. The first patch of the series is not really part of the series: it adds a --do-not-exclude option to tell the command not to exclude. I think this is useful anyway, but it also simplifies behaviour decisions with the excludes. For example notmuch count will only count matching non-excluded messages but notmuch count --do-not-exclude will count all matching messages excluded or not. One outstanding issue is that raised in id:"20120124025331.GZ16740@mit.edu". I will need to think about that. Best wishes Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 1/7] cli: add --do-not-exclude option to count and search. 2012-01-29 18:36 ` Mark Walters @ 2012-01-29 18:39 ` Mark Walters 2012-01-31 4:17 ` Austin Clements 2012-02-11 18:44 ` Jameson Graef Rollins 2012-01-29 18:39 ` [PATCH 2/7] lib: Rearrange the exclude code in query.cc Mark Walters ` (6 subsequent siblings) 7 siblings, 2 replies; 176+ messages in thread From: Mark Walters @ 2012-01-29 18:39 UTC (permalink / raw) To: notmuch, amdragon This option turns off the exclusion so all matching messages are returned. We do not need to add this to show as notmuch-show does not (yet) exclude. --- notmuch-count.c | 12 ++++++++---- notmuch-search.c | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/notmuch-count.c b/notmuch-count.c index 63459fb..c88975e 100644 --- a/notmuch-count.c +++ b/notmuch-count.c @@ -37,6 +37,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) int output = OUTPUT_MESSAGES; const char **search_exclude_tags; size_t search_exclude_tags_length; + notmuch_bool_t do_not_exclude = FALSE; unsigned int i; notmuch_opt_desc_t options[] = { @@ -44,6 +45,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) (notmuch_keyword_t []){ { "threads", OUTPUT_THREADS }, { "messages", OUTPUT_MESSAGES }, { 0, 0 } } }, + { NOTMUCH_OPT_BOOLEAN, &do_not_exclude, "do-not-exclude", 'd', 0 }, { 0, 0, 0, 0, 0 } }; @@ -78,10 +80,12 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) return 1; } - search_exclude_tags = notmuch_config_get_search_exclude_tags - (config, &search_exclude_tags_length); - for (i = 0; i < search_exclude_tags_length; i++) - notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); + if (!do_not_exclude) { + search_exclude_tags = notmuch_config_get_search_exclude_tags + (config, &search_exclude_tags_length); + for (i = 0; i < search_exclude_tags_length; i++) + notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); + } switch (output) { case OUTPUT_MESSAGES: diff --git a/notmuch-search.c b/notmuch-search.c index d504051..084dd05 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -425,6 +425,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) int limit = -1; /* unlimited */ const char **search_exclude_tags; size_t search_exclude_tags_length; + notmuch_bool_t do_not_exclude = FALSE; unsigned int i; enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT } @@ -446,6 +447,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) { "files", OUTPUT_FILES }, { "tags", OUTPUT_TAGS }, { 0, 0 } } }, + { NOTMUCH_OPT_BOOLEAN, &do_not_exclude, "do-not-exclude", 'd', 0 }, { NOTMUCH_OPT_INT, &offset, "offset", 'O', 0 }, { NOTMUCH_OPT_INT, &limit, "limit", 'L', 0 }, { 0, 0, 0, 0, 0 } @@ -493,10 +495,12 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) notmuch_query_set_sort (query, sort); - search_exclude_tags = notmuch_config_get_search_exclude_tags - (config, &search_exclude_tags_length); - for (i = 0; i < search_exclude_tags_length; i++) - notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); + if (!do_not_exclude) { + search_exclude_tags = notmuch_config_get_search_exclude_tags + (config, &search_exclude_tags_length); + for (i = 0; i < search_exclude_tags_length; i++) + notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); + } switch (output) { default: -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH 1/7] cli: add --do-not-exclude option to count and search. 2012-01-29 18:39 ` [PATCH 1/7] cli: add --do-not-exclude option to count and search Mark Walters @ 2012-01-31 4:17 ` Austin Clements 2012-01-31 11:40 ` Mark Walters 2012-02-11 18:44 ` Jameson Graef Rollins 1 sibling, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-31 4:17 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch Quoth Mark Walters on Jan 29 at 6:39 pm: > This option turns off the exclusion so all matching messages are > returned. We do not need to add this to show as notmuch-show does not > (yet) exclude. > --- > notmuch-count.c | 12 ++++++++---- > notmuch-search.c | 12 ++++++++---- > 2 files changed, 16 insertions(+), 8 deletions(-) > > diff --git a/notmuch-count.c b/notmuch-count.c > index 63459fb..c88975e 100644 > --- a/notmuch-count.c > +++ b/notmuch-count.c > @@ -37,6 +37,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) > int output = OUTPUT_MESSAGES; > const char **search_exclude_tags; > size_t search_exclude_tags_length; > + notmuch_bool_t do_not_exclude = FALSE; > unsigned int i; > > notmuch_opt_desc_t options[] = { > @@ -44,6 +45,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) > (notmuch_keyword_t []){ { "threads", OUTPUT_THREADS }, > { "messages", OUTPUT_MESSAGES }, > { 0, 0 } } }, > + { NOTMUCH_OPT_BOOLEAN, &do_not_exclude, "do-not-exclude", 'd', 0 }, Maybe just "no-exclude"? "do-not-exclude" seems needlessly verbose. Also, you have an extra space after the first comma. > { 0, 0, 0, 0, 0 } > }; > > @@ -78,10 +80,12 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) > return 1; > } > > - search_exclude_tags = notmuch_config_get_search_exclude_tags > - (config, &search_exclude_tags_length); > - for (i = 0; i < search_exclude_tags_length; i++) > - notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); > + if (!do_not_exclude) { You could move search_exclude_tags and search_exclude_tags_length in here now that it's a block (but you don't have to). > + search_exclude_tags = notmuch_config_get_search_exclude_tags > + (config, &search_exclude_tags_length); > + for (i = 0; i < search_exclude_tags_length; i++) > + notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); > + } > > switch (output) { > case OUTPUT_MESSAGES: > diff --git a/notmuch-search.c b/notmuch-search.c > index d504051..084dd05 100644 > --- a/notmuch-search.c > +++ b/notmuch-search.c > @@ -425,6 +425,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) > int limit = -1; /* unlimited */ > const char **search_exclude_tags; > size_t search_exclude_tags_length; > + notmuch_bool_t do_not_exclude = FALSE; > unsigned int i; > > enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT } > @@ -446,6 +447,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) > { "files", OUTPUT_FILES }, > { "tags", OUTPUT_TAGS }, > { 0, 0 } } }, > + { NOTMUCH_OPT_BOOLEAN, &do_not_exclude, "do-not-exclude", 'd', 0 }, Same. > { NOTMUCH_OPT_INT, &offset, "offset", 'O', 0 }, > { NOTMUCH_OPT_INT, &limit, "limit", 'L', 0 }, > { 0, 0, 0, 0, 0 } > @@ -493,10 +495,12 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) > > notmuch_query_set_sort (query, sort); > > - search_exclude_tags = notmuch_config_get_search_exclude_tags > - (config, &search_exclude_tags_length); > - for (i = 0; i < search_exclude_tags_length; i++) > - notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); > + if (!do_not_exclude) { > + search_exclude_tags = notmuch_config_get_search_exclude_tags > + (config, &search_exclude_tags_length); > + for (i = 0; i < search_exclude_tags_length; i++) > + notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); > + } > > switch (output) { > default: ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 1/7] cli: add --do-not-exclude option to count and search. 2012-01-31 4:17 ` Austin Clements @ 2012-01-31 11:40 ` Mark Walters 2012-01-31 16:18 ` Austin Clements 2012-01-31 16:31 ` Jameson Graef Rollins 0 siblings, 2 replies; 176+ messages in thread From: Mark Walters @ 2012-01-31 11:40 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch Thanks for the review. Almost all of it (for all all the patches) I agree with and will just fix but I do have a couple of queries. On Mon, 30 Jan 2012 23:17:32 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > Quoth Mark Walters on Jan 29 at 6:39 pm: > > This option turns off the exclusion so all matching messages are > > returned. We do not need to add this to show as notmuch-show does not > > (yet) exclude. > > --- > > notmuch-count.c | 12 ++++++++---- > > notmuch-search.c | 12 ++++++++---- > > 2 files changed, 16 insertions(+), 8 deletions(-) > > > > diff --git a/notmuch-count.c b/notmuch-count.c > > index 63459fb..c88975e 100644 > > --- a/notmuch-count.c > > +++ b/notmuch-count.c > > @@ -37,6 +37,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) > > int output = OUTPUT_MESSAGES; > > const char **search_exclude_tags; > > size_t search_exclude_tags_length; > > + notmuch_bool_t do_not_exclude = FALSE; > > unsigned int i; > > > > notmuch_opt_desc_t options[] = { > > @@ -44,6 +45,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) > > (notmuch_keyword_t []){ { "threads", OUTPUT_THREADS }, > > { "messages", OUTPUT_MESSAGES }, > > { 0, 0 } } }, > > + { NOTMUCH_OPT_BOOLEAN, &do_not_exclude, "do-not-exclude", 'd', 0 }, > > Maybe just "no-exclude"? "do-not-exclude" seems needlessly verbose. The reason I went for verbose do-not-exclude was to try and avoid the double negative ambiguity: does no-exclude mean do-not-exclude or do-note-return-excluded-messages. Possibly I am worrying needlessly, and obviously I am quite happy to change. > Also, you have an extra space after the first comma. Will fix. > > > { 0, 0, 0, 0, 0 } > > }; > > > > @@ -78,10 +80,12 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) > > return 1; > > } > > > > - search_exclude_tags = notmuch_config_get_search_exclude_tags > > - (config, &search_exclude_tags_length); > > - for (i = 0; i < search_exclude_tags_length; i++) > > - notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); > > + if (!do_not_exclude) { > > You could move search_exclude_tags and search_exclude_tags_length in > here now that it's a block (but you don't have to). Will fix > > + search_exclude_tags = notmuch_config_get_search_exclude_tags > > + (config, &search_exclude_tags_length); > > + for (i = 0; i < search_exclude_tags_length; i++) > > + notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); > > + } > > > > switch (output) { > > case OUTPUT_MESSAGES: > > diff --git a/notmuch-search.c b/notmuch-search.c > > index d504051..084dd05 100644 > > --- a/notmuch-search.c > > +++ b/notmuch-search.c > > @@ -425,6 +425,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) > > int limit = -1; /* unlimited */ > > const char **search_exclude_tags; > > size_t search_exclude_tags_length; > > + notmuch_bool_t do_not_exclude = FALSE; > > unsigned int i; > > > > enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT } > > @@ -446,6 +447,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) > > { "files", OUTPUT_FILES }, > > { "tags", OUTPUT_TAGS }, > > { 0, 0 } } }, > > + { NOTMUCH_OPT_BOOLEAN, &do_not_exclude, "do-not-exclude", 'd', 0 }, > > Same. Will fix > > > { NOTMUCH_OPT_INT, &offset, "offset", 'O', 0 }, > > { NOTMUCH_OPT_INT, &limit, "limit", 'L', 0 }, > > { 0, 0, 0, 0, 0 } > > @@ -493,10 +495,12 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) > > > > notmuch_query_set_sort (query, sort); > > > > - search_exclude_tags = notmuch_config_get_search_exclude_tags > > - (config, &search_exclude_tags_length); > > - for (i = 0; i < search_exclude_tags_length; i++) > > - notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); > > + if (!do_not_exclude) { > > + search_exclude_tags = notmuch_config_get_search_exclude_tags > > + (config, &search_exclude_tags_length); > > + for (i = 0; i < search_exclude_tags_length; i++) > > + notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); > > + } > > > > switch (output) { > > default: Thanks Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 1/7] cli: add --do-not-exclude option to count and search. 2012-01-31 11:40 ` Mark Walters @ 2012-01-31 16:18 ` Austin Clements 2012-01-31 16:31 ` Jameson Graef Rollins 1 sibling, 0 replies; 176+ messages in thread From: Austin Clements @ 2012-01-31 16:18 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch Quoth Mark Walters on Jan 31 at 11:40 am: > > Thanks for the review. Almost all of it (for all all the patches) I > agree with and will just fix but I do have a couple of queries. > > On Mon, 30 Jan 2012 23:17:32 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > Quoth Mark Walters on Jan 29 at 6:39 pm: > > > This option turns off the exclusion so all matching messages are > > > returned. We do not need to add this to show as notmuch-show does not > > > (yet) exclude. > > > --- > > > notmuch-count.c | 12 ++++++++---- > > > notmuch-search.c | 12 ++++++++---- > > > 2 files changed, 16 insertions(+), 8 deletions(-) > > > > > > diff --git a/notmuch-count.c b/notmuch-count.c > > > index 63459fb..c88975e 100644 > > > --- a/notmuch-count.c > > > +++ b/notmuch-count.c > > > @@ -37,6 +37,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) > > > int output = OUTPUT_MESSAGES; > > > const char **search_exclude_tags; > > > size_t search_exclude_tags_length; > > > + notmuch_bool_t do_not_exclude = FALSE; > > > unsigned int i; > > > > > > notmuch_opt_desc_t options[] = { > > > @@ -44,6 +45,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) > > > (notmuch_keyword_t []){ { "threads", OUTPUT_THREADS }, > > > { "messages", OUTPUT_MESSAGES }, > > > { 0, 0 } } }, > > > + { NOTMUCH_OPT_BOOLEAN, &do_not_exclude, "do-not-exclude", 'd', 0 }, > > > > Maybe just "no-exclude"? "do-not-exclude" seems needlessly verbose. > > The reason I went for verbose do-not-exclude was to try and avoid the > double negative ambiguity: does no-exclude mean do-not-exclude or > do-note-return-excluded-messages. Possibly I am worrying needlessly, and > obviously I am quite happy to change. Oh. Hmm. --no-exclusions? --unexcluded? --all? --include-excludes? Maybe --do-not-exclude is best. ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 1/7] cli: add --do-not-exclude option to count and search. 2012-01-31 11:40 ` Mark Walters 2012-01-31 16:18 ` Austin Clements @ 2012-01-31 16:31 ` Jameson Graef Rollins 1 sibling, 0 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-31 16:31 UTC (permalink / raw) To: Mark Walters, Austin Clements; +Cc: notmuch [-- Attachment #1: Type: text/plain, Size: 534 bytes --] On Tue, 31 Jan 2012 11:40:00 +0000, Mark Walters <markwalters1009@gmail.com> wrote: > The reason I went for verbose do-not-exclude was to try and avoid the > double negative ambiguity: does no-exclude mean do-not-exclude or > do-note-return-excluded-messages. Possibly I am worrying needlessly, and > obviously I am quite happy to change. I also think "no-exclude" or "no-excludes" would be more appropriate. It's not a command that people will likely use that frequently, so as long as it's well documented it will be fine. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 1/7] cli: add --do-not-exclude option to count and search. 2012-01-29 18:39 ` [PATCH 1/7] cli: add --do-not-exclude option to count and search Mark Walters 2012-01-31 4:17 ` Austin Clements @ 2012-02-11 18:44 ` Jameson Graef Rollins 2012-02-11 18:50 ` Austin Clements 1 sibling, 1 reply; 176+ messages in thread From: Jameson Graef Rollins @ 2012-02-11 18:44 UTC (permalink / raw) To: Mark Walters, notmuch, amdragon [-- Attachment #1: Type: text/plain, Size: 678 bytes --] On Sun, 29 Jan 2012 18:39:48 +0000, Mark Walters <markwalters1009@gmail.com> wrote: > This option turns off the exclusion so all matching messages are > returned. We do not need to add this to show as notmuch-show does not > (yet) exclude. Hi. What is the status of this patch? It looks like we're waiting on a new version. I found a bug in the emacs interface that actually requires the --no-excludes search option to fix. It we can get another version of the patch I'll work my bug fix on top of it. I'm tempted to ask for the next version in a new thread, since this thread has gotten obscenely long and includes what are essentially multiple separate threads. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 1/7] cli: add --do-not-exclude option to count and search. 2012-02-11 18:44 ` Jameson Graef Rollins @ 2012-02-11 18:50 ` Austin Clements 2012-02-11 19:00 ` Jameson Graef Rollins 0 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-02-11 18:50 UTC (permalink / raw) To: Jameson Graef Rollins; +Cc: notmuch Quoth Jameson Graef Rollins on Feb 11 at 10:44 am: > On Sun, 29 Jan 2012 18:39:48 +0000, Mark Walters <markwalters1009@gmail.com> wrote: > > This option turns off the exclusion so all matching messages are > > returned. We do not need to add this to show as notmuch-show does not > > (yet) exclude. > > Hi. What is the status of this patch? It looks like we're waiting on a > new version. I found a bug in the emacs interface that actually > requires the --no-excludes search option to fix. It we can get another > version of the patch I'll work my bug fix on top of it. > > I'm tempted to ask for the next version in a new thread, since this > thread has gotten obscenely long and includes what are essentially > multiple separate threads. It has moved to a new thread: id:"874nv9rv79.fsf@qmul.ac.uk". It's waiting for a rebase on Jani's command line parsing change and probably needs some more review, too. ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 1/7] cli: add --do-not-exclude option to count and search. 2012-02-11 18:50 ` Austin Clements @ 2012-02-11 19:00 ` Jameson Graef Rollins 0 siblings, 0 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-02-11 19:00 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch [-- Attachment #1: Type: text/plain, Size: 290 bytes --] On Sat, 11 Feb 2012 13:50:23 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > It has moved to a new thread: id:"874nv9rv79.fsf@qmul.ac.uk". It's > waiting for a rebase on Jani's command line parsing change and > probably needs some more review, too. So it has! Thanks, Austin. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 2/7] lib: Rearrange the exclude code in query.cc 2012-01-29 18:36 ` Mark Walters 2012-01-29 18:39 ` [PATCH 1/7] cli: add --do-not-exclude option to count and search Mark Walters @ 2012-01-29 18:39 ` Mark Walters 2012-01-29 18:39 ` [PATCH 3/7] lib: Make notmuch_query_search_messages set the exclude flag Mark Walters ` (5 subsequent siblings) 7 siblings, 0 replies; 176+ messages in thread From: Mark Walters @ 2012-01-29 18:39 UTC (permalink / raw) To: notmuch, amdragon Slightly refactor the exclude code to give the callers access to the exclude query itself. There should be no functional change. --- lib/query.cc | 29 +++++++++++++++++++---------- 1 files changed, 19 insertions(+), 10 deletions(-) diff --git a/lib/query.cc b/lib/query.cc index 0b36602..c25b301 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -122,12 +122,15 @@ _notmuch_messages_destructor (notmuch_mset_messages_t *messages) return 0; } -/* Return a query that does not match messages with the excluded tags - * registered with the query. Any tags that explicitly appear in - * xquery will not be excluded. */ +/* Return a query that matches messages with the excluded tags + * registered with query. Any tags that explicitly appear in xquery + * will not be excluded. The caller of this function has to combine + * the returned query appropriately.*/ static Xapian::Query _notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery) { + Xapian::Query exclude_query = Xapian::Query::MatchNothing; + for (notmuch_string_node_t *term = query->exclude_terms->head; term; term = term->next) { Xapian::TermIterator it = xquery.get_terms_begin (); @@ -137,10 +140,10 @@ _notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery) break; } if (it == end) - xquery = Xapian::Query (Xapian::Query::OP_AND_NOT, - xquery, Xapian::Query (term->string)); + exclude_query = Xapian::Query (Xapian::Query::OP_OR, + exclude_query, Xapian::Query (term->string)); } - return xquery; + return exclude_query; } notmuch_messages_t * @@ -168,7 +171,7 @@ notmuch_query_search_messages (notmuch_query_t *query) Xapian::Query mail_query (talloc_asprintf (query, "%s%s", _find_prefix ("type"), "mail")); - Xapian::Query string_query, final_query; + Xapian::Query string_query, final_query, exclude_query; Xapian::MSet mset; unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN | Xapian::QueryParser::FLAG_PHRASE | @@ -188,7 +191,10 @@ notmuch_query_search_messages (notmuch_query_t *query) mail_query, string_query); } - final_query = _notmuch_exclude_tags (query, final_query); + exclude_query = _notmuch_exclude_tags (query, final_query); + + final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, + final_query, exclude_query); enquire.set_weighting_scheme (Xapian::BoolWeight()); @@ -449,7 +455,7 @@ notmuch_query_count_messages (notmuch_query_t *query) Xapian::Query mail_query (talloc_asprintf (query, "%s%s", _find_prefix ("type"), "mail")); - Xapian::Query string_query, final_query; + Xapian::Query string_query, final_query, exclude_query; Xapian::MSet mset; unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN | Xapian::QueryParser::FLAG_PHRASE | @@ -469,7 +475,10 @@ notmuch_query_count_messages (notmuch_query_t *query) mail_query, string_query); } - final_query = _notmuch_exclude_tags (query, final_query); + exclude_query = _notmuch_exclude_tags (query, final_query); + + final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, + final_query, exclude_query); enquire.set_weighting_scheme(Xapian::BoolWeight()); enquire.set_docid_order(Xapian::Enquire::ASCENDING); -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH 3/7] lib: Make notmuch_query_search_messages set the exclude flag 2012-01-29 18:36 ` Mark Walters 2012-01-29 18:39 ` [PATCH 1/7] cli: add --do-not-exclude option to count and search Mark Walters 2012-01-29 18:39 ` [PATCH 2/7] lib: Rearrange the exclude code in query.cc Mark Walters @ 2012-01-29 18:39 ` Mark Walters 2012-01-31 4:43 ` Austin Clements 2012-01-29 18:39 ` [PATCH 4/7] lib: Add the exclude flag to notmuch_query_search_threads Mark Walters ` (4 subsequent siblings) 7 siblings, 1 reply; 176+ messages in thread From: Mark Walters @ 2012-01-29 18:39 UTC (permalink / raw) To: notmuch, amdragon Add a flag NOTMUCH_MESSAGE_FLAG_EXCLUDED which is set by notmuch_query_search_messages for excluded messages. Also add an option omit_excluded_messages to the search that we do not want the excludes at all. This exclude flag will be added to notmuch_query_search threads in the next patch. --- lib/notmuch-private.h | 1 + lib/notmuch.h | 8 ++++++- lib/query.cc | 52 +++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h index 7bf153e..e791bb0 100644 --- a/lib/notmuch-private.h +++ b/lib/notmuch-private.h @@ -401,6 +401,7 @@ typedef struct _notmuch_message_list { */ struct visible _notmuch_messages { notmuch_bool_t is_of_list_type; + notmuch_doc_id_set_t *excluded_doc_ids; notmuch_message_node_t *iterator; }; diff --git a/lib/notmuch.h b/lib/notmuch.h index 7929fe7..740d005 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -449,6 +449,11 @@ typedef enum { const char * notmuch_query_get_query_string (notmuch_query_t *query); +/* specify whether to results should omit the excluded results rather + * than just marking them excluded */ +void +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit); + /* Specify the sorting desired for this query. */ void notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort); @@ -895,7 +900,8 @@ notmuch_message_get_filenames (notmuch_message_t *message); /* Message flags */ typedef enum _notmuch_message_flag { - NOTMUCH_MESSAGE_FLAG_MATCH + NOTMUCH_MESSAGE_FLAG_MATCH, + NOTMUCH_MESSAGE_FLAG_EXCLUDED } notmuch_message_flag_t; /* Get a value of a flag for the email corresponding to 'message'. */ diff --git a/lib/query.cc b/lib/query.cc index c25b301..7d165d2 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -28,6 +28,7 @@ struct _notmuch_query { const char *query_string; notmuch_sort_t sort; notmuch_string_list_t *exclude_terms; + notmuch_bool_t omit_excluded_messages; }; typedef struct _notmuch_mset_messages { @@ -57,6 +58,12 @@ struct visible _notmuch_threads { notmuch_doc_id_set_t match_set; }; +/* we need this in the message functions so forward declare */ +static notmuch_bool_t +_notmuch_doc_id_set_init (void *ctx, + notmuch_doc_id_set_t *doc_ids, + GArray *arr); + notmuch_query_t * notmuch_query_create (notmuch_database_t *notmuch, const char *query_string) @@ -79,6 +86,8 @@ notmuch_query_create (notmuch_database_t *notmuch, query->exclude_terms = _notmuch_string_list_create (query); + query->omit_excluded_messages = FALSE; + return query; } @@ -89,6 +98,12 @@ notmuch_query_get_query_string (notmuch_query_t *query) } void +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit) +{ + query->omit_excluded_messages = omit; +} + +void notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort) { query->sort = sort; @@ -173,6 +188,7 @@ notmuch_query_search_messages (notmuch_query_t *query) "mail")); Xapian::Query string_query, final_query, exclude_query; Xapian::MSet mset; + Xapian::MSetIterator iterator; unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN | Xapian::QueryParser::FLAG_PHRASE | Xapian::QueryParser::FLAG_LOVEHATE | @@ -190,11 +206,35 @@ notmuch_query_search_messages (notmuch_query_t *query) final_query = Xapian::Query (Xapian::Query::OP_AND, mail_query, string_query); } + messages->base.excluded_doc_ids = NULL; + + if (query->exclude_terms) { + exclude_query = _notmuch_exclude_tags (query, final_query); + exclude_query = Xapian::Query (Xapian::Query::OP_AND, + exclude_query, final_query); + + if (query->omit_excluded_messages) + final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, + final_query, exclude_query); + else { + enquire.set_weighting_scheme (Xapian::BoolWeight()); + enquire.set_query (exclude_query); + + mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ()); + + GArray *excluded_doc_ids = g_array_new (FALSE, FALSE, sizeof (unsigned int)); + + for (iterator = mset.begin (); iterator != mset.end (); iterator++) + { + unsigned int doc_id = *iterator; + g_array_append_val (excluded_doc_ids, doc_id); + } + messages->base.excluded_doc_ids = talloc (query, _notmuch_doc_id_set); + _notmuch_doc_id_set_init (query, messages->base.excluded_doc_ids, + excluded_doc_ids); + } + } - exclude_query = _notmuch_exclude_tags (query, final_query); - - final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, - final_query, exclude_query); enquire.set_weighting_scheme (Xapian::BoolWeight()); @@ -283,6 +323,10 @@ _notmuch_mset_messages_get (notmuch_messages_t *messages) INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n"); } + if ((messages->excluded_doc_ids) && + (_notmuch_doc_id_set_contains (messages->excluded_doc_ids, doc_id))) + notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE); + return message; } -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH 3/7] lib: Make notmuch_query_search_messages set the exclude flag 2012-01-29 18:39 ` [PATCH 3/7] lib: Make notmuch_query_search_messages set the exclude flag Mark Walters @ 2012-01-31 4:43 ` Austin Clements 2012-01-31 11:45 ` Mark Walters 0 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-31 4:43 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch Quoth Mark Walters on Jan 29 at 6:39 pm: > Add a flag NOTMUCH_MESSAGE_FLAG_EXCLUDED which is set by > notmuch_query_search_messages for excluded messages. Also add an > option omit_excluded_messages to the search that we do not want the > excludes at all. > > This exclude flag will be added to notmuch_query_search threads in the > next patch. > --- > lib/notmuch-private.h | 1 + > lib/notmuch.h | 8 ++++++- > lib/query.cc | 52 +++++++++++++++++++++++++++++++++++++++++++++--- > 3 files changed, 56 insertions(+), 5 deletions(-) > > diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h > index 7bf153e..e791bb0 100644 > --- a/lib/notmuch-private.h > +++ b/lib/notmuch-private.h > @@ -401,6 +401,7 @@ typedef struct _notmuch_message_list { > */ > struct visible _notmuch_messages { > notmuch_bool_t is_of_list_type; > + notmuch_doc_id_set_t *excluded_doc_ids; I might be following the diff wrong, but shouldn't this be a field of notmuch_mset_messages_t? (Then it also doesn't have to be a pointer, which is really how notmuch_doc_id_set_t was designed to be used.) > notmuch_message_node_t *iterator; > }; > > diff --git a/lib/notmuch.h b/lib/notmuch.h > index 7929fe7..740d005 100644 > --- a/lib/notmuch.h > +++ b/lib/notmuch.h > @@ -449,6 +449,11 @@ typedef enum { > const char * > notmuch_query_get_query_string (notmuch_query_t *query); > > +/* specify whether to results should omit the excluded results rather > + * than just marking them excluded */ > +void > +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit); > + I don't think we should add this API. The library behavior will not change for library users that don't use excludes and library users that do use excludes should by aware of the excluded flag and do the appropriate thing. I can see why this is handy in some cases, but I don't think it provides enough utility to warrant becoming part of the permanent and minimal library interface. > /* Specify the sorting desired for this query. */ > void > notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort); > @@ -895,7 +900,8 @@ notmuch_message_get_filenames (notmuch_message_t *message); > > /* Message flags */ > typedef enum _notmuch_message_flag { > - NOTMUCH_MESSAGE_FLAG_MATCH > + NOTMUCH_MESSAGE_FLAG_MATCH, > + NOTMUCH_MESSAGE_FLAG_EXCLUDED > } notmuch_message_flag_t; > > /* Get a value of a flag for the email corresponding to 'message'. */ > diff --git a/lib/query.cc b/lib/query.cc > index c25b301..7d165d2 100644 > --- a/lib/query.cc > +++ b/lib/query.cc > @@ -28,6 +28,7 @@ struct _notmuch_query { > const char *query_string; > notmuch_sort_t sort; > notmuch_string_list_t *exclude_terms; > + notmuch_bool_t omit_excluded_messages; > }; > > typedef struct _notmuch_mset_messages { > @@ -57,6 +58,12 @@ struct visible _notmuch_threads { > notmuch_doc_id_set_t match_set; > }; > > +/* we need this in the message functions so forward declare */ Comments should start with a capital letter and end with a period. (The code isn't completely consistent about this, but it is something we're codifying in the upcoming style guide.) > +static notmuch_bool_t > +_notmuch_doc_id_set_init (void *ctx, > + notmuch_doc_id_set_t *doc_ids, > + GArray *arr); > + > notmuch_query_t * > notmuch_query_create (notmuch_database_t *notmuch, > const char *query_string) > @@ -79,6 +86,8 @@ notmuch_query_create (notmuch_database_t *notmuch, > > query->exclude_terms = _notmuch_string_list_create (query); > > + query->omit_excluded_messages = FALSE; > + > return query; > } > > @@ -89,6 +98,12 @@ notmuch_query_get_query_string (notmuch_query_t *query) > } > > void > +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit) > +{ > + query->omit_excluded_messages = omit; > +} > + > +void > notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort) > { > query->sort = sort; > @@ -173,6 +188,7 @@ notmuch_query_search_messages (notmuch_query_t *query) > "mail")); > Xapian::Query string_query, final_query, exclude_query; > Xapian::MSet mset; > + Xapian::MSetIterator iterator; > unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN | > Xapian::QueryParser::FLAG_PHRASE | > Xapian::QueryParser::FLAG_LOVEHATE | > @@ -190,11 +206,35 @@ notmuch_query_search_messages (notmuch_query_t *query) > final_query = Xapian::Query (Xapian::Query::OP_AND, > mail_query, string_query); > } > + messages->base.excluded_doc_ids = NULL; > + > + if (query->exclude_terms) { > + exclude_query = _notmuch_exclude_tags (query, final_query); > + exclude_query = Xapian::Query (Xapian::Query::OP_AND, > + exclude_query, final_query); > + > + if (query->omit_excluded_messages) > + final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, > + final_query, exclude_query); > + else { > + enquire.set_weighting_scheme (Xapian::BoolWeight()); > + enquire.set_query (exclude_query); > + > + mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ()); > + > + GArray *excluded_doc_ids = g_array_new (FALSE, FALSE, sizeof (unsigned int)); > + > + for (iterator = mset.begin (); iterator != mset.end (); iterator++) > + { No newline before the brace. > + unsigned int doc_id = *iterator; > + g_array_append_val (excluded_doc_ids, doc_id); > + } > + messages->base.excluded_doc_ids = talloc (query, _notmuch_doc_id_set); > + _notmuch_doc_id_set_init (query, messages->base.excluded_doc_ids, > + excluded_doc_ids); Don't forget to g_array_unref excluded_doc_ids. > + } > + } > > - exclude_query = _notmuch_exclude_tags (query, final_query); > - > - final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, > - final_query, exclude_query); > > enquire.set_weighting_scheme (Xapian::BoolWeight()); > > @@ -283,6 +323,10 @@ _notmuch_mset_messages_get (notmuch_messages_t *messages) > INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n"); > } > > + if ((messages->excluded_doc_ids) && > + (_notmuch_doc_id_set_contains (messages->excluded_doc_ids, doc_id))) No need for so many parens (just a nit). > + notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE); > + > return message; > } > ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/7] lib: Make notmuch_query_search_messages set the exclude flag 2012-01-31 4:43 ` Austin Clements @ 2012-01-31 11:45 ` Mark Walters 2012-01-31 16:25 ` Austin Clements 0 siblings, 1 reply; 176+ messages in thread From: Mark Walters @ 2012-01-31 11:45 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch On Mon, 30 Jan 2012 23:43:52 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > Quoth Mark Walters on Jan 29 at 6:39 pm: > > Add a flag NOTMUCH_MESSAGE_FLAG_EXCLUDED which is set by > > notmuch_query_search_messages for excluded messages. Also add an > > option omit_excluded_messages to the search that we do not want the > > excludes at all. > > > > This exclude flag will be added to notmuch_query_search threads in the > > next patch. > > --- > > lib/notmuch-private.h | 1 + > > lib/notmuch.h | 8 ++++++- > > lib/query.cc | 52 +++++++++++++++++++++++++++++++++++++++++++++--- > > 3 files changed, 56 insertions(+), 5 deletions(-) > > > > diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h > > index 7bf153e..e791bb0 100644 > > --- a/lib/notmuch-private.h > > +++ b/lib/notmuch-private.h > > @@ -401,6 +401,7 @@ typedef struct _notmuch_message_list { > > */ > > struct visible _notmuch_messages { > > notmuch_bool_t is_of_list_type; > > + notmuch_doc_id_set_t *excluded_doc_ids; > > I might be following the diff wrong, but shouldn't this be a field of > notmuch_mset_messages_t? (Then it also doesn't have to be a pointer, > which is really how notmuch_doc_id_set_t was designed to be used.) I will need to think about that. > > notmuch_message_node_t *iterator; > > }; > > > > diff --git a/lib/notmuch.h b/lib/notmuch.h > > index 7929fe7..740d005 100644 > > --- a/lib/notmuch.h > > +++ b/lib/notmuch.h > > @@ -449,6 +449,11 @@ typedef enum { > > const char * > > notmuch_query_get_query_string (notmuch_query_t *query); > > > > +/* specify whether to results should omit the excluded results rather > > + * than just marking them excluded */ > > +void > > +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit); > > + > > I don't think we should add this API. The library behavior will not > change for library users that don't use excludes and library users > that do use excludes should by aware of the excluded flag and do the > appropriate thing. > > I can see why this is handy in some cases, but I don't think it > provides enough utility to warrant becoming part of the permanent and > minimal library interface. This is really a performance improvement: suppose that there are lots of threads that only match in excluded messages. Then without this flag we will spend lots of time constructing the thread only for it to be ignored. (In contrived situations this could be arbitrarily slower.) Note the benchmarks were against master with the exclude code switched off so that I was comparing the creation of the same threads. Sorry if I didn't make that clear. > > /* Specify the sorting desired for this query. */ > > void > > notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort); > > @@ -895,7 +900,8 @@ notmuch_message_get_filenames (notmuch_message_t *message); > > > > /* Message flags */ > > typedef enum _notmuch_message_flag { > > - NOTMUCH_MESSAGE_FLAG_MATCH > > + NOTMUCH_MESSAGE_FLAG_MATCH, > > + NOTMUCH_MESSAGE_FLAG_EXCLUDED > > } notmuch_message_flag_t; > > > > /* Get a value of a flag for the email corresponding to 'message'. */ > > diff --git a/lib/query.cc b/lib/query.cc > > index c25b301..7d165d2 100644 > > --- a/lib/query.cc > > +++ b/lib/query.cc > > @@ -28,6 +28,7 @@ struct _notmuch_query { > > const char *query_string; > > notmuch_sort_t sort; > > notmuch_string_list_t *exclude_terms; > > + notmuch_bool_t omit_excluded_messages; > > }; > > > > typedef struct _notmuch_mset_messages { > > @@ -57,6 +58,12 @@ struct visible _notmuch_threads { > > notmuch_doc_id_set_t match_set; > > }; > > > > +/* we need this in the message functions so forward declare */ > > Comments should start with a capital letter and end with a period. > (The code isn't completely consistent about this, but it is something > we're codifying in the upcoming style guide.) Will fix > > +static notmuch_bool_t > > +_notmuch_doc_id_set_init (void *ctx, > > + notmuch_doc_id_set_t *doc_ids, > > + GArray *arr); > > + > > notmuch_query_t * > > notmuch_query_create (notmuch_database_t *notmuch, > > const char *query_string) > > @@ -79,6 +86,8 @@ notmuch_query_create (notmuch_database_t *notmuch, > > > > query->exclude_terms = _notmuch_string_list_create (query); > > > > + query->omit_excluded_messages = FALSE; > > + > > return query; > > } > > > > @@ -89,6 +98,12 @@ notmuch_query_get_query_string (notmuch_query_t *query) > > } > > > > void > > +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit) > > +{ > > + query->omit_excluded_messages = omit; > > +} > > + > > +void > > notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort) > > { > > query->sort = sort; > > @@ -173,6 +188,7 @@ notmuch_query_search_messages (notmuch_query_t *query) > > "mail")); > > Xapian::Query string_query, final_query, exclude_query; > > Xapian::MSet mset; > > + Xapian::MSetIterator iterator; > > unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN | > > Xapian::QueryParser::FLAG_PHRASE | > > Xapian::QueryParser::FLAG_LOVEHATE | > > @@ -190,11 +206,35 @@ notmuch_query_search_messages (notmuch_query_t *query) > > final_query = Xapian::Query (Xapian::Query::OP_AND, > > mail_query, string_query); > > } > > + messages->base.excluded_doc_ids = NULL; > > + > > + if (query->exclude_terms) { > > + exclude_query = _notmuch_exclude_tags (query, final_query); > > + exclude_query = Xapian::Query (Xapian::Query::OP_AND, > > + exclude_query, final_query); > > + > > + if (query->omit_excluded_messages) > > + final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, > > + final_query, exclude_query); > > + else { > > + enquire.set_weighting_scheme (Xapian::BoolWeight()); > > + enquire.set_query (exclude_query); > > + > > + mset = enquire.get_mset (0, notmuch->xapian_db->get_doccount ()); > > + > > + GArray *excluded_doc_ids = g_array_new (FALSE, FALSE, sizeof (unsigned int)); > > + > > + for (iterator = mset.begin (); iterator != mset.end (); iterator++) > > + { > > No newline before the brace. Will fix. > > > + unsigned int doc_id = *iterator; > > + g_array_append_val (excluded_doc_ids, doc_id); > > + } > > + messages->base.excluded_doc_ids = talloc (query, _notmuch_doc_id_set); > > + _notmuch_doc_id_set_init (query, messages->base.excluded_doc_ids, > > + excluded_doc_ids); > > Don't forget to g_array_unref excluded_doc_ids. Yes I will add that. > > + } > > + } > > > > - exclude_query = _notmuch_exclude_tags (query, final_query); > > - > > - final_query = Xapian::Query (Xapian::Query::OP_AND_NOT, > > - final_query, exclude_query); > > > > enquire.set_weighting_scheme (Xapian::BoolWeight()); > > > > @@ -283,6 +323,10 @@ _notmuch_mset_messages_get (notmuch_messages_t *messages) > > INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n"); > > } > > > > + if ((messages->excluded_doc_ids) && > > + (_notmuch_doc_id_set_contains (messages->excluded_doc_ids, doc_id))) > > No need for so many parens (just a nit). Will fix. > > + notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE); > > + > > return message; > > } > > Thanks Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/7] lib: Make notmuch_query_search_messages set the exclude flag 2012-01-31 11:45 ` Mark Walters @ 2012-01-31 16:25 ` Austin Clements 2012-02-01 18:00 ` Mark Walters 0 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-31 16:25 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch Quoth Mark Walters on Jan 31 at 11:45 am: > On Mon, 30 Jan 2012 23:43:52 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > Quoth Mark Walters on Jan 29 at 6:39 pm: > > > notmuch_message_node_t *iterator; > > > }; > > > > > > diff --git a/lib/notmuch.h b/lib/notmuch.h > > > index 7929fe7..740d005 100644 > > > --- a/lib/notmuch.h > > > +++ b/lib/notmuch.h > > > @@ -449,6 +449,11 @@ typedef enum { > > > const char * > > > notmuch_query_get_query_string (notmuch_query_t *query); > > > > > > +/* specify whether to results should omit the excluded results rather > > > + * than just marking them excluded */ > > > +void > > > +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit); > > > + > > > > I don't think we should add this API. The library behavior will not > > change for library users that don't use excludes and library users > > that do use excludes should by aware of the excluded flag and do the > > appropriate thing. > > > > I can see why this is handy in some cases, but I don't think it > > provides enough utility to warrant becoming part of the permanent and > > minimal library interface. > > This is really a performance improvement: suppose that there are lots of > threads that only match in excluded messages. Then without this flag we > will spend lots of time constructing the thread only for it to be > ignored. (In contrived situations this could be arbitrarily slower.) I would prefer to keep the public API minimal and only introduce something like this if people actually experience performance problems. ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 3/7] lib: Make notmuch_query_search_messages set the exclude flag 2012-01-31 16:25 ` Austin Clements @ 2012-02-01 18:00 ` Mark Walters 0 siblings, 0 replies; 176+ messages in thread From: Mark Walters @ 2012-02-01 18:00 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch On Tue, 31 Jan 2012 11:25:06 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > Quoth Mark Walters on Jan 31 at 11:45 am: > > On Mon, 30 Jan 2012 23:43:52 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > > > Quoth Mark Walters on Jan 29 at 6:39 pm: > > > > notmuch_message_node_t *iterator; > > > > }; > > > > > > > > diff --git a/lib/notmuch.h b/lib/notmuch.h > > > > index 7929fe7..740d005 100644 > > > > --- a/lib/notmuch.h > > > > +++ b/lib/notmuch.h > > > > @@ -449,6 +449,11 @@ typedef enum { > > > > const char * > > > > notmuch_query_get_query_string (notmuch_query_t *query); > > > > > > > > +/* specify whether to results should omit the excluded results rather > > > > + * than just marking them excluded */ > > > > +void > > > > +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit); > > > > + > > > > > > I don't think we should add this API. The library behavior will not > > > change for library users that don't use excludes and library users > > > that do use excludes should by aware of the excluded flag and do the > > > appropriate thing. > > > > > > I can see why this is handy in some cases, but I don't think it > > > provides enough utility to warrant becoming part of the permanent and > > > minimal library interface. > > > > This is really a performance improvement: suppose that there are lots of > > threads that only match in excluded messages. Then without this flag we > > will spend lots of time constructing the thread only for it to be > > ignored. (In contrived situations this could be arbitrarily slower.) > > I would prefer to keep the public API minimal and only introduce > something like this if people actually experience performance > problems. I have looked at removing this api and it does make things inconvenient. It is nice to be able to pass a notmuch_messages_t around without having to teach every function that takes notmuch_messages_t (e.g., notmuch_messages_collect_tags) about the exclude flag. An alternative might be to make it possible to set an omit excludes flag on a notmuch_messages_t object but that seems worse than the current patches. Any thoughts? Mark PS I think my current version fixes all the other queries so I will post that later today (in a new thread!). ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 4/7] lib: Add the exclude flag to notmuch_query_search_threads 2012-01-29 18:36 ` Mark Walters ` (2 preceding siblings ...) 2012-01-29 18:39 ` [PATCH 3/7] lib: Make notmuch_query_search_messages set the exclude flag Mark Walters @ 2012-01-29 18:39 ` Mark Walters 2012-01-31 4:50 ` Austin Clements 2012-01-31 5:07 ` Austin Clements 2012-01-29 18:39 ` [PATCH 5/7] cli: Make notmuch-show respect excludes Mark Walters ` (3 subsequent siblings) 7 siblings, 2 replies; 176+ messages in thread From: Mark Walters @ 2012-01-29 18:39 UTC (permalink / raw) To: notmuch, amdragon Add the NOTMUCH_MESSAGE_FLAG_EXCLUDED flag to notmuch_query_search_threads. Implemented by inspecting the tags directly in _notmuch_thread_create/_thread_add_message rather than as a Xapian query for speed reasons. --- lib/notmuch-private.h | 16 ++++++++++------ lib/query.cc | 1 + lib/thread.cc | 18 +++++++++++++++--- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h index e791bb0..56b87c6 100644 --- a/lib/notmuch-private.h +++ b/lib/notmuch-private.h @@ -211,12 +211,8 @@ _notmuch_directory_get_document_id (notmuch_directory_t *directory); /* thread.cc */ -notmuch_thread_t * -_notmuch_thread_create (void *ctx, - notmuch_database_t *notmuch, - unsigned int seed_doc_id, - notmuch_doc_id_set_t *match_set, - notmuch_sort_t sort); +/* Definition of _notmuch_thread_create moved later since now uses + * string_list_t */ /* message.cc */ @@ -492,6 +488,14 @@ notmuch_filenames_t * _notmuch_filenames_create (const void *ctx, notmuch_string_list_t *list); +notmuch_thread_t * +_notmuch_thread_create (void *ctx, + notmuch_database_t *notmuch, + unsigned int seed_doc_id, + notmuch_doc_id_set_t *match_set, + notmuch_string_list_t *excluded_terms, + notmuch_sort_t sort); + #pragma GCC visibility pop NOTMUCH_END_DECLS diff --git a/lib/query.cc b/lib/query.cc index 7d165d2..dee7ec0 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -472,6 +472,7 @@ notmuch_threads_get (notmuch_threads_t *threads) threads->query->notmuch, doc_id, &threads->match_set, + threads->query->exclude_terms, threads->query->sort); } diff --git a/lib/thread.cc b/lib/thread.cc index 0435ee6..6d65d52 100644 --- a/lib/thread.cc +++ b/lib/thread.cc @@ -214,7 +214,8 @@ _thread_cleanup_author (notmuch_thread_t *thread, */ static void _thread_add_message (notmuch_thread_t *thread, - notmuch_message_t *message) + notmuch_message_t *message, + notmuch_string_list_t *exclude_terms) { notmuch_tags_t *tags; const char *tag; @@ -262,6 +263,15 @@ _thread_add_message (notmuch_thread_t *thread, notmuch_tags_move_to_next (tags)) { tag = notmuch_tags_get (tags); + /* mark excluded messages */ + for (notmuch_string_node_t *term = exclude_terms->head; term; + term = term->next) { + /* we ignore initial 'K' */ + if (strcmp(tag, (term->string + 1)) == 0) { + notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE); + break; + } + } g_hash_table_insert (thread->tags, xstrdup (tag), NULL); } } @@ -321,7 +331,8 @@ _thread_add_matched_message (notmuch_thread_t *thread, _thread_set_subject_from_message (thread, message); } - thread->matched_messages++; + if (!notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED)) + thread->matched_messages++; if (g_hash_table_lookup_extended (thread->message_hash, notmuch_message_get_message_id (message), NULL, @@ -392,6 +403,7 @@ _notmuch_thread_create (void *ctx, notmuch_database_t *notmuch, unsigned int seed_doc_id, notmuch_doc_id_set_t *match_set, + notmuch_string_list_t *exclude_terms, notmuch_sort_t sort) { notmuch_thread_t *thread; @@ -467,7 +479,7 @@ _notmuch_thread_create (void *ctx, if (doc_id == seed_doc_id) message = seed_message; - _thread_add_message (thread, message); + _thread_add_message (thread, message, exclude_terms); if ( _notmuch_doc_id_set_contains (match_set, doc_id)) { _notmuch_doc_id_set_remove (match_set, doc_id); -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH 4/7] lib: Add the exclude flag to notmuch_query_search_threads 2012-01-29 18:39 ` [PATCH 4/7] lib: Add the exclude flag to notmuch_query_search_threads Mark Walters @ 2012-01-31 4:50 ` Austin Clements 2012-01-31 11:47 ` Mark Walters 2012-01-31 5:07 ` Austin Clements 1 sibling, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-31 4:50 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch Quoth Mark Walters on Jan 29 at 6:39 pm: > Add the NOTMUCH_MESSAGE_FLAG_EXCLUDED flag to > notmuch_query_search_threads. Implemented by inspecting the tags > directly in _notmuch_thread_create/_thread_add_message rather than as > a Xapian query for speed reasons. > --- > lib/notmuch-private.h | 16 ++++++++++------ > lib/query.cc | 1 + > lib/thread.cc | 18 +++++++++++++++--- > 3 files changed, 26 insertions(+), 9 deletions(-) > > diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h > index e791bb0..56b87c6 100644 > --- a/lib/notmuch-private.h > +++ b/lib/notmuch-private.h > @@ -211,12 +211,8 @@ _notmuch_directory_get_document_id (notmuch_directory_t *directory); > > /* thread.cc */ > > -notmuch_thread_t * > -_notmuch_thread_create (void *ctx, > - notmuch_database_t *notmuch, > - unsigned int seed_doc_id, > - notmuch_doc_id_set_t *match_set, > - notmuch_sort_t sort); > +/* Definition of _notmuch_thread_create moved later since now uses > + * string_list_t */ Naw, leave the definition here along with the other things from thread.cc and just add a typedef struct _notmuch_string_list notmuch_string_list_t; along with the typedef for notmuch_doc_id_set_t near the top. (You might also have to tweak the typedef of notmuch_string_list_t later so it's just the struct definition.) > > /* message.cc */ > > @@ -492,6 +488,14 @@ notmuch_filenames_t * > _notmuch_filenames_create (const void *ctx, > notmuch_string_list_t *list); > > +notmuch_thread_t * > +_notmuch_thread_create (void *ctx, > + notmuch_database_t *notmuch, > + unsigned int seed_doc_id, > + notmuch_doc_id_set_t *match_set, > + notmuch_string_list_t *excluded_terms, > + notmuch_sort_t sort); > + > #pragma GCC visibility pop > > NOTMUCH_END_DECLS > diff --git a/lib/query.cc b/lib/query.cc > index 7d165d2..dee7ec0 100644 > --- a/lib/query.cc > +++ b/lib/query.cc > @@ -472,6 +472,7 @@ notmuch_threads_get (notmuch_threads_t *threads) > threads->query->notmuch, > doc_id, > &threads->match_set, > + threads->query->exclude_terms, > threads->query->sort); > } > > diff --git a/lib/thread.cc b/lib/thread.cc > index 0435ee6..6d65d52 100644 > --- a/lib/thread.cc > +++ b/lib/thread.cc > @@ -214,7 +214,8 @@ _thread_cleanup_author (notmuch_thread_t *thread, > */ > static void > _thread_add_message (notmuch_thread_t *thread, > - notmuch_message_t *message) > + notmuch_message_t *message, > + notmuch_string_list_t *exclude_terms) > { > notmuch_tags_t *tags; > const char *tag; > @@ -262,6 +263,15 @@ _thread_add_message (notmuch_thread_t *thread, > notmuch_tags_move_to_next (tags)) > { > tag = notmuch_tags_get (tags); > + /* mark excluded messages */ Capital and period. > + for (notmuch_string_node_t *term = exclude_terms->head; term; > + term = term->next) { > + /* we ignore initial 'K' */ Same. > + if (strcmp(tag, (term->string + 1)) == 0) { > + notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE); > + break; > + } > + } > g_hash_table_insert (thread->tags, xstrdup (tag), NULL); > } > } > @@ -321,7 +331,8 @@ _thread_add_matched_message (notmuch_thread_t *thread, > _thread_set_subject_from_message (thread, message); > } > > - thread->matched_messages++; > + if (!notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED)) > + thread->matched_messages++; I'd still say this warrants a better API. > > if (g_hash_table_lookup_extended (thread->message_hash, > notmuch_message_get_message_id (message), NULL, > @@ -392,6 +403,7 @@ _notmuch_thread_create (void *ctx, > notmuch_database_t *notmuch, > unsigned int seed_doc_id, > notmuch_doc_id_set_t *match_set, > + notmuch_string_list_t *exclude_terms, > notmuch_sort_t sort) > { > notmuch_thread_t *thread; > @@ -467,7 +479,7 @@ _notmuch_thread_create (void *ctx, > if (doc_id == seed_doc_id) > message = seed_message; > > - _thread_add_message (thread, message); > + _thread_add_message (thread, message, exclude_terms); > > if ( _notmuch_doc_id_set_contains (match_set, doc_id)) { > _notmuch_doc_id_set_remove (match_set, doc_id); ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 4/7] lib: Add the exclude flag to notmuch_query_search_threads 2012-01-31 4:50 ` Austin Clements @ 2012-01-31 11:47 ` Mark Walters 0 siblings, 0 replies; 176+ messages in thread From: Mark Walters @ 2012-01-31 11:47 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch On Mon, 30 Jan 2012 23:50:20 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > Quoth Mark Walters on Jan 29 at 6:39 pm: > > Add the NOTMUCH_MESSAGE_FLAG_EXCLUDED flag to > > notmuch_query_search_threads. Implemented by inspecting the tags > > directly in _notmuch_thread_create/_thread_add_message rather than as > > a Xapian query for speed reasons. > > --- > > lib/notmuch-private.h | 16 ++++++++++------ > > lib/query.cc | 1 + > > lib/thread.cc | 18 +++++++++++++++--- > > 3 files changed, 26 insertions(+), 9 deletions(-) > > > > diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h > > index e791bb0..56b87c6 100644 > > --- a/lib/notmuch-private.h > > +++ b/lib/notmuch-private.h > > @@ -211,12 +211,8 @@ _notmuch_directory_get_document_id (notmuch_directory_t *directory); > > > > /* thread.cc */ > > > > -notmuch_thread_t * > > -_notmuch_thread_create (void *ctx, > > - notmuch_database_t *notmuch, > > - unsigned int seed_doc_id, > > - notmuch_doc_id_set_t *match_set, > > - notmuch_sort_t sort); > > +/* Definition of _notmuch_thread_create moved later since now uses > > + * string_list_t */ > > Naw, leave the definition here along with the other things from > thread.cc and just add a > > typedef struct _notmuch_string_list notmuch_string_list_t; > > along with the typedef for notmuch_doc_id_set_t near the top. (You > might also have to tweak the typedef of notmuch_string_list_t later so > it's just the struct definition.) Will do. > > /* message.cc */ > > > > @@ -492,6 +488,14 @@ notmuch_filenames_t * > > _notmuch_filenames_create (const void *ctx, > > notmuch_string_list_t *list); > > > > +notmuch_thread_t * > > +_notmuch_thread_create (void *ctx, > > + notmuch_database_t *notmuch, > > + unsigned int seed_doc_id, > > + notmuch_doc_id_set_t *match_set, > > + notmuch_string_list_t *excluded_terms, > > + notmuch_sort_t sort); > > + > > #pragma GCC visibility pop > > > > NOTMUCH_END_DECLS > > diff --git a/lib/query.cc b/lib/query.cc > > index 7d165d2..dee7ec0 100644 > > --- a/lib/query.cc > > +++ b/lib/query.cc > > @@ -472,6 +472,7 @@ notmuch_threads_get (notmuch_threads_t *threads) > > threads->query->notmuch, > > doc_id, > > &threads->match_set, > > + threads->query->exclude_terms, > > threads->query->sort); > > } > > > > diff --git a/lib/thread.cc b/lib/thread.cc > > index 0435ee6..6d65d52 100644 > > --- a/lib/thread.cc > > +++ b/lib/thread.cc > > @@ -214,7 +214,8 @@ _thread_cleanup_author (notmuch_thread_t *thread, > > */ > > static void > > _thread_add_message (notmuch_thread_t *thread, > > - notmuch_message_t *message) > > + notmuch_message_t *message, > > + notmuch_string_list_t *exclude_terms) > > { > > notmuch_tags_t *tags; > > const char *tag; > > @@ -262,6 +263,15 @@ _thread_add_message (notmuch_thread_t *thread, > > notmuch_tags_move_to_next (tags)) > > { > > tag = notmuch_tags_get (tags); > > + /* mark excluded messages */ > > Capital and period. Will fix. > > + for (notmuch_string_node_t *term = exclude_terms->head; term; > > + term = term->next) { > > + /* we ignore initial 'K' */ > > Same. Will fix > > + if (strcmp(tag, (term->string + 1)) == 0) { > > + notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE); > > + break; > > + } > > + } > > g_hash_table_insert (thread->tags, xstrdup (tag), NULL); > > } > > } > > @@ -321,7 +331,8 @@ _thread_add_matched_message (notmuch_thread_t *thread, > > _thread_set_subject_from_message (thread, message); > > } > > > > - thread->matched_messages++; > > + if (!notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED)) > > + thread->matched_messages++; > > I'd still say this warrants a better API. I agree: I will think about that. > > if (g_hash_table_lookup_extended (thread->message_hash, > > notmuch_message_get_message_id (message), NULL, > > @@ -392,6 +403,7 @@ _notmuch_thread_create (void *ctx, > > notmuch_database_t *notmuch, > > unsigned int seed_doc_id, > > notmuch_doc_id_set_t *match_set, > > + notmuch_string_list_t *exclude_terms, > > notmuch_sort_t sort) > > { > > notmuch_thread_t *thread; > > @@ -467,7 +479,7 @@ _notmuch_thread_create (void *ctx, > > if (doc_id == seed_doc_id) > > message = seed_message; > > > > - _thread_add_message (thread, message); > > + _thread_add_message (thread, message, exclude_terms); > > > > if ( _notmuch_doc_id_set_contains (match_set, doc_id)) { > > _notmuch_doc_id_set_remove (match_set, doc_id); ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 4/7] lib: Add the exclude flag to notmuch_query_search_threads 2012-01-29 18:39 ` [PATCH 4/7] lib: Add the exclude flag to notmuch_query_search_threads Mark Walters 2012-01-31 4:50 ` Austin Clements @ 2012-01-31 5:07 ` Austin Clements 1 sibling, 0 replies; 176+ messages in thread From: Austin Clements @ 2012-01-31 5:07 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch Quoth Mark Walters on Jan 29 at 6:39 pm: > Add the NOTMUCH_MESSAGE_FLAG_EXCLUDED flag to > notmuch_query_search_threads. Implemented by inspecting the tags > directly in _notmuch_thread_create/_thread_add_message rather than as > a Xapian query for speed reasons. Hmm. Won't the thread sort be influenced by excluded messages? It's not completely obvious to me if it should or shouldn't be. If excluded messages are counted for thread sorting, it would be very natural to toggle their visibility in the search view; otherwise we probably need to perform the entire query again with exclusions disabled. If we do want to ignore excluded messages for sorting, I think notmuch_query_search_threads can simply shuffle excluded messages to the end of doc_ids (which is slightly awkward to implement, but not too bad). ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 5/7] cli: Make notmuch-show respect excludes. 2012-01-29 18:36 ` Mark Walters ` (3 preceding siblings ...) 2012-01-29 18:39 ` [PATCH 4/7] lib: Add the exclude flag to notmuch_query_search_threads Mark Walters @ 2012-01-29 18:39 ` Mark Walters 2012-01-31 4:56 ` Austin Clements 2012-01-29 18:39 ` [PATCH 6/7] cli: omit excluded messages in results where appropriate Mark Walters ` (2 subsequent siblings) 7 siblings, 1 reply; 176+ messages in thread From: Mark Walters @ 2012-01-29 18:39 UTC (permalink / raw) To: notmuch, amdragon This adds the excludes to notmuch-show.c. We do not exclude when only a single message (or part) is requested. notmuch-show will output the exclude information when either text or json format is requested. As this changes the output from notmuch-show it breaks many tests (in a trivial and expected fashion). --- notmuch-show.c | 26 +++++++++++++++++++++----- 1 files changed, 21 insertions(+), 5 deletions(-) diff --git a/notmuch-show.c b/notmuch-show.c index dec799c..681827f 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -193,10 +193,12 @@ _get_one_line_summary (const void *ctx, notmuch_message_t *message) static void format_message_text (unused (const void *ctx), notmuch_message_t *message, int indent) { - printf ("id:%s depth:%d match:%d filename:%s\n", + /* Could changing this could break users ? */ + printf ("id:%s depth:%d match:%d excluded:%d filename:%s\n", notmuch_message_get_message_id (message), indent, - notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH), + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 1 : 0, + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 1 : 0, notmuch_message_get_filename (message)); } @@ -212,9 +214,10 @@ format_message_json (const void *ctx, notmuch_message_t *message, unused (int in date = notmuch_message_get_date (message); relative_date = notmuch_time_relative_date (ctx, date); - printf ("\"id\": %s, \"match\": %s, \"filename\": %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [", + printf ("\"id\": %s, \"match\": %s, \"excluded\": %s, \"filename\": %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [", json_quote_str (ctx_quote, notmuch_message_get_message_id (message)), notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? "true" : "false", + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? "true" : "false", json_quote_str (ctx_quote, notmuch_message_get_filename (message)), date, relative_date); @@ -1059,9 +1062,13 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) char *opt; const notmuch_show_format_t *format = &format_text; notmuch_show_params_t params; + const char **search_exclude_tags; + size_t search_exclude_tags_length; int mbox = 0; int format_specified = 0; int i; + notmuch_bool_t do_not_exclude = FALSE; + unsigned int j; params.entire_thread = 0; params.raw = 0; @@ -1098,6 +1105,8 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) params.part = atoi(argv[i] + sizeof ("--part=") - 1); } else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) { params.entire_thread = 1; + } else if (STRNCMP_LITERAL (argv[i], "--do-not-exclude") == 0) { + do_not_exclude = TRUE; } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) || (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) { if (params.cryptoctx == NULL) { @@ -1105,7 +1114,7 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) /* TODO: GMimePasswordRequestFunc */ if (NULL == (params.cryptoctx = g_mime_gpg_context_new(NULL, "gpg"))) #else - GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL); + GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL); if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg"))) #endif fprintf (stderr, "Failed to construct gpg context.\n"); @@ -1167,10 +1176,17 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) if (params.raw && params.part < 0) params.part = 0; + /* if a single message is requested we do not use search_excludes */ if (params.part >= 0) return do_show_single (ctx, query, format, ¶ms); else - return do_show (ctx, query, format, ¶ms); + if (!do_not_exclude) { + search_exclude_tags = notmuch_config_get_search_exclude_tags + (config, &search_exclude_tags_length); + for (j = 0; j < search_exclude_tags_length; j++) + notmuch_query_add_tag_exclude (query, search_exclude_tags[j]); + return do_show (ctx, query, format, ¶ms); + } notmuch_query_destroy (query); notmuch_database_close (notmuch); -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH 5/7] cli: Make notmuch-show respect excludes. 2012-01-29 18:39 ` [PATCH 5/7] cli: Make notmuch-show respect excludes Mark Walters @ 2012-01-31 4:56 ` Austin Clements 2012-01-31 12:30 ` Mark Walters 0 siblings, 1 reply; 176+ messages in thread From: Austin Clements @ 2012-01-31 4:56 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch Quoth Mark Walters on Jan 29 at 6:39 pm: > This adds the excludes to notmuch-show.c. We do not exclude when only > a single message (or part) is requested. notmuch-show will output the > exclude information when either text or json format is requested. As > this changes the output from notmuch-show it breaks many tests (in a > trivial and expected fashion). > --- > notmuch-show.c | 26 +++++++++++++++++++++----- > 1 files changed, 21 insertions(+), 5 deletions(-) > > diff --git a/notmuch-show.c b/notmuch-show.c > index dec799c..681827f 100644 > --- a/notmuch-show.c > +++ b/notmuch-show.c > @@ -193,10 +193,12 @@ _get_one_line_summary (const void *ctx, notmuch_message_t *message) > static void > format_message_text (unused (const void *ctx), notmuch_message_t *message, int indent) > { > - printf ("id:%s depth:%d match:%d filename:%s\n", > + /* Could changing this could break users ? */ I don't think anybody seriously tries to parse the text format, so I wouldn't worry about breaking anything. > + printf ("id:%s depth:%d match:%d excluded:%d filename:%s\n", > notmuch_message_get_message_id (message), > indent, > - notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH), > + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 1 : 0, > + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 1 : 0, > notmuch_message_get_filename (message)); > } > > @@ -212,9 +214,10 @@ format_message_json (const void *ctx, notmuch_message_t *message, unused (int in > date = notmuch_message_get_date (message); > relative_date = notmuch_time_relative_date (ctx, date); > > - printf ("\"id\": %s, \"match\": %s, \"filename\": %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [", > + printf ("\"id\": %s, \"match\": %s, \"excluded\": %s, \"filename\": %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [", I wonder if it would be better to switch to an array of flag names... That obviously would break consumers, but it's worth thinking about in the longer term. > json_quote_str (ctx_quote, notmuch_message_get_message_id (message)), > notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? "true" : "false", > + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? "true" : "false", > json_quote_str (ctx_quote, notmuch_message_get_filename (message)), > date, relative_date); > > @@ -1059,9 +1062,13 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) > char *opt; > const notmuch_show_format_t *format = &format_text; > notmuch_show_params_t params; > + const char **search_exclude_tags; > + size_t search_exclude_tags_length; > int mbox = 0; > int format_specified = 0; > int i; > + notmuch_bool_t do_not_exclude = FALSE; > + unsigned int j; > > params.entire_thread = 0; > params.raw = 0; > @@ -1098,6 +1105,8 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) > params.part = atoi(argv[i] + sizeof ("--part=") - 1); > } else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) { > params.entire_thread = 1; > + } else if (STRNCMP_LITERAL (argv[i], "--do-not-exclude") == 0) { > + do_not_exclude = TRUE; "no-exclude" if you change the others. > } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) || > (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) { > if (params.cryptoctx == NULL) { > @@ -1105,7 +1114,7 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) > /* TODO: GMimePasswordRequestFunc */ > if (NULL == (params.cryptoctx = g_mime_gpg_context_new(NULL, "gpg"))) > #else > - GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL); > + GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL); Accidental reindent? > if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg"))) > #endif > fprintf (stderr, "Failed to construct gpg context.\n"); > @@ -1167,10 +1176,17 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) > if (params.raw && params.part < 0) > params.part = 0; > > + /* if a single message is requested we do not use search_excludes */ Capital and period. > if (params.part >= 0) > return do_show_single (ctx, query, format, ¶ms); > else > - return do_show (ctx, query, format, ¶ms); > + if (!do_not_exclude) { > + search_exclude_tags = notmuch_config_get_search_exclude_tags > + (config, &search_exclude_tags_length); > + for (j = 0; j < search_exclude_tags_length; j++) > + notmuch_query_add_tag_exclude (query, search_exclude_tags[j]); > + return do_show (ctx, query, format, ¶ms); > + } I don't think this is the control flow you meant. With --do-not-exclude, there won't be any output. > > notmuch_query_destroy (query); > notmuch_database_close (notmuch); Cool. That was easy! ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH 5/7] cli: Make notmuch-show respect excludes. 2012-01-31 4:56 ` Austin Clements @ 2012-01-31 12:30 ` Mark Walters 0 siblings, 0 replies; 176+ messages in thread From: Mark Walters @ 2012-01-31 12:30 UTC (permalink / raw) To: Austin Clements; +Cc: notmuch On Mon, 30 Jan 2012 23:56:24 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > Quoth Mark Walters on Jan 29 at 6:39 pm: > > This adds the excludes to notmuch-show.c. We do not exclude when only > > a single message (or part) is requested. notmuch-show will output the > > exclude information when either text or json format is requested. As > > this changes the output from notmuch-show it breaks many tests (in a > > trivial and expected fashion). > > --- > > notmuch-show.c | 26 +++++++++++++++++++++----- > > 1 files changed, 21 insertions(+), 5 deletions(-) > > > > diff --git a/notmuch-show.c b/notmuch-show.c > > index dec799c..681827f 100644 > > --- a/notmuch-show.c > > +++ b/notmuch-show.c > > @@ -193,10 +193,12 @@ _get_one_line_summary (const void *ctx, notmuch_message_t *message) > > static void > > format_message_text (unused (const void *ctx), notmuch_message_t *message, int indent) > > { > > - printf ("id:%s depth:%d match:%d filename:%s\n", > > + /* Could changing this could break users ? */ > > I don't think anybody seriously tries to parse the text format, so I > wouldn't worry about breaking anything. Right: I will remove the comment. > > + printf ("id:%s depth:%d match:%d excluded:%d filename:%s\n", > > notmuch_message_get_message_id (message), > > indent, > > - notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH), > > + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 1 : 0, > > + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 1 : 0, > > notmuch_message_get_filename (message)); > > } > > > > @@ -212,9 +214,10 @@ format_message_json (const void *ctx, notmuch_message_t *message, unused (int in > > date = notmuch_message_get_date (message); > > relative_date = notmuch_time_relative_date (ctx, date); > > > > - printf ("\"id\": %s, \"match\": %s, \"filename\": %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [", > > + printf ("\"id\": %s, \"match\": %s, \"excluded\": %s, \"filename\": %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [", > > I wonder if it would be better to switch to an array of flag names... > That obviously would break consumers, but it's worth thinking about in > the longer term. Unless you have a strong feeling for this I will leave that for a later patch. > > json_quote_str (ctx_quote, notmuch_message_get_message_id (message)), > > notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? "true" : "false", > > + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? "true" : "false", > > json_quote_str (ctx_quote, notmuch_message_get_filename (message)), > > date, relative_date); > > > > @@ -1059,9 +1062,13 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) > > char *opt; > > const notmuch_show_format_t *format = &format_text; > > notmuch_show_params_t params; > > + const char **search_exclude_tags; > > + size_t search_exclude_tags_length; > > int mbox = 0; > > int format_specified = 0; > > int i; > > + notmuch_bool_t do_not_exclude = FALSE; > > + unsigned int j; > > > > params.entire_thread = 0; > > params.raw = 0; > > @@ -1098,6 +1105,8 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) > > params.part = atoi(argv[i] + sizeof ("--part=") - 1); > > } else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) { > > params.entire_thread = 1; > > + } else if (STRNCMP_LITERAL (argv[i], "--do-not-exclude") == 0) { > > + do_not_exclude = TRUE; > > "no-exclude" if you change the others. See comment on first patch: will make sure they are consistent. > > } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) || > > (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) { > > if (params.cryptoctx == NULL) { > > @@ -1105,7 +1114,7 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) > > /* TODO: GMimePasswordRequestFunc */ > > if (NULL == (params.cryptoctx = g_mime_gpg_context_new(NULL, "gpg"))) > > #else > > - GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL); > > + GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL); > > Accidental reindent? Yes will fix. > > if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg"))) > > #endif > > fprintf (stderr, "Failed to construct gpg context.\n"); > > @@ -1167,10 +1176,17 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) > > if (params.raw && params.part < 0) > > params.part = 0; > > > > + /* if a single message is requested we do not use search_excludes */ > > Capital and period. Will fix. > > if (params.part >= 0) > > return do_show_single (ctx, query, format, ¶ms); > > else > > - return do_show (ctx, query, format, ¶ms); > > + if (!do_not_exclude) { > > + search_exclude_tags = notmuch_config_get_search_exclude_tags > > + (config, &search_exclude_tags_length); > > + for (j = 0; j < search_exclude_tags_length; j++) > > + notmuch_query_add_tag_exclude (query, search_exclude_tags[j]); > > + return do_show (ctx, query, format, ¶ms); > > + } > > I don't think this is the control flow you meant. With > --do-not-exclude, there won't be any output. Good catch! Will fix. Thanks Mark ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 6/7] cli: omit excluded messages in results where appropriate. 2012-01-29 18:36 ` Mark Walters ` (4 preceding siblings ...) 2012-01-29 18:39 ` [PATCH 5/7] cli: Make notmuch-show respect excludes Mark Walters @ 2012-01-29 18:39 ` Mark Walters 2012-01-29 18:39 ` [PATCH 7/7] emacs: show: recognize the exclude flag Mark Walters 2012-01-31 5:08 ` [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Austin Clements 7 siblings, 0 replies; 176+ messages in thread From: Mark Walters @ 2012-01-29 18:39 UTC (permalink / raw) To: notmuch, amdragon In all cases of notmuch count/search/show where the results returned cannot reflect the exclude flag return just the matched not-excluded results. If the caller wishes to have all the matched results (i.e., including the excluded ones) they should call with the --do-not-exclude option. The relevant cases are count: both threads and messages search: all cases except the summary view show: mbox format --- notmuch-count.c | 2 ++ notmuch-search.c | 9 +++++++++ notmuch-show.c | 5 +++++ 3 files changed, 16 insertions(+), 0 deletions(-) diff --git a/notmuch-count.c b/notmuch-count.c index c88975e..1aa3f1a 100644 --- a/notmuch-count.c +++ b/notmuch-count.c @@ -87,6 +87,8 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); } + notmuch_query_set_omit_excluded_messages (query, TRUE); + switch (output) { case OUTPUT_MESSAGES: printf ("%u\n", notmuch_query_count_messages (query)); diff --git a/notmuch-search.c b/notmuch-search.c index 084dd05..339ce82 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -207,6 +207,9 @@ do_search_threads (const search_format_t *format, int first_thread = 1; int i; + if (output == OUTPUT_THREADS) + notmuch_query_set_omit_excluded_messages (query, TRUE); + if (offset < 0) { offset += notmuch_query_count_threads (query); if (offset < 0) @@ -297,6 +300,8 @@ do_search_messages (const search_format_t *format, int first_message = 1; int i; + notmuch_query_set_omit_excluded_messages (query, TRUE); + if (offset < 0) { offset += notmuch_query_count_messages (query); if (offset < 0) @@ -368,6 +373,10 @@ do_search_tags (notmuch_database_t *notmuch, const char *tag; int first_tag = 1; + notmuch_query_set_omit_excluded_messages (query, TRUE); + /* should the following only special case if no excluded terms + * specified? */ + /* Special-case query of "*" for better performance. */ if (strcmp (notmuch_query_get_query_string (query), "*") == 0) { tags = notmuch_database_get_all_tags (notmuch); diff --git a/notmuch-show.c b/notmuch-show.c index 681827f..5d98724 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -1167,6 +1167,11 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) return 1; } + /* if format=mbox then we can not output excluded messages as + * there is no way to make the exclude flag available */ + if (mbox) + notmuch_query_set_omit_excluded_messages (query, TRUE); + /* if part was requested and format was not specified, use format=raw */ if (params.part >= 0 && !format_specified) format = &format_raw; -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* [PATCH 7/7] emacs: show: recognize the exclude flag. 2012-01-29 18:36 ` Mark Walters ` (5 preceding siblings ...) 2012-01-29 18:39 ` [PATCH 6/7] cli: omit excluded messages in results where appropriate Mark Walters @ 2012-01-29 18:39 ` Mark Walters 2012-01-31 5:08 ` [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Austin Clements 7 siblings, 0 replies; 176+ messages in thread From: Mark Walters @ 2012-01-29 18:39 UTC (permalink / raw) To: notmuch, amdragon Show mode will recognize the exclude flag by not opening excluding messages by default, and will start at the first matching non-excluded message. If there are no matching non-excluded messages it will go to the first matching (necessarily excluded) message. --- emacs/notmuch-show.el | 18 +++++++++++++++++- 1 files changed, 17 insertions(+), 1 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 84ac624..8efadf6 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -905,7 +905,8 @@ current buffer, if possible." ;; Message visibility depends on whether it matched the search ;; criteria. - (notmuch-show-message-visible msg (plist-get msg :match)))) + (notmuch-show-message-visible msg (and (plist-get msg :match) + (not (plist-get msg :excluded)))))) (defun notmuch-show-insert-tree (tree depth) "Insert the message tree TREE at depth DEPTH in the current thread." @@ -1015,6 +1016,9 @@ buffer." ;; Move straight to the first open message (unless (notmuch-show-message-visible-p) (notmuch-show-next-open-message)) + (when (eq (point) (point-max)) + (goto-char (point-min)) + (notmuch-show-next-matching-message)) ;; Set the header line to the subject of the first open message. (setq header-line-format (notmuch-show-strip-re (notmuch-show-get-subject))) @@ -1417,6 +1421,18 @@ any effects from previous calls to (notmuch-show-message-adjust)) (goto-char (point-max))))) +(defun notmuch-show-next-matching-message () + "Show the next matching message." + (interactive) + (let (r) + (while (and (setq r (notmuch-show-goto-message-next)) + (not (notmuch-show-get-prop :match)))) + (if r + (progn + (notmuch-show-mark-read) + (notmuch-show-message-adjust)) + (goto-char (point-max))))) + (defun notmuch-show-previous-open-message () "Show the previous message." (interactive) -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag 2012-01-29 18:36 ` Mark Walters ` (6 preceding siblings ...) 2012-01-29 18:39 ` [PATCH 7/7] emacs: show: recognize the exclude flag Mark Walters @ 2012-01-31 5:08 ` Austin Clements 7 siblings, 0 replies; 176+ messages in thread From: Austin Clements @ 2012-01-31 5:08 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch This is looking really good. I think this overall approach is significantly better than the initial exclude support and the UI aspects look like they should be much more pleasant. Quoth Mark Walters on Jan 29 at 6:36 pm: > > Ok I now have a patch set which might be complete enough to be worth > reviewing. It is essentially complete and appears to work. > > Things that still need doing: > updating the test suite. The series changes notmuch-show to > output the exclude flag so several tests need updating. Of > course, the new functionality needs some tests too. > > emacs/notmuch.el I think it would be nice to hide (make > invisible) threads with no matching non-excluded messages (with a > toggle for visibility) but that is definitely beyond my elisp > skills. I'm happy to do that once this goes in. > The first patch of the series is not really part of the series: it adds > a --do-not-exclude option to tell the command not to exclude. I think > this is useful anyway, but it also simplifies behaviour decisions with > the excludes. For example notmuch count will only count matching > non-excluded messages but notmuch count --do-not-exclude will count > all matching messages excluded or not. > > One outstanding issue is that raised in > id:"20120124025331.GZ16740@mit.edu". I will need to think about > that. > > Best wishes > > Mark > ^ permalink raw reply [flat|nested] 176+ messages in thread
* [RFC PATCH 3/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag 2012-01-24 1:16 ` Austin Clements 2012-01-24 1:18 ` [RFC PATCH 1/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters 2012-01-24 1:18 ` [RFC PATCH 2/4] " Mark Walters @ 2012-01-24 1:18 ` Mark Walters 2012-01-24 2:53 ` Austin Clements 2012-01-24 1:18 ` [PATCH 4/4] " Mark Walters 3 siblings, 1 reply; 176+ messages in thread From: Mark Walters @ 2012-01-24 1:18 UTC (permalink / raw) To: notmuch, Austin Clements Add the actual NOTMUCH_MESSAGE_FLAG_EXCLUDED flag. --- lib/notmuch-private.h | 1 + lib/notmuch.h | 3 ++- lib/query.cc | 11 +++++++---- lib/thread.cc | 14 ++++++++++---- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h index e791bb0..cb3eca6 100644 --- a/lib/notmuch-private.h +++ b/lib/notmuch-private.h @@ -216,6 +216,7 @@ _notmuch_thread_create (void *ctx, notmuch_database_t *notmuch, unsigned int seed_doc_id, notmuch_doc_id_set_t *match_set, + notmuch_doc_id_set_t *excluded_doc_ids, notmuch_sort_t sort); /* message.cc */ diff --git a/lib/notmuch.h b/lib/notmuch.h index 7929fe7..cf0d45d 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -895,7 +895,8 @@ notmuch_message_get_filenames (notmuch_message_t *message); /* Message flags */ typedef enum _notmuch_message_flag { - NOTMUCH_MESSAGE_FLAG_MATCH + NOTMUCH_MESSAGE_FLAG_MATCH, + NOTMUCH_MESSAGE_FLAG_EXCLUDED } notmuch_message_flag_t; /* Get a value of a flag for the email corresponding to 'message'. */ diff --git a/lib/query.cc b/lib/query.cc index 92fa834..69e32bd 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -55,6 +55,7 @@ struct visible _notmuch_threads { /* The set of matched docid's that have not been assigned to a * thread. Initially, this contains every docid in doc_ids. */ notmuch_doc_id_set_t match_set; + notmuch_doc_id_set_t *excluded_doc_ids; }; static notmuch_bool_t @@ -302,6 +303,9 @@ _notmuch_mset_messages_get (notmuch_messages_t *messages) INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n"); } + if (_notmuch_doc_id_set_contains (messages->excluded_doc_ids, doc_id)) + notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE); + return message; } @@ -314,10 +318,6 @@ _notmuch_mset_messages_move_to_next (notmuch_messages_t *messages) mset_messages->iterator++; - while ((mset_messages->iterator != mset_messages->iterator_end) && - (_notmuch_doc_id_set_contains (messages->excluded_doc_ids, - *mset_messages->iterator))) - mset_messages->iterator++; } static notmuch_bool_t @@ -403,6 +403,8 @@ notmuch_query_search_threads (notmuch_query_t *query) notmuch_messages_move_to_next (messages); } threads->doc_id_pos = 0; + /* the excluded messages are in query context so this should be ok */ + threads->excluded_doc_ids = messages->excluded_doc_ids; talloc_free (messages); @@ -452,6 +454,7 @@ notmuch_threads_get (notmuch_threads_t *threads) threads->query->notmuch, doc_id, &threads->match_set, + threads->excluded_doc_ids, threads->query->sort); } diff --git a/lib/thread.cc b/lib/thread.cc index 0435ee6..6ea2a44 100644 --- a/lib/thread.cc +++ b/lib/thread.cc @@ -302,7 +302,8 @@ _thread_set_subject_from_message (notmuch_thread_t *thread, static void _thread_add_matched_message (notmuch_thread_t *thread, notmuch_message_t *message, - notmuch_sort_t sort) + notmuch_sort_t sort, + notmuch_bool_t excluded) { time_t date; notmuch_message_t *hashed_message; @@ -321,7 +322,8 @@ _thread_add_matched_message (notmuch_thread_t *thread, _thread_set_subject_from_message (thread, message); } - thread->matched_messages++; + if (!excluded) + thread->matched_messages++; if (g_hash_table_lookup_extended (thread->message_hash, notmuch_message_get_message_id (message), NULL, @@ -392,6 +394,7 @@ _notmuch_thread_create (void *ctx, notmuch_database_t *notmuch, unsigned int seed_doc_id, notmuch_doc_id_set_t *match_set, + notmuch_doc_id_set_t *excluded_doc_ids, notmuch_sort_t sort) { notmuch_thread_t *thread; @@ -456,7 +459,9 @@ _notmuch_thread_create (void *ctx, * oldest or newest subject is desired. */ notmuch_query_set_sort (thread_id_query, NOTMUCH_SORT_OLDEST_FIRST); - for (messages = notmuch_query_search_messages (thread_id_query); + messages = notmuch_query_search_messages (thread_id_query); + messages->excluded_doc_ids = excluded_doc_ids; + for (; notmuch_messages_valid (messages); notmuch_messages_move_to_next (messages)) { @@ -471,7 +476,8 @@ _notmuch_thread_create (void *ctx, if ( _notmuch_doc_id_set_contains (match_set, doc_id)) { _notmuch_doc_id_set_remove (match_set, doc_id); - _thread_add_matched_message (thread, message, sort); + _thread_add_matched_message (thread, message, sort, + _notmuch_doc_id_set_contains (excluded_doc_ids, doc_id)); } _notmuch_message_close (message); -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [RFC PATCH 3/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag 2012-01-24 1:18 ` [RFC PATCH 3/4] " Mark Walters @ 2012-01-24 2:53 ` Austin Clements 0 siblings, 0 replies; 176+ messages in thread From: Austin Clements @ 2012-01-24 2:53 UTC (permalink / raw) To: Mark Walters; +Cc: notmuch Quoth Mark Walters on Jan 24 at 1:18 am: > Add the actual NOTMUCH_MESSAGE_FLAG_EXCLUDED flag. > > --- > lib/notmuch-private.h | 1 + > lib/notmuch.h | 3 ++- > lib/query.cc | 11 +++++++---- > lib/thread.cc | 14 ++++++++++---- > 4 files changed, 20 insertions(+), 9 deletions(-) > > diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h > index e791bb0..cb3eca6 100644 > --- a/lib/notmuch-private.h > +++ b/lib/notmuch-private.h > @@ -216,6 +216,7 @@ _notmuch_thread_create (void *ctx, > notmuch_database_t *notmuch, > unsigned int seed_doc_id, > notmuch_doc_id_set_t *match_set, > + notmuch_doc_id_set_t *excluded_doc_ids, > notmuch_sort_t sort); > > /* message.cc */ > diff --git a/lib/notmuch.h b/lib/notmuch.h > index 7929fe7..cf0d45d 100644 > --- a/lib/notmuch.h > +++ b/lib/notmuch.h > @@ -895,7 +895,8 @@ notmuch_message_get_filenames (notmuch_message_t *message); > > /* Message flags */ > typedef enum _notmuch_message_flag { > - NOTMUCH_MESSAGE_FLAG_MATCH > + NOTMUCH_MESSAGE_FLAG_MATCH, > + NOTMUCH_MESSAGE_FLAG_EXCLUDED > } notmuch_message_flag_t; > > /* Get a value of a flag for the email corresponding to 'message'. */ > diff --git a/lib/query.cc b/lib/query.cc > index 92fa834..69e32bd 100644 > --- a/lib/query.cc > +++ b/lib/query.cc > @@ -55,6 +55,7 @@ struct visible _notmuch_threads { > /* The set of matched docid's that have not been assigned to a > * thread. Initially, this contains every docid in doc_ids. */ > notmuch_doc_id_set_t match_set; > + notmuch_doc_id_set_t *excluded_doc_ids; > }; > > static notmuch_bool_t > @@ -302,6 +303,9 @@ _notmuch_mset_messages_get (notmuch_messages_t *messages) > INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n"); > } > > + if (_notmuch_doc_id_set_contains (messages->excluded_doc_ids, doc_id)) > + notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE); > + > return message; > } > > @@ -314,10 +318,6 @@ _notmuch_mset_messages_move_to_next (notmuch_messages_t *messages) > > mset_messages->iterator++; > > - while ((mset_messages->iterator != mset_messages->iterator_end) && > - (_notmuch_doc_id_set_contains (messages->excluded_doc_ids, > - *mset_messages->iterator))) > - mset_messages->iterator++; > } > > static notmuch_bool_t > @@ -403,6 +403,8 @@ notmuch_query_search_threads (notmuch_query_t *query) > notmuch_messages_move_to_next (messages); > } > threads->doc_id_pos = 0; > + /* the excluded messages are in query context so this should be ok */ > + threads->excluded_doc_ids = messages->excluded_doc_ids; > > talloc_free (messages); > > @@ -452,6 +454,7 @@ notmuch_threads_get (notmuch_threads_t *threads) > threads->query->notmuch, > doc_id, > &threads->match_set, > + threads->excluded_doc_ids, > threads->query->sort); > } > > diff --git a/lib/thread.cc b/lib/thread.cc > index 0435ee6..6ea2a44 100644 > --- a/lib/thread.cc > +++ b/lib/thread.cc > @@ -302,7 +302,8 @@ _thread_set_subject_from_message (notmuch_thread_t *thread, > static void > _thread_add_matched_message (notmuch_thread_t *thread, > notmuch_message_t *message, > - notmuch_sort_t sort) > + notmuch_sort_t sort, > + notmuch_bool_t excluded) > { > time_t date; > notmuch_message_t *hashed_message; > @@ -321,7 +322,8 @@ _thread_add_matched_message (notmuch_thread_t *thread, > _thread_set_subject_from_message (thread, message); > } > > - thread->matched_messages++; > + if (!excluded) > + thread->matched_messages++; I interpret notmuch_thread_get_matched_messages as returning the number of messages with the "match" flag, which this approach changes. I would suggest introducing a new, more flexible API along the lines of /* Return the number of messages in thread for which * notmuch_message_get_flag(msg) & msg == match. */ int notmuch_thread_count_flags (notmuch_thread_t *thread, int mask, int match); This would subsume the existing notmuch_thread_get_{matched,total}_messages APIs. It could either iterate over the message list (which, curiously, we don't currently track), or it could proactively count messages in an array indexed by the message's flags (which wouldn't scale to large numbers of flags but, for now, would only be of length 4). > > if (g_hash_table_lookup_extended (thread->message_hash, > notmuch_message_get_message_id (message), NULL, > @@ -392,6 +394,7 @@ _notmuch_thread_create (void *ctx, > notmuch_database_t *notmuch, > unsigned int seed_doc_id, > notmuch_doc_id_set_t *match_set, > + notmuch_doc_id_set_t *excluded_doc_ids, > notmuch_sort_t sort) > { > notmuch_thread_t *thread; > @@ -456,7 +459,9 @@ _notmuch_thread_create (void *ctx, > * oldest or newest subject is desired. */ > notmuch_query_set_sort (thread_id_query, NOTMUCH_SORT_OLDEST_FIRST); > > - for (messages = notmuch_query_search_messages (thread_id_query); > + messages = notmuch_query_search_messages (thread_id_query); > + messages->excluded_doc_ids = excluded_doc_ids; > + for (; > notmuch_messages_valid (messages); > notmuch_messages_move_to_next (messages)) > { > @@ -471,7 +476,8 @@ _notmuch_thread_create (void *ctx, > > if ( _notmuch_doc_id_set_contains (match_set, doc_id)) { > _notmuch_doc_id_set_remove (match_set, doc_id); > - _thread_add_matched_message (thread, message, sort); > + _thread_add_matched_message (thread, message, sort, > + _notmuch_doc_id_set_contains (excluded_doc_ids, doc_id)); > } > > _notmuch_message_close (message); ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH 4/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag 2012-01-24 1:16 ` Austin Clements ` (2 preceding siblings ...) 2012-01-24 1:18 ` [RFC PATCH 3/4] " Mark Walters @ 2012-01-24 1:18 ` Mark Walters 3 siblings, 0 replies; 176+ messages in thread From: Mark Walters @ 2012-01-24 1:18 UTC (permalink / raw) To: notmuch, Austin Clements Make notmuch-search.c respect the NOTMUCH_MESSAGE_FLAG_EXCLUDED. All tests should pass: i.e., the behaviour should be the same as before the series. --- notmuch-search.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/notmuch-search.c b/notmuch-search.c index 8867aab..b005abf 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -227,7 +227,7 @@ do_search_threads (const search_format_t *format, thread = notmuch_threads_get (threads); - if (i < offset) { + if ((i < offset) || (notmuch_thread_get_matched_messages (thread) == 0)) { notmuch_thread_destroy (thread); continue; } @@ -318,6 +318,9 @@ do_search_messages (const search_format_t *format, message = notmuch_messages_get (messages); + if (notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED)) + continue; + if (output == OUTPUT_FILES) { filenames = notmuch_message_get_filenames (message); -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: [PATCH v3 2/2] search: Support automatic tag exclusions 2012-01-19 22:01 ` Mark Walters 2012-01-19 22:03 ` [PATCH] Automatically exclude tags in notmuch-show Mark Walters @ 2012-01-19 22:44 ` Pieter Praet 1 sibling, 0 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-19 22:44 UTC (permalink / raw) To: Mark Walters, Austin Clements; +Cc: Notmuch Mail, Aaron Ecay On Thu, 19 Jan 2012 22:01:27 +0000, Mark Walters <markwalters1009@gmail.com> wrote: > > > > I am happy with them appearing as a non matching message, but currently > > > they appear as a full open message. (The patch to achieve this is > > > trivial: essentially transpose part of Austin's patch of > > > notmuch-search.c into notmuch-show.c) > > > > This definitely sounds like the right thing to do. We can argue about > > more sophisticated UIs, but it should do this at a minimum. > > I will post the trivial patch in a moment (trivial but I could easily > have done something stupid). > > I haven't written a test yet: should it have one, [...] That would be preferrable, yes. > [...] and if so, could > someone point me to the appropriate place to put it? > In "test/emacs", right after "Hiding message with visible citation in notmuch-show view" would be perfect IMO. As you can see, that test uses `test-visible-output', which should provide the functionality you need. > Best wishes > > Mark Thanks! Peace -- Pieter ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v3 2/2] search: Support automatic tag exclusions 2012-01-19 19:36 ` [PATCH v3 2/2] search: Support automatic tag exclusions Austin Clements 2012-01-19 20:06 ` markwalters1009 @ 2012-01-19 21:21 ` Pieter Praet 1 sibling, 0 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-19 21:21 UTC (permalink / raw) To: Austin Clements; +Cc: Notmuch Mail On Thu, 19 Jan 2012 14:36:47 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > Quoth Pieter Praet on Jan 19 at 8:19 pm: > > Nice feature! I won't be using it myself, but I can imagine it being > > *very* useful for those who still feel the need to "delete" email :). > > Same here. I probably will use the spam tag, though. > Really? Then how will you be able to reply to my emails?!? ;) > > Nitpicking: > > > > - All other config-related functions and args include the section title > > in their name [1], so for the sake of consistency, we might want to > > mirror that. Also, the "auto"matic part is pretty much a given. > > > > So I'd like to suggest replacing all occurences of "auto_exclude_tags" > > with "search_exclude_tags" (and simply "exclude_tags" in the args to > > `_config_get_list' and `_config_set_list', of course). > > You are technically correct, the best kind of correct. I'd completely > missed this pattern. This should get fixed ASAP, while this feature > still has limited adoption. > > > Unfortunately, this would also partially invalidate your recent NEWS > > submission [2]. > > No worries, though maybe you want to tack an updated version of that > patch on the end of your series? > Will do. > > - If the 'search.exclude_tags' option is missing from the config file, > > its value is automatically set to "deleted;spam;", which probably isn't > > a sane default. Luckily, you've already provided the solution [3]. > > I'm good either way. I got lost in the discussion of defaults but > Jamie assured me everything was okay, so I took the path of least > resistance and left things as they were. > Hmm. I probably haven't read everything pertaining to that issue yet, but IMO it violates the Principle of Least Surprise with a vengeance. Tagging stuff some way or another shouldn't make it disappear by default. What if "spam" means "read it when you're bored", or "deleted" means "processed request for user deletion" (pretty far-fetched, but still...) for someone? > > - To make new users aware of the config option's existence, we should > > prompt them to configure it during setup. > > Sure. > > > Patches follow. > > > > > > Peace > > > > > > [1] Eg. `notmuch_config_get_user_name', `notmuch_config_get_new_tags', > > `notmuch_config_get_maildir_synchronize_flags', ... > > > > [2] id:"1326920330-31496-1-git-send-email-amdragon@mit.edu" > > > > [3] id:"20120117203211.GQ16740@mit.edu" > > Peace -- Pieter ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v3 2/2] search: Support automatic tag exclusions 2012-01-19 19:19 ` Pieter Praet ` (4 preceding siblings ...) 2012-01-19 19:36 ` [PATCH v3 2/2] search: Support automatic tag exclusions Austin Clements @ 2012-01-22 22:09 ` Xavier Maillard 2012-01-23 4:15 ` Pieter Praet 5 siblings, 1 reply; 176+ messages in thread From: Xavier Maillard @ 2012-01-22 22:09 UTC (permalink / raw) To: Pieter Praet, Austin Clements; +Cc: Notmuch Mail Hey Pieter, On Thu, 19 Jan 2012 20:19:00 +0100, Pieter Praet <pieter@praet.org> wrote: > Nice feature! I won't be using it myself, but I can imagine it being > *very* useful for those who still feel the need to "delete" email :). Adding a 'deleted' tag does not mean there will be a delete/purge process ;) (currently I got 5k messages with the tag deleted ;). > Nitpicking: > [ ... ] > So I'd like to suggest replacing all occurences of "auto_exclude_tags" > with "search_exclude_tags" (and simply "exclude_tags" in the args to > `_config_get_list' and `_config_set_list', of course). +1 > Unfortunately, this would also partially invalidate your recent NEWS > submission [2]. > > - If the 'search.exclude_tags' option is missing from the config file, > its value is automatically set to "deleted;spam;", which probably isn't > a sane default. Luckily, you've already provided the solution [3]. I am against doing something /unsafe/ in the user's back. If there is no option set intentionnaly by the user, there is nothing notmuch should do -i.e no exclusion - > - To make new users aware of the config option's existence, we should > prompt them to configure it during setup. +1 /Xavier ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v3 2/2] search: Support automatic tag exclusions 2012-01-22 22:09 ` Xavier Maillard @ 2012-01-23 4:15 ` Pieter Praet 0 siblings, 0 replies; 176+ messages in thread From: Pieter Praet @ 2012-01-23 4:15 UTC (permalink / raw) To: Xavier Maillard, Austin Clements; +Cc: Notmuch Mail On Sun, 22 Jan 2012 23:09:30 +0100, Xavier Maillard <xavier@maillard.im> wrote: > Hey Pieter, > Hi! > On Thu, 19 Jan 2012 20:19:00 +0100, Pieter Praet <pieter@praet.org> wrote: > > Nice feature! I won't be using it myself, but I can imagine it being > > *very* useful for those who still feel the need to "delete" email :). > > Adding a 'deleted' tag does not mean there will be a delete/purge > process ;) (currently I got 5k messages with the tag deleted ;). > Very true, that's why I put quotes around "delete". Deleting email for real is *so* old-fashioned... :D ;) > > Nitpicking: > > > > [ ... ] > > > So I'd like to suggest replacing all occurences of "auto_exclude_tags" > > with "search_exclude_tags" (and simply "exclude_tags" in the args to > > `_config_get_list' and `_config_set_list', of course). > > +1 > > > Unfortunately, this would also partially invalidate your recent NEWS > > submission [2]. > > > > - If the 'search.exclude_tags' option is missing from the config file, > > its value is automatically set to "deleted;spam;", which probably isn't > > a sane default. Luckily, you've already provided the solution [3]. > > I am against doing something /unsafe/ in the user's back. If there is no > option set intentionnaly by the user, there is nothing notmuch should > do -i.e no exclusion - > Absolutely. Actually, that's *exactly* what I meant. I thought that would be pretty clear, but perhaps it wasn't. I've reworded some of the commit messages, and will pay more attention to it in the future. > > - To make new users aware of the config option's existence, we should > > prompt them to configure it during setup. > > +1 > > /Xavier Thanks for your input! Peace -- Pieter ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v3 0/2] Automatic tag-based exclusion 2012-01-15 0:17 ` [PATCH v3 0/2] Automatic tag-based exclusion Austin Clements 2012-01-15 0:17 ` [PATCH v3 1/2] lib: Add support for automatically excluding tags from queries Austin Clements 2012-01-15 0:17 ` [PATCH v3 2/2] search: Support automatic tag exclusions Austin Clements @ 2012-01-16 19:35 ` Jameson Graef Rollins 2012-01-17 1:08 ` David Bremner 2012-01-18 20:58 ` [PATCH] News for tag exclusion Austin Clements 4 siblings, 0 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-16 19:35 UTC (permalink / raw) To: Austin Clements, notmuch [-- Attachment #1: Type: text/plain, Size: 202 bytes --] On Sat, 14 Jan 2012 19:17:32 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > This fixes the symbol visibility warning Jamie pointed out. LGTM. I'm using this now and it works like a charm. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: [PATCH v3 0/2] Automatic tag-based exclusion 2012-01-15 0:17 ` [PATCH v3 0/2] Automatic tag-based exclusion Austin Clements ` (2 preceding siblings ...) 2012-01-16 19:35 ` [PATCH v3 0/2] Automatic tag-based exclusion Jameson Graef Rollins @ 2012-01-17 1:08 ` David Bremner 2012-01-18 20:58 ` [PATCH] News for tag exclusion Austin Clements 4 siblings, 0 replies; 176+ messages in thread From: David Bremner @ 2012-01-17 1:08 UTC (permalink / raw) To: Austin Clements, notmuch On Sat, 14 Jan 2012 19:17:32 -0500, Austin Clements <amdragon@MIT.EDU> wrote: > This fixes the symbol visibility warning Jamie pointed out. Third time the charm. pushed. Please (somebody) consider writing NEWS and man page updates. d ^ permalink raw reply [flat|nested] 176+ messages in thread
* [PATCH] News for tag exclusion 2012-01-15 0:17 ` [PATCH v3 0/2] Automatic tag-based exclusion Austin Clements ` (3 preceding siblings ...) 2012-01-17 1:08 ` David Bremner @ 2012-01-18 20:58 ` Austin Clements 4 siblings, 0 replies; 176+ messages in thread From: Austin Clements @ 2012-01-18 20:58 UTC (permalink / raw) To: notmuch --- NEWS | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/NEWS b/NEWS index 1e561a9..6afa912 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,13 @@ Reply to sender to all. The feature is available through the new command line option --reply-to=(all|sender). +Tag exclusion + + Tags can be automatically excluded from search results unless they + appear explicitly in a query. By default, notmuch excludes the tags + deleted and spam. This can be changed using the new config setting + search.auto_exclude_tags. + Emacs Interface --------------- @@ -21,6 +28,14 @@ Reply to sender and search modes, 'r' has been bound to reply to sender, replacing reply to all, which now has key binding 'R'. +Library changes +--------------- + +New functions + + notmuch_query_add_tag_exclude supports the new tag exclusion + feature. + Notmuch 0.11 (2012-01-13) ========================= -- 1.7.7.3 ^ permalink raw reply related [flat|nested] 176+ messages in thread
* Re: another attempt to add delete functionality in emacs 2012-01-07 22:28 another attempt to add delete functionality in emacs Jameson Graef Rollins 2012-01-07 22:28 ` [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search Jameson Graef Rollins @ 2012-01-10 7:47 ` David Edmondson 2012-01-10 20:01 ` David Bremner 2012-01-11 2:56 ` Jameson Graef Rollins 1 sibling, 2 replies; 176+ messages in thread From: David Edmondson @ 2012-01-10 7:47 UTC (permalink / raw) To: Jameson Graef Rollins, Notmuch Mail [-- Attachment #1: Type: text/plain, Size: 1235 bytes --] On Sat, 7 Jan 2012 14:28:10 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > I try to address the concerns that have come up in previous attempts. > In particular, I include a patch that creates a new customization > variable, notmuch-search-exclude-deleted, that will exclude any > messages with the "deleted" tag from searches. This actually makes > "deleted" messages appear effectively deleted, which is one of the > things cworth wanted to see, and one of the reasons he kept pushing > back on previous attempts at this functionality. I honestly don't understand the reason for this. If someone wants to not see messages that they have tagged as 'deleted', they add 'and not tag:deleted' to the end of the search expression. The messages aren't actually deleted because they have the 'deleted' tag, so why would they not be shown? If it's really intended that those messages not be shown then perhaps the tag should be called 'not-shown' or something. > Also, no tags other than "deleted" are modified. All tags should be > orthogonal, and should be handled so. +1 The name 'deleted' for the tag should be a configuration option, as a non-English speaker (for example) might want to use something else. [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: another attempt to add delete functionality in emacs 2012-01-10 7:47 ` another attempt to add delete functionality in emacs David Edmondson @ 2012-01-10 20:01 ` David Bremner 2012-01-11 3:12 ` Jameson Graef Rollins 2012-01-11 2:56 ` Jameson Graef Rollins 1 sibling, 1 reply; 176+ messages in thread From: David Bremner @ 2012-01-10 20:01 UTC (permalink / raw) To: David Edmondson, Jameson Graef Rollins, Notmuch Mail On Tue, 10 Jan 2012 07:47:23 +0000, David Edmondson <dme@dme.org> wrote: > On Sat, 7 Jan 2012 14:28:10 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > > I try to address the concerns that have come up in previous attempts. > > In particular, I include a patch that creates a new customization > > variable, notmuch-search-exclude-deleted, that will exclude any > > messages with the "deleted" tag from searches. [snip] > I honestly don't understand the reason for this. If someone wants to not > see messages that they have tagged as 'deleted', they add 'and not > tag:deleted' to the end of the search expression. Just thinking out loud here, but it does seem a bit unfortunate to me that it represents a pretty fundamental divergence between the CLI and the emacs interface. Mind you, I guess one could make the same argument about the libs versus the CLI. Lack of configuration information in the library (possibly among other reasons) makes this not too nice to support in the current library either. d ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: another attempt to add delete functionality in emacs 2012-01-10 20:01 ` David Bremner @ 2012-01-11 3:12 ` Jameson Graef Rollins 2012-01-11 5:16 ` Jani Nikula 2012-01-11 8:26 ` David Edmondson 0 siblings, 2 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-11 3:12 UTC (permalink / raw) To: David Bremner, David Edmondson, Notmuch Mail [-- Attachment #1: Type: text/plain, Size: 1782 bytes --] On Tue, 10 Jan 2012 16:01:32 -0400, David Bremner <david@tethera.net> wrote: > Just thinking out loud here, but it does seem a bit unfortunate to me > that it represents a pretty fundamental divergence between the CLI and > the emacs interface. Mind you, I guess one could make the same argument > about the libs versus the CLI. Lack of configuration information in the > library (possibly among other reasons) makes this not too nice to > support in the current library either. I think a consensus has formed that this functionality (automatically suppressing messages with certain tags from searches) is better left to the CLI, rather than implementing it just in the emacs UI. Unfortunately I'm not going to get to that any time soon. However, without that functionality, I really see no reason why we should be adding any built-in support for adding "deleted" tags in the emacs UI. Without the CLI change, "deleted" tags aren't handled any differently than any other tag, so why should the default emacs UI care. If users want to bind keys to special tagging operations, they can do so for themselves [0]. In fact, I'm now starting to think we don't need to add any support for special tagging operations (such as "deleted") even if we *do* have support for suppressing them in the CLI. Special tagging operations should only be supported if the tagged messages are somehow handled specially. If not, then again, we should just leave them up to the user [0]. All that said, I think I'll just resubmit the couple small changes to the emacs UI that I think we should consider adopting anyway. jamie. [0] (define-key notmuch-show-mode-map "d" (lambda () "Delete message" (interactive) (notmuch-show-add-tag "deleted") (notmuch-show-next-open-message))) [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: another attempt to add delete functionality in emacs 2012-01-11 3:12 ` Jameson Graef Rollins @ 2012-01-11 5:16 ` Jani Nikula 2012-01-11 5:38 ` Austin Clements 2012-01-11 8:26 ` David Edmondson 1 sibling, 1 reply; 176+ messages in thread From: Jani Nikula @ 2012-01-11 5:16 UTC (permalink / raw) To: Jameson Graef Rollins, David Bremner, David Edmondson, Notmuch Mail On Tue, 10 Jan 2012 19:12:16 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > On Tue, 10 Jan 2012 16:01:32 -0400, David Bremner <david@tethera.net> wrote: > > Just thinking out loud here, but it does seem a bit unfortunate to me > > that it represents a pretty fundamental divergence between the CLI and > > the emacs interface. Mind you, I guess one could make the same argument > > about the libs versus the CLI. Lack of configuration information in the > > library (possibly among other reasons) makes this not too nice to > > support in the current library either. > > I think a consensus has formed that this functionality (automatically > suppressing messages with certain tags from searches) is better left to > the CLI, rather than implementing it just in the emacs UI. > Unfortunately I'm not going to get to that any time soon. I could have a go at it, but I can't make any promises about getting to that any time soon either. So what if emacs ui goes head first and does something that should be done in the CLI in a perfect world? If it's added properly, it can be taken out if/when this pops up in the CLI. Also, there already *is* filtering for "all tags" list. See notmuch-hello-tag-list-make-query. How about having something like that for saved searches? I know it's not the same as your original, but it's middle ground... > However, without that functionality, I really see no reason why we > should be adding any built-in support for adding "deleted" tags in the > emacs UI. Without the CLI change, "deleted" tags aren't handled any > differently than any other tag, so why should the default emacs UI care. > If users want to bind keys to special tagging operations, they can do so > for themselves [0]. In fact, "deleted" used to be special, but that was, err, deleted because it had problems: 2c262042ac174d7bc96d6035ab9c88bd0abe7f35. If that ever gets fixed, "deleted" would be special again. BR, Jani. ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: another attempt to add delete functionality in emacs 2012-01-11 5:16 ` Jani Nikula @ 2012-01-11 5:38 ` Austin Clements 0 siblings, 0 replies; 176+ messages in thread From: Austin Clements @ 2012-01-11 5:38 UTC (permalink / raw) To: Jani Nikula; +Cc: Notmuch Mail Quoth Jani Nikula on Jan 11 at 7:16 am: > On Tue, 10 Jan 2012 19:12:16 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > > On Tue, 10 Jan 2012 16:01:32 -0400, David Bremner <david@tethera.net> wrote: > > > Just thinking out loud here, but it does seem a bit unfortunate to me > > > that it represents a pretty fundamental divergence between the CLI and > > > the emacs interface. Mind you, I guess one could make the same argument > > > about the libs versus the CLI. Lack of configuration information in the > > > library (possibly among other reasons) makes this not too nice to > > > support in the current library either. > > > > I think a consensus has formed that this functionality (automatically > > suppressing messages with certain tags from searches) is better left to > > the CLI, rather than implementing it just in the emacs UI. > > Unfortunately I'm not going to get to that any time soon. > > I could have a go at it, but I can't make any promises about getting to > that any time soon either. So what if emacs ui goes head first and does > something that should be done in the CLI in a perfect world? If it's > added properly, it can be taken out if/when this pops up in the CLI. Too late. See id:"1326258173-21163-1-git-send-email-amdragon@mit.edu" ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: another attempt to add delete functionality in emacs 2012-01-11 3:12 ` Jameson Graef Rollins 2012-01-11 5:16 ` Jani Nikula @ 2012-01-11 8:26 ` David Edmondson 1 sibling, 0 replies; 176+ messages in thread From: David Edmondson @ 2012-01-11 8:26 UTC (permalink / raw) To: Jameson Graef Rollins, David Bremner, Notmuch Mail [-- Attachment #1: Type: text/plain, Size: 727 bytes --] On Tue, 10 Jan 2012 19:12:16 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote: > In fact, I'm now starting to think we don't need to add any support > for special tagging operations (such as "deleted") even if we *do* > have support for suppressing them in the CLI. Special tagging > operations should only be supported if the tagged messages are somehow > handled specially. If not, then again, we should just leave them up > to the user [0]. Agreed. The more interesting patch is the one that maps from the 'deleted' tag to the 'T' bit, at least as someone who is mostly maildir-ignorant it seems that way. The keybindings are easy for a user to play with. The behaviour of the core library much less so. [-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
* Re: another attempt to add delete functionality in emacs 2012-01-10 7:47 ` another attempt to add delete functionality in emacs David Edmondson 2012-01-10 20:01 ` David Bremner @ 2012-01-11 2:56 ` Jameson Graef Rollins 1 sibling, 0 replies; 176+ messages in thread From: Jameson Graef Rollins @ 2012-01-11 2:56 UTC (permalink / raw) To: David Edmondson, Notmuch Mail [-- Attachment #1: Type: text/plain, Size: 514 bytes --] On Tue, 10 Jan 2012 07:47:23 +0000, David Edmondson <dme@dme.org> wrote: > I honestly don't understand the reason for this. If someone wants to not > see messages that they have tagged as 'deleted', they add 'and not > tag:deleted' to the end of the search expression. Adding "and not tag:deleted" in all of your searches vs. having it done automatically? That a pretty big usability difference to me. The config variable is included so that people can turn the functionality on or off as they see fit. jamie. [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 176+ messages in thread
end of thread, other threads:[~2012-02-11 19:00 UTC | newest] Thread overview: 176+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-01-07 22:28 another attempt to add delete functionality in emacs Jameson Graef Rollins 2012-01-07 22:28 ` [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search Jameson Graef Rollins 2012-01-07 22:28 ` [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging Jameson Graef Rollins 2012-01-07 22:28 ` [PATCH 3/4] emacs: add ability to "delete" messages and threads Jameson Graef Rollins 2012-01-07 22:28 ` [PATCH 4/4] emacs: modify help message for notmuch-search-line-faces to reflect preferred "deleted" tag name Jameson Graef Rollins 2012-01-08 1:26 ` change to default archive/delete key bindings Jameson Graef Rollins 2012-01-08 1:26 ` [PATCH 1/4] emacs: add show-mode functions to archive/delete only current message Jameson Graef Rollins 2012-01-08 1:26 ` [PATCH 2/4] emacs: add option to notmuch-show-next-open-message to pop out to parent buffer if at end Jameson Graef Rollins 2012-01-08 1:26 ` [PATCH 3/4] emacs: modify the default show-mode key bindings for archiving/deleting Jameson Graef Rollins 2012-01-08 1:26 ` [PATCH 4/4] emacs: use pop-at-end functionality in archive/delete-message functions Jameson Graef Rollins 2012-01-08 18:56 ` [PATCH 4/4 v2] " Jameson Graef Rollins 2012-01-08 19:28 ` [PATCH 4/4 v3] " Jameson Graef Rollins 2012-01-09 1:12 ` [PATCH 2/4] emacs: add option to notmuch-show-next-open-message to pop out to parent buffer if at end Aaron Ecay 2012-01-08 19:09 ` [PATCH 1/4 v2] emacs: add show-mode functions to archive/delete only current message Jameson Graef Rollins 2012-01-10 7:43 ` David Edmondson 2012-01-10 7:48 ` change to default archive/delete key bindings David Edmondson 2012-01-09 1:08 ` [PATCH 2/4] emacs: repurpose notmuch-show-archive-thread-internal function for general thread tagging Aaron Ecay 2012-01-09 2:49 ` Jameson Graef Rollins 2012-01-09 5:02 ` Aaron Ecay 2012-01-11 2:56 ` Jameson Graef Rollins 2012-01-11 5:53 ` Aaron Ecay 2012-01-11 7:07 ` Jameson Graef Rollins 2012-01-09 1:14 ` [PATCH 1/4] emacs: new customization variable to exclude "deleted" messages from search Aaron Ecay 2012-01-09 1:49 ` Austin Clements 2012-01-09 2:34 ` Jameson Graef Rollins 2012-01-09 2:46 ` Austin Clements 2012-01-09 4:31 ` Austin Clements 2012-01-11 5:02 ` [PATCH 0/3] Automatic tag-based exclusion Austin Clements 2012-01-11 5:02 ` [PATCH 1/3] count: Convert to new-style argument parsing Austin Clements 2012-01-11 8:17 ` Jani Nikula 2012-01-11 18:26 ` Austin Clements 2012-01-11 18:27 ` Jani Nikula 2012-01-11 5:02 ` [PATCH 2/3] lib: Add support for automatically excluding tags from queries Austin Clements 2012-01-11 10:11 ` Jani Nikula 2012-01-11 18:48 ` Austin Clements 2012-01-11 5:02 ` [PATCH 3/3] search: Support automatic tag exclusions Austin Clements 2012-01-11 19:27 ` Jani Nikula 2012-01-11 7:05 ` [PATCH 0/3] Automatic tag-based exclusion Jameson Graef Rollins 2012-01-13 23:07 ` [PATCH v2 0/3] Austin Clements 2012-01-13 23:07 ` [PATCH v2 1/3] count: Convert to new-style argument parsing Austin Clements 2012-01-14 1:49 ` David Bremner 2012-01-13 23:07 ` [PATCH v2 2/3] lib: Add support for automatically excluding tags from queries Austin Clements 2012-01-14 23:38 ` Jameson Graef Rollins 2012-01-15 0:05 ` Austin Clements 2012-01-13 23:07 ` [PATCH v2 3/3] search: Support automatic tag exclusions Austin Clements 2012-01-14 23:40 ` Jameson Graef Rollins 2012-01-15 0:14 ` Austin Clements 2012-01-16 9:12 ` David Edmondson 2012-01-16 19:28 ` Austin Clements 2012-01-16 22:18 ` Jeremy Nickurak 2012-01-16 22:25 ` Jameson Graef Rollins [not found] ` <CA+eQo_3xxuhgUUXWXWyVD1LFhvhkw2psbA3ZnFnZk=BjjHXy8w@mail.gmail.com> 2012-01-17 9:08 ` David Edmondson 2012-01-17 20:32 ` Austin Clements 2012-01-18 8:38 ` David Edmondson 2012-01-18 8:52 ` Jameson Graef Rollins 2012-01-18 9:52 ` David Edmondson 2012-01-18 18:51 ` Jameson Graef Rollins 2012-01-16 19:34 ` Jameson Graef Rollins 2012-01-14 23:38 ` [PATCH v2 0/3] Jameson Graef Rollins 2012-01-15 0:17 ` [PATCH v3 0/2] Automatic tag-based exclusion Austin Clements 2012-01-15 0:17 ` [PATCH v3 1/2] lib: Add support for automatically excluding tags from queries Austin Clements 2012-01-15 0:17 ` [PATCH v3 2/2] search: Support automatic tag exclusions Austin Clements 2012-01-19 19:19 ` Pieter Praet 2012-01-19 19:19 ` [PATCH 1/4] search: rename auto_exclude_tags to {search, }exclude_tags Pieter Praet 2012-01-19 19:41 ` [PATCH 1/4] search: rename auto_exclude_tags to {search,}exclude_tags Austin Clements 2012-01-19 21:14 ` [PATCH 1/4] search: rename auto_exclude_tags to {search, }exclude_tags Pieter Praet 2012-01-19 19:19 ` [PATCH 2/4] test: only exclude "deleted" messages from search if explicitly configured Pieter Praet 2012-01-19 19:19 ` [PATCH 3/4] config: only set search.exclude_tags to "deleted; spam; " during setup Pieter Praet 2012-01-22 22:14 ` Xavier Maillard 2012-01-22 22:53 ` Jameson Graef Rollins 2012-01-23 5:05 ` Pieter Praet 2012-01-23 5:34 ` Jameson Graef Rollins 2012-01-23 7:35 ` Pieter Praet 2012-01-23 7:22 ` Jani Nikula 2012-01-23 7:38 ` Jameson Graef Rollins 2012-01-23 8:24 ` Jani Nikula 2012-01-23 8:45 ` Jameson Graef Rollins 2012-01-25 0:43 ` Pieter Praet 2012-01-23 8:03 ` Pieter Praet 2012-01-23 8:31 ` Jani Nikula 2012-01-25 0:42 ` Pieter Praet 2012-01-23 4:16 ` Pieter Praet 2012-01-19 19:19 ` [PATCH 4/4] setup: prompt user for search.exclude_tags value Pieter Praet 2012-01-19 19:44 ` Austin Clements 2012-01-19 21:16 ` Pieter Praet 2012-01-20 4:19 ` Austin Clements 2012-01-22 6:55 ` Pieter Praet 2012-01-22 17:08 ` Austin Clements 2012-01-23 4:17 ` Pieter Praet 2012-01-23 4:22 ` [PATCH v2 1/6] search: rename auto_exclude_tags to {search, }exclude_tags Pieter Praet 2012-01-23 23:28 ` David Bremner 2012-01-23 4:22 ` [PATCH v2 2/6] test: only exclude "deleted" messages from search if explicitly configured Pieter Praet 2012-01-23 4:22 ` [PATCH v2 3/6] config: only exclude messages if 'search.exclude_tags' is explicitly set Pieter Praet 2012-01-23 4:22 ` [PATCH v2 4/6] setup: move tag printing and parsing into separate functions Pieter Praet 2012-01-23 5:07 ` Austin Clements 2012-01-23 5:50 ` [PATCH v3 4/6] setup: Create functions for tag list printing and parsing Pieter Praet 2012-01-23 4:22 ` [PATCH v2 5/6] setup: prompt user for search.exclude_tags value Pieter Praet 2012-01-23 4:34 ` Austin Clements 2012-01-23 5:40 ` [PATCH v3 " Pieter Praet 2012-01-23 4:22 ` [PATCH v2 6/6] NEWS: update "Tag exclusion" section Pieter Praet 2012-01-23 4:41 ` Austin Clements 2012-01-23 5:41 ` [PATCH v3 " Pieter Praet 2012-01-23 14:49 ` Austin Clements 2012-01-19 19:36 ` [PATCH v3 2/2] search: Support automatic tag exclusions Austin Clements 2012-01-19 20:06 ` markwalters1009 2012-01-19 20:16 ` Aaron Ecay 2012-01-19 20:23 ` Mark Walters 2012-01-19 20:28 ` Austin Clements 2012-01-19 22:01 ` Mark Walters 2012-01-19 22:03 ` [PATCH] Automatically exclude tags in notmuch-show Mark Walters 2012-01-19 22:59 ` Austin Clements 2012-01-19 23:54 ` Pieter Praet 2012-01-20 0:10 ` Mark Walters 2012-01-20 17:18 ` Austin Clements 2012-01-22 0:38 ` Mark Walters 2012-01-22 17:31 ` Austin Clements 2012-01-22 18:16 ` Austin Clements 2012-01-22 18:47 ` Mark Walters 2012-01-23 1:13 ` Mark Walters 2012-01-23 1:52 ` Austin Clements 2012-01-24 1:05 ` Mark Walters 2012-01-24 1:16 ` Austin Clements 2012-01-24 1:18 ` [RFC PATCH 1/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters 2012-01-24 1:18 ` [RFC PATCH 2/4] " Mark Walters 2012-01-24 2:45 ` Austin Clements 2012-01-24 11:20 ` Mark Walters 2012-01-28 10:51 ` Mark Walters 2012-01-28 18:33 ` Austin Clements 2012-01-28 23:57 ` Mark Walters 2012-01-29 0:04 ` [PATCH 1/4] Add exclude flag Mark Walters 2012-01-29 0:04 ` [PATCH 2/4] " Mark Walters 2012-01-29 0:04 ` [PATCH 3/4] " Mark Walters 2012-01-29 0:04 ` [PATCH 4/4] " Mark Walters 2012-01-29 10:37 ` [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Mark Walters 2012-01-29 18:36 ` Mark Walters 2012-01-29 18:39 ` [PATCH 1/7] cli: add --do-not-exclude option to count and search Mark Walters 2012-01-31 4:17 ` Austin Clements 2012-01-31 11:40 ` Mark Walters 2012-01-31 16:18 ` Austin Clements 2012-01-31 16:31 ` Jameson Graef Rollins 2012-02-11 18:44 ` Jameson Graef Rollins 2012-02-11 18:50 ` Austin Clements 2012-02-11 19:00 ` Jameson Graef Rollins 2012-01-29 18:39 ` [PATCH 2/7] lib: Rearrange the exclude code in query.cc Mark Walters 2012-01-29 18:39 ` [PATCH 3/7] lib: Make notmuch_query_search_messages set the exclude flag Mark Walters 2012-01-31 4:43 ` Austin Clements 2012-01-31 11:45 ` Mark Walters 2012-01-31 16:25 ` Austin Clements 2012-02-01 18:00 ` Mark Walters 2012-01-29 18:39 ` [PATCH 4/7] lib: Add the exclude flag to notmuch_query_search_threads Mark Walters 2012-01-31 4:50 ` Austin Clements 2012-01-31 11:47 ` Mark Walters 2012-01-31 5:07 ` Austin Clements 2012-01-29 18:39 ` [PATCH 5/7] cli: Make notmuch-show respect excludes Mark Walters 2012-01-31 4:56 ` Austin Clements 2012-01-31 12:30 ` Mark Walters 2012-01-29 18:39 ` [PATCH 6/7] cli: omit excluded messages in results where appropriate Mark Walters 2012-01-29 18:39 ` [PATCH 7/7] emacs: show: recognize the exclude flag Mark Walters 2012-01-31 5:08 ` [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag Austin Clements 2012-01-24 1:18 ` [RFC PATCH 3/4] " Mark Walters 2012-01-24 2:53 ` Austin Clements 2012-01-24 1:18 ` [PATCH 4/4] " Mark Walters 2012-01-19 22:44 ` [PATCH v3 2/2] search: Support automatic tag exclusions Pieter Praet 2012-01-19 21:21 ` Pieter Praet 2012-01-22 22:09 ` Xavier Maillard 2012-01-23 4:15 ` Pieter Praet 2012-01-16 19:35 ` [PATCH v3 0/2] Automatic tag-based exclusion Jameson Graef Rollins 2012-01-17 1:08 ` David Bremner 2012-01-18 20:58 ` [PATCH] News for tag exclusion Austin Clements 2012-01-10 7:47 ` another attempt to add delete functionality in emacs David Edmondson 2012-01-10 20:01 ` David Bremner 2012-01-11 3:12 ` Jameson Graef Rollins 2012-01-11 5:16 ` Jani Nikula 2012-01-11 5:38 ` Austin Clements 2012-01-11 8:26 ` David Edmondson 2012-01-11 2:56 ` Jameson Graef Rollins
Code repositories for project(s) associated with this public inbox https://yhetil.org/notmuch.git/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).