aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Aranda2025-02-06 08:01:08 -0300
committerEli Zaretskii2025-02-22 11:19:17 +0200
commit3e269371507ea4cd7e933e39320d258a3b98de44 (patch)
tree57fcaa623db864e159bfc75587093dd08b4e0912
parent79ab873b9b679ec0aedb03ce246035d8e5d4b09c (diff)
downloademacs-3e269371507ea4cd7e933e39320d258a3b98de44.tar.gz
emacs-3e269371507ea4cd7e933e39320d258a3b98de44.zip
Speed up widget creation (Bug#53606)
* lisp/wid-edit.el (widget-default-create, widget-checklist-add-item) (widget-radio-add-item, widget-editable-list-entry-create): Don't insert format escapes into the buffer, only to delete them after. This avoids calls to delete-char and makes widget creation about 3 times faster.
-rw-r--r--lisp/wid-edit.el74
1 files changed, 47 insertions, 27 deletions
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index a1d4c4850ae..2d6075c10a8 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -1776,18 +1776,20 @@ to a given widget."
1776(defun widget-default-create (widget) 1776(defun widget-default-create (widget)
1777 "Create WIDGET at point in the current buffer." 1777 "Create WIDGET at point in the current buffer."
1778 (widget-specify-insert 1778 (widget-specify-insert
1779 (let ((from (point)) 1779 (let ((str (widget-get widget :format))
1780 (onext 0) (next 0)
1780 button-begin button-end 1781 button-begin button-end
1781 sample-begin sample-end 1782 sample-begin sample-end
1782 doc-begin doc-end 1783 doc-begin doc-end
1783 value-pos 1784 value-pos
1784 (markers (widget--prepare-markers-for-inside-insertion widget))) 1785 (markers (widget--prepare-markers-for-inside-insertion widget)))
1785 (insert (widget-get widget :format))
1786 (goto-char from)
1787 ;; Parse escapes in format. 1786 ;; Parse escapes in format.
1788 (while (re-search-forward "%\\(.\\)" nil t) 1787 (while (string-match "%\\(.\\)" str next)
1789 (let ((escape (char-after (match-beginning 1)))) 1788 (setq next (match-end 1))
1790 (delete-char -2) 1789 ;; If we skipped some literal text, insert it.
1790 (when (/= (- next onext) 2)
1791 (insert (substring str onext (- next 2))))
1792 (let ((escape (string-to-char (match-string 1 str))))
1791 (cond ((eq escape ?%) 1793 (cond ((eq escape ?%)
1792 (insert ?%)) 1794 (insert ?%))
1793 ((eq escape ?\[) 1795 ((eq escape ?\[)
@@ -1831,7 +1833,11 @@ to a given widget."
1831 (widget-apply widget :value-create) 1833 (widget-apply widget :value-create)
1832 (setq value-pos (point)))) 1834 (setq value-pos (point))))
1833 (t 1835 (t
1834 (widget-apply widget :format-handler escape))))) 1836 (widget-apply widget :format-handler escape))))
1837 (setq onext next))
1838 ;; Insert remaining literal text, if any.
1839 (when (> (length str) next)
1840 (insert (substring str next)))
1835 ;; Specify button, sample, and doc, and insert value. 1841 ;; Specify button, sample, and doc, and insert value.
1836 (and button-begin button-end 1842 (and button-begin button-end
1837 (widget-specify-button widget button-begin button-end)) 1843 (widget-specify-button widget button-begin button-end))
@@ -2578,14 +2584,15 @@ If the item is checked, CHOSEN is a cons whose cdr is the value."
2578 (buttons (widget-get widget :buttons)) 2584 (buttons (widget-get widget :buttons))
2579 (button-args (or (widget-get type :sibling-args) 2585 (button-args (or (widget-get type :sibling-args)
2580 (widget-get widget :button-args))) 2586 (widget-get widget :button-args)))
2581 (from (point)) 2587 (str (widget-get widget :entry-format))
2588 (onext 0) (next 0)
2582 child button) 2589 child button)
2583 (insert (widget-get widget :entry-format))
2584 (goto-char from)
2585 ;; Parse % escapes in format. 2590 ;; Parse % escapes in format.
2586 (while (re-search-forward "%\\([bv%]\\)" nil t) 2591 (while (string-match "%\\([bv%]\\)" str next)
2587 (let ((escape (char-after (match-beginning 1)))) 2592 (setq next (match-end 1))
2588 (delete-char -2) 2593 (when (/= (- next onext) 2)
2594 (insert (substring str onext (- next 2))))
2595 (let ((escape (string-to-char (match-string 1 str))))
2589 (cond ((eq escape ?%) 2596 (cond ((eq escape ?%)
2590 (insert ?%)) 2597 (insert ?%))
2591 ((eq escape ?b) 2598 ((eq escape ?b)
@@ -2609,7 +2616,10 @@ If the item is checked, CHOSEN is a cons whose cdr is the value."
2609 (widget-create-child-value 2616 (widget-create-child-value
2610 widget type (car (cdr chosen))))))) 2617 widget type (car (cdr chosen)))))))
2611 (t 2618 (t
2612 (error "Unknown escape `%c'" escape))))) 2619 (error "Unknown escape `%c'" escape))))
2620 (setq onext next))
2621 (when (> (length str) next)
2622 (insert (substring str next)))
2613 ;; Update properties. 2623 ;; Update properties.
2614 (and button child (widget-put child :button button)) 2624 (and button child (widget-put child :button button))
2615 (and button (widget-put widget :buttons (cons button buttons))) 2625 (and button (widget-put widget :buttons (cons button buttons)))
@@ -2756,16 +2766,17 @@ Return an alist of (TYPE MATCH)."
2756 (buttons (widget-get widget :buttons)) 2766 (buttons (widget-get widget :buttons))
2757 (button-args (or (widget-get type :sibling-args) 2767 (button-args (or (widget-get type :sibling-args)
2758 (widget-get widget :button-args))) 2768 (widget-get widget :button-args)))
2759 (from (point)) 2769 (str (widget-get widget :entry-format))
2770 (onext 0) (next 0)
2760 (chosen (and (null (widget-get widget :choice)) 2771 (chosen (and (null (widget-get widget :choice))
2761 (widget-apply type :match value))) 2772 (widget-apply type :match value)))
2762 child button) 2773 child button)
2763 (insert (widget-get widget :entry-format))
2764 (goto-char from)
2765 ;; Parse % escapes in format. 2774 ;; Parse % escapes in format.
2766 (while (re-search-forward "%\\([bv%]\\)" nil t) 2775 (while (string-match "%\\([bv%]\\)" str next)
2767 (let ((escape (char-after (match-beginning 1)))) 2776 (setq next (match-end 1))
2768 (delete-char -2) 2777 (when (/= (- next onext) 2)
2778 (insert (substring str onext (- next 2))))
2779 (let ((escape (string-to-char (match-string 1 str))))
2769 (cond ((eq escape ?%) 2780 (cond ((eq escape ?%)
2770 (insert ?%)) 2781 (insert ?%))
2771 ((eq escape ?b) 2782 ((eq escape ?b)
@@ -2784,7 +2795,10 @@ Return an alist of (TYPE MATCH)."
2784 (to (widget-get child :to))) 2795 (to (widget-get child :to)))
2785 (widget-specify-unselected child from to)))) 2796 (widget-specify-unselected child from to))))
2786 (t 2797 (t
2787 (error "Unknown escape `%c'" escape))))) 2798 (error "Unknown escape `%c'" escape))))
2799 (setq onext next))
2800 (when (> (length str) next)
2801 (insert (substring str next)))
2788 ;; Update properties. 2802 ;; Update properties.
2789 (when chosen 2803 (when chosen
2790 (widget-put widget :choice type)) 2804 (widget-put widget :choice type))
@@ -3053,17 +3067,20 @@ Save CHILD into the :last-deleted list, so it can be inserted later."
3053 ;; Create a new entry to the list. 3067 ;; Create a new entry to the list.
3054 (let ((type (nth 0 (widget-get widget :args))) 3068 (let ((type (nth 0 (widget-get widget :args)))
3055 ;; (widget-push-button-gui widget-editable-list-gui) 3069 ;; (widget-push-button-gui widget-editable-list-gui)
3070 (str (widget-get widget :entry-format))
3071 (onext 0) (next 0)
3056 child delete insert) 3072 child delete insert)
3057 (widget-specify-insert 3073 (widget-specify-insert
3058 (save-excursion 3074 (save-excursion
3059 (and (widget--should-indent-p) 3075 (and (widget--should-indent-p)
3060 (widget-get widget :indent) 3076 (widget-get widget :indent)
3061 (insert-char ?\s (widget-get widget :indent))) 3077 (insert-char ?\s (widget-get widget :indent))))
3062 (insert (widget-get widget :entry-format)))
3063 ;; Parse % escapes in format. 3078 ;; Parse % escapes in format.
3064 (while (re-search-forward "%\\(.\\)" nil t) 3079 (while (string-match "%\\(.\\)" str next)
3065 (let ((escape (char-after (match-beginning 1)))) 3080 (setq next (match-end 1))
3066 (delete-char -2) 3081 (when (/= (- next onext) 2)
3082 (insert (substring str onext (- next 2))))
3083 (let ((escape (string-to-char (match-string 1 str))))
3067 (cond ((eq escape ?%) 3084 (cond ((eq escape ?%)
3068 (insert ?%)) 3085 (insert ?%))
3069 ((eq escape ?i) 3086 ((eq escape ?i)
@@ -3079,7 +3096,10 @@ Save CHILD into the :last-deleted list, so it can be inserted later."
3079 widget type 3096 widget type
3080 (if conv value (widget-default-get type))))) 3097 (if conv value (widget-default-get type)))))
3081 (t 3098 (t
3082 (error "Unknown escape `%c'" escape))))) 3099 (error "Unknown escape `%c'" escape))))
3100 (setq onext next))
3101 (when (> (length str) next)
3102 (insert (substring str next)))
3083 (let ((buttons (widget-get widget :buttons))) 3103 (let ((buttons (widget-get widget :buttons)))
3084 (if insert (push insert buttons)) 3104 (if insert (push insert buttons))
3085 (if delete (push delete buttons)) 3105 (if delete (push delete buttons))