From 0f49fa055c1f55204b88c6b547a3f95feba4128a Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Tue, 7 Jan 2025 22:11:53 +0200 Subject: [PATCH] mu4e: add mu4e-analyze-last-query Add some mu4e command to show the query as analyzed by the server. --- mu4e/mu4e-helpers.el | 24 ++++++++++++++++++++---- mu4e/mu4e-server.el | 14 ++++++++++++-- mu4e/mu4e-window.el | 11 +++++++---- mu4e/mu4e.texi | 9 ++++++--- 4 files changed, 45 insertions(+), 13 deletions(-) diff --git a/mu4e/mu4e-helpers.el b/mu4e/mu4e-helpers.el index c96509b5..d756b81e 100644 --- a/mu4e/mu4e-helpers.el +++ b/mu4e/mu4e-helpers.el @@ -1,6 +1,6 @@ ;;; mu4e-helpers.el --- Helper functions -*- lexical-binding: t -*- -;; Copyright (C) 2022-2024 Dirk-Jan C. Binnema +;; Copyright (C) 2022-2025 Dirk-Jan C. Binnema ;; Author: Dirk-Jan C. Binnema ;; Maintainer: Dirk-Jan C. Binnema @@ -68,8 +68,7 @@ might want to add something like the following in your configuration. :group 'mu4e) (defcustom mu4e-read-option-use-builtin t - "Whether to use mu4e's traditional completion for -`mu4e-read-option'. + "Whether to use mu4e's traditional completion for `mu4e-read-option'. If nil, use the value of `mu4e-completing-read-function', integrated into mu4e. @@ -546,6 +545,23 @@ Or go to the top level if there is none." (when-let* ((msgid (bookmark-prop-get bookmark 'message-id))) (mu4e-view-message-with-message-id msgid))) +(defun mu4e--popup-lisp-buffer (bufname data) + "Show or hide an s-expression string in a popup-buffer. +BUFNAME is the name of the buffer, and DATA is lisp-data, if any." + (if-let* ((win (get-buffer-window bufname))) + (delete-window win) + (when data + (when (buffer-live-p bufname) + (kill-buffer bufname)) + (with-current-buffer-window + (get-buffer-create bufname) nil nil + ;; sadly, the default indentation for plists + ;; is not very nice, and I failed to overwrite it + (lisp-mode) + (insert (pp-to-string data)) + ;; add basic `quit-window' bindings + (view-mode 1))))) + ;;; Macros (defmacro mu4e-setq-if-nil (var val) @@ -566,7 +582,7 @@ COMPONENTS." (defun mu4e-string-replace (from-string to-string in-string) "Replace FROM-STRING with TO-STRING in IN-STRING each time it occurs. -Mu4e version of emacs 28's string-replace." +Mu4e's version of Emacs 28's `string-replace'." (replace-regexp-in-string (regexp-quote from-string) to-string in-string nil 'literal)) diff --git a/mu4e/mu4e-server.el b/mu4e/mu4e-server.el index 85ba0329..02942af3 100644 --- a/mu4e/mu4e-server.el +++ b/mu4e/mu4e-server.el @@ -196,11 +196,21 @@ This has the following fields: - :query: this is the last query the server executed (a string) - :query-sexp: this is that last query as processed by the query engine (an s-expression as a string) -- :query-sexp-expanded: like last-query-sexp, but with combination fields - expanded." +- :query-sexp-expanded: like :query-sexp, but with combination fields + expanded (if any)." (cl-remf mu4e--server-query :found) ;; there's no plist-delete mu4e--server-query) +(defvar mu4e--last-query-buffer-name) +(defun mu4e-analyze-last-query () + "Pop-up a buffer with the most recent query as the server saw it. +See `mu4e-server-last-query' for the fields. +It is the mu4e-version of \"mu find --analyze\"." + (interactive) + (mu4e--popup-lisp-buffer + mu4e--last-query-buffer-name + (mu4e-server-last-query))) + ;; temporary (defun mu4e--server-xapian-single-threaded-p() "Are we using Xapian in single-threaded mode?" diff --git a/mu4e/mu4e-window.el b/mu4e/mu4e-window.el index 8437b098..a172144d 100644 --- a/mu4e/mu4e-window.el +++ b/mu4e/mu4e-window.el @@ -1,7 +1,7 @@ ;;; mu4e-window.el --- Window management -*- lexical-binding: t; -*- ;; Copyright (C) 2022 Mickey Petersen -;; Copyright (C) 2023-2024 Dirk-Jan C. Binnema +;; Copyright (C) 2023-2025 Dirk-Jan C. Binnema ;; Author: Mickey Petersen ;; Keywords: mail @@ -26,7 +26,10 @@ ;;; Buffer names for internal use (defconst mu4e--sexp-buffer-name "*mu4e-sexp-at-point*" - "Buffer name for sexp buffers.") + "Name for the buffer which shows the sexp for the message-at-point.") + +(defconst mu4e--last-query-buffer-name "*mu4e-last-query*" + "Name for the buffer which shows the last server-query.") (defvar mu4e-main-buffer-name "*mu4e-main*" "Name of the mu4e main buffer.") @@ -77,14 +80,14 @@ function; this is no longer supported; instead you can use :group 'mu4e-headers) (defcustom mu4e-headers-visible-lines 10 - "Number of lines to display in the header view when using the + "Number of lines to display in the headers view (horizontal split-view). horizontal split-view. This includes the header-line at the top, and the mode-line." :type 'integer :group 'mu4e-headers) (defcustom mu4e-headers-visible-columns 30 - "Number of columns to display for the header view when using the + "Number of columns to display for the header view (vertical split-view). vertical split-view." :type 'integer :group 'mu4e-headers) diff --git a/mu4e/mu4e.texi b/mu4e/mu4e.texi index 739a573f..6a5045ca 100644 --- a/mu4e/mu4e.texi +++ b/mu4e/mu4e.texi @@ -1975,9 +1975,12 @@ see @ref{Sorting and threading}. @section Queries @t{mu4e} queries are the same as the ones that @t{mu find} -understands@footnote{with the caveat that command-line queries are -subject to the shell's interpretation before @t{mu} sees them}. You can -consult the @code{mu-query} man page for the details. +understands@footnote{with the caveat that command-line queries are subject to +the shell's interpretation before @t{mu} sees them}. You can consult the +@code{mu-query} man-page for the details. In addition, @t{mu4e} provides a +command @code{mu4e-analyze-last-query}, which shows how the @t{mu} server has +interpreted the query, similar to what the the @t{--analyze} option does for +@t{mu find}. Additionally, @t{mu4e} supports @kbd{TAB}-completion for queries. There there is completion for all search keywords such as @code{and},