X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=emacs%2Fnotmuch.el;h=d09252828f6b063300308adef096ff674a716e00;hp=69954824ec959cd3cb471406c05918ceae4d8e56;hb=90e741ef81668d9b7db62b57e9a0c88877e2631e;hpb=2a91f636d8c3d478619c0a5040685aca1ac75842 diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 69954824..d0925282 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -69,7 +69,13 @@ date, count, authors, subject, tags For example: (setq notmuch-search-result-format \(\(\"authors\" . \"%-40s\"\) - \(\"subject\" . \"%s\"\)\)\)" + \(\"subject\" . \"%s\"\)\)\) +Line breaks are permitted in format strings (though this is +currently experimental). Note that a line break at the end of an +\"authors\" field will get elided if the authors list is long; +place it instead at the beginning of the following field. To +enter a line break when setting this variable with setq, use \\n. +To enter a line break in customize, press \\[quoted-insert] C-j." :type '(alist :key-type (string) :value-type (string)) :group 'notmuch-search) @@ -427,25 +433,50 @@ returns nil" (next-single-property-change (or pos (point)) 'notmuch-search-result nil (point-max)))) +(defun notmuch-search-foreach-result (beg end function) + "Invoke FUNCTION for each result between BEG and END. + +FUNCTION should take one argument. It will be applied to the +character position of the beginning of each result that overlaps +the region between points BEG and END. As a special case, if (= +BEG END), FUNCTION will be applied to the result containing point +BEG." + + (lexical-let ((pos (notmuch-search-result-beginning beg)) + ;; End must be a marker in case function changes the + ;; text. + (end (copy-marker end)) + ;; Make sure we examine at least one result, even if + ;; (= beg end). + (first t)) + ;; We have to be careful if the region extends beyond the results. + ;; In this case, pos could be null or there could be no result at + ;; pos. + (while (and pos (or (< pos end) first)) + (when (notmuch-search-get-result pos) + (funcall function pos)) + (setq pos (notmuch-search-result-end pos) + first nil)))) +;; Unindent the function argument of notmuch-search-foreach-result so +;; the indentation of callers doesn't get out of hand. +(put 'notmuch-search-foreach-result 'lisp-indent-function 2) + (defun notmuch-search-properties-in-region (property beg end) - (save-excursion - (let ((output nil) - (last-line (line-number-at-pos end)) - (max-line (- (line-number-at-pos (point-max)) 2))) - (goto-char beg) - (beginning-of-line) - (while (<= (line-number-at-pos) (min last-line max-line)) - (setq output (cons (get-text-property (point) property) output)) - (forward-line 1)) - output))) + (let (output) + (notmuch-search-foreach-result beg end + (lambda (pos) + (push (plist-get (notmuch-search-get-result pos) property) output))) + output)) (defun notmuch-search-find-thread-id () "Return the thread for the current thread" - (get-text-property (point) 'notmuch-search-thread-id)) + (let ((thread (plist-get (notmuch-search-get-result) :thread))) + (when thread (concat "thread:" thread)))) (defun notmuch-search-find-thread-id-region (beg end) "Return a list of threads for the current region" - (notmuch-search-properties-in-region 'notmuch-search-thread-id beg end)) + (mapcar (lambda (thread) (concat "thread:" thread)) + (notmuch-search-properties-in-region :thread beg end))) (defun notmuch-search-find-thread-id-region-search (beg end) "Return a search string for threads for the current region" @@ -453,19 +484,19 @@ returns nil" (defun notmuch-search-find-authors () "Return the authors for the current thread" - (get-text-property (point) 'notmuch-search-authors)) + (plist-get (notmuch-search-get-result) :authors)) (defun notmuch-search-find-authors-region (beg end) "Return a list of authors for the current region" - (notmuch-search-properties-in-region 'notmuch-search-authors beg end)) + (notmuch-search-properties-in-region :authors beg end)) (defun notmuch-search-find-subject () "Return the subject for the current thread" - (get-text-property (point) 'notmuch-search-subject)) + (plist-get (notmuch-search-get-result) :subject)) (defun notmuch-search-find-subject-region (beg end) "Return a list of authors for the current region" - (notmuch-search-properties-in-region 'notmuch-search-subject beg end)) + (notmuch-search-properties-in-region :subject beg end)) (defun notmuch-search-show-thread () "Display the currently selected thread." @@ -517,28 +548,21 @@ and will also appear in a buffer named \"*Notmuch errors*\"." (plist-get (notmuch-search-get-result pos) :tags)) (defun notmuch-search-get-tags-region (beg end) - (save-excursion - (let ((output nil) - (last-line (line-number-at-pos end)) - (max-line (- (line-number-at-pos (point-max)) 2))) - (goto-char beg) - (while (<= (line-number-at-pos) (min last-line max-line)) - (setq output (append output (notmuch-search-get-tags))) - (forward-line 1)) - output))) + (let (output) + (notmuch-search-foreach-result beg end + (lambda (pos) + (setq output (append output (notmuch-search-get-tags pos))))) + output)) (defun notmuch-search-tag-region (beg end &optional tag-changes) "Change tags for threads in the given region." (let ((search-string (notmuch-search-find-thread-id-region-search beg end))) (setq tag-changes (funcall 'notmuch-tag search-string tag-changes)) - (save-excursion - (let ((last-line (line-number-at-pos end)) - (max-line (- (line-number-at-pos (point-max)) 2))) - (goto-char beg) - (while (<= (line-number-at-pos) (min last-line max-line)) - (notmuch-search-set-tags - (notmuch-update-tags (notmuch-search-get-tags) tag-changes)) - (forward-line)))))) + (notmuch-search-foreach-result beg end + (lambda (pos) + (notmuch-search-set-tags + (notmuch-update-tags (notmuch-search-get-tags pos) tag-changes) + pos))))) (defun notmuch-search-tag (&optional tag-changes) "Change tags for the currently selected thread or region. @@ -751,11 +775,9 @@ non-authors is found, assume that all of the authors match." (notmuch-search-insert-authors format-string (plist-get result :authors))) ((string-equal field "tags") - ;; Ignore format-string here because notmuch-search-set-tags - ;; depends on the format of this - (insert (concat "(" (propertize - (mapconcat 'identity (plist-get result :tags) " ") - 'font-lock-face 'notmuch-tag-face) ")"))))) + (let ((tags-str (mapconcat 'identity (plist-get result :tags) " "))) + (insert (propertize (format format-string tags-str) + 'face 'notmuch-tag-face)))))) (defun notmuch-search-show-result (result &optional pos) "Insert RESULT at POS or the end of the buffer if POS is null." @@ -768,13 +790,7 @@ non-authors is found, assume that all of the authors match." (notmuch-search-insert-field (car spec) (cdr spec) result)) (insert "\n") (notmuch-search-color-line beg (point) (plist-get result :tags)) - (put-text-property beg (point) 'notmuch-search-result result) - (put-text-property beg (point) 'notmuch-search-thread-id - (concat "thread:" (plist-get result :thread))) - (put-text-property beg (point) 'notmuch-search-authors - (plist-get result :authors)) - (put-text-property beg (point) 'notmuch-search-subject - (plist-get result :subject))) + (put-text-property beg (point) 'notmuch-search-result result)) (when (string= (plist-get result :thread) notmuch-search-target-thread) (setq notmuch-search-target-thread "found") (goto-char beg)))))