mirror of https://github.com/djcb/mu.git
Merge branch 'master' into mu4e-view
This commit is contained in:
commit
fc4e2c743b
|
@ -6,7 +6,8 @@ test -f mu/mu.cc || {
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if test -z `which autoreconf`; then
|
command -V autoreconf > /dev/null
|
||||||
|
if [[ $? != 0 ]]; then
|
||||||
echo "*** No autoreconf found, please install it ***"
|
echo "*** No autoreconf found, please install it ***"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -239,10 +239,13 @@ factor_2 (Mux::Tokens& tokens, Node::Type& op, ProcPtr proc,
|
||||||
tokens.pop_front();
|
tokens.pop_front();
|
||||||
op = Node::Type::OpAnd;
|
op = Node::Type::OpAnd;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Token::Type::Open:
|
case Token::Type::Open:
|
||||||
case Token::Type::Data:
|
case Token::Type::Data:
|
||||||
|
case Token::Type::Not:
|
||||||
op = Node::Type::OpAnd; // implicit AND
|
op = Node::Type::OpAnd; // implicit AND
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return empty();
|
return empty();
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,8 +84,9 @@ test_complex ()
|
||||||
{ "foo and bar or cuux",
|
{ "foo and bar or cuux",
|
||||||
R"#((or(and(value "" "foo")(value "" "bar")))#" +
|
R"#((or(and(value "" "foo")(value "" "bar")))#" +
|
||||||
std::string(R"#((value "" "cuux")))#") },
|
std::string(R"#((value "" "cuux")))#") },
|
||||||
|
|
||||||
{ "a and not b",
|
{ "a and not b",
|
||||||
R"#((andnot(value "" "a")(value "" "b")))#"
|
R"#((and(value "" "a")(not(value "" "b"))))#"
|
||||||
},
|
},
|
||||||
{ "a and b and c",
|
{ "a and b and c",
|
||||||
R"#((and(value "" "a")(and(value "" "b")(value "" "c"))))#"
|
R"#((and(value "" "a")(and(value "" "b")(value "" "c"))))#"
|
||||||
|
@ -97,7 +98,7 @@ test_complex ()
|
||||||
R"#((and(value "" "a")(value "" "b")))#"
|
R"#((and(value "" "a")(value "" "b")))#"
|
||||||
},
|
},
|
||||||
{ "a not b", // implicit and not
|
{ "a not b", // implicit and not
|
||||||
R"#((andnot(value "" "a")(value "" "b")))#"
|
R"#((and(value "" "a")(not(value "" "b"))))#"
|
||||||
},
|
},
|
||||||
{ "not b", // implicit and not
|
{ "not b", // implicit and not
|
||||||
R"#((not(value "" "b")))#"
|
R"#((not(value "" "b")))#"
|
||||||
|
|
|
@ -149,9 +149,6 @@ Mux::utf8_clean (const std::string& dirty)
|
||||||
return clean;
|
return clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<std::string>
|
std::vector<std::string>
|
||||||
Mux::split (const std::string& str, const std::string& sepa)
|
Mux::split (const std::string& str, const std::string& sepa)
|
||||||
{
|
{
|
||||||
|
@ -213,7 +210,7 @@ date_boundary (bool is_first)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
Mux::date_to_time_t_string (time_t t)
|
Mux::date_to_time_t_string (int64_t t)
|
||||||
{
|
{
|
||||||
char buf[sizeof(InternalDateMax)];
|
char buf[sizeof(InternalDateMax)];
|
||||||
snprintf (buf, sizeof(buf), InternalDateFormat, t);
|
snprintf (buf, sizeof(buf), InternalDateFormat, t);
|
||||||
|
@ -332,7 +329,7 @@ Mux::date_to_time_t_string (const std::string& dstr, bool is_first)
|
||||||
return date_boundary (is_first);
|
return date_boundary (is_first);
|
||||||
}
|
}
|
||||||
|
|
||||||
t = (gint64)g_date_time_to_unix (dtime);
|
t = g_date_time_to_unix (dtime);
|
||||||
g_date_time_unref (dtime);
|
g_date_time_unref (dtime);
|
||||||
|
|
||||||
if (t < 0 || t > 9999999999)
|
if (t < 0 || t > 9999999999)
|
||||||
|
|
|
@ -88,13 +88,14 @@ std::string format (const char *frm, ...)
|
||||||
std::string date_to_time_t_string (const std::string& date, bool first);
|
std::string date_to_time_t_string (const std::string& date, bool first);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* time_t expressed as a string with a 10-digit time_t
|
* 64-bit incarnation of time_t expressed as a 10-digit string. Uses 64-bit for the time-value,
|
||||||
|
* regardless of the size of time_t.
|
||||||
*
|
*
|
||||||
* @param t
|
* @param t some time value
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
std::string date_to_time_t_string (time_t t);
|
std::string date_to_time_t_string (int64_t t);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -122,8 +122,9 @@ test_parse_arglist (void)
|
||||||
|
|
||||||
g_assert_cmpstr (g_hash_table_lookup (hash, "cmd"), ==,
|
g_assert_cmpstr (g_hash_table_lookup (hash, "cmd"), ==,
|
||||||
"find");
|
"find");
|
||||||
|
/* note, mu4e now passes queries as base64 */
|
||||||
g_assert_cmpstr (g_hash_table_lookup (hash, "query"), ==,
|
g_assert_cmpstr (g_hash_table_lookup (hash, "query"), ==,
|
||||||
"maildir:\"/sent items\"");
|
"maildir:/sent items");
|
||||||
g_assert_cmpstr (g_hash_table_lookup (hash, "maxnum"), ==,
|
g_assert_cmpstr (g_hash_table_lookup (hash, "maxnum"), ==,
|
||||||
"500");
|
"500");
|
||||||
|
|
||||||
|
|
|
@ -183,20 +183,23 @@ query have been received and are displayed."
|
||||||
|
|
||||||
(defcustom mu4e-headers-search-bookmark-hook nil
|
(defcustom mu4e-headers-search-bookmark-hook nil
|
||||||
"Hook run just after we invoke a bookmarked search. This
|
"Hook run just after we invoke a bookmarked search. This
|
||||||
function receives the query as its parameter.
|
function receives the query as its parameter, before any
|
||||||
|
rewriting as per `mu4e-query-rewrite-function' has taken place.
|
||||||
|
|
||||||
The reason to use this instead of `mu4e-headers-search-hook'
|
The reason to use this instead of `mu4e-headers-search-hook' is
|
||||||
is if you only want to execute a hook when a search is entered
|
if you only want to execute a hook when a search is entered via a
|
||||||
via a bookmark, e.g. if you'd like to treat the bookmarks as a
|
bookmark, e.g. if you'd like to treat the bookmarks as a custom
|
||||||
custom folder and change the options for the search,
|
folder and change the options for the search, e.g.
|
||||||
e.g. `mu4e-headers-show-threads', `mu4e-headers-include-related',
|
`mu4e-headers-show-threads', `mu4e-headers-include-related',
|
||||||
`mu4e-headers-skip-duplicates` or `mu4e-headers-results-limit'."
|
`mu4e-headers-skip-duplicates` or `mu4e-headers-results-limit'.
|
||||||
|
"
|
||||||
:type 'hook
|
:type 'hook
|
||||||
:group 'mu4e-headers)
|
:group 'mu4e-headers)
|
||||||
|
|
||||||
(defcustom mu4e-headers-search-hook nil
|
(defcustom mu4e-headers-search-hook nil
|
||||||
"Hook run just before executing a new search operation. This
|
"Hook run just before executing a new search operation. This
|
||||||
function receives the query as its parameter.
|
function receives the query as its parameter, before any
|
||||||
|
rewriting as per `mu4e-query-rewrite-function' has taken place
|
||||||
|
|
||||||
This is a more general hook facility than the
|
This is a more general hook facility than the
|
||||||
`mu4e-headers-search-bookmark-hook'. It gets called on every
|
`mu4e-headers-search-bookmark-hook'. It gets called on every
|
||||||
|
@ -1084,7 +1087,31 @@ docid is not found."
|
||||||
(unless ignore-missing
|
(unless ignore-missing
|
||||||
(mu4e-error "Cannot find message with docid %S" docid)))))
|
(mu4e-error "Cannot find message with docid %S" docid)))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
(defcustom mu4e-query-rewrite-function 'identity
|
||||||
|
"Function that takes a search expression string, and returns a
|
||||||
|
possibly changed search expression string.
|
||||||
|
|
||||||
|
This function is applied on the search expression just before
|
||||||
|
searching, and allows users to modify the query.
|
||||||
|
|
||||||
|
For instance, we could change and of workmail into
|
||||||
|
\"maildir:/long-path-to-work-related-emails\", by setting the function
|
||||||
|
|
||||||
|
(setq mu4e-query-rewrite-function
|
||||||
|
(lambda(expr)
|
||||||
|
(replace-regexp-in-string \"workmail\"
|
||||||
|
\"maildir:/long-path-to-work-related-emails\" expr)))
|
||||||
|
|
||||||
|
It is good to remember that the replacement does not understand
|
||||||
|
anything about the query, it just does text replacement."
|
||||||
|
:type 'function
|
||||||
|
:group 'mu4e)
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e~headers-search-execute (expr ignore-history)
|
(defun mu4e~headers-search-execute (expr ignore-history)
|
||||||
"Search in the mu database for EXPR, and switch to the output
|
"Search in the mu database for EXPR, and switch to the output
|
||||||
buffer for the results. If IGNORE-HISTORY is true, do *not* update
|
buffer for the results. If IGNORE-HISTORY is true, do *not* update
|
||||||
|
@ -1093,7 +1120,8 @@ the query history stack."
|
||||||
;; `mu4e~headers-query-next' or `mu4e~headers-query-prev'.
|
;; `mu4e~headers-query-next' or `mu4e~headers-query-prev'.
|
||||||
;;(mu4e-hide-other-mu4e-buffers)
|
;;(mu4e-hide-other-mu4e-buffers)
|
||||||
(let* ((buf (get-buffer-create mu4e~headers-buffer-name))
|
(let* ((buf (get-buffer-create mu4e~headers-buffer-name))
|
||||||
(inhibit-read-only t)
|
(inhibit-read-only t)
|
||||||
|
(rewritten-expr (funcall mu4e-query-rewrite-function expr))
|
||||||
(maxnum (unless mu4e-headers-full-search mu4e-headers-results-limit)))
|
(maxnum (unless mu4e-headers-full-search mu4e-headers-results-limit)))
|
||||||
(with-current-buffer buf
|
(with-current-buffer buf
|
||||||
(mu4e-headers-mode)
|
(mu4e-headers-mode)
|
||||||
|
@ -1103,7 +1131,7 @@ the query history stack."
|
||||||
(mu4e~headers-push-query mu4e~headers-last-query 'past)))
|
(mu4e~headers-push-query mu4e~headers-last-query 'past)))
|
||||||
(setq
|
(setq
|
||||||
mode-name "mu4e-headers"
|
mode-name "mu4e-headers"
|
||||||
mu4e~headers-last-query expr)
|
mu4e~headers-last-query rewritten-expr)
|
||||||
(add-to-list 'global-mode-string
|
(add-to-list 'global-mode-string
|
||||||
'(:eval
|
'(:eval
|
||||||
(concat
|
(concat
|
||||||
|
@ -1126,7 +1154,7 @@ the query history stack."
|
||||||
(run-hook-with-args 'mu4e-headers-search-hook expr)
|
(run-hook-with-args 'mu4e-headers-search-hook expr)
|
||||||
(mu4e~headers-clear mu4e~searching)
|
(mu4e~headers-clear mu4e~searching)
|
||||||
(mu4e~proc-find
|
(mu4e~proc-find
|
||||||
expr
|
rewritten-expr
|
||||||
mu4e-headers-show-threads
|
mu4e-headers-show-threads
|
||||||
mu4e-headers-sort-field
|
mu4e-headers-sort-field
|
||||||
mu4e-headers-sort-direction
|
mu4e-headers-sort-direction
|
||||||
|
@ -1387,7 +1415,9 @@ or `past'."
|
||||||
"Whether to automatically view (open) the target message (as
|
"Whether to automatically view (open) the target message (as
|
||||||
per `mu4e~headers-msgid-target').")
|
per `mu4e~headers-msgid-target').")
|
||||||
|
|
||||||
(defun mu4e-headers-search (&optional expr prompt edit ignore-history msgid show)
|
|
||||||
|
(defun mu4e-headers-search (&optional expr prompt edit
|
||||||
|
ignore-history msgid show)
|
||||||
"Search in the mu database for EXPR, and switch to the output
|
"Search in the mu database for EXPR, and switch to the output
|
||||||
buffer for the results. This is an interactive function which ask
|
buffer for the results. This is an interactive function which ask
|
||||||
user for EXPR. PROMPT, if non-nil, is the prompt used by this
|
user for EXPR. PROMPT, if non-nil, is the prompt used by this
|
||||||
|
|
|
@ -328,8 +328,8 @@ marking if it still had that."
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(mu4e~fontify-cited)
|
(mu4e~fontify-cited)
|
||||||
(mu4e~fontify-signature)
|
(mu4e~fontify-signature)
|
||||||
|
(mu4e~view-make-urls-clickable)
|
||||||
(mu4e~view-show-images-maybe msg)
|
(mu4e~view-show-images-maybe msg)
|
||||||
(mu4e~view-make-urls-clickable)
|
|
||||||
(when embedded (local-set-key "q" 'kill-buffer-and-window))
|
(when embedded (local-set-key "q" 'kill-buffer-and-window))
|
||||||
(unless mode-enabled (run-mode-hooks 'mu4e-view-mode-hook)))))
|
(unless mode-enabled (run-mode-hooks 'mu4e-view-mode-hook)))))
|
||||||
(switch-to-buffer buf)))
|
(switch-to-buffer buf)))
|
||||||
|
|
Loading…
Reference in New Issue