X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=emacs%2Fnotmuch-hello.el;h=6db62a01c46b09e7851c9259552c13d7a7574c6b;hp=e9caade5d4c1e6ad5fe2f6d76c63182d527c9212;hb=d273ed6cf1bdaa2d644cec4909cbf415ff4d257b;hpb=fc4e5248d29cf7264481cbff82343eade5fcc2ca diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index e9caade5..6db62a01 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -41,7 +41,7 @@ (defun notmuch-sort-saved-searches (alist) "Generate an alphabetically sorted saved searches alist." - (sort alist (lambda (a b) (string< (car a) (car b))))) + (sort (copy-sequence alist) (lambda (a b) (string< (car a) (car b))))) (defcustom notmuch-saved-search-sort-function nil "Function used to sort the saved searches for the notmuch-hello view. @@ -154,11 +154,6 @@ International Bureau of Weights and Measures." (defvar notmuch-hello-url "http://notmuchmail.org" "The `notmuch' web site.") -(defvar notmuch-hello-search-pos nil - "Position of search widget, if any. - -This should only be set by `notmuch-hello-insert-search'.") - (defvar notmuch-hello-custom-section-options '((:filter (string :tag "Filter for each tag")) (:filter-count (string :tag "Different filter to generate message counts")) @@ -187,7 +182,7 @@ This should only be set by `notmuch-hello-insert-search'.") :tag "Customized queries section (see docstring for details)" :type `(list :tag "" - (const :tag "" notmuch-hello-insert-query-list) + (const :tag "" notmuch-hello-insert-searches) (string :tag "Title for this section") (repeat :tag "Queries" (cons (string :tag "Name") (string :tag "Query"))) @@ -209,11 +204,8 @@ function produces a section simply by adding content to the current buffer. A section should not end with an empty line, because a newline will be inserted after each section by `notmuch-hello'. -Each function should take no arguments. If the produced section -includes `notmuch-hello-target' (i.e. cursor should be positioned -inside this section), the function should return this element's -position. -Otherwise, it should return nil. +Each function should take no arguments. The return value is +ignored. For convenience an element can also be a list of the form (FUNC ARG1 ARG2 .. ARGN) in which case FUNC will be applied to the rest of the @@ -226,7 +218,7 @@ by an additional filter query. Similarly, the count of messages displayed next to the buttons can be generated by applying a different filter to the tag query. These filters are also supported for \"Customized queries section\" items." - :group 'notmuch + :group 'notmuch-hello :type '(repeat (choice (function-item notmuch-hello-insert-header) @@ -240,15 +232,6 @@ supported for \"Customized queries section\" items." notmuch-hello-query-section (function :tag "Custom section")))) -(defvar notmuch-hello-target nil - "Button text at position of point before rebuilding the notmuch-buffer. - -This variable contains the text of the button, if any, the -point was positioned at before the notmuch-hello buffer was -rebuilt. This should never actually be global and is defined as a -defvar only for documentation purposes and to avoid a compiler -warning about it occurring as a free variable.") - (defvar notmuch-hello-hidden-sections nil "List of sections titles whose contents are hidden") @@ -429,51 +412,41 @@ Such a list can be computed with `notmuch-hello-query-counts'." (let* ((widest (notmuch-hello-longest-label searches)) (tags-and-width (notmuch-hello-tags-per-line widest)) (tags-per-line (car tags-and-width)) - (widest (cdr tags-and-width)) + (column-width (cdr tags-and-width)) + (column-indent 0) (count 0) (reordered-list (notmuch-hello-reflect searches tags-per-line)) ;; Hack the display of the buttons used. (widget-push-button-prefix "") - (widget-push-button-suffix "") - (found-target-pos nil)) + (widget-push-button-suffix "")) ;; dme: It feels as though there should be a better way to ;; implement this loop than using an incrementing counter. (mapc (lambda (elem) ;; (not elem) indicates an empty slot in the matrix. (when elem + (if (> column-indent 0) + (widget-insert (make-string column-indent ? ))) (let* ((name (first elem)) (query (second elem)) - (msg-count (third elem)) - (formatted-name (format "%s " name))) + (msg-count (third elem))) (widget-insert (format "%8s " (notmuch-hello-nice-number msg-count))) - (if (string= formatted-name notmuch-hello-target) - (setq found-target-pos (point-marker))) (widget-create 'push-button :notify #'notmuch-hello-widget-search :notmuch-search-terms query - formatted-name) - (unless (eq (% count tags-per-line) (1- tags-per-line)) - ;; If this is not the last tag on the line, insert - ;; enough space to consume the rest of the column. - ;; Because the button for the name is `(1+ (length - ;; name))' long (due to the trailing space) we can - ;; just insert `(- widest (length name))' spaces - the - ;; column separator is included in the button if - ;; `(equal widest (length name)'. - (widget-insert (make-string (max 1 - (- widest (length name))) - ? ))))) + name) + (setq column-indent + (1+ (max 0 (- column-width (length name))))))) (setq count (1+ count)) - (if (eq (% count tags-per-line) 0) - (widget-insert "\n"))) + (when (eq (% count tags-per-line) 0) + (setq column-indent 0) + (widget-insert "\n"))) reordered-list) ;; If the last line was not full (and hence did not include a ;; carriage return), insert one now. (unless (eq (% count tags-per-line) 0) - (widget-insert "\n")) - found-target-pos)) + (widget-insert "\n")))) (defimage notmuch-hello-logo ((:type png :file "notmuch-logo.png"))) @@ -527,7 +500,7 @@ Complete list of currently available key bindings: (defun notmuch-hello-generate-tag-alist (&optional hide-tags) "Return an alist from tags to queries to display in the all-tags section." (mapcar (lambda (tag) - (cons tag (format "tag:%s" tag))) + (cons tag (concat "tag:" (notmuch-escape-boolean-term tag)))) (notmuch-remove-if-not (lambda (tag) (not (member tag hide-tags))) @@ -577,8 +550,7 @@ Complete list of currently available key bindings: (funcall notmuch-saved-search-sort-function notmuch-saved-searches) notmuch-saved-searches) - :show-empty-searches notmuch-show-empty-saved-searches)) - found-target-pos) + :show-empty-searches notmuch-show-empty-saved-searches))) (when searches (widget-insert "Saved searches: ") (widget-create 'push-button @@ -587,15 +559,12 @@ Complete list of currently available key bindings: "edit") (widget-insert "\n\n") (let ((start (point))) - (setq found-target-pos - (notmuch-hello-insert-buttons searches)) - (indent-rigidly start (point) notmuch-hello-indent) - found-target-pos)))) + (notmuch-hello-insert-buttons searches) + (indent-rigidly start (point) notmuch-hello-indent))))) (defun notmuch-hello-insert-search () "Insert a search widget." (widget-insert "Search: ") - (setq notmuch-hello-search-pos (point-marker)) (widget-create 'editable-field ;; Leave some space at the start and end of the ;; search boxes. @@ -695,16 +664,13 @@ Supports the following entries in OPTIONS as a plist: (notmuch-hello-update)) "hide")) (widget-insert "\n") - (let (target-pos) - (when (not is-hidden) - (let ((searches (apply 'notmuch-hello-query-counts query-alist options))) - (when (or (not (plist-get options :hide-if-empty)) - searches) - (widget-insert "\n") - (setq target-pos - (notmuch-hello-insert-buttons searches)) - (indent-rigidly start (point) notmuch-hello-indent)))) - target-pos))) + (when (not is-hidden) + (let ((searches (apply 'notmuch-hello-query-counts query-alist options))) + (when (or (not (plist-get options :hide-if-empty)) + searches) + (widget-insert "\n") + (notmuch-hello-insert-buttons searches) + (indent-rigidly start (point) notmuch-hello-indent)))))) (defun notmuch-hello-insert-tags-section (&optional title &rest options) "Insert a section displaying all tags with message counts. @@ -723,7 +689,7 @@ following: "Show an entry for each saved search and inboxed messages for each tag" (notmuch-hello-insert-searches "What's in your inbox" (append - (notmuch-saved-searches) + notmuch-saved-searches (notmuch-hello-generate-tag-alist)) :filter "tag:inbox")) @@ -760,22 +726,12 @@ following: "Run notmuch and display saved searches, known tags, etc." (interactive) - ;; Jump through a hoop to get this value from the deprecated variable - ;; name (`notmuch-folders') or from the default value. - (unless notmuch-saved-searches - (setq notmuch-saved-searches (notmuch-saved-searches))) - (if no-display (set-buffer "*notmuch-hello*") (switch-to-buffer "*notmuch-hello*")) - (let ((notmuch-hello-target (if (widget-at) - (widget-value (widget-at)) - (condition-case nil - (progn - (widget-forward 1) - (widget-value (widget-at))) - (error nil)))) + (let ((target-line (line-number-at-pos)) + (target-column (current-column)) (inhibit-read-only t)) ;; Delete all editable widget fields. Editable widget fields are @@ -794,30 +750,25 @@ following: (mapc 'delete-overlay (car all)) (mapc 'delete-overlay (cdr all))) - (let (final-target-pos) - (mapc - (lambda (section) - (let ((point-before (point)) - (result (if (functionp section) - (funcall section) - (apply (car section) (cdr section))))) - (if (and (not final-target-pos) (integer-or-marker-p result)) - (setq final-target-pos result)) - ;; don't insert a newline when the previous section didn't show - ;; anything. - (unless (eq (point) point-before) - (widget-insert "\n")))) - notmuch-hello-sections) - (widget-setup) - - (when final-target-pos - (goto-char final-target-pos) - (unless (widget-at) - (widget-forward 1))) - - (unless (widget-at) - (when notmuch-hello-search-pos - (goto-char notmuch-hello-search-pos))))) + (mapc + (lambda (section) + (let ((point-before (point))) + (if (functionp section) + (funcall section) + (apply (car section) (cdr section))) + ;; don't insert a newline when the previous section didn't + ;; show anything. + (unless (eq (point) point-before) + (widget-insert "\n")))) + notmuch-hello-sections) + (widget-setup) + + ;; Move point back to where it was before refresh. Use line and + ;; column instead of point directly to be insensitive to additions + ;; and removals of text within earlier lines. + (goto-char (point-min)) + (forward-line (1- target-line)) + (move-to-column target-column)) (run-hooks 'notmuch-hello-refresh-hook) (setq notmuch-hello-first-run nil))