notmuch.el: Refactor citation markup. Variables for minimum size, button text.

This is a fairly intrusive rewrite.

- I pulled the common code for the signature and citation case out
  into a separate function. This is not so much shorter, but I think it
  will be easier to maintain.

- I replaced the sequence of (looking-at blah) (forward-line)  with a single
  re-search-forward per citation.

New variables

- notmuch-show-signature-button-format, notmuch-show-citation-button-format
  Allow customization of button text.

- notmuch-show-citation-lines-min
  Do not buttonize citations below the given threshold.

Reviewed-by: Kan-Ru Chen <kanru@kanru.info>
This commit is contained in:
David Bremner 2009-12-25 16:09:07 -04:00 committed by Carl Worth
parent 7a9bacac67
commit 24b2f7699f

View file

@ -94,9 +94,24 @@ for indentation at the beginning of the line. But notmuch will
move past the indentation when testing this pattern, (so that the move past the indentation when testing this pattern, (so that the
pattern can still test against the entire line).") pattern can still test against the entire line).")
(defvar notmuch-show-signature-button-format
"[ %d-line hidden signature. Click/Enter to show ]"
"String used to construct button text for hidden signatures
Can use up to one integer format parameter, i.e. %d")
(defvar notmuch-show-citation-button-format
"[ %d-line hidden citation. Click/Enter to show ]"
"String used to construct button text for hidden citations.
Can use up to one integer format parameter, i.e. %d")
(defvar notmuch-show-signature-lines-max 12 (defvar notmuch-show-signature-lines-max 12
"Maximum length of signature that will be hidden by default.") "Maximum length of signature that will be hidden by default.")
(defvar notmuch-show-citation-lines-min 4
"Minimum length of citation that will be hidden.")
(defvar notmuch-command "notmuch" (defvar notmuch-command "notmuch"
"Command to run the notmuch binary.") "Command to run the notmuch binary.")
@ -616,54 +631,78 @@ which this thread was originally shown."
'face 'notmuch-message-summary-face 'face 'notmuch-message-summary-face
:supertype 'notmuch-button-invisibility-toggle-type) :supertype 'notmuch-button-invisibility-toggle-type)
(defun notmuch-show-citation-regexp (depth)
"Build a regexp for matching citations at a given DEPTH (indent)"
(let ((line-regexp (format "[[:space:]]\\{%d\\}>.*\n" depth)))
(concat "\\(?:^" line-regexp
"\\(?:[[:space:]]*\n" line-regexp
"\\)?\\)+")))
(defun notmuch-show-region-to-button (beg end type prefix button-text)
"Auxilary function to do the actual making of overlays and buttons
BEG and END are buffer locations. TYPE should a string, either
\"citation\" or \"signature\". PREFIX is some arbitrary text to
insert before the button, probably for indentation. BUTTON-TEXT
is what to put on the button."
;; This uses some slightly tricky conversions between strings and
;; symbols because of the way the button code works. Note that
;; replacing intern-soft with make-symbol will cause this to fail,
;; since the newly created symbol has no plist.
(let ((overlay (make-overlay beg end))
(invis-spec (make-symbol (concat "notmuch-" type "-region")))
(button-type (intern-soft (concat "notmuch-button-"
type "-toggle-type"))))
(add-to-invisibility-spec invis-spec)
(overlay-put overlay 'invisible invis-spec)
(goto-char (1+ end))
(save-excursion
(goto-char (1- beg))
(insert prefix)
(insert-button button-text
'invisibility-spec invis-spec
:type button-type)
)))
(defun notmuch-show-markup-citations-region (beg end depth) (defun notmuch-show-markup-citations-region (beg end depth)
(goto-char beg) "Markup citations, and up to one signature in the given region"
(beginning-of-line) ;; it would be nice if the untabify was not required, but
(while (< (point) end) ;; that would require notmuch to indent with spaces.
(let ((beg-sub (point-marker)) (untabify beg end)
(indent (make-string depth ? )) (let ((citation-regexp (notmuch-show-citation-regexp depth))
(citation ">")) (signature-regexp (concat (format "^[[:space:]]\\{%d\\}" depth)
(move-to-column depth) notmuch-show-signature-regexp))
(if (looking-at citation) (indent (concat "\n" (make-string depth ? ))))
(progn (goto-char beg)
(while (looking-at citation) (beginning-of-line)
(forward-line) (while (and (< (point) end)
(move-to-column depth)) (re-search-forward citation-regexp end t))
(let ((overlay (make-overlay beg-sub (point))) (let* ((cite-start (match-beginning 0))
(invis-spec (make-symbol "notmuch-citation-region"))) (cite-end (match-end 0))
(add-to-invisibility-spec invis-spec) (cite-lines (count-lines cite-start cite-end)))
(overlay-put overlay 'invisible invis-spec) (if (>= cite-lines notmuch-show-citation-lines-min)
(let ((p (point-marker)) (notmuch-show-region-to-button
(cite-button-text cite-start cite-end
(concat "[" (number-to-string (count-lines beg-sub (point))) "citation"
"-line citation. Click/Enter to show.]"))) indent
(goto-char (- beg-sub 1)) (format notmuch-show-citation-button-format cite-lines)
(insert (concat "\n" indent)) ))))
(insert-button cite-button-text (if (and (< (point) end)
'invisibility-spec invis-spec (re-search-forward signature-regexp end t))
:type 'notmuch-button-citation-toggle-type) (let* ((sig-start (match-beginning 0))
(forward-line) (sig-end (match-end 0))
)))) (sig-lines (1- (count-lines sig-start end))))
(move-to-column depth) (if (<= sig-lines notmuch-show-signature-lines-max)
(if (looking-at notmuch-show-signature-regexp) (notmuch-show-region-to-button
(let ((sig-lines (- (count-lines beg-sub end) 1))) sig-start
(if (<= sig-lines notmuch-show-signature-lines-max) end
(progn "signature"
(let ((invis-spec (make-symbol "notmuch-signature-region"))) indent
(add-to-invisibility-spec invis-spec) (format notmuch-show-signature-button-format sig-lines)
(overlay-put (make-overlay beg-sub end) ))))))
'invisible invis-spec)
(goto-char (- beg-sub 1))
(insert (concat "\n" indent))
(let ((sig-button-text (concat "[" (number-to-string sig-lines)
"-line signature. Click/Enter to show.]")))
(insert-button sig-button-text 'invisibility-spec invis-spec
:type 'notmuch-button-signature-toggle-type)
)
(insert "\n")
(goto-char end))))))
(forward-line))))
(defun notmuch-show-markup-part (beg end depth) (defun notmuch-show-markup-part (beg end depth)
(if (re-search-forward notmuch-show-part-begin-regexp nil t) (if (re-search-forward notmuch-show-part-begin-regexp nil t)
@ -961,7 +1000,7 @@ The optional PARENT-BUFFER is the notmuch-search buffer from
which this notmuch-show command was executed, (so that the next which this notmuch-show command was executed, (so that the next
thread from that buffer can be show when done with this one). thread from that buffer can be show when done with this one).
The optional QUERY-CONTEXT is a notmuch search term. Only messages from the thread The optional QUERY-CONTEXT is a notmuch search term. Only messages from the thread
matching this search term are shown if non-nil. " matching this search term are shown if non-nil. "
(interactive "sNotmuch show: ") (interactive "sNotmuch show: ")
(let ((buffer (get-buffer-create (concat "*notmuch-show-" thread-id "*")))) (let ((buffer (get-buffer-create (concat "*notmuch-show-" thread-id "*"))))