X-Git-Url: https://git.notmuchmail.org/git?a=blobdiff_plain;f=emacs%2Fnotmuch.el;h=a23d0c2031654ec563cd729092bb49d4f94d557a;hb=c51d5b3cdb5ca0816816e88ca6f7136a24e74eee;hp=593374758c7139a1120a2281f9c6b87e16db99f5;hpb=2b433736a56ec1ccac67ada9cc81337a157a45a2;p=notmuch diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 59337475..a23d0c20 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -563,6 +563,10 @@ This function advances the next thread when finished." (notmuch-search-remove-tag-thread "inbox") (forward-line)) +(defvar notmuch-search-process-filter-data nil + "Data that has not yet been processed.") +(make-variable-buffer-local 'notmuch-search-process-filter-data) + (defun notmuch-search-process-sentinel (proc msg) "Add a message to let user know when \"notmuch search\" exits" (let ((buffer (process-buffer proc)) @@ -580,6 +584,8 @@ This function advances the next thread when finished." (insert "Incomplete search results (search process was killed).\n")) (if (eq status 'exit) (progn + (if notmuch-search-process-filter-data + (insert (concat "Error: Unexpected output from notmuch search:\n" notmuch-search-process-filter-data))) (insert "End of search results.") (if (not (= exit-status 0)) (insert (format " (process returned %d)" exit-status))) @@ -606,7 +612,7 @@ The attributes defined for matching tags are merged, with later attributes overriding earlier. A message having both \"delete\" and \"unread\" tags with the above settings would have a green foreground and blue background." - :type '(alist :key-type (string) :value-type (list)) + :type '(alist :key-type (string) :value-type (custom-face-edit)) :group 'notmuch) (defun notmuch-search-color-line (start end line-tag-list) @@ -629,49 +635,87 @@ foreground and blue background." (defun notmuch-search-isearch-authors-show (overlay) (remove-from-invisibility-spec (cons (overlay-get overlay 'invisible) t))) +(defun notmuch-search-author-propertize (authors) + "Split `authors' into matching and non-matching authors and +propertize appropriately. If no boundary between authors and +non-authors is found, assume that all of the authors match." + (if (string-match "\\(.*\\)|\\(.*\\)" authors) + (concat (propertize (concat (match-string 1 authors) ",") + 'face 'notmuch-search-matching-authors) + (propertize (match-string 2 authors) + 'face 'notmuch-search-non-matching-authors)) + (propertize authors 'face 'notmuch-search-matching-authors))) + (defun notmuch-search-insert-authors (format-string authors) - (let* ((propertized-authors - ;; Need to save the match data to avoid interfering with - ;; `notmuch-search-process-filter'. - (save-match-data - ;; Authors that don't match the search query are shown in a - ;; different font. - (if (string-match "\\(.*\\)|\\(..*\\)" authors) - (concat (propertize (concat (match-string 1 authors) ",") - 'face 'notmuch-search-matching-authors) - (propertize (match-string 2 authors) - 'face 'notmuch-search-non-matching-authors)) - (propertize authors 'face 'notmuch-search-matching-authors)))) - - (formatted-sample (format format-string "")) - (formatted-authors (format format-string propertized-authors)) - visible-string invisible-string) - - ;; Determine the part of the authors that will be visible by - ;; default. - (if (> (length formatted-authors) - (length formatted-sample)) - ;; 4 is `(length "... ")'. - (let ((visible-length (- (length formatted-sample) 4))) - (setq visible-string (substring propertized-authors 0 visible-length) - invisible-string (substring propertized-authors visible-length))) - (setq visible-string formatted-authors - invisible-string nil)) - - ;; Insert both the visible and invisible author strings. - (insert visible-string) - (when invisible-string - (let ((start (point)) - (invis-spec (make-symbol "notmuch-search-authors")) - overlay) - (insert invisible-string) - ;; Using a cons-cell here causes an ellipsis to be inserted - ;; instead of the invisible text. - (add-to-invisibility-spec (cons invis-spec t)) - (setq overlay (make-overlay start (point))) - (overlay-put overlay 'invisible invis-spec) - (overlay-put overlay 'isearch-open-invisible #'notmuch-search-isearch-authors-show) - (insert " "))))) + ;; Save the match data to avoid interfering with + ;; `notmuch-search-process-filter'. + (save-match-data + (let* ((formatted-authors (format format-string authors)) + (formatted-sample (format format-string "")) + (visible-string formatted-authors) + (invisible-string "") + (padding "")) + + ;; Truncate the author string to fit the specification. + (if (> (length formatted-authors) + (length formatted-sample)) + (let ((visible-length (- (length formatted-sample) + (length "... ")))) + ;; Truncate the visible string according to the width of + ;; the display string. + (setq visible-string (substring formatted-authors 0 visible-length) + invisible-string (substring formatted-authors visible-length)) + ;; If possible, truncate the visible string at a natural + ;; break (comma or pipe), as incremental search doesn't + ;; match across the visible/invisible border. + (when (string-match "\\(.*\\)\\([,|] \\)\\([^,|]*\\)" visible-string) + ;; Second clause is destructive on `visible-string', so + ;; order is important. + (setq invisible-string (concat (match-string 3 visible-string) + invisible-string) + visible-string (concat (match-string 1 visible-string) + (match-string 2 visible-string)))) + ;; `visible-string' may be shorter than the space allowed + ;; by `format-string'. If so we must insert some padding + ;; after `invisible-string'. + (setq padding (make-string (- (length formatted-sample) + (length visible-string) + (length "...")) + ? )))) + + ;; Use different faces to show matching and non-matching authors. + (if (string-match "\\(.*\\)|\\(.*\\)" visible-string) + ;; The visible string contains both matching and + ;; non-matching authors. + (setq visible-string (notmuch-search-author-propertize visible-string) + ;; The invisible string must contain only non-matching + ;; authors, as the visible-string contains both. + invisible-string (propertize invisible-string + 'face 'notmuch-search-non-matching-authors)) + ;; The visible string contains only matching authors. + (setq visible-string (propertize visible-string + 'face 'notmuch-search-matching-authors) + ;; The invisible string may contain both matching and + ;; non-matching authors. + invisible-string (notmuch-search-author-propertize invisible-string))) + + ;; If there is any invisible text, add it as a tooltip to the + ;; visible text. + (when (not (string= invisible-string "")) + (setq visible-string (propertize visible-string 'help-echo (concat "..." invisible-string)))) + + ;; Insert the visible and, if present, invisible author strings. + (insert visible-string) + (when (not (string= invisible-string "")) + (let ((start (point)) + (invis-spec (make-symbol "notmuch-search-authors")) + overlay) + (insert invisible-string) + (add-to-invisibility-spec (cons invis-spec t)) + (setq overlay (make-overlay start (point))) + (overlay-put overlay 'invisible invis-spec) + (overlay-put overlay 'isearch-open-invisible #'notmuch-search-isearch-authors-show))) + (insert padding)))) (defun notmuch-search-insert-field (field date count authors subject tags) (cond @@ -707,8 +751,12 @@ foreground and blue background." (save-excursion (let ((line 0) (more t) - (inhibit-read-only t)) + (inhibit-read-only t) + (string (concat notmuch-search-process-filter-data string))) + (setq notmuch-search-process-filter-data nil) (while more + (while (and (< line (length string)) (= (elt string line) ?\n)) + (setq line (1+ line))) (if (string-match "^\\(thread:[0-9A-Fa-f]*\\) \\([^][]*\\) \\(\\[[0-9/]*\\]\\) \\([^;]*\\); \\(.*\\) (\\([^()]*\\))$" string line) (let* ((thread-id (match-string 1 string)) (date (match-string 2 string)) @@ -718,6 +766,8 @@ foreground and blue background." (tags (match-string 6 string)) (tag-list (if tags (save-match-data (split-string tags))))) (goto-char (point-max)) + (if (/= (match-beginning 1) line) + (insert (concat "Error: Unexpected output from notmuch search:\n" (substring string line (match-beginning 1)) "\n"))) (let ((beg (point-marker))) (notmuch-search-show-result date count authors subject tags) (notmuch-search-color-line beg (point-marker) tag-list) @@ -729,7 +779,12 @@ foreground and blue background." (set 'found-target beg) (set 'notmuch-search-target-thread "found")))) (set 'line (match-end 0))) - (set 'more nil))))) + (set 'more nil) + (while (and (< line (length string)) (= (elt string line) ?\n)) + (setq line (1+ line))) + (if (< line (length string)) + (setq notmuch-search-process-filter-data (substring string line))) + )))) (if found-target (goto-char found-target))) (delete-process proc))))