unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH 1/3] notmuch-search: implement 'filesize' search
@ 2017-05-06 20:45 Ioan-Adrian Ratiu
  2017-05-06 20:45 ` [PATCH 2/3] emacs: make notmuch-search-oldest-first generic Ioan-Adrian Ratiu
  2017-05-06 20:45 ` [PATCH 3/3] emacs: notmuch-search: add filesize sorting Ioan-Adrian Ratiu
  0 siblings, 2 replies; 3+ messages in thread
From: Ioan-Adrian Ratiu @ 2017-05-06 20:45 UTC (permalink / raw)
  To: notmuch

I need to keep track of my mail file sizes and writing custom
parsers/scripts and running them on the maildir is problematic
especially for managing large collections of email.

Having a way to search email based on file sizes would be very useful,
also copled with notmuch's incremental maildir indexing/parsing, rapid
result navigation/sorting via Emacs makes my life a lot easier.

So this commit adds the following capability (sizes are in bytes
because that's what I'm interested in, other inputs can be added
I guess). Replace the range param to get mails of a specific size:

notmuch search --sort=biggest-first filesize:1000..100000

I didn't think of another front-end for this other than the command
line and saved searches from the Emacs GUI, which work well enough for
me with this patch series, but it would be simple to also expose the
filesize info on the screen somewhere in the results/show buffer.

Another interesting idea would be to offer some optional statistics
in the UI buffers like we do for saved searches `query-count` to show
stuff like disk space occupied by mail files maching a search, etc.

Signed-off-by: Ioan-Adrian Ratiu <adi@adirat.com>
---
 lib/database-private.h |  1 +
 lib/database.cc        |  6 ++++++
 lib/index.cc           | 10 ++++++++++
 lib/message-file.c     | 18 +++++++++++++++++-
 lib/message.cc         | 29 +++++++++++++++++++++++++++++
 lib/notmuch-private.h  | 16 ++++++++++++++++
 lib/notmuch.h          | 14 ++++++++++++++
 lib/query.cc           |  6 ++++++
 notmuch-search.c       |  2 ++
 9 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/lib/database-private.h b/lib/database-private.h
index ab3d9691..a7e0a020 100644
--- a/lib/database-private.h
+++ b/lib/database-private.h
@@ -217,6 +217,7 @@ struct _notmuch_database {
     Xapian::ValueRangeProcessor *value_range_processor;
     Xapian::ValueRangeProcessor *date_range_processor;
     Xapian::ValueRangeProcessor *last_mod_range_processor;
+    Xapian::ValueRangeProcessor *filesize_range_processor;
 };
 
 /* Prior to database version 3, features were implied by the database
diff --git a/lib/database.cc b/lib/database.cc
index 5bc131a3..e6d5dd11 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -290,6 +290,7 @@ prefix_t prefix_table[] = {
     { "subject",		"XSUBJECT",	NOTMUCH_FIELD_EXTERNAL |
 						NOTMUCH_FIELD_PROBABILISTIC |
 						NOTMUCH_FIELD_PROCESSOR},
+    { "filesize",		"XFILESIZE",	NOTMUCH_FIELD_EXTERNAL },
 };
 
 static void
@@ -1076,6 +1077,7 @@ notmuch_database_open_verbose (const char *path,
 	notmuch->value_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP);
 	notmuch->date_range_processor = new ParseTimeValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP);
 	notmuch->last_mod_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_LAST_MOD, "lastmod:");
+	notmuch->filesize_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_FILESIZE, "filesize:");
 
 	notmuch->query_parser->set_default_op (Xapian::Query::OP_AND);
 	notmuch->query_parser->set_database (*notmuch->xapian_db);
@@ -1084,6 +1086,7 @@ notmuch_database_open_verbose (const char *path,
 	notmuch->query_parser->add_valuerangeprocessor (notmuch->value_range_processor);
 	notmuch->query_parser->add_valuerangeprocessor (notmuch->date_range_processor);
 	notmuch->query_parser->add_valuerangeprocessor (notmuch->last_mod_range_processor);
+	notmuch->query_parser->add_valuerangeprocessor (notmuch->filesize_range_processor);
 
 	for (i = 0; i < ARRAY_SIZE (prefix_table); i++) {
 	    const prefix_t *prefix = &prefix_table[i];
@@ -1160,6 +1163,8 @@ notmuch_database_close (notmuch_database_t *notmuch)
     notmuch->date_range_processor = NULL;
     delete notmuch->last_mod_range_processor;
     notmuch->last_mod_range_processor = NULL;
+    delete notmuch->filesize_range_processor;
+    notmuch->filesize_range_processor = NULL;
 
     return status;
 }
@@ -2557,6 +2562,7 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
 	}
 
 	_notmuch_message_add_filename (message, filename);
+	_notmuch_message_add_filesize (message, message_file);
 
 	/* Is this a newly created message object or a ghost
 	 * message?  We have to be slightly careful: if this is a
diff --git a/lib/index.cc b/lib/index.cc
index 8c145540..e8655bc1 100644
--- a/lib/index.cc
+++ b/lib/index.cc
@@ -441,6 +441,8 @@ _notmuch_message_index_file (notmuch_message_t *message,
     InternetAddressList *addresses;
     const char *from, *subject;
     notmuch_status_t status;
+    unsigned long filesize;
+    char *filesize_str;
 
     status = _notmuch_message_file_get_mime_message (message_file,
 						     &mime_message);
@@ -464,6 +466,14 @@ _notmuch_message_index_file (notmuch_message_t *message,
     subject = g_mime_message_get_subject (mime_message);
     _notmuch_message_gen_terms (message, "subject", subject);
 
+    filesize = _notmuch_message_file_get_size (message_file);
+    filesize_str = talloc_asprintf(NULL, "%lu", filesize);
+    if (! filesize_str)
+	return NOTMUCH_STATUS_OUT_OF_MEMORY;
+
+    _notmuch_message_add_term (message, "filesize", filesize_str);
+    talloc_free (filesize_str);
+
     _index_mime_part (message, g_mime_message_get_mime_part (mime_message));
 
     return NOTMUCH_STATUS_SUCCESS;
diff --git a/lib/message-file.c b/lib/message-file.c
index db18b163..f75593e3 100644
--- a/lib/message-file.c
+++ b/lib/message-file.c
@@ -26,10 +26,13 @@
 
 #include <glib.h> /* GHashTable */
 
+#include <glib/gstdio.h>
+
 struct _notmuch_message_file {
     /* File object */
     FILE *file;
     char *filename;
+    unsigned long filesize; /* in bytes */
 
     /* Cache for decoded headers */
     GHashTable *headers;
@@ -64,7 +67,7 @@ _notmuch_message_file_open_ctx (notmuch_database_t *notmuch,
     if (unlikely (message == NULL))
 	return NULL;
 
-    /* Only needed for error messages during parsing. */
+    /* Only needed during parsing */
     message->filename = talloc_strdup (message, filename);
     if (message->filename == NULL)
 	goto FAIL;
@@ -98,6 +101,12 @@ _notmuch_message_file_close (notmuch_message_file_t *message)
     talloc_free (message);
 }
 
+unsigned long
+_notmuch_message_file_get_size (notmuch_message_file_t *message)
+{
+    return message->filesize;
+}
+
 static notmuch_bool_t
 _is_mbox (FILE *file)
 {
@@ -122,6 +131,8 @@ _notmuch_message_file_parse (notmuch_message_file_t *message)
     notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
     static int initialized = 0;
     notmuch_bool_t is_mbox;
+    GStatBuf statResult;
+    int ret;
 
     if (message->message)
 	return NOTMUCH_STATUS_SUCCESS;
@@ -133,6 +144,11 @@ _notmuch_message_file_parse (notmuch_message_file_t *message)
 	initialized = 1;
     }
 
+    /* filesize defaults to zero which is ignored */
+    ret = g_stat(message->filename, &statResult);
+    if (! ret)
+	message->filesize = statResult.st_size;
+
     message->headers = g_hash_table_new_full (strcase_hash, strcase_equal,
 					      free, g_free);
     if (! message->headers)
diff --git a/lib/message.cc b/lib/message.cc
index c2721191..83b4c4db 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -988,6 +988,26 @@ notmuch_message_get_date (notmuch_message_t *message)
     return Xapian::sortable_unserialise (value);
 }
 
+unsigned long
+notmuch_message_get_filesize (notmuch_message_t *message)
+{
+    std::string value;
+
+    try {
+	value = message->doc.get_value (NOTMUCH_VALUE_FILESIZE);
+    } catch (Xapian::Error &error) {
+	_notmuch_database_log(_notmuch_message_database (message), "A Xapian exception occurred when reading filesize: %s\n",
+		 error.get_msg().c_str());
+	message->notmuch->exception_reported = TRUE;
+	return 0;
+    }
+
+    if (value.empty ())
+	/* sortable_unserialise is undefined on empty string */
+	return 0;
+    return Xapian::sortable_unserialise (value);
+}
+
 notmuch_tags_t *
 notmuch_message_get_tags (notmuch_message_t *message)
 {
@@ -1208,6 +1228,15 @@ _notmuch_message_close (notmuch_message_t *message)
     }
 }
 
+void
+_notmuch_message_add_filesize (notmuch_message_t *message,
+			       notmuch_message_file_t *message_file)
+{
+    unsigned long filesize = _notmuch_message_file_get_size(message_file);
+    message->doc.add_value (NOTMUCH_VALUE_FILESIZE,
+			    Xapian::sortable_serialise (filesize));
+}
+
 /* Add a name:value term to 'message', (the actual term will be
  * encoded by prefixing the value with a short prefix). See
  * NORMAL_PREFIX and BOOLEAN_PREFIX arrays for the mapping of term
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 8587e86c..3c15ed3d 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -110,6 +110,7 @@ typedef enum {
     NOTMUCH_VALUE_FROM,
     NOTMUCH_VALUE_SUBJECT,
     NOTMUCH_VALUE_LAST_MOD,
+    NOTMUCH_VALUE_FILESIZE,
 } notmuch_value_t;
 
 /* Xapian (with flint backend) complains if we provide a term longer
@@ -400,6 +401,21 @@ _notmuch_message_file_close (notmuch_message_file_t *message);
 notmuch_status_t
 _notmuch_message_file_parse (notmuch_message_file_t *message);
 
+/*
+ * Get the filesize of a message file
+ *
+ * This filesize member is read during file parsing.
+ */
+unsigned long
+_notmuch_message_file_get_size (notmuch_message_file_t *message);
+
+/*
+ * Set the message filesize to the size of the message_file
+ */
+void
+_notmuch_message_add_filesize (notmuch_message_t *message,
+			       notmuch_message_file_t *message_file);
+
 /* Get the gmime message of a message file.
  *
  * The message file is parsed as necessary.
diff --git a/lib/notmuch.h b/lib/notmuch.h
index d374dc96..8cff214f 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -741,6 +741,14 @@ typedef enum {
      */
     NOTMUCH_SORT_MESSAGE_ID,
     /**
+     * Smallest first.
+     */
+    NOTMUCH_SORT_SMALLEST_FIRST,
+    /**
+     * Biggest first
+     */
+    NOTMUCH_SORT_BIGGEST_FIRST,
+    /**
      * Do not sort.
      */
     NOTMUCH_SORT_UNSORTED
@@ -1411,6 +1419,12 @@ time_t
 notmuch_message_get_date  (notmuch_message_t *message);
 
 /**
+ * Get the filesize in bytes of 'message'.
+ */
+unsigned long
+notmuch_message_get_filesize  (notmuch_message_t *message);
+
+/**
  * Get the value of the specified header from 'message' as a UTF-8 string.
  *
  * Common headers are stored in the database when the message is
diff --git a/lib/query.cc b/lib/query.cc
index 212e27f0..6b0b6dd7 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -330,6 +330,12 @@ _notmuch_query_search_documents (notmuch_query_t *query,
 	case NOTMUCH_SORT_MESSAGE_ID:
 	    enquire.set_sort_by_value (NOTMUCH_VALUE_MESSAGE_ID, FALSE);
 	    break;
+	case NOTMUCH_SORT_SMALLEST_FIRST:
+	    enquire.set_sort_by_value (NOTMUCH_VALUE_FILESIZE, FALSE);
+	    break;
+	case NOTMUCH_SORT_BIGGEST_FIRST:
+	    enquire.set_sort_by_value (NOTMUCH_VALUE_FILESIZE, TRUE);
+	    break;
 	case NOTMUCH_SORT_UNSORTED:
 	    break;
 	}
diff --git a/notmuch-search.c b/notmuch-search.c
index 019e14ee..65ecfaab 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -778,6 +778,8 @@ static const notmuch_opt_desc_t common_options[] = {
     { NOTMUCH_OPT_KEYWORD, &search_context.sort, "sort", 's',
       (notmuch_keyword_t []){ { "oldest-first", NOTMUCH_SORT_OLDEST_FIRST },
 			      { "newest-first", NOTMUCH_SORT_NEWEST_FIRST },
+			      { "smallest-first", NOTMUCH_SORT_SMALLEST_FIRST },
+			      { "biggest-first", NOTMUCH_SORT_BIGGEST_FIRST },
 			      { 0, 0 } } },
     { NOTMUCH_OPT_KEYWORD, &search_context.format_sel, "format", 'f',
       (notmuch_keyword_t []){ { "json", NOTMUCH_FORMAT_JSON },
-- 
2.12.2

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/3] emacs: make notmuch-search-oldest-first generic
  2017-05-06 20:45 [PATCH 1/3] notmuch-search: implement 'filesize' search Ioan-Adrian Ratiu
@ 2017-05-06 20:45 ` Ioan-Adrian Ratiu
  2017-05-06 20:45 ` [PATCH 3/3] emacs: notmuch-search: add filesize sorting Ioan-Adrian Ratiu
  1 sibling, 0 replies; 3+ messages in thread
From: Ioan-Adrian Ratiu @ 2017-05-06 20:45 UTC (permalink / raw)
  To: notmuch

The current search result order logic assumes results are always
sorted by date and thus uses a boolean switch for oldest/newest
ordering specifications.

This is problematic if I want to introduce other result orderings,
like for example based on the mail-file size with smallest/biggest
ordering specifications.

In the interest of keeping all current logic intact and reusable,
while at the same time supporting multiple search result orderings,
change the defcustom configuration notmuch-search-oldest-first to
notmuch-search-default-sort-order which takes values 'oldest-first
and 'newest-first (for now).

Implementing new result orderings thus becomes a simple matter of
adding more possible entries for notmuch-search-default-sort-order.

Aside from the UI variable rename change, this commit should be
totally transparent for the user, it does not modify or add any new
result sorting logic.

Signed-off-by: Ioan-Adrian Ratiu <adi@adirat.com>
---
 doc/notmuch-emacs.rst  |  4 ++--
 emacs/notmuch-hello.el | 15 +++++++--------
 emacs/notmuch-jump.el  | 11 +++++------
 emacs/notmuch-lib.el   |  7 ++++---
 emacs/notmuch-tree.el  |  2 +-
 emacs/notmuch.el       | 29 +++++++++++++++--------------
 6 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst
index 5e25996f..66a69bb8 100644
--- a/doc/notmuch-emacs.rst
+++ b/doc/notmuch-emacs.rst
@@ -169,8 +169,8 @@ variables.
     Control how each thread of messages is presented in the
     ``notmuch-show-mode`` buffer
 
-:index:`notmuch-search-oldest-first`
-    Display the oldest threads at the top of the buffer
+:index:`notmuch-search-default-sort-order`
+    Control the default search result method
 
 .. _notmuch-show:
 
diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index c858a20b..3ba2a16b 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -28,7 +28,7 @@
 (require 'notmuch-lib)
 (require 'notmuch-mua)
 
-(declare-function notmuch-search "notmuch" (&optional query oldest-first target-thread target-line continuation))
+(declare-function notmuch-search "notmuch" (&optional query sort-order target-thread target-line continuation))
 (declare-function notmuch-poll "notmuch" ())
 (declare-function notmuch-tree "notmuch-tree"
                   (&optional query query-context target buffer-name open-target))
@@ -381,7 +381,7 @@ afterwards.")
     (setq search (notmuch-hello-trim search))
     (let ((history-delete-duplicates t))
       (add-to-history 'notmuch-search-history search)))
-  (notmuch-search search notmuch-search-oldest-first))
+  (notmuch-search search notmuch-search-default-sort-order))
 
 (defun notmuch-hello-add-saved-search (widget)
   (interactive)
@@ -443,7 +443,7 @@ diagonal."
     (notmuch-search (widget-get widget
 				:notmuch-search-terms)
 		    (widget-get widget
-				:notmuch-search-oldest-first))))
+				:notmuch-search-sort-order))))
 
 (defun notmuch-saved-search-count (search)
   (car (process-lines notmuch-command "count" search)))
@@ -575,10 +575,9 @@ with `notmuch-hello-query-counts'."
 		  (widget-insert (make-string column-indent ? )))
 	      (let* ((name (plist-get elem :name))
 		     (query (plist-get elem :query))
-		     (oldest-first (case (plist-get elem :sort-order)
-				     (newest-first nil)
-				     (oldest-first t)
-				     (otherwise notmuch-search-oldest-first)))
+		     (sort-order (if (plist-get elem :sort-order)
+				     (plist-get elem :sort-order)
+				   notmuch-search-default-sort-order))
 		     (search-type (eq (plist-get elem :search-type) 'tree))
 		     (msg-count (plist-get elem :count)))
 		(widget-insert (format "%8s "
@@ -586,7 +585,7 @@ with `notmuch-hello-query-counts'."
 		(widget-create 'push-button
 			       :notify #'notmuch-hello-widget-search
 			       :notmuch-search-terms query
-			       :notmuch-search-oldest-first oldest-first
+			       :notmuch-search-sort-order sort-order
 			       :notmuch-search-type search-type
 			       name)
 		(setq column-indent
diff --git a/emacs/notmuch-jump.el b/emacs/notmuch-jump.el
index 3e20b8c7..716d39b8 100644
--- a/emacs/notmuch-jump.el
+++ b/emacs/notmuch-jump.el
@@ -50,15 +50,14 @@ fast way to jump to a saved search from anywhere in Notmuch."
 	(when key
 	  (let ((name (plist-get saved-search :name))
 		(query (plist-get saved-search :query))
-		(oldest-first
-		 (case (plist-get saved-search :sort-order)
-		   (newest-first nil)
-		   (oldest-first t)
-		   (otherwise (default-value 'notmuch-search-oldest-first)))))
+		(sort-order
+		 (if (plist-get saved-search :sort-order)
+		     (plist-get saved-search :sort-order)
+		   (notmuch-search-default-sort-order))))
 	    (push (list key name
 			(if (eq (plist-get saved-search :search-type) 'tree)
 			    `(lambda () (notmuch-tree ',query))
-			  `(lambda () (notmuch-search ',query ',oldest-first))))
+			  `(lambda () (notmuch-search ',query ',sort-order))))
 		  action-map)))))
     (setq action-map (nreverse action-map))
 
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 337b20ac..34ffa712 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -92,14 +92,15 @@ $PATH)."
   :type 'string
   :group 'notmuch-external)
 
-(defcustom notmuch-search-oldest-first t
-  "Show the oldest mail first when searching.
+(defcustom notmuch-search-default-sort-order 'oldest-first
+  "Default result sorting to use when searching.
 
 This variable defines the default sort order for displaying
 search results. Note that any filtered searches created by
 `notmuch-search-filter' retain the search order of the parent
 search."
-  :type 'boolean
+  :type '(choice (const :tag "oldest-first" oldest-first)
+		 (const :tag "newest-first" newest-first))
   :group 'notmuch-search)
 
 (defcustom notmuch-poll-script nil
diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index 7bebdbab..cca40249 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -33,7 +33,7 @@
 (require 'notmuch-parser)
 
 (eval-when-compile (require 'cl))
-(declare-function notmuch-search "notmuch" (&optional query oldest-first target-thread target-line))
+(declare-function notmuch-search "notmuch" (&optional query sort-order target-thread target-line))
 (declare-function notmuch-call-notmuch-process "notmuch" (&rest args))
 (declare-function notmuch-read-query "notmuch" (prompt))
 (declare-function notmuch-search-find-thread-id "notmuch" (&optional bare))
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 40b9fabd..248b97c7 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -367,7 +367,7 @@ Complete list of currently available key bindings:
 
 \\{notmuch-search-mode-map}"
   (make-local-variable 'notmuch-search-query-string)
-  (make-local-variable 'notmuch-search-oldest-first)
+  (make-local-variable 'notmuch-search-default-sort-order)
   (make-local-variable 'notmuch-search-target-thread)
   (make-local-variable 'notmuch-search-target-line)
   (setq notmuch-buffer-refresh-function #'notmuch-search-refresh-view)
@@ -942,13 +942,13 @@ PROMPT is the string to prompt with."
 
 (put 'notmuch-search 'notmuch-doc "Search for messages.")
 ;;;###autoload
-(defun notmuch-search (&optional query oldest-first target-thread target-line no-display)
+(defun notmuch-search (&optional query sort-order target-thread target-line no-display)
   "Display threads matching QUERY in a notmuch-search buffer.
 
 If QUERY is nil, it is read interactively from the minibuffer.
 Other optional parameters are used as follows:
 
-  OLDEST-FIRST: A Boolean controlling the sort order of returned threads
+  SORT-ORDER: Sort order of the returned threads
   TARGET-THREAD: A thread ID (without the thread: prefix) that will be made
                  current if it appears in the search results.
   TARGET-LINE: The line number to move to if the target thread does not
@@ -965,7 +965,7 @@ the configured default sort order."
     nil
     ;; Use the default search order (if we're doing a search from a
     ;; search buffer, ignore any buffer-local overrides)
-    (default-value 'notmuch-search-oldest-first)))
+    (default-value 'notmuch-search-default-sort-order)))
 
   (let* ((query (or query (notmuch-read-query "Notmuch search: ")))
 	 (buffer (get-buffer-create (notmuch-search-buffer-title query))))
@@ -976,7 +976,7 @@ the configured default sort order."
     ;; Don't track undo information for this buffer
     (set 'buffer-undo-list t)
     (set 'notmuch-search-query-string query)
-    (set 'notmuch-search-oldest-first oldest-first)
+    (set 'notmuch-search-default-sort-order sort-order)
     (set 'notmuch-search-target-thread target-thread)
     (set 'notmuch-search-target-line target-line)
     (notmuch-tag-clear-cache)
@@ -991,9 +991,7 @@ the configured default sort order."
 	(let ((proc (notmuch-start-notmuch
 		     "notmuch-search" buffer #'notmuch-search-process-sentinel
 		     "search" "--format=sexp" "--format-version=2"
-		     (if oldest-first
-			 "--sort=oldest-first"
-		       "--sort=newest-first")
+		     (concat "--sort=" (symbol-name sort-order))
 		     query))
 	      ;; Use a scratch buffer to accumulate partial output.
 	      ;; This buffer will be killed by the sentinel, which
@@ -1014,20 +1012,23 @@ thread. Otherwise, point will be moved to attempt to be in the
 same relative position within the new buffer."
   (interactive)
   (let ((target-line (line-number-at-pos))
-	(oldest-first notmuch-search-oldest-first)
+	(sort-order notmuch-search-default-sort-order)
 	(target-thread (notmuch-search-find-thread-id 'bare))
 	(query notmuch-search-query-string))
     ;; notmuch-search erases the current buffer.
-    (notmuch-search query oldest-first target-thread target-line t)
+    (notmuch-search query sort-order target-thread target-line t)
     (goto-char (point-min))))
 
 (defun notmuch-search-toggle-order ()
   "Toggle the current search order.
 
 This command toggles the sort order for the current search. The
-default sort order is defined by `notmuch-search-oldest-first'."
+default sort order is defined by `notmuch-search-default-sort-order'."
   (interactive)
-  (set 'notmuch-search-oldest-first (not notmuch-search-oldest-first))
+  (setq notmuch-search-default-sort-order
+	(case notmuch-search-default-sort-order
+	  ('oldest-first 'newest-first)
+	  (otherwise 'oldest-first)))
   (notmuch-search-refresh-view))
 
 (defun notmuch-group-disjunctive-query-string (query-string)
@@ -1051,7 +1052,7 @@ current search results AND the additional query string provided."
     (notmuch-search (if (string= grouped-original-query "*")
 			grouped-query
 		      (concat grouped-original-query " and " grouped-query))
-		    notmuch-search-oldest-first)))
+		    notmuch-search-default-sort-order)))
 
 (defun notmuch-search-filter-by-tag (tag)
   "Filter the current search results based on a single tag.
@@ -1060,7 +1061,7 @@ Runs a new search matching only messages that match both the
 current search results AND that are tagged with the given tag."
   (interactive
    (list (notmuch-select-tag-with-completion "Filter by tag: ")))
-  (notmuch-search (concat notmuch-search-query-string " and tag:" tag) notmuch-search-oldest-first))
+  (notmuch-search (concat notmuch-search-query-string " and tag:" tag) notmuch-search-default-sort-order))
 
 ;;;###autoload
 (defun notmuch ()
-- 
2.12.2

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 3/3] emacs: notmuch-search: add filesize sorting
  2017-05-06 20:45 [PATCH 1/3] notmuch-search: implement 'filesize' search Ioan-Adrian Ratiu
  2017-05-06 20:45 ` [PATCH 2/3] emacs: make notmuch-search-oldest-first generic Ioan-Adrian Ratiu
@ 2017-05-06 20:45 ` Ioan-Adrian Ratiu
  1 sibling, 0 replies; 3+ messages in thread
From: Ioan-Adrian Ratiu @ 2017-05-06 20:45 UTC (permalink / raw)
  To: notmuch

Besides the previous date-based result orderings (oldest-first and
newest-first) add two more filesize-based orderings: biggest-first
smallest-first.

The orderings are interchangeable, you can specify any one as the
default via notmuch-search-default-sort-order or as the preffered
ordering for a saved search (via the :sort-order property).

The only restriction I've imposed is that you can't toggle from a
date-based result ordering to a filesize-based one. Meaning you can
toggle as before from oldest-first to newest-first or from the new
smallest-first to biggest-first and viceversa, but you can't toggle
from oldest-first to biggest-first. I've found this kind of toggling
confusing so I've prohibited it, but enabling it is trivial if need be.

Signed-off-by: Ioan-Adrian Ratiu <adi@adirat.com>
---
 emacs/notmuch-hello.el |  9 ++++++---
 emacs/notmuch-lib.el   |  4 +++-
 emacs/notmuch.el       | 12 ++++++++++--
 3 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 3ba2a16b..51117577 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -95,7 +95,9 @@ searches so they still work in customize."
 			    (choice :tag " Sort Order"
 				    (const :tag "Default" nil)
 				    (const :tag "Oldest-first" oldest-first)
-				    (const :tag "Newest-first" newest-first)))
+				    (const :tag "Newest-first" newest-first)
+				    (const :tag "Biggest-first" biggest-first)
+				    (const :tag "Smallest-first" smallest-first)))
 		     (group :format "%v" :inline t (const :format "" :search-type)
 			    (choice :tag " Search Type"
 				    (const :tag "Search mode" nil)
@@ -120,8 +122,9 @@ a plist. Supported properties are
                    shown. If not present then the :query property
                    is used.
   :sort-order      Specify the sort order to be used for the search.
-                   Possible values are 'oldest-first 'newest-first or
-                   nil. Nil means use the default sort order.
+                   Possible values are 'oldest-first 'newest-first
+                   'biggest-first 'smallest-first or nil.
+                   Nil means use the default sort order.
   :search-type     Specify whether to run the search in search-mode
                    or tree mode. Set to 'tree to specify tree
                    mode, set to nil (or anything except tree) to
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 34ffa712..ded75c2e 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -100,7 +100,9 @@ search results. Note that any filtered searches created by
 `notmuch-search-filter' retain the search order of the parent
 search."
   :type '(choice (const :tag "oldest-first" oldest-first)
-		 (const :tag "newest-first" newest-first))
+		 (const :tag "newest-first" newest-first)
+		 (const :tag "biggest-first" biggest-first)
+		 (const :tag "smallest-first" smallest-first))
   :group 'notmuch-search)
 
 (defcustom notmuch-poll-script nil
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 248b97c7..4ba29880 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -1023,12 +1023,20 @@ same relative position within the new buffer."
   "Toggle the current search order.
 
 This command toggles the sort order for the current search. The
-default sort order is defined by `notmuch-search-default-sort-order'."
+default sort order is defined by `notmuch-search-default-sort-order'.
+
+There are two types of orderings: by date and by filesize. Toggling is
+permitted only within a specific type (for ex. you can't toggle from
+oldest-first to smallest-first, only from oldest-first to newest-first)
+to avoid confusion."
   (interactive)
   (setq notmuch-search-default-sort-order
 	(case notmuch-search-default-sort-order
 	  ('oldest-first 'newest-first)
-	  (otherwise 'oldest-first)))
+	  ('newest-first 'oldest-first)
+	  ('biggest-first 'smallest-first)
+	  ('smallest-first 'biggest-first)
+	  (otherwise notmuch-search-default-sort-order)))
   (notmuch-search-refresh-view))
 
 (defun notmuch-group-disjunctive-query-string (query-string)
-- 
2.12.2

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-05-06 20:44 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-05-06 20:45 [PATCH 1/3] notmuch-search: implement 'filesize' search Ioan-Adrian Ratiu
2017-05-06 20:45 ` [PATCH 2/3] emacs: make notmuch-search-oldest-first generic Ioan-Adrian Ratiu
2017-05-06 20:45 ` [PATCH 3/3] emacs: notmuch-search: add filesize sorting Ioan-Adrian Ratiu

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).