From 22fef60073d0c1efdfbe1b7d63928bf5b4f029e2 Mon Sep 17 00:00:00 2001 From: Tobias Zawada Date: Mon, 24 Jul 2023 22:09:55 +0200 Subject: [PATCH 1/7] Fixes #33. Noticeable lag when typing in larger code blocks - Set text property `font-lock-fontified` for fontified code blocks - also fix compiler error by quoting lambdas with sharp quote --- adoc-mode.el | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/adoc-mode.el b/adoc-mode.el index 38d3d5f..4d114bf 100644 --- a/adoc-mode.el +++ b/adoc-mode.el @@ -253,7 +253,7 @@ are fontified natively regardless of their size." :type '(choice :tag "Fontify code blocks " :format "\n%{%t%}: %[Size%] %v" (integer :tag "limited to") (boolean :tag "unlimited")) - :safe '(lambda (x) (or (booleanp x) (numberp x))) + :safe #'(lambda (x) (or (booleanp x) (numberp x))) :package-version '(adoc-mode . "0.8.0")) ;; This is based on `org-src-lang-modes' from org-src.el @@ -1725,7 +1725,7 @@ Concerning TYPE, LEVEL and SUB-TYPE see `adoc-re-llisti'." (list ;; see also regexp of forced line break, which is similar. it is not directly ;; obvious from asciidoc sourcecode what the exact rules are. - '(lambda (end) (adoc-kwf-std end "^\\(\\+\\)[ \t]*$" '(1))) + #'(lambda (end) (adoc-kwf-std end "^\\(\\+\\)[ \t]*$" '(1))) '(1 '(face adoc-meta-face adoc-reserved block-del) t))) (defun adoc-kw-delimited-block (del &optional text-face inhibit-text-reserved) @@ -2119,6 +2119,8 @@ Use this function as matching function MATCHER in `font-lock-keywords'." ;; Set background for block as well as opening and closing lines. (font-lock-append-text-property start-src end-src+nl 'face 'adoc-native-code-face) + (add-text-properties + start-src end-src+nl '(font-lock-fontified t font-lock-multiline t)) ))) t))) @@ -2351,7 +2353,7 @@ Use this function as matching function MATCHER in `font-lock-keywords'." ;; --- general attribute list block element ;; ^\[(?P.*)\]$ - (list '(lambda (end) (adoc-kwf-std end "^\\(\\[\\(.*\\)\\]\\)[ \t]*$" '(0))) + (list #'(lambda (end) (adoc-kwf-std end "^\\(\\[\\(.*\\)\\]\\)[ \t]*$" '(0))) '(1 '(face adoc-meta-face adoc-reserved block-del)) '(2 '(face adoc-meta-face adoc-attribute-list t))) From c0e445fb7c1dfc146b070c14b14f64936cf81f78 Mon Sep 17 00:00:00 2001 From: Tobias Zawada Date: Wed, 26 Jul 2023 02:16:49 +0200 Subject: [PATCH 2/7] Addresses #33. Reduce formatting lag by `adoc-kwf-search` Replace `re-search-forward` by `adoc-kwf-search` in font-lock keywords. `adoc-kwf-search` continues search if the adoc-code-block text property is set at the matching position. --- adoc-mode.el | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/adoc-mode.el b/adoc-mode.el index 4d114bf..fa1fa11 100644 --- a/adoc-mode.el +++ b/adoc-mode.el @@ -1556,6 +1556,19 @@ Subgroups of returned regexp: ;;;; font lock keywords +(defsubst adoc-kwf-search (regexp &optional bound noerror count) + "Keyword search for Adoc. +Like `re-search-forward' with the same arguments +REGEXP, BOUND, NOERROR and COUNT. +If a match for REGEXP is found where the text property +`adoc-code-block' is non-nil continue the search." + (let (ret) + (while (and + (setq ret (re-search-forward regexp bound noerror count)) + (get-text-property (point) 'adoc-code-block) + (null (eobp)))) + ret)) + (defun adoc-kwf-std (end regexp &optional must-free-groups no-block-del-groups) "Standard function for keywords Intendent to be called from font lock keyword functions. END is @@ -1567,7 +1580,7 @@ text having adoc-reserved set to symbol `block-del'." (let ((found t) (prevented t) saved-point) (while (and found prevented (<= (point) end) (not (eobp))) (setq saved-point (point)) - (setq found (re-search-forward regexp end t)) + (setq found (adoc-kwf-search regexp end t)) (setq prevented (and found (or @@ -1679,7 +1692,7 @@ text having adoc-reserved set to symbol `block-del'." ;; matcher function `(lambda (end) (and adoc-enable-two-line-title - (re-search-forward ,(adoc-re-two-line-title del) end t) + (adoc-kwf-search ,(adoc-re-two-line-title del) end t) (< (abs (- (length (match-string 2)) (length (match-string 3)))) 3) (or (not (numberp adoc-enable-two-line-title)) (not (equal adoc-enable-two-line-title (length (match-string 2))))) @@ -1754,7 +1767,7 @@ Concerning TYPE, LEVEL and SUB-TYPE see `adoc-re-llisti'." `(list ;; matcher function (lambda (end) - (and (re-search-forward "^[ \t]*\\(\\(?:CAUTION\\|WARNING\\|IMPORTANT\\|TIP\\|NOTE\\):\\)\\([ \t]+\\)" end t) + (and (adoc-kwf-search "^[ \t]*\\(\\(?:CAUTION\\|WARNING\\|IMPORTANT\\|TIP\\|NOTE\\):\\)\\([ \t]+\\)" end t) (not (text-property-not-all (match-beginning 0) (match-end 0) 'adoc-reserved nil)))) ;; highlighers '(1 '(face adoc-complex-replacement-face adoc-reserved t)) @@ -1765,7 +1778,7 @@ Concerning TYPE, LEVEL and SUB-TYPE see `adoc-re-llisti'." (list ;; matcher function `(lambda (end) - (and (re-search-forward ,(adoc-re-verbatim-paragraph-sequence) end t) + (and (adoc-kwf-search ,(adoc-re-verbatim-paragraph-sequence) end t) (not (text-property-not-all (match-beginning 0) (match-end 0) 'adoc-reserved nil)))) ;; highlighers '(1 '(face adoc-typewriter-face adoc-reserved t font-lock-multiline t)))) @@ -1893,7 +1906,7 @@ meta characters." (while (and found prevented) (setq saved-point (point)) (setq found - (re-search-forward ,regexp end t)) + (adoc-kwf-search ,regexp end t)) (setq prevented ; prevented is only meaningful wenn found is non-nil (or (not found) ; the following is only needed when found @@ -1931,7 +1944,7 @@ meta characters." ;; line beginning would also be underlined, which looks akward. (defun adoc-flf-first-whites-fixed-width(end) ;; it makes no sense to do something with a blank line, so require at least one non blank char. - (and (re-search-forward "\\(^[ \t]+\\)[^ \t\n]" end t) + (and (adoc-kwf-search "\\(^[ \t]+\\)[^ \t\n]" end t) ;; don't replace a face with with adoc-align-face which already is a fixed with ;; font (most probably), because then it also won't look aligned (text-property-not-all (match-beginning 1) (match-end 1) 'face 'adoc-typewriter-face) @@ -2120,7 +2133,7 @@ Use this function as matching function MATCHER in `font-lock-keywords'." (font-lock-append-text-property start-src end-src+nl 'face 'adoc-native-code-face) (add-text-properties - start-src end-src+nl '(font-lock-fontified t font-lock-multiline t)) + start-src end-src+nl '(font-lock-fontified t font-lock-multiline t adoc-code-block t)) ))) t))) @@ -2154,9 +2167,7 @@ Use this function as matching function MATCHER in `font-lock-keywords'." (defun adoc-get-font-lock-keywords () "Return list of keywords for `adoc-mode'." (list - ;; Fontify code blocks first to mark these regions as fontified. - '(adoc-fontify-code-blocks) - + '(adoc-fontify-code-blocks) ; listing ;; Asciidoc BUG: Lex.next has a different order than the following extract ;; from the documentation states. @@ -2292,7 +2303,6 @@ Use this function as matching function MATCHER in `font-lock-keywords'." ;; ------------------------------ (adoc-kw-delimited-block 0 adoc-comment-face) ; comment (adoc-kw-delimited-block 1 adoc-passthrough-face) ; passthrough - (adoc-kw-delimited-block 2 adoc-code-face) ; listing (adoc-kw-delimited-block 3 adoc-verbatim-face) ; literal (adoc-kw-delimited-block 4 nil t) ; quote (adoc-kw-delimited-block 5 nil t) ; example From 47f5559d34fb16f2975dcd54b0451666d57865f9 Mon Sep 17 00:00:00 2001 From: Tobias Zawada Date: Fri, 28 Jul 2023 00:16:39 +0200 Subject: [PATCH 3/7] Addresses #33. Restart search in `adoc-kwf-std` at last prevented match + 1 --- adoc-mode.el | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/adoc-mode.el b/adoc-mode.el index fa1fa11..bd054b0 100644 --- a/adoc-mode.el +++ b/adoc-mode.el @@ -1577,9 +1577,8 @@ MUST-FREE-GROUPS a list of regexp group numbers which may not match text that has an adoc-reserved text-property with a non-nil value. Likewise, groups in NO-BLOCK-DEL-GROUPS may not contain text having adoc-reserved set to symbol `block-del'." - (let ((found t) (prevented t) saved-point) + (let ((found t) (prevented t)) (while (and found prevented (<= (point) end) (not (eobp))) - (setq saved-point (point)) (setq found (adoc-kwf-search regexp end t)) (setq prevented (and found @@ -1597,7 +1596,7 @@ text having adoc-reserved set to symbol `block-del'." 'adoc-reserved 'block-del))) no-block-del-groups)))) (when (and found prevented (<= (point) end)) - (goto-char (1+ saved-point)))) + (goto-char (1+ (match-beginning 0))))) (and found (not prevented)))) (defun adoc-kwf-attribute-list (end) From 22191ba45e50a3856c2d2bb6c5ce577a9cf953e0 Mon Sep 17 00:00:00 2001 From: Tobias Zawada Date: Fri, 28 Jul 2023 01:02:30 +0200 Subject: [PATCH 4/7] Addresses #33. Re-introduce adoc-kw-delimited-block 2 because of failing ERT. --- adoc-mode.el | 1 + 1 file changed, 1 insertion(+) diff --git a/adoc-mode.el b/adoc-mode.el index bd054b0..d2a5d96 100644 --- a/adoc-mode.el +++ b/adoc-mode.el @@ -2302,6 +2302,7 @@ Use this function as matching function MATCHER in `font-lock-keywords'." ;; ------------------------------ (adoc-kw-delimited-block 0 adoc-comment-face) ; comment (adoc-kw-delimited-block 1 adoc-passthrough-face) ; passthrough + (adoc-kw-delimited-block 2 adoc-code-face) ; listing (adoc-kw-delimited-block 3 adoc-verbatim-face) ; literal (adoc-kw-delimited-block 4 nil t) ; quote (adoc-kw-delimited-block 5 nil t) ; example From 41105ba0aa4c105e295b3961b301f38ecd1e4a70 Mon Sep 17 00:00:00 2001 From: Tobias Zawada Date: Sat, 29 Jul 2023 07:30:08 +0200 Subject: [PATCH 5/7] Addresses #33. Re-structure also `adoc-kw-replacement`. Also add ert test for keyword-replacement --- adoc-mode.el | 21 ++++++++------------- test/adoc-mode-test.el | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/adoc-mode.el b/adoc-mode.el index d2a5d96..aba1a8d 100644 --- a/adoc-mode.el +++ b/adoc-mode.el @@ -1901,18 +1901,13 @@ meta characters." `(list ;; matcher function (lambda (end) - (let ((found t) (prevented t) saved-point) - (while (and found prevented) - (setq saved-point (point)) - (setq found - (adoc-kwf-search ,regexp end t)) - (setq prevented ; prevented is only meaningful wenn found is non-nil - (or - (not found) ; the following is only needed when found - (text-property-not-all (match-beginning 1) (match-end 1) 'adoc-reserved nil))) - (when (and found prevented) - (goto-char (+ saved-point 1)))) - (when (and found (not prevented) adoc-insert-replacement ,replacement) + (let (found) + (while (and (setq found + (adoc-kwf-search ,regexp end t)) + (text-property-not-all (match-beginning 1) (match-end 1) 'adoc-reserved nil)) + (setq found nil) + (goto-char (+ (match-beginning 0) 1))) + (when (and found adoc-insert-replacement ,replacement) (let* ((s (cond ((stringp ,replacement) ,replacement) @@ -1924,7 +1919,7 @@ meta characters." (setq adoc-replacement-failed (not o)) (unless adoc-replacement-failed (overlay-put o 'after-string s)))) - (and found (not prevented)))) + found)) ;; highlighers ;; TODO: replacement instead warining face if resolver is not given diff --git a/test/adoc-mode-test.el b/test/adoc-mode-test.el index c6b1d3e..d20ced6 100644 --- a/test/adoc-mode-test.el +++ b/test/adoc-mode-test.el @@ -1026,6 +1026,23 @@ Don't use it for anything real.") (cons "sub chapter 2.1" 262))))) (kill-buffer "adoc-test"))) +(ert-deftest adoctest-adoc-kw-replacement () + (unwind-protect + (progn + (set-buffer (get-buffer-create "adoc-test")) + (erase-buffer) + (adoc-mode) + (let ((adoc-insert-replacement t)) + (adoc-calc) + (insert "(C)") + (font-lock-flush) + (font-lock-ensure) + (should (string-equal (overlay-get (car (overlays-in (point) (point-max))) 'after-string) "©")) + ) + ) + (adoc-calc) + (kill-buffer "adoc-test"))) + ;; purpose ;; - ensure that the latest version, i.e. the one currently in buffer(s), of ;; adoc-mode and adoc-mode-test is used for the test From 3ab5480d83b34ad0de03739a880253fb1ac57283 Mon Sep 17 00:00:00 2001 From: Tobias Zawada Date: Sat, 29 Jul 2023 10:10:16 +0200 Subject: [PATCH 6/7] Addresses #33. Remove the superfluous (setq found nil) in adoc-kw-replacement --- adoc-mode.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/adoc-mode.el b/adoc-mode.el index aba1a8d..86945c2 100644 --- a/adoc-mode.el +++ b/adoc-mode.el @@ -1902,10 +1902,8 @@ meta characters." ;; matcher function (lambda (end) (let (found) - (while (and (setq found - (adoc-kwf-search ,regexp end t)) + (while (and (setq found (adoc-kwf-search ,regexp end t)) (text-property-not-all (match-beginning 1) (match-end 1) 'adoc-reserved nil)) - (setq found nil) (goto-char (+ (match-beginning 0) 1))) (when (and found adoc-insert-replacement ,replacement) (let* ((s (cond From 7690cc85231cf8971b6488359806fe59d59863ff Mon Sep 17 00:00:00 2001 From: Tobias Zawada Date: Wed, 2 Aug 2023 15:07:23 +0200 Subject: [PATCH 7/7] [#33] Describe purpose of adoc-kwf-search --- adoc-mode.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/adoc-mode.el b/adoc-mode.el index 86945c2..1ea3106 100644 --- a/adoc-mode.el +++ b/adoc-mode.el @@ -1561,7 +1561,9 @@ Subgroups of returned regexp: Like `re-search-forward' with the same arguments REGEXP, BOUND, NOERROR and COUNT. If a match for REGEXP is found where the text property -`adoc-code-block' is non-nil continue the search." +`adoc-code-block' is non-nil continue the search. +This speeds up the search and avoids the application of +adoc-syntax to code blocks." (let (ret) (while (and (setq ret (re-search-forward regexp bound noerror count))