summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2019-05-02 09:00:53 -0400
committerStefan Monnier <monnier@iro.umontreal.ca>2019-05-02 09:00:53 -0400
commit0efaae78f2b66de7ebeff7d1c16771ddafdf2d06 (patch)
treebd1c649ff6001c334bf5976113952a1da492a730
parentcd3a7f35de8b0f39524912529d6fceda26571276 (diff)
downloademacs-0efaae78f2b66de7ebeff7d1c16771ddafdf2d06.tar.gz
* lisp/mail/footnote.el: Use dolist and hoist regexps out of loops
(footnote--refresh-footnotes): Use pcase-dolist; compute regexp once outside of the loops. Use less confusing `literal` arg to `replace-match` and specify `fixedcase` since footnote--index-to-string already chose the proper case for us. (footnote--renumber): Use dolist; compute regexp once outside of the loops; shortcircuit when number is unchanged. (footnote--text-under-cursor): Rewrite. (footnote--make-hole): Use dolist. (footnote-add-footnote): CSE. (footnote-delete-footnote): Use dolist; compute regexp once outside of the loop. (footnote-delete-footnote): Don't renumber if there's no footnote left. (footnote-renumber-footnotes): Use dolist.
-rw-r--r--lisp/mail/footnote.el183
1 files changed, 77 insertions, 106 deletions
diff --git a/lisp/mail/footnote.el b/lisp/mail/footnote.el
index ef359b62b40..9a918376e67 100644
--- a/lisp/mail/footnote.el
+++ b/lisp/mail/footnote.el
@@ -164,7 +164,9 @@ left with the first character of footnote text."
"List of (FN TEXT . POINTERS).
Where FN is the footnote number, TEXT is a marker pointing to
the footnote's text, and POINTERS is a list of markers pointing
-to the places from which the footnote is referenced.")
+to the places from which the footnote is referenced.
+TEXT points right *before* the [...] and POINTERS point right
+*after* the [...].")
(defvar footnote-mouse-highlight 'highlight
;; FIXME: This `highlight' property is not currently used.
@@ -452,52 +454,41 @@ Conversion is done based upon the current selected style."
(defun footnote--refresh-footnotes (&optional index-regexp)
"Redraw all footnotes.
-You must call this or arrange to have this called after changing footnote
-styles."
- (unless index-regexp
- (setq index-regexp (footnote--current-regexp)))
- (save-excursion
- ;; Take care of the pointers first
- (let ((i 0) locn alist)
- (while (setq alist (nth i footnote--markers-alist))
- (setq locn (cddr alist))
- (while locn
- (goto-char (car locn))
+You must call this or arrange to have this called after changing
+footnote styles."
+ (let ((fn-regexp (concat
+ (regexp-quote footnote-start-tag)
+ "\\(" (or index-regexp (footnote--current-regexp)) "+\\)"
+ (regexp-quote footnote-end-tag))))
+ (save-excursion
+ (pcase-dolist (`(,fn ,text . ,pointers) footnote--markers-alist)
+ ;; Take care of the pointers first
+ (dolist (locn pointers)
+ (goto-char locn)
;; Try to handle the case where `footnote-start-tag' and
;; `footnote-end-tag' are the same string.
- (when (looking-back (concat
- (regexp-quote footnote-start-tag)
- "\\(" index-regexp "+\\)"
- (regexp-quote footnote-end-tag))
+ (when (looking-back fn-regexp
(line-beginning-position))
(replace-match
(propertize
(concat
footnote-start-tag
- (footnote--index-to-string (1+ i))
+ (footnote--index-to-string fn)
footnote-end-tag)
- 'footnote-number (1+ i) footnote-mouse-highlight t)
- nil "\\1"))
- (setq locn (cdr locn)))
- (setq i (1+ i))))
-
- ;; Now take care of the text section
- (let ((i 0) alist)
- (while (setq alist (nth i footnote--markers-alist))
- (goto-char (cadr alist))
- (when (looking-at (concat
- (regexp-quote footnote-start-tag)
- "\\(" index-regexp "+\\)"
- (regexp-quote footnote-end-tag)))
+ 'footnote-number fn footnote-mouse-highlight t)
+ t t)))
+
+ ;; Now take care of the text section
+ (goto-char text)
+ (when (looking-at fn-regexp)
(replace-match
(propertize
(concat
footnote-start-tag
- (footnote--index-to-string (1+ i))
+ (footnote--index-to-string fn)
footnote-end-tag)
- 'footnote-number (1+ i))
- nil "\\1"))
- (setq i (1+ i))))))
+ 'footnote-number fn)
+ t t))))))
(defun footnote-cycle-style ()
"Select next defined footnote style."
@@ -532,31 +523,28 @@ styles."
(defun footnote--renumber (to alist-elem)
"Renumber a single footnote."
- (let* ((posn-list (cddr alist-elem)))
- (setcar alist-elem to)
- (while posn-list
- (goto-char (car posn-list))
- (when (looking-back (concat (regexp-quote footnote-start-tag)
- (footnote--current-regexp)
- (regexp-quote footnote-end-tag))
- (line-beginning-position))
- (replace-match
- (propertize
+ (unless (equal to (car alist-elem)) ;Nothing to do.
+ (let* ((fn-regexp (concat (regexp-quote footnote-start-tag)
+ (footnote--current-regexp)
+ (regexp-quote footnote-end-tag))))
+ (setcar alist-elem to)
+ (dolist (posn (cddr alist-elem))
+ (goto-char posn)
+ (when (looking-back fn-regexp (line-beginning-position))
+ (replace-match
+ (propertize
+ (concat footnote-start-tag
+ (footnote--index-to-string to)
+ footnote-end-tag)
+ 'footnote-number to footnote-mouse-highlight t))))
+ (goto-char (cadr alist-elem))
+ (when (looking-at fn-regexp)
+ (replace-match
+ (propertize
(concat footnote-start-tag
(footnote--index-to-string to)
footnote-end-tag)
- 'footnote-number to footnote-mouse-highlight t)))
- (setq posn-list (cdr posn-list)))
- (goto-char (cadr alist-elem))
- (when (looking-at (concat (regexp-quote footnote-start-tag)
- (footnote--current-regexp)
- (regexp-quote footnote-end-tag)))
- (replace-match
- (propertize
- (concat footnote-start-tag
- (footnote--index-to-string to)
- footnote-end-tag)
- 'footnote-number to)))))
+ 'footnote-number to))))))
(defun footnote--narrow-to-footnotes ()
"Restrict text in buffer to show only text of footnotes."
@@ -652,18 +640,11 @@ Presumes we're within the footnote area already."
"Return the number of the current footnote if in footnote text.
Return nil if the cursor is not positioned over the text of
a footnote."
- (when (and footnote--markers-alist
- (<= (footnote--get-area-point-min)
- (point)
- (footnote--get-area-point-max)))
- (let ((i 1) alist-txt result)
- (while (and (setq alist-txt (nth i footnote--markers-alist))
- (null result))
- (when (< (point) (cadr alist-txt))
- (setq result (car (nth (1- i) footnote--markers-alist))))
- (setq i (1+ i)))
- (when (and (null result) (null alist-txt))
- (setq result (car (nth (1- i) footnote--markers-alist))))
+ (when (<= (point) (footnote--get-area-point-max))
+ (let ((result nil))
+ (pcase-dolist (`(,fn ,text . ,_) footnote--markers-alist)
+ (if (<= text (point))
+ (setq result fn)))
result)))
(defun footnote--under-cursor ()
@@ -750,11 +731,8 @@ footnote area, returns `point-max'."
(defun footnote--make-hole ()
(save-excursion
- (let ((i 0)
- (notes (length footnote--markers-alist))
- alist-elem rc)
- (while (< i notes)
- (setq alist-elem (nth i footnote--markers-alist))
+ (let (rc)
+ (dolist (alist-elem footnote--markers-alist)
(when (< (point) (- (cl-caddr alist-elem) 3))
(unless rc
(setq rc (car alist-elem)))
@@ -764,8 +742,7 @@ footnote area, returns `point-max'."
(footnote--index-to-string
(1+ (car alist-elem))))
(footnote--renumber (1+ (car alist-elem))
- alist-elem)))
- (setq i (1+ i)))
+ alist-elem))))
rc)))
(defun footnote-add-footnote ()
@@ -778,9 +755,10 @@ by using `footnote-back-to-message'."
(interactive "*")
(let ((num
(if footnote--markers-alist
- (if (< (point) (cl-caddar (last footnote--markers-alist)))
- (footnote--make-hole)
- (1+ (caar (last footnote--markers-alist))))
+ (let ((last (car (last footnote--markers-alist))))
+ (if (< (point) (cl-caddr last))
+ (footnote--make-hole)
+ (1+ (car last))))
1)))
(message "Adding footnote %d" num)
(footnote--insert-footnote num)
@@ -807,20 +785,17 @@ delete the footnote with that number."
(when (and arg
(or (not footnote-prompt-before-deletion)
(y-or-n-p (format "Really delete footnote %d?" arg))))
- (let (alist-elem locn)
- (setq alist-elem (assq arg footnote--markers-alist))
- (unless alist-elem
- (error "Can't delete footnote %d" arg))
- (setq locn (cddr alist-elem))
- (while (car locn)
+ (let ((alist-elem (or (assq arg footnote--markers-alist)
+ (error "Can't delete footnote %d" arg)))
+ (fn-regexp (concat (regexp-quote footnote-start-tag)
+ (footnote--current-regexp)
+ (regexp-quote footnote-end-tag))))
+ (dolist (locn (cddr alist-elem))
(save-excursion
- (goto-char (car locn))
- (when (looking-back (concat (regexp-quote footnote-start-tag)
- (footnote--current-regexp)
- (regexp-quote footnote-end-tag))
+ (goto-char locn)
+ (when (looking-back fn-regexp
(line-beginning-position))
- (delete-region (match-beginning 0) (match-end 0))))
- (setq locn (cdr locn)))
+ (delete-region (match-beginning 0) (match-end 0)))))
(save-excursion
(goto-char (cadr alist-elem))
(delete-region
@@ -833,8 +808,8 @@ delete the footnote with that number."
(point) 'footnote-number nil (footnote--goto-char-point-max))))))
(setq footnote--markers-alist
(delq alist-elem footnote--markers-alist))
- (footnote-renumber-footnotes)
- (when (null footnote--markers-alist)
+ (if footnote--markers-alist
+ (footnote-renumber-footnotes)
(save-excursion
(if (not (string-equal footnote-section-tag ""))
(let* ((end (footnote--goto-char-point-max))
@@ -855,13 +830,9 @@ delete the footnote with that number."
"Renumber footnotes, starting from 1."
(interactive "*")
(save-excursion
- (let ((i 0)
- (notes (length footnote--markers-alist))
- alist-elem)
- (while (< i notes)
- (setq alist-elem (nth i footnote--markers-alist))
- (unless (= (1+ i) (car alist-elem))
- (footnote--renumber (1+ i) alist-elem))
+ (let ((i 1))
+ (dolist (alist-elem footnote--markers-alist)
+ (footnote--renumber i alist-elem)
(setq i (1+ i))))))
(defun footnote-goto-footnote (&optional arg)
@@ -900,13 +871,13 @@ being set it is automatically widened."
(defvar footnote-mode-map
(let ((map (make-sparse-keymap)))
- (define-key map "a" 'footnote-add-footnote)
- (define-key map "b" 'footnote-back-to-message)
- (define-key map "c" 'footnote-cycle-style)
- (define-key map "d" 'footnote-delete-footnote)
- (define-key map "g" 'footnote-goto-footnote)
- (define-key map "r" 'footnote-renumber-footnotes)
- (define-key map "s" 'footnote-set-style)
+ (define-key map "a" #'footnote-add-footnote)
+ (define-key map "b" #'footnote-back-to-message)
+ (define-key map "c" #'footnote-cycle-style)
+ (define-key map "d" #'footnote-delete-footnote)
+ (define-key map "g" #'footnote-goto-footnote)
+ (define-key map "r" #'footnote-renumber-footnotes)
+ (define-key map "s" #'footnote-set-style)
map))
(defvar footnote-minor-mode-map