* implement / document changing sort order and threading
- update the protocol a bit (mu4e-proc, mu-cmd-server) - provide the user-interface (mu4e-headers.el) - document it (mu4e.texi, mu-server.1) - some cosmetics (the other changes)
This commit is contained in:
@ -83,6 +83,18 @@ are of the form:
|
||||
* NAME is the name of the action (e.g. \"Count lines\")
|
||||
* SHORTCUT is a one-character shortcut to call this action
|
||||
* FUNC is a function which receives a message plist as an argument.")
|
||||
|
||||
(defvar mu4e-headers-sortfield 'date
|
||||
"Field to sort the headers by. Field must be a symbol, one of:
|
||||
date, subject, size, prio, from, to.")
|
||||
|
||||
(defvar mu4e-headers-sort-revert t
|
||||
"Whether to revert the sort-order, i.e. Z->A instead of A-Z. When
|
||||
sorting by date, it's useful to go from biggest to smallest, so
|
||||
newest messages come first.")
|
||||
|
||||
(defvar mu4e-headers-show-threads t
|
||||
"Whether to show threads in the headers list.")
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
@ -100,6 +112,20 @@ are of the form:
|
||||
(defvar mu4e~headers-view-win nil
|
||||
"The view window connected to this headers view.")
|
||||
|
||||
(defvar mu4e~headers-sortfield-choices
|
||||
'( ("date" nil date)
|
||||
("from" nil from)
|
||||
("prio" nil prio)
|
||||
("size" ?z size)
|
||||
("subject" nil subject)
|
||||
("to" nil to))
|
||||
"List of cells describing the various sort-options (in the format
|
||||
needed for `mu4e-read-option'.")
|
||||
|
||||
(defvar mu4e~headers-full-search nil
|
||||
"Whether the last search was a 'full search'.")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defun mu4e~headers-clear ()
|
||||
"Clear the header buffer and related data structures."
|
||||
@ -222,7 +248,7 @@ if provided, or at the end of the buffer otherwise."
|
||||
(:subject
|
||||
(concat ;; prefix subject with a thread indicator
|
||||
(mu4e~headers-thread-prefix (plist-get msg :thread))
|
||||
;; "["(plist-get (plist-get msg :thread) :path) "] "
|
||||
;; "["(plist-get (plist-get msg :thread) :path) "] "
|
||||
val))
|
||||
((:maildir :path) val)
|
||||
((:to :from :cc :bcc) (mu4e~headers-contact-str val))
|
||||
@ -231,10 +257,14 @@ if provided, or at the end of the buffer otherwise."
|
||||
(:from-or-to
|
||||
(let* ((from-lst (plist-get msg :from))
|
||||
(from (and from-lst (cdar from-lst))))
|
||||
(if (and from (string-match mu4e-user-mail-address-regexp from))
|
||||
(concat (or (cdr-safe mu4e-headers-from-or-to-prefix))
|
||||
(if (and from
|
||||
(string-match mu4e-user-mail-address-regexp
|
||||
from))
|
||||
(concat (or (cdr-safe
|
||||
mu4e-headers-from-or-to-prefix))
|
||||
(mu4e~headers-contact-str (plist-get msg :to)))
|
||||
(concat (or (car-safe mu4e-headers-from-or-to-prefix))
|
||||
(concat (or (car-safe
|
||||
mu4e-headers-from-or-to-prefix))
|
||||
(mu4e~headers-contact-str from-lst)))))
|
||||
(:date (format-time-string mu4e-headers-date-format val))
|
||||
(:flags (mu4e-flags-to-string val))
|
||||
@ -312,6 +342,9 @@ after the end of the search results."
|
||||
(define-key map "b" 'mu4e-headers-search-bookmark)
|
||||
(define-key map "B" 'mu4e-headers-search-bookmark-edit)
|
||||
|
||||
(define-key map "O" 'mu4e-headers-change-sorting)
|
||||
(define-key map "P" 'mu4e-headers-toggle-threading)
|
||||
|
||||
(define-key map "q" 'mu4e~headers-kill-buffer-and-window)
|
||||
(define-key map "z" 'mu4e~headers-kill-buffer-and-window)
|
||||
|
||||
@ -391,8 +424,10 @@ after the end of the search results."
|
||||
(define-key menumap [unmark-all] '("Unmark all" . mu4e-mark-unmark-all))
|
||||
(define-key menumap [unmark] '("Unmark" . mu4e~headers-mark-unmark))
|
||||
|
||||
(define-key menumap [mark-pattern] '("Mark pattern" . mu4e-headers-mark-pattern))
|
||||
(define-key menumap [mark-as-read] '("Mark as read" . mu4e~headers-mark-read))
|
||||
(define-key menumap [mark-pattern] '("Mark pattern" .
|
||||
mu4e-headers-mark-pattern))
|
||||
(define-key menumap [mark-as-read] '("Mark as read" .
|
||||
mu4e~headers-mark-read))
|
||||
(define-key menumap [mark-as-unread]
|
||||
'("Mark as unread" . mu4e~headers-mark-unread))
|
||||
|
||||
@ -410,10 +445,14 @@ after the end of the search results."
|
||||
(define-key menumap [sepa2] '("--"))
|
||||
|
||||
(define-key menumap [query-next] '("Next query" . mu4e-headers-query-next))
|
||||
(define-key menumap [query-prev] '("Previous query" . mu4e-headers-query-prev))
|
||||
(define-key menumap [narrow-search] '("Narrow search" . mu4e-headers-search-narrow))
|
||||
(define-key menumap [bookmark] '("Search bookmark" . mu4e-headers-search-bookmark))
|
||||
(define-key menumap [jump] '("Jump to maildir" . mu4e~headers-jump-to-maildir))
|
||||
(define-key menumap [query-prev] '("Previous query" .
|
||||
mu4e-headers-query-prev))
|
||||
(define-key menumap [narrow-search] '("Narrow search" .
|
||||
mu4e-headers-search-narrow))
|
||||
(define-key menumap [bookmark] '("Search bookmark" .
|
||||
mu4e-headers-search-bookmark))
|
||||
(define-key menumap [jump] '("Jump to maildir" .
|
||||
mu4e~headers-jump-to-maildir))
|
||||
(define-key menumap [refresh] '("Refresh" . mu4e-headers-rerun-search))
|
||||
(define-key menumap [search] '("Search" . mu4e-headers-search))
|
||||
|
||||
@ -598,10 +637,27 @@ non-nill, don't raise an error when the docid is not found."
|
||||
(unless ignore-missing
|
||||
(error "Cannot find message with docid %S" docid)))))
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
(defun mu4e~headers-update-global-mode-string ()
|
||||
"Determine the mode string for the headers buffers (based on the
|
||||
last query, sorting settings."
|
||||
(let* ((cell (find-if
|
||||
(lambda (cell)
|
||||
(eq (nth 2 cell) mu4e-headers-sortfield))
|
||||
mu4e~headers-sortfield-choices))
|
||||
(optchar (or (nth 1 cell) (substring (nth 0 cell) 0 1))))
|
||||
(setq global-mode-string
|
||||
(concat
|
||||
(propertize expr 'face 'mu4e-title-face)
|
||||
"("
|
||||
optchar
|
||||
(if mu4e-headers-sort-revert "d" "a")
|
||||
(when mu4e-headers-show-threads "T")
|
||||
(when mu4e~headers-full-search "F")
|
||||
")"))))
|
||||
|
||||
(defun mu4e~headers-search-execute (expr search-all ignore-history)
|
||||
(defun mu4e~headers-search-execute (expr full-search ignore-history)
|
||||
"Search in the mu database for EXPR, and switch to the output
|
||||
buffer for the results. If SEARCH-ALL is non-nil return all
|
||||
buffer for the results. If FULL-SEARCH is non-nil return all
|
||||
results, otherwise, limit number of results to
|
||||
`mu4e-search-results-limit'. If IGNORE-HISTORY is true, do *not*
|
||||
update the query history stack."
|
||||
@ -613,17 +669,21 @@ update the query history stack."
|
||||
(mu4e-headers-mode)
|
||||
(unless ignore-history
|
||||
;; save the old present query to the history list
|
||||
(when mu4e~headers-query-present
|
||||
(mu4e~headers-push-query mu4e~headers-query-present 'past)))
|
||||
(when mu4e~headers-last-query
|
||||
(mu4e~headers-push-query mu4e~headers-last-query 'past)))
|
||||
(setq
|
||||
global-mode-string (propertize expr 'face 'mu4e-title-face)
|
||||
mu4e~headers-buffer buf
|
||||
mode-name "mu4e-headers"
|
||||
mu4e~headers-query-present expr))
|
||||
mu4e~headers-last-query expr
|
||||
mu4e~headers-full-search full-search)
|
||||
(mu4e~headers-update-global-mode-string))
|
||||
(switch-to-buffer buf)
|
||||
(mu4e~proc-find
|
||||
(replace-regexp-in-string "\"" "\\\\\"" expr) ;; escape "\"
|
||||
(unless search-all mu4e-search-results-limit))
|
||||
mu4e-headers-show-threads
|
||||
mu4e-headers-sortfield
|
||||
mu4e-headers-sort-revert
|
||||
(unless full-search mu4e-search-results-limit))
|
||||
;;; when we're starting a new search, we also kill the
|
||||
;;; view window, if any
|
||||
(ignore-errors (delete-window mu4e~headers-view-win))))
|
||||
@ -765,7 +825,7 @@ limited to the message at point and its descendants."
|
||||
"Stack of queries before the present one.")
|
||||
(defvar mu4e~headers-query-future nil
|
||||
"Stack of queries after the present one.")
|
||||
(defvar mu4e~headers-query-present nil
|
||||
(defvar mu4e~headers-last-query nil
|
||||
"The present (most recent) query.")
|
||||
(defvar mu4e~headers-query-stack-size 20
|
||||
"Maximum size for the query stacks.")
|
||||
@ -807,9 +867,6 @@ to get it from; it's a symbol, either 'future or 'past."
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;;; interactive functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
(defvar mu4e~headers-search-hist nil
|
||||
@ -846,7 +903,7 @@ IGNORE-HISTORY is true, do *not* update the query history stack."
|
||||
is non-nil, retrieve *all* results, otherwise only get up to
|
||||
`mu4e-search-results-limit'."
|
||||
(interactive "P")
|
||||
(mu4e-headers-search mu4e~headers-query-present search-all nil t))
|
||||
(mu4e-headers-search mu4e~headers-last-query search-all nil t))
|
||||
|
||||
|
||||
(defun mu4e-headers-search-bookmark (&optional expr search-all edit)
|
||||
@ -878,10 +935,35 @@ non-nil, retrieve *all* results, otherwise only get up to
|
||||
nil 'mu4e~headers-search-hist nil t))
|
||||
(search-all current-prefix-arg))
|
||||
(list filter search-all)))
|
||||
(unless mu4e~headers-query-present
|
||||
(unless mu4e~headers-last-query
|
||||
(error "There's nothing to filter"))
|
||||
(mu4e-headers-search
|
||||
(format "(%s) AND %s" mu4e~headers-query-present filter) search-all))
|
||||
(format "(%s) AND %s" mu4e~headers-last-query filter) search-all))
|
||||
|
||||
|
||||
(defun mu4e-headers-change-sorting (&optional rerun)
|
||||
"Interactively change the sorting/threading parameters. With prefix-argument,
|
||||
rerun the last search with the new parameters."
|
||||
(interactive "P")
|
||||
(let* ((sortfield
|
||||
(mu4e-read-option "Sortfield: " mu4e~headers-sortfield-choices))
|
||||
(revert
|
||||
(mu4e-read-option "Direction: "
|
||||
'(("ascending" nil nil) ("descending" nil t)))))
|
||||
(setq
|
||||
mu4e-headers-sortfield sortfield
|
||||
mu4e-headers-sort-revert revert)
|
||||
(when rerun
|
||||
(mu4e-headers-rerun-search))))
|
||||
|
||||
(defun mu4e-headers-toggle-threading (&optional rerun)
|
||||
"Toggle threading on/off for the search results. With prefix-argument,
|
||||
rerun the last search with the new setting for threading."
|
||||
(interactive "P")
|
||||
(setq mu4e-headers-show-threads (not mu4e-headers-show-threads))
|
||||
(when rerun
|
||||
(mu4e-headers-rerun-search)))
|
||||
|
||||
|
||||
(defun mu4e-headers-view-message ()
|
||||
"View message at point. If there's an existing window for the
|
||||
@ -915,12 +997,12 @@ current window. "
|
||||
(kill-buffer buf)))
|
||||
(mu4e~main-view))
|
||||
|
||||
(defun mu4e-headers-rerun-search (full-search)
|
||||
"Rerun the search for the last search expression; if none exists,
|
||||
do a new search. If full-search is non-nil, return /all/ search
|
||||
results, otherwise show up to `mu4e-search-results-limit'."
|
||||
(interactive "P")
|
||||
(mu4e-headers-search mu4e~headers-query-present full-search))
|
||||
(defun mu4e-headers-rerun-search ()
|
||||
"Rerun the search for the last search expression."
|
||||
(interactive)
|
||||
(mu4e-headers-search
|
||||
mu4e~headers-last-query
|
||||
mu4e~headers-full-search))
|
||||
|
||||
(defun mu4e~headers-query-navigate (full-search whence)
|
||||
"Execute the previous query from the query stacks. WHENCE
|
||||
@ -928,7 +1010,7 @@ determines where the query is taken from and is a symbol, either
|
||||
`future' or `past'."
|
||||
(let ((query (mu4e~headers-pop-query whence))
|
||||
(where (if (eq whence 'future) 'past 'future)))
|
||||
(mu4e~headers-push-query mu4e~headers-query-present where)
|
||||
(mu4e~headers-push-query mu4e~headers-last-query where)
|
||||
(mu4e-headers-search query full-search nil nil t)))
|
||||
|
||||
(defun mu4e-headers-query-next (full-search)
|
||||
|
||||
@ -299,19 +299,26 @@ terminates."
|
||||
|
||||
(defun mu4e~proc-remove (docid)
|
||||
"Remove message identified by docid.
|
||||
The results are reporter through either (:update ... ) or (:error
|
||||
) sexp, which are handled my `mu4e-error-func', respectively."
|
||||
The results are reporter through either (:update ... ) or (:error)
|
||||
sexp, which are handled my `mu4e-error-func', respectively."
|
||||
(mu4e~proc-send-command "remove docid:%d" docid))
|
||||
|
||||
(defun mu4e~proc-find (query &optional maxnum)
|
||||
"Start a database query for QUERY, (optionally) getting up to
|
||||
MAXNUM results. For each result found, a function is called,
|
||||
depending on the kind of result. The variables `mu4e-error-func'
|
||||
contain the function that will be called for, resp., a
|
||||
message (header row) or an error."
|
||||
(defun mu4e~proc-find (query threads sortfield revert maxnum)
|
||||
"Start a database query for QUERY. If THREADS is non-nil, show
|
||||
results in threaded fasion, SORTFIELD is a symmbol describing the
|
||||
field to sort by (or nil); see `mu4e~headers-sortfield-choices'. If
|
||||
REVERT is non-nil, sort Z->A instead of A->Z. MAXNUM determines the
|
||||
maximum number of results to return, or nil for 'unlimited'. For
|
||||
each result found, a function is called, depending on the kind of
|
||||
result. The variables `mu4e-error-func' contain the function that
|
||||
will be called for, resp., a message (header row) or an error."
|
||||
(mu4e~proc-send-command
|
||||
"find query:\"%s\"%s" query
|
||||
(if maxnum (format " maxnum:%d" maxnum) "")))
|
||||
"find query:\"%s\" threads:%s sortfield:%s reverse:%s maxnum:%d"
|
||||
query
|
||||
(if threads "true" "false")
|
||||
(format "%S" sortfield)
|
||||
(if revert "true" "false")
|
||||
(if maxnum maxnum -1)))
|
||||
|
||||
(defun mu4e~proc-move (docid-or-msgid &optional maildir flags)
|
||||
"Move message identified by DOCID-OR-MSGID. At least one of
|
||||
|
||||
@ -30,7 +30,6 @@
|
||||
(require 'mu4e-vars)
|
||||
(require 'doc-view)
|
||||
|
||||
|
||||
(defcustom mu4e-html2text-command nil
|
||||
"Shell command that converts HTML from stdin into plain text on
|
||||
stdout. If this is not defined, the emacs `html2text' tool will be
|
||||
@ -433,7 +432,6 @@ A message plist looks something like:
|
||||
\"6BDC23465F79238203498230942D81EE81AF0114E4E74@123213.mail.example.com\")
|
||||
:in-reply-to \"6BDC23465F79238203498230942D81EE81AF0114E4E74@123213.mail.example.com\"
|
||||
:body-txt \"Hi Tom, ...\"
|
||||
\)).
|
||||
\)).
|
||||
Some notes on the format:
|
||||
- The address fields are lists of pairs (NAME . EMAIL), where NAME can be nil.
|
||||
@ -470,7 +468,7 @@ point in eiter the headers buffer or the view buffer."
|
||||
(defun mu4e-last-query ()
|
||||
"Get the most recent query or nil if there is none."
|
||||
(when (buffer-live-p mu4e~headers-buffer)
|
||||
(with-current-buffer mu4e~headers-buffer
|
||||
(with-current-buffer mu4e~headers-buffer
|
||||
mu4e~headers-last-query)))
|
||||
|
||||
(defun mu4e-select-other-view ()
|
||||
@ -790,6 +788,5 @@ is ignored."
|
||||
(when img
|
||||
(newline)
|
||||
(insert-image img imgpath nil t))))
|
||||
|
||||
|
||||
(provide 'mu4e-utils)
|
||||
|
||||
@ -542,6 +542,9 @@ j jump to maildir
|
||||
M-left previous query
|
||||
M-right next query
|
||||
|
||||
O change sort order
|
||||
P toggle threading
|
||||
|
||||
a execute some action on header
|
||||
|
||||
d mark for moving to the trash folder
|
||||
@ -596,6 +599,34 @@ behavior can be influenced with the variable
|
||||
|
||||
For more information about marking, @xref{Marking}.
|
||||
|
||||
@subsection Sort order and threading
|
||||
@anchor{Sort order and threading}
|
||||
|
||||
By default, @t{mu4e} sorts messages by date, in descending order: the most
|
||||
recent messages are at the top. In addition, the messages are @emph{threaded},
|
||||
i.e., shown in the context of a message thread; this also affects the sort
|
||||
order.
|
||||
|
||||
You can change the sort order with @t{M-x mu4e-headers-change-sorting} or
|
||||
@key{O}, and you can toggle threading on/off using @t{M-x
|
||||
mu4e-headers-toggle-threading}. For both of these functions, if you provide a
|
||||
prefix argument (@key{C-u}), the current search is updated immediately using
|
||||
the new parameters.
|
||||
|
||||
If you want to change the defaults for these settings, you can use the
|
||||
variables @code{mu4e-headers-sortfield} and @code{mu4e-headers-show-threads}.
|
||||
|
||||
Note that you can see the current settings in the emacs modeline; it shows the
|
||||
current query, followed by the shortcut character for sortfield (the same
|
||||
character you'd use in @code{mu4e-headers-change-sorting}. The next character
|
||||
is either @t{a} (for ascending, A->Z order), or @t{d} (for descending, Z->A
|
||||
order). If threading is enabled, the next character is a @t{T}, and finally,
|
||||
if we're doing an unlimited, full search, the last character is an @t{F}.
|
||||
|
||||
So, suppose our query is @t{subject:foo maildir:/bar}, we're sorting by
|
||||
subject in ascending order with threads enabled, and it's a full search. The
|
||||
mode string will then look like: @t{subject:foo maildir:/bar(saTF)}.
|
||||
|
||||
@subsection Actions
|
||||
|
||||
@code{mu4e-headers-action} (@key{a}) lets you pick some custom action to perform
|
||||
|
||||
@ -288,8 +288,7 @@ mu_msg_field_id_from_name (const char* str, gboolean err)
|
||||
for (i = 0; i != G_N_ELEMENTS(FIELD_DATA); ++i)
|
||||
if (g_strcmp0(str, FIELD_DATA[i]._name) == 0)
|
||||
return FIELD_DATA[i]._id;
|
||||
|
||||
if (err)
|
||||
if (err)
|
||||
g_return_val_if_reached (MU_MSG_FIELD_ID_NONE);
|
||||
|
||||
return MU_MSG_FIELD_ID_NONE;
|
||||
|
||||
@ -323,7 +323,8 @@ mu_query_run (MuQuery *self, const char* searchexpr, gboolean threads,
|
||||
Xapian::Enquire enq (self->db());
|
||||
|
||||
/* note, when our result will be *threaded*, we sort
|
||||
* there, and don't let Xapian do any sorting */
|
||||
* in our threading code (mu-threader etc.), and don't
|
||||
* let Xapian do any sorting */
|
||||
if (!threads && sortfieldid != MU_MSG_FIELD_ID_NONE)
|
||||
enq.set_sort_by_value ((Xapian::valueno)sortfieldid,
|
||||
revert ? true : false);
|
||||
|
||||
@ -119,8 +119,17 @@ to a shell command.
|
||||
|
||||
Using the \fBfind\fR command we can search for messages.
|
||||
.nf
|
||||
-> find query:"<query>" [maxnum:<maxnum>]
|
||||
-> find query:"<query>" [threads:true|false] [sortfield:<sortfield>]
|
||||
[reverse:true|false] [maxnum:<maxnum>]
|
||||
.fi
|
||||
The \fBquery\fR-parameter provides the search query; the
|
||||
\fBthreads\fR-parameter determines whether the results will be returned in
|
||||
threaded fashion or not; the \fBsortfield\fR-parameter (a string, "to",
|
||||
"from", "subject", "date", "size", "prio") sets the search field, the
|
||||
\fBreverse\fR-parameter, if true, set the sorting order Z->A and, finally, the
|
||||
\fBmaxnum\fR-parameter limits the number of results to return (<= 0
|
||||
means 'unlimited').
|
||||
|
||||
First, this will return an 'erase'-sexp, to clear the buffer from possible
|
||||
results from a previous query.
|
||||
.nf
|
||||
|
||||
@ -517,23 +517,23 @@ cmd_compose (MuStore *store, MuQuery *query, GSList *args, GError **err)
|
||||
|
||||
|
||||
static unsigned
|
||||
print_sexps (MuMsgIter *iter, int maxnum)
|
||||
print_sexps (MuMsgIter *iter, gboolean threads)
|
||||
{
|
||||
unsigned u, max;
|
||||
|
||||
unsigned u;
|
||||
u = 0;
|
||||
max = (maxnum > 0) ? (unsigned)maxnum : G_MAXUINT32;
|
||||
|
||||
while (!mu_msg_iter_is_done (iter) && u < max && !MU_TERMINATE) {
|
||||
while (!mu_msg_iter_is_done (iter) && !MU_TERMINATE) {
|
||||
|
||||
MuMsg *msg;
|
||||
msg = mu_msg_iter_get_msg_floating (iter);
|
||||
|
||||
if (mu_msg_is_readable (msg)) {
|
||||
char *sexp;
|
||||
const MuMsgIterThreadInfo* ti;
|
||||
|
||||
ti = threads ? mu_msg_iter_get_thread_info (iter) : NULL;
|
||||
sexp = mu_msg_to_sexp (msg, mu_msg_iter_get_docid (iter),
|
||||
mu_msg_iter_get_thread_info (iter),
|
||||
TRUE, FALSE);
|
||||
ti, TRUE, FALSE);
|
||||
print_expr ("%s", sexp);
|
||||
g_free (sexp);
|
||||
++u;
|
||||
@ -686,6 +686,37 @@ cmd_extract (MuStore *store, MuQuery *query, GSList *args, GError **err)
|
||||
return MU_OK;
|
||||
}
|
||||
|
||||
/* parse the find parameters, and return the values as out params */
|
||||
static MuError
|
||||
get_find_params (GSList *args, gboolean *threads, MuMsgFieldId *sortfield,
|
||||
gboolean *reverse, int *maxnum, GError **err)
|
||||
{
|
||||
const char *maxnumstr, *sortfieldstr;
|
||||
|
||||
/* maximum number of results */
|
||||
maxnumstr = get_string_from_args (args, "maxnum", TRUE, NULL);
|
||||
*maxnum = maxnumstr ? atoi (maxnumstr) : 0;
|
||||
|
||||
/* whether to show threads or not */
|
||||
*threads = get_bool_from_args (args, "threads", TRUE, NULL);
|
||||
|
||||
/* field to sort by */
|
||||
sortfieldstr = get_string_from_args (args, "sortfield", TRUE, NULL);
|
||||
if (sortfieldstr) {
|
||||
*sortfield = mu_msg_field_id_from_name (sortfieldstr, FALSE);
|
||||
/* note: shortcuts are not allowed here */
|
||||
if (*sortfield == MU_MSG_FIELD_ID_NONE) {
|
||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_IN_PARAMETERS,
|
||||
"not a valid sort field: '%s'\n", sortfield);
|
||||
return MU_G_ERROR_CODE(err);
|
||||
}
|
||||
} else
|
||||
*sortfield = MU_MSG_FIELD_ID_DATE;
|
||||
|
||||
*reverse = get_bool_from_args (args, "reverse", TRUE, NULL);
|
||||
|
||||
return MU_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@ -701,21 +732,21 @@ static MuError
|
||||
cmd_find (MuStore *store, MuQuery *query, GSList *args, GError **err)
|
||||
{
|
||||
MuMsgIter *iter;
|
||||
int maxnum;
|
||||
unsigned foundnum;
|
||||
const char *querystr, *maxnumstr;
|
||||
int maxnum;
|
||||
gboolean threads, reverse;
|
||||
MuMsgFieldId sortfield;
|
||||
const char *querystr;
|
||||
|
||||
GET_STRING_OR_ERROR_RETURN (args, "query", &querystr, err);
|
||||
/* optional */
|
||||
maxnumstr = get_string_from_args (args, "maxnum", TRUE, NULL);
|
||||
maxnum = maxnumstr ? atoi (maxnumstr) : 0;
|
||||
if (get_find_params (args, &threads, &sortfield,
|
||||
&reverse, &maxnum, err) != MU_OK) {
|
||||
print_and_clear_g_error (err);
|
||||
return MU_OK;
|
||||
}
|
||||
|
||||
/* TODO: ask for *all* results, then, get the <maxnum> newest
|
||||
* ones; it seems we cannot get a sorted list of a subset of
|
||||
* the result --> needs investigation, this is a
|
||||
* work-around */
|
||||
iter = mu_query_run (query, querystr, TRUE,
|
||||
MU_MSG_FIELD_ID_DATE, TRUE, -1, err);
|
||||
iter = mu_query_run (query, querystr, threads, sortfield, reverse,
|
||||
maxnum, err);
|
||||
if (!iter) {
|
||||
print_and_clear_g_error (err);
|
||||
return MU_OK;
|
||||
@ -723,12 +754,11 @@ cmd_find (MuStore *store, MuQuery *query, GSList *args, GError **err)
|
||||
|
||||
/* before sending new results, send an 'erase' message, so the
|
||||
* frontend knows it should erase the headers buffer. this
|
||||
* will ensure that the output of two finds quickly will not
|
||||
* be mixed. */
|
||||
* will ensure that the output of two finds will not be
|
||||
* mixed. */
|
||||
print_expr ("(:erase t)");
|
||||
foundnum = print_sexps (iter, maxnum);
|
||||
foundnum = print_sexps (iter, threads);
|
||||
print_expr ("(:found %u)", foundnum);
|
||||
|
||||
mu_msg_iter_destroy (iter);
|
||||
|
||||
return MU_OK;
|
||||
|
||||
Reference in New Issue
Block a user