diff --git a/configure.ac b/configure.ac index 16fb4690..d0ba81e5 100644 --- a/configure.ac +++ b/configure.ac @@ -14,7 +14,7 @@ ## along with this program; if not, write to the Free Software Foundation, ## Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -AC_INIT([mu],[0.9.9.5],[http://code.google.com/p/mu0/issues/list],[mu]) +AC_INIT([mu],[0.9.9.6pre2],[http://code.google.com/p/mu0/issues/list],[mu]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_SRCDIR([mu/mu.cc]) # libtoolize wants to put some stuff in here; if you have an old diff --git a/man/mu-find.1 b/man/mu-find.1 index 152bd4f7..738d24f5 100644 --- a/man/mu-find.1 +++ b/man/mu-find.1 @@ -1,4 +1,4 @@ -.TH MU FIND 1 "June 2013" "User Manuals" +.TH MU FIND 1 "September 2013" "User Manuals" .SH NAME @@ -344,14 +344,12 @@ Note, if you specify a sortfield, by default, messages are sorted in reverse choice, but for dates it may be more useful to sort in the opposite direction. .TP -\fB\-\-summary-len=\fR -If > 0, use that number of lines of the message to provide a summary. +\fB\-n\fR, \fB\-\-maxnum=\fR +If > 0, display maximally that number of entries. If not specified, all matching entries are displayed. .TP -\fB\-\-include\-unreadable\fR normally, \fBmu find\fR does not include -messages for which the corresponding file is unreadable. With this option even -such messages are included. Note, for \fB\-\-format=\fRlinks, unreadable -message are ignored even when this option is set. +\fB\-\-summary-len=\fR +If > 0, use that number of lines of the message to provide a summary. .TP \fB\-\-format\fR=\fIplain|links|xquery|xml|sexp\fR diff --git a/mu/mu-cmd-find.c b/mu/mu-cmd-find.c index 05ec4ad8..1a1afb07 100644 --- a/mu/mu-cmd-find.c +++ b/mu/mu-cmd-find.c @@ -132,7 +132,7 @@ run_query (MuQuery *xapian, const gchar *query, MuConfig *opts, GError **err) if (opts->threads) qflags |= MU_QUERY_FLAG_THREADS; - iter = mu_query_run (xapian, query, sortid, -1, qflags, err); + iter = mu_query_run (xapian, query, sortid, opts->maxnum, qflags, err); return iter; } @@ -585,9 +585,9 @@ output_finish (MuConfig *opts) static gboolean output_query_results (MuMsgIter *iter, MuConfig *opts, GError **err) { - unsigned count; - gboolean rv; - OutputFunc *output_func; + int count; + gboolean rv; + OutputFunc *output_func; output_func = output_prepare (opts, err); if (!output_func) @@ -598,6 +598,8 @@ output_query_results (MuMsgIter *iter, MuConfig *opts, GError **err) MuMsg *msg; + if (count == opts->maxnum) + break; msg = get_message (iter, opts->after); if (!msg) break; diff --git a/mu/mu-config.c b/mu/mu-config.c index bfd1e104..aa0caca4 100644 --- a/mu/mu-config.c +++ b/mu/mu-config.c @@ -205,6 +205,8 @@ config_options_group_find (void) {"sortfield", 's', 0, G_OPTION_ARG_STRING, &MU_CONFIG.sortfield, "field to sort on", ""}, + {"maxnum", 'n', 0, G_OPTION_ARG_INT, &MU_CONFIG.maxnum, + "number of entries to display in the output", ""}, {"threads", 't', 0, G_OPTION_ARG_NONE, &MU_CONFIG.threads, "show message threads", NULL}, {"bookmark", 'b', 0, G_OPTION_ARG_STRING, &MU_CONFIG.bookmark, @@ -477,9 +479,14 @@ cmd_from_string (const char *str) for (i = 0; i != G_N_ELEMENTS(cmd_map); ++i) if (strcmp (str, cmd_map[i].name) == 0) return cmd_map[i].cmd; +#ifdef BUILD_GUILE + /* if we don't recognize it and it's not an option, it may be + * some script */ + if (str[0] == '-') + return MU_CONFIG_CMD_SCRIPT; +#endif /*BUILD_GUILE*/ - /* if we don't recognize it, it may be some script */ - return MU_CONFIG_CMD_SCRIPT; + return MU_CONFIG_CMD_UNKNOWN; } @@ -509,6 +516,14 @@ parse_cmd (int *argcp, char ***argvp, GError **err) } #endif /*!BUILD_GUILE*/ + if (MU_CONFIG.cmdstr && MU_CONFIG.cmdstr[0] != '-' && + MU_CONFIG.cmd == MU_CONFIG_CMD_UNKNOWN) { + mu_util_g_set_error (err, MU_ERROR_IN_PARAMETERS, + "unknown command '%s'", + MU_CONFIG.cmdstr); + return FALSE; + } + return TRUE; } @@ -702,6 +717,8 @@ mu_config_init (int *argcp, char ***argvp, GError **err) memset (&MU_CONFIG, 0, sizeof(MU_CONFIG)); + MU_CONFIG.maxnum = -1; /* By default, output all matching entries. */ + if (!parse_cmd (argcp, argvp, err)) goto errexit; diff --git a/mu/mu-config.h b/mu/mu-config.h index dfd278d2..08636246 100644 --- a/mu/mu-config.h +++ b/mu/mu-config.h @@ -123,6 +123,7 @@ struct _MuConfig { /* options for querying 'find' (and view-> 'summary') */ gchar *fields; /* fields to show in output */ gchar *sortfield; /* field to sort by (string) */ + int maxnum; /* max # of entries to print */ gboolean reverse; /* sort in revers order (z->a) */ gboolean threads; /* show message threads */ diff --git a/mu4e/mu4e-compose.el b/mu4e/mu4e-compose.el index 89987160..2656d25a 100644 --- a/mu4e/mu4e-compose.el +++ b/mu4e/mu4e-compose.el @@ -119,9 +119,15 @@ for quering the message information." (defvar mu4e-compose-pre-hook nil "Hook run just *before* message composition starts. -If the compose-type is either /reply/ or /forward/, the variable +If the compose-type is either 'reply' or 'forward', the variable `mu4e-compose-parent-message' points to the message replied to / -being forwarded / edited.") +being forwarded / edited. + +Note that there is no draft message yet when this hook runs, it +is meant for influencing the how mu4e constructs the draft +message. If you want to do something with the draft messages after +it has been constructed, `mu4e-compose-mode-hook' would be the +place to do that.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/mu4e/mu4e-headers.el b/mu4e/mu4e-headers.el index d419e09b..c240eb1c 100644 --- a/mu4e/mu4e-headers.el +++ b/mu4e/mu4e-headers.el @@ -411,6 +411,16 @@ date. The formats used for date and time are (propertize (mu4e-get-mailing-list-shortname list) 'help-echo list) "")) +(defun mu4e~headers-custom-field (msg field) + "Show some custom header field, or raise an error if it is not +found." + (let* ((item (or (assoc field mu4e-header-info-custom) + (mu4e-error "field %S not found" field))) + (func (or (plist-get (cdr-safe item) :function) + (mu4e-error "no :function defined for field %S %S" field (cdr item))))) + (funcall func msg))) + + ;; note: this function is very performance-sensitive (defun mu4e~headers-header-handler (msg &optional point) "Create a one line description of MSG in this buffer, at POINT, @@ -426,7 +436,7 @@ if provided, or at the end of the buffer otherwise." (mu4e~headers-thread-prefix (mu4e-message-field msg :thread)) ;; "["(plist-get (mu4e-message-field msg :thread) :path) "] " val)) - ((:maildir :path) val) + ((:maildir :path :message-id) val) ((:to :from :cc :bcc) (mu4e~headers-contact-str val)) ;; if we (ie. `user-mail-address' is the 'From', show ;; 'To', otherwise show From @@ -441,7 +451,7 @@ if provided, or at the end of the buffer otherwise." 'help-echo (format "%S" val))) (:tags (propertize (mapconcat 'identity val ", "))) (:size (mu4e-display-size val)) - (t (mu4e-error "Unsupported header field (%S)" field)))) + (t (mu4e~headers-custom-field msg field)))) (when str (setq line (concat line @@ -677,7 +687,8 @@ after the end of the search results." (mapcar (lambda (item) (let* ((field (car item)) (width (cdr item)) - (info (cdr (assoc field mu4e-header-info))) + (info (cdr (assoc field + (append mu4e-header-info mu4e-header-info-custom)))) (sortable (plist-get info :sortable)) (help (plist-get info :help)) (uparrow (if mu4e-use-fancy-chars " ▲" " ^")) diff --git a/mu4e/mu4e-vars.el b/mu4e/mu4e-vars.el index e4df2a15..b4ed2438 100644 --- a/mu4e/mu4e-vars.el +++ b/mu4e/mu4e-vars.el @@ -505,7 +505,6 @@ I.e. a message with the draft flag set." :group 'mu4e-faces) - ;; headers info (defconst mu4e-header-info '( (:attachments . @@ -558,6 +557,11 @@ I.e. a message with the draft flag set." :shortname "List" :help "Mailing list for this message" :sortable nil)) + (:message-id . + ( :name "Message-Id" + :shortname "MsgID" + :help "Message-Id for this message" + :sortable nil)) (:path . ( :name "Path" :shortname "Path" @@ -603,7 +607,26 @@ symbol for /another/ field. For example, the `:human-date' field uses `:date' for that. Note, `:sortable' does not work for custom header fields.") - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defvar mu4e-header-info-custom + '( (:recipnum . + ( :name "Number of recipients" + :shortname "Recip#" + :help "Number of recipients for this message" + :function + (lambda (msg) + (format "%d" + (+ (length (mu4e-message-field msg :to)) + (length (mu4e-message-field msg :cc)))))))) +"A list of custom (user-defined) headerr. The format is similar +to `mu4e-header-info', but addds a :function property, which should +point to a function that takes a message p-list as argument, and +returns a string. See the default value of `mu4e-header-info-custom +for an example.") + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/mu4e/mu4e-view.el b/mu4e/mu4e-view.el index 97892771..fff38196 100644 --- a/mu4e/mu4e-view.el +++ b/mu4e/mu4e-view.el @@ -149,6 +149,16 @@ messages - for example, `mu4e-org'." ;; need an extra policy... (mu4e~proc-view msgid mu4e-view-show-images mu4e-decryption-policy)) +(defun mu4e~view-custom-field (msg field) + "Show some custom header field, or raise an error if it is not +found." + (let* ((item (or (assoc field mu4e-header-info-custom) + (mu4e-error "field %S not found" field))) + (func (or (plist-get (cdr-safe item) :function) + (mu4e-error "no :function defined for field %S %S" + field (cdr item))))) + (funcall func msg))) + (defun mu4e-view-message-text (msg) "Return the message to display (as a string), based on the MSG plist." @@ -187,11 +197,14 @@ messages - for example, `mu4e-org'." (mu4e~view-construct-header field (mu4e-display-size fieldval))) (:mailing-list (mu4e~view-construct-header field fieldval)) + (:message-id + (mu4e~view-construct-header field fieldval)) ;; attachments (:attachments (mu4e~view-construct-attachments-header msg)) ;; pgp-signatures (:signature (mu4e~view-construct-signature-header msg)) - (t (mu4e-error "Unsupported field: %S" field))))) + (t (mu4e~view-construct-header field + (mu4e~view-custom-field msg field)))))) mu4e-view-fields "") "\n" (mu4e-message-body-text msg))) @@ -253,7 +266,8 @@ marking if it still had that." "Return header field FIELD (as in `mu4e-header-info') with value VAL if VAL is non-nil. If DONT-PROPERTIZE-VAL is non-nil, do not add text-properties to VAL." - (let* ((info (cdr (assoc field mu4e-header-info))) + (let* ((info (cdr (assoc field + (append mu4e-header-info mu4e-header-info-custom)))) (key (plist-get info :name)) (help (plist-get info :help))) (if (and val (> (length val) 0)) @@ -775,7 +789,7 @@ Also number them so they can be opened using `mu4e-view-go-to-url'." mouse-face highlight keymap ,map help-echo - ("[mouse-1] or [M-RET] to open the link")) url) + "[mouse-1] or [M-RET] to open the link") url) (replace-match (concat url (propertize (format "[%d]" num) diff --git a/mu4e/mu4e.texi b/mu4e/mu4e.texi index 78a04037..7a78516a 100644 --- a/mu4e/mu4e.texi +++ b/mu4e/mu4e.texi @@ -577,10 +577,12 @@ with @kbd{M-x mu4e}. @t{mu4e} does some checks to ensure everything is set up correctly, and then shows you the @t{mu4e} main view. Its major mode is @code{mu4e-main-mode}. + + @menu -* Overview:MV Overview. +* Overview: MV Overview. * Basic actions:: -* Bookmarks:MV Bookmarks. +* Bookmarks: MV Bookmarks. * Miscellaneous:: @end menu @@ -685,7 +687,7 @@ message, followed by a footer line. The major-mode for the headers view is @code{mu4e-headers-mode}. @menu -* Overview:HV Overview. +* Overview: HV Overview. * Keybindings:: * Marking messages:: * Sort order and threading:: @@ -718,7 +720,9 @@ Some notes to explain what you see in the example: @itemize @item The fields shown in the headers view can be influenced by customizing the variable @code{mu4e-headers-fields}; see @code{mu4e-header-info} for the -list of available fields. +list of built-in fields. Apart from the built-in fields, you can also create +custom fields using @code{mu4e-header-info-custom}; see its documentation for +the details. @item By default, the date is shown with the @t{:human-date} field, which shows the @emph{time} for today's messages, and the @emph{date} for older messages. If you want to distinguish between 'today' and 'older', you can use @@ -926,13 +930,13 @@ view window, which shows the message headers, followed by the message body. Its major mode is @code{mu4e-view-mode}. @menu -* Overview:MSGV Overview. -* Keybindings:MSGV Keybindings. +* Overview: MSGV Overview. +* Keybindings: MSGV Keybindings. * Opening and saving attachments:: * Viewing images inline:: * Displaying rich-text messages:: -* Crypto:MSGV Crypto. -* Actions:MSGV Actions. +* Crypto: MSGV Crypto. +* Actions: MSGV Actions. @end menu @node MSGV Overview @@ -965,7 +969,10 @@ An example message view: Some notes: @itemize -@item The variable @code{mu4e-view-fields} determines the header fields to be shown. +@item The variable @code{mu4e-view-fields} determines the header fields to be +shown; see @code{mu4e-header-info} for a list of built-in fields. Apart from +the built-in fields, you can also create custom fields using +@code{mu4e-header-info-custom}; see its documentation for the details. @item You can set the date format with the variable @code{mu4e-date-format-long}. @item By default, only the names of contacts in address fields are visible @@ -1510,10 +1517,10 @@ You can also influence the sort order and whether threads are shown or not; see @ref{Sort order and threading}. @menu -* Queries::Searching for messages -* Bookmarks::Remembering queries -* Maildir searches::Queries for maildirs -* Other search functionality::Some more tricks +* Queries:: Searching for messages. +* Bookmarks:: Remembering queries. +* Maildir searches:: Queries for maildirs. +* Other search functionality:: Some more tricks. @end menu @node Queries