From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by arlo.cworth.org (Postfix) with ESMTP id D23A26DE0B36 for ; Thu, 11 Feb 2016 00:33:36 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at cworth.org X-Spam-Flag: NO X-Spam-Score: -0.12 X-Spam-Level: X-Spam-Status: No, score=-0.12 tagged_above=-999 required=5 tests=[AWL=-0.053, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_NEUTRAL=0.652, UNPARSEABLE_RELAY=0.001] autolearn=disabled Received: from arlo.cworth.org ([127.0.0.1]) by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id EIMAa3HwO4k2 for ; Thu, 11 Feb 2016 00:33:34 -0800 (PST) Received: from mail-wm0-f65.google.com (mail-wm0-f65.google.com [74.125.82.65]) by arlo.cworth.org (Postfix) with ESMTPS id 3DA206DE0BF6 for ; Thu, 11 Feb 2016 00:33:34 -0800 (PST) Received: by mail-wm0-f65.google.com with SMTP id p63so9190312wmp.1 for ; Thu, 11 Feb 2016 00:33:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dme-org.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=dk1ZJLD46xW1KACbIWEz+5OrH68bZ4c0ppWpwopj4vw=; b=NGKBXzKouEMX/ZAJwpcOgdR5a+w+Y4rHO/+xQ3RF4A1MYYhEvzCikXV8NqaGorRl+T js7mcl8CmuzdvZHHmosHa7XxVy/bjrRGoCxXMw42rkOgwFfZTgAI8lPYas98GEWrEZu+ BzZ1XjZMg7/V6sFm0dhg7zlBtI7SoHQpjQFxGU7cydqhlVftth7uXa6k68Vdn6qzc8WL Lx+kvVD37kHbWmNmkC0bv0PTSXEG3fmHSxJO1For9uvQSQxQ4cyDbc+FnBuQt8SJxHgq 2EJNEI4X96pyewGelPlUadDfthjUQlm85m5y52tEnJkFPOJuVmWgzgq30630Ub/avOOS 2o9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=dk1ZJLD46xW1KACbIWEz+5OrH68bZ4c0ppWpwopj4vw=; b=JiueOgVvv3+Qu4aJYXrF1mhBnJpGmXY6rOOgqbEYNzWV84ypp+u/fEKVIzsC3jy8Ko fBh0xYdJa4TZBb8TejdHllCt69QA8U9/lm7F06wucNlCpR0H8f26Cf5NInY+yENhsiZx m+2yA5lZSzMavxO9SYZZ+7MKpVAF68GZriV+YhCW/KnB2YNaP/RfMK1kqGL+ZMFM7Vgf DjnGJsFvmxzo14g6MzcrBWqJ4iIG4Q8U/tjJxjtiBL8h9bslYQnq6lfk6S5nbOU6KqLs 6myT3m0fq/vYyK9wiEY8p+X9GipcDhLPTwbrHeqUvhX6/NWtAc8B9ut/PhwJnnUsJvGS yJIw== X-Gm-Message-State: AG10YOQY9muAxXAMoo7DMwHAYy5jC8V56GiFybFWVjD5ON+/rtfeM4RVXDqG89//fNlPDQ== X-Received: by 10.28.221.68 with SMTP id u65mr16510591wmg.95.1455179612952; Thu, 11 Feb 2016 00:33:32 -0800 (PST) Received: from disaster-area.hh.sledj.net ([2a01:348:1a2:1:ea39:35ff:fe2c:a227]) by smtp.gmail.com with ESMTPSA id e19sm22903696wmd.1.2016.02.11.00.33.31 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 11 Feb 2016 00:33:31 -0800 (PST) Received: from localhost (disaster-area.hh.sledj.net [local]) by disaster-area.hh.sledj.net (OpenSMTPD) with ESMTPA id 723b7469 for ; Thu, 11 Feb 2016 08:33:27 +0000 (UTC) From: David Edmondson To: notmuch@notmuchmail.org Subject: [PATCH v3] emacs: Report a lack of matches when calling `notmuch-show'. Date: Thu, 11 Feb 2016 08:33:27 +0000 Message-Id: <1455179607-16870-2-git-send-email-dme@dme.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1455179607-16870-1-git-send-email-dme@dme.org> References: <1455179607-16870-1-git-send-email-dme@dme.org> X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 Feb 2016 08:33:37 -0000 If the basic query passed to `notmuch-show' generates no results, ring the bell and inform the user that no messages matched the query rather than displaying an empty buffer and showing an obscure error. Similarly when refreshing a `notmuch-show' buffer and no messages match. --- emacs/notmuch-show.el | 144 +++++++++++++++++++++++++++++--------------------- emacs/notmuch.el | 6 ++- 2 files changed, 89 insertions(+), 61 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 3345878..4629c64 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -153,27 +153,21 @@ indentation." (defvar notmuch-show-thread-id nil) (make-variable-buffer-local 'notmuch-show-thread-id) -(put 'notmuch-show-thread-id 'permanent-local t) (defvar notmuch-show-parent-buffer nil) (make-variable-buffer-local 'notmuch-show-parent-buffer) -(put 'notmuch-show-parent-buffer 'permanent-local t) (defvar notmuch-show-query-context nil) (make-variable-buffer-local 'notmuch-show-query-context) -(put 'notmuch-show-query-context 'permanent-local t) (defvar notmuch-show-process-crypto nil) (make-variable-buffer-local 'notmuch-show-process-crypto) -(put 'notmuch-show-process-crypto 'permanent-local t) (defvar notmuch-show-elide-non-matching-messages nil) (make-variable-buffer-local 'notmuch-show-elide-non-matching-messages) -(put 'notmuch-show-elide-non-matching-messages 'permanent-local t) (defvar notmuch-show-indent-content t) (make-variable-buffer-local 'notmuch-show-indent-content) -(put 'notmuch-show-indent-content 'permanent-local t) (defvar notmuch-show-attachment-debug nil "If t log stdout and stderr from attachment handlers @@ -1197,71 +1191,101 @@ non-nil. The optional BUFFER-NAME provides the name of the buffer in which the message thread is shown. If it is nil (which occurs when the command is called interactively) the argument to the -function is used." +function is used. + +Returns the buffer containing the messages, or NIL if no messages +matched." (interactive "sNotmuch show: \nP") (let ((buffer-name (generate-new-buffer-name (or buffer-name (concat "*notmuch-" thread-id "*"))))) (switch-to-buffer (get-buffer-create buffer-name)) - ;; Set the default value for `notmuch-show-process-crypto' in this - ;; buffer. - (setq notmuch-show-process-crypto notmuch-crypto-process-mime) - ;; Set the default value for - ;; `notmuch-show-elide-non-matching-messages' in this buffer. If - ;; elide-toggle is set, invert the default. - (setq notmuch-show-elide-non-matching-messages notmuch-show-only-matching-messages) - (if elide-toggle - (setq notmuch-show-elide-non-matching-messages (not notmuch-show-elide-non-matching-messages))) + ;; No need to track undo information for this buffer. + (setq buffer-undo-list t) + + (notmuch-show-mode) + ;; Set various buffer local variables to their appropriate initial + ;; state. Do this after enabling `notmuch-show-mode' so that they + ;; aren't wiped out. (setq notmuch-show-thread-id thread-id notmuch-show-parent-buffer parent-buffer - notmuch-show-query-context query-context) - (notmuch-show-build-buffer) - (notmuch-show-goto-first-wanted-message) - (current-buffer))) + notmuch-show-query-context query-context -(defun notmuch-show-build-buffer () - (let ((inhibit-read-only t)) + notmuch-show-process-crypto notmuch-crypto-process-mime + ;; If `elide-toggle', invert the default value. + notmuch-show-elide-non-matching-messages + (if elide-toggle + (not notmuch-show-only-matching-messages) + notmuch-show-only-matching-messages)) - (notmuch-show-mode) (add-hook 'post-command-hook #'notmuch-show-command-hook nil t) - - ;; Don't track undo information for this buffer - (set 'buffer-undo-list t) + (jit-lock-register #'notmuch-show-buttonise-links) (notmuch-tag-clear-cache) - (erase-buffer) - (goto-char (point-min)) - (save-excursion - (let* ((basic-args (list notmuch-show-thread-id)) - (args (if notmuch-show-query-context - (append (list "\'") basic-args - (list "and (" notmuch-show-query-context ")\'")) - (append (list "\'") basic-args (list "\'")))) - (cli-args (cons "--exclude=false" - (when notmuch-show-elide-non-matching-messages - (list "--entire-thread=false"))))) - - (notmuch-show-insert-forest (notmuch-query-get-threads (append cli-args args))) - ;; If the query context reduced the results to nothing, run - ;; the basic query. - (when (and (eq (buffer-size) 0) - notmuch-show-query-context) - (notmuch-show-insert-forest - (notmuch-query-get-threads (append cli-args basic-args))))) - - (jit-lock-register #'notmuch-show-buttonise-links) - - (notmuch-show-mapc (lambda () (notmuch-show-set-prop :orig-tags (notmuch-show-get-tags)))) + + (let ((inhibit-read-only t)) + (if (notmuch-show--build-buffer) + ;; Messages were inserted into the buffer. + (current-buffer) + + ;; No messages were inserted - presumably none matched the + ;; query. + (kill-buffer (current-buffer)) + (ding) + (message "No messages matched the query!") + nil)))) + +(defun notmuch-show--build-buffer (&optional state) + "Display messages matching the current buffer context. + +Apply the previously saved STATE if supplied, otherwise show the +first relevant message. + +If no messages match the query return NIL." + (let* ((basic-args (list notmuch-show-thread-id)) + (args (if notmuch-show-query-context + (append (list "\'") basic-args + (list "and (" notmuch-show-query-context ")\'")) + (append (list "\'") basic-args (list "\'")))) + (cli-args (cons "--exclude=false" + (when notmuch-show-elide-non-matching-messages + (list "--entire-thread=false")))) + + (forest (or (notmuch-query-get-threads (append cli-args args)) + ;; If a query context reduced the number of + ;; results to zero, try again without it. + (and notmuch-show-query-context + (notmuch-query-get-threads (append cli-args basic-args))))) + + ;; Must be reset every time we are going to start inserting + ;; messages into the buffer. + (notmuch-show-previous-subject "")) + + (when forest + (notmuch-show-insert-forest forest) + + ;; Store the original tags for each message so that we can + ;; display changes. + (notmuch-show-mapc + (lambda () (notmuch-show-set-prop :orig-tags (notmuch-show-get-tags)))) ;; Set the header line to the subject of the first message. (setq header-line-format (replace-regexp-in-string "%" "%%" - (notmuch-sanitize - (notmuch-show-strip-re - (notmuch-show-get-subject))))) + (notmuch-sanitize + (notmuch-show-strip-re + (notmuch-show-get-subject))))) - (run-hooks 'notmuch-show-hook)))) + (run-hooks 'notmuch-show-hook) + + (if state + (notmuch-show-apply-state state) + ;; With no state to apply, just go to the first message. + (notmuch-show-goto-first-wanted-message))) + + ;; Report back to the caller whether any messages matched. + forest)) (defun notmuch-show-capture-state () "Capture the state of the current buffer. @@ -1320,17 +1344,17 @@ reset based on the original query." (let ((inhibit-read-only t) (state (unless reset-state (notmuch-show-capture-state)))) - ;; erase-buffer does not seem to remove overlays, which can lead + ;; `erase-buffer' does not seem to remove overlays, which can lead ;; to weird effects such as remaining images, so remove them ;; manually. (remove-overlays) (erase-buffer) - (notmuch-show-build-buffer) - (if state - (notmuch-show-apply-state state) - ;; We're resetting state, so navigate to the first open message - ;; and mark it read, just like opening a new show buffer. - (notmuch-show-goto-first-wanted-message)))) + + (unless (notmuch-show--build-buffer state) + ;; No messages were inserted. + (kill-buffer (current-buffer)) + (ding) + (message "Refreshing the buffer resulted in no messages!")))) (defvar notmuch-show-stash-map (let ((map (make-sparse-keymap))) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 463b926..3100b97 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -458,7 +458,11 @@ no messages in the region then return nil." (notmuch-search-properties-in-region :subject beg end)) (defun notmuch-search-show-thread (&optional elide-toggle) - "Display the currently selected thread." + "Display the currently selected thread. + +With a prefix argument, invert the default value of +`notmuch-show-only-matching-messages' when displaying the +thread." (interactive "P") (let ((thread-id (notmuch-search-find-thread-id)) (subject (notmuch-search-find-subject))) -- 2.1.4