aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2019-05-02 09:00:53 -0400
committerStefan Monnier2019-05-02 09:00:53 -0400
commit0efaae78f2b66de7ebeff7d1c16771ddafdf2d06 (patch)
treebd1c649ff6001c334bf5976113952a1da492a730
parentcd3a7f35de8b0f39524912529d6fceda26571276 (diff)
downloademacs-0efaae78f2b66de7ebeff7d1c16771ddafdf2d06.tar.gz
emacs-0efaae78f2b66de7ebeff7d1c16771ddafdf2d06.zip
* 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."
164 "List of (FN TEXT . POINTERS). 164 "List of (FN TEXT . POINTERS).
165Where FN is the footnote number, TEXT is a marker pointing to 165Where FN is the footnote number, TEXT is a marker pointing to
166the footnote's text, and POINTERS is a list of markers pointing 166the footnote's text, and POINTERS is a list of markers pointing
167to the places from which the footnote is referenced.") 167to the places from which the footnote is referenced.
168TEXT points right *before* the [...] and POINTERS point right
169*after* the [...].")
168 170
169(defvar footnote-mouse-highlight 'highlight 171(defvar footnote-mouse-highlight 'highlight
170 ;; FIXME: This `highlight' property is not currently used. 172 ;; FIXME: This `highlight' property is not currently used.
@@ -452,52 +454,41 @@ Conversion is done based upon the current selected style."
452 454
453(defun footnote--refresh-footnotes (&optional index-regexp) 455(defun footnote--refresh-footnotes (&optional index-regexp)
454 "Redraw all footnotes. 456 "Redraw all footnotes.
455You must call this or arrange to have this called after changing footnote 457You must call this or arrange to have this called after changing
456styles." 458footnote styles."
457 (unless index-regexp 459 (let ((fn-regexp (concat
458 (setq index-regexp (footnote--current-regexp))) 460 (regexp-quote footnote-start-tag)
459 (save-excursion 461 "\\(" (or index-regexp (footnote--current-regexp)) "+\\)"
460 ;; Take care of the pointers first 462 (regexp-quote footnote-end-tag))))
461 (let ((i 0) locn alist) 463 (save-excursion
462 (while (setq alist (nth i footnote--markers-alist)) 464 (pcase-dolist (`(,fn ,text . ,pointers) footnote--markers-alist)
463 (setq locn (cddr alist)) 465 ;; Take care of the pointers first
464 (while locn 466 (dolist (locn pointers)
465 (goto-char (car locn)) 467 (goto-char locn)
466 ;; Try to handle the case where `footnote-start-tag' and 468 ;; Try to handle the case where `footnote-start-tag' and
467 ;; `footnote-end-tag' are the same string. 469 ;; `footnote-end-tag' are the same string.
468 (when (looking-back (concat 470 (when (looking-back fn-regexp
469 (regexp-quote footnote-start-tag)
470 "\\(" index-regexp "+\\)"
471 (regexp-quote footnote-end-tag))
472 (line-beginning-position)) 471 (line-beginning-position))
473 (replace-match 472 (replace-match
474 (propertize 473 (propertize
475 (concat 474 (concat
476 footnote-start-tag 475 footnote-start-tag
477 (footnote--index-to-string (1+ i)) 476 (footnote--index-to-string fn)
478 footnote-end-tag) 477 footnote-end-tag)
479 'footnote-number (1+ i) footnote-mouse-highlight t) 478 'footnote-number fn footnote-mouse-highlight t)
480 nil "\\1")) 479 t t)))
481 (setq locn (cdr locn))) 480
482 (setq i (1+ i)))) 481 ;; Now take care of the text section
483 482 (goto-char text)
484 ;; Now take care of the text section 483 (when (looking-at fn-regexp)
485 (let ((i 0) alist)
486 (while (setq alist (nth i footnote--markers-alist))
487 (goto-char (cadr alist))
488 (when (looking-at (concat
489 (regexp-quote footnote-start-tag)
490 "\\(" index-regexp "+\\)"
491 (regexp-quote footnote-end-tag)))
492 (replace-match 484 (replace-match
493 (propertize 485 (propertize
494 (concat 486 (concat
495 footnote-start-tag 487 footnote-start-tag
496 (footnote--index-to-string (1+ i)) 488 (footnote--index-to-string fn)
497 footnote-end-tag) 489 footnote-end-tag)
498 'footnote-number (1+ i)) 490 'footnote-number fn)
499 nil "\\1")) 491 t t))))))
500 (setq i (1+ i))))))
501 492
502(defun footnote-cycle-style () 493(defun footnote-cycle-style ()
503 "Select next defined footnote style." 494 "Select next defined footnote style."
@@ -532,31 +523,28 @@ styles."
532 523
533(defun footnote--renumber (to alist-elem) 524(defun footnote--renumber (to alist-elem)
534 "Renumber a single footnote." 525 "Renumber a single footnote."
535 (let* ((posn-list (cddr alist-elem))) 526 (unless (equal to (car alist-elem)) ;Nothing to do.
536 (setcar alist-elem to) 527 (let* ((fn-regexp (concat (regexp-quote footnote-start-tag)
537 (while posn-list 528 (footnote--current-regexp)
538 (goto-char (car posn-list)) 529 (regexp-quote footnote-end-tag))))
539 (when (looking-back (concat (regexp-quote footnote-start-tag) 530 (setcar alist-elem to)
540 (footnote--current-regexp) 531 (dolist (posn (cddr alist-elem))
541 (regexp-quote footnote-end-tag)) 532 (goto-char posn)
542 (line-beginning-position)) 533 (when (looking-back fn-regexp (line-beginning-position))
543 (replace-match 534 (replace-match
544 (propertize 535 (propertize
536 (concat footnote-start-tag
537 (footnote--index-to-string to)
538 footnote-end-tag)
539 'footnote-number to footnote-mouse-highlight t))))
540 (goto-char (cadr alist-elem))
541 (when (looking-at fn-regexp)
542 (replace-match
543 (propertize
545 (concat footnote-start-tag 544 (concat footnote-start-tag
546 (footnote--index-to-string to) 545 (footnote--index-to-string to)
547 footnote-end-tag) 546 footnote-end-tag)
548 'footnote-number to footnote-mouse-highlight t))) 547 'footnote-number to))))))
549 (setq posn-list (cdr posn-list)))
550 (goto-char (cadr alist-elem))
551 (when (looking-at (concat (regexp-quote footnote-start-tag)
552 (footnote--current-regexp)
553 (regexp-quote footnote-end-tag)))
554 (replace-match
555 (propertize
556 (concat footnote-start-tag
557 (footnote--index-to-string to)
558 footnote-end-tag)
559 'footnote-number to)))))
560 548
561(defun footnote--narrow-to-footnotes () 549(defun footnote--narrow-to-footnotes ()
562 "Restrict text in buffer to show only text of footnotes." 550 "Restrict text in buffer to show only text of footnotes."
@@ -652,18 +640,11 @@ Presumes we're within the footnote area already."
652 "Return the number of the current footnote if in footnote text. 640 "Return the number of the current footnote if in footnote text.
653Return nil if the cursor is not positioned over the text of 641Return nil if the cursor is not positioned over the text of
654a footnote." 642a footnote."
655 (when (and footnote--markers-alist 643 (when (<= (point) (footnote--get-area-point-max))
656 (<= (footnote--get-area-point-min) 644 (let ((result nil))
657 (point) 645 (pcase-dolist (`(,fn ,text . ,_) footnote--markers-alist)
658 (footnote--get-area-point-max))) 646 (if (<= text (point))
659 (let ((i 1) alist-txt result) 647 (setq result fn)))
660 (while (and (setq alist-txt (nth i footnote--markers-alist))
661 (null result))
662 (when (< (point) (cadr alist-txt))
663 (setq result (car (nth (1- i) footnote--markers-alist))))
664 (setq i (1+ i)))
665 (when (and (null result) (null alist-txt))
666 (setq result (car (nth (1- i) footnote--markers-alist))))
667 result))) 648 result)))
668 649
669(defun footnote--under-cursor () 650(defun footnote--under-cursor ()
@@ -750,11 +731,8 @@ footnote area, returns `point-max'."
750 731
751(defun footnote--make-hole () 732(defun footnote--make-hole ()
752 (save-excursion 733 (save-excursion
753 (let ((i 0) 734 (let (rc)
754 (notes (length footnote--markers-alist)) 735 (dolist (alist-elem footnote--markers-alist)
755 alist-elem rc)
756 (while (< i notes)
757 (setq alist-elem (nth i footnote--markers-alist))
758 (when (< (point) (- (cl-caddr alist-elem) 3)) 736 (when (< (point) (- (cl-caddr alist-elem) 3))
759 (unless rc 737 (unless rc
760 (setq rc (car alist-elem))) 738 (setq rc (car alist-elem)))
@@ -764,8 +742,7 @@ footnote area, returns `point-max'."
764 (footnote--index-to-string 742 (footnote--index-to-string
765 (1+ (car alist-elem)))) 743 (1+ (car alist-elem))))
766 (footnote--renumber (1+ (car alist-elem)) 744 (footnote--renumber (1+ (car alist-elem))
767 alist-elem))) 745 alist-elem))))
768 (setq i (1+ i)))
769 rc))) 746 rc)))
770 747
771(defun footnote-add-footnote () 748(defun footnote-add-footnote ()
@@ -778,9 +755,10 @@ by using `footnote-back-to-message'."
778 (interactive "*") 755 (interactive "*")
779 (let ((num 756 (let ((num
780 (if footnote--markers-alist 757 (if footnote--markers-alist
781 (if (< (point) (cl-caddar (last footnote--markers-alist))) 758 (let ((last (car (last footnote--markers-alist))))
782 (footnote--make-hole) 759 (if (< (point) (cl-caddr last))
783 (1+ (caar (last footnote--markers-alist)))) 760 (footnote--make-hole)
761 (1+ (car last))))
784 1))) 762 1)))
785 (message "Adding footnote %d" num) 763 (message "Adding footnote %d" num)
786 (footnote--insert-footnote num) 764 (footnote--insert-footnote num)
@@ -807,20 +785,17 @@ delete the footnote with that number."
807 (when (and arg 785 (when (and arg
808 (or (not footnote-prompt-before-deletion) 786 (or (not footnote-prompt-before-deletion)
809 (y-or-n-p (format "Really delete footnote %d?" arg)))) 787 (y-or-n-p (format "Really delete footnote %d?" arg))))
810 (let (alist-elem locn) 788 (let ((alist-elem (or (assq arg footnote--markers-alist)
811 (setq alist-elem (assq arg footnote--markers-alist)) 789 (error "Can't delete footnote %d" arg)))
812 (unless alist-elem 790 (fn-regexp (concat (regexp-quote footnote-start-tag)
813 (error "Can't delete footnote %d" arg)) 791 (footnote--current-regexp)
814 (setq locn (cddr alist-elem)) 792 (regexp-quote footnote-end-tag))))
815 (while (car locn) 793 (dolist (locn (cddr alist-elem))
816 (save-excursion 794 (save-excursion
817 (goto-char (car locn)) 795 (goto-char locn)
818 (when (looking-back (concat (regexp-quote footnote-start-tag) 796 (when (looking-back fn-regexp
819 (footnote--current-regexp)
820 (regexp-quote footnote-end-tag))
821 (line-beginning-position)) 797 (line-beginning-position))
822 (delete-region (match-beginning 0) (match-end 0)))) 798 (delete-region (match-beginning 0) (match-end 0)))))
823 (setq locn (cdr locn)))
824 (save-excursion 799 (save-excursion
825 (goto-char (cadr alist-elem)) 800 (goto-char (cadr alist-elem))
826 (delete-region 801 (delete-region
@@ -833,8 +808,8 @@ delete the footnote with that number."
833 (point) 'footnote-number nil (footnote--goto-char-point-max)))))) 808 (point) 'footnote-number nil (footnote--goto-char-point-max))))))
834 (setq footnote--markers-alist 809 (setq footnote--markers-alist
835 (delq alist-elem footnote--markers-alist)) 810 (delq alist-elem footnote--markers-alist))
836 (footnote-renumber-footnotes) 811 (if footnote--markers-alist
837 (when (null footnote--markers-alist) 812 (footnote-renumber-footnotes)
838 (save-excursion 813 (save-excursion
839 (if (not (string-equal footnote-section-tag "")) 814 (if (not (string-equal footnote-section-tag ""))
840 (let* ((end (footnote--goto-char-point-max)) 815 (let* ((end (footnote--goto-char-point-max))
@@ -855,13 +830,9 @@ delete the footnote with that number."
855 "Renumber footnotes, starting from 1." 830 "Renumber footnotes, starting from 1."
856 (interactive "*") 831 (interactive "*")
857 (save-excursion 832 (save-excursion
858 (let ((i 0) 833 (let ((i 1))
859 (notes (length footnote--markers-alist)) 834 (dolist (alist-elem footnote--markers-alist)
860 alist-elem) 835 (footnote--renumber i alist-elem)
861 (while (< i notes)
862 (setq alist-elem (nth i footnote--markers-alist))
863 (unless (= (1+ i) (car alist-elem))
864 (footnote--renumber (1+ i) alist-elem))
865 (setq i (1+ i)))))) 836 (setq i (1+ i))))))
866 837
867(defun footnote-goto-footnote (&optional arg) 838(defun footnote-goto-footnote (&optional arg)
@@ -900,13 +871,13 @@ being set it is automatically widened."
900 871
901(defvar footnote-mode-map 872(defvar footnote-mode-map
902 (let ((map (make-sparse-keymap))) 873 (let ((map (make-sparse-keymap)))
903 (define-key map "a" 'footnote-add-footnote) 874 (define-key map "a" #'footnote-add-footnote)
904 (define-key map "b" 'footnote-back-to-message) 875 (define-key map "b" #'footnote-back-to-message)
905 (define-key map "c" 'footnote-cycle-style) 876 (define-key map "c" #'footnote-cycle-style)
906 (define-key map "d" 'footnote-delete-footnote) 877 (define-key map "d" #'footnote-delete-footnote)
907 (define-key map "g" 'footnote-goto-footnote) 878 (define-key map "g" #'footnote-goto-footnote)
908 (define-key map "r" 'footnote-renumber-footnotes) 879 (define-key map "r" #'footnote-renumber-footnotes)
909 (define-key map "s" 'footnote-set-style) 880 (define-key map "s" #'footnote-set-style)
910 map)) 881 map))
911 882
912(defvar footnote-minor-mode-map 883(defvar footnote-minor-mode-map