diff --git a/ChangeLog b/ChangeLog index d4e9989b..e03a662e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2024-04-20 Bob Weiner + +* hui-select.el (hui-c++-defun-prompt-regexp): Add to eliminate an Emacs + hang in c++-mode caused by setting 'defun-prompt-regexp'. Update + provided by Alan Mackenzie. Fixes Emacs bug#61436 from 2023 + and gh#rswgnu/hyperbole/issue-518 from 2024. + 2024-04-16 Bob Weiner * hyrolo.py: For Org files, create hyrolo match file header from all @@ -10,7 +17,7 @@ * hui-select.el (hui-select-initialize): Disable C++ defun selection regexp until regexp is rewritten to prevent Emacs hangs. See Emacs bug#61436 from 2023 - and; gh#rswgnu/hyperbole/issue-518 from 2024. + and gh#rswgnu/hyperbole/issue-518 from 2024. 2024-04-14 Mats Lidell diff --git a/hui-select.el b/hui-select.el index 8c4cc4bf..e34c52cc 100644 --- a/hui-select.el +++ b/hui-select.el @@ -3,7 +3,7 @@ ;; Author: Bob Weiner ;; ;; Orig-Date: 19-Oct-96 at 02:25:27 -;; Last-Mod: 16-Apr-24 at 22:21:45 by Bob Weiner +;; Last-Mod: 20-Apr-24 at 12:02:16 by Bob Weiner ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -203,6 +203,90 @@ Used to include a final line when marking indented code.") :type 'boolean :group 'hyperbole-commands) +(defconst hui-c++-defun-prompt-regexp + (let* ((space* "[ \t\n\r\f]*") + (space+ "[ \t\n\r\f]+") + (ad-hoc-requires-clause + (concat "\\(?:requires" space* "[][()<> \t\n\r\f_$a-zA-Z0-9&|\"'+=.,*:~-]+" space* "\\)?")) + (id (concat "[_$~a-zA-Z][_$a-zA-Z0-9]*") + ;; (concat "\\(\\(~" space* "\\)?" "\\([_$a-zA-Z][_$a-zA-Z0-9]*\\)\\)") + ) + (template-brackets "\\(?:<[^;{}]*>\\)") + (id-<> (concat id "\\(?:" space* template-brackets "\\)?")) + (id-:: (concat id-<> "\\(?:" space* "::" space* id-<> "\\)*")) + (paren-exp "([^{};]*)") + (template-exp\? (concat "\\(?:template" space* template-brackets space* "\\)?")) + (type-prefix-modifier* (concat "\\(?:\\(?:" + "\\(?:\\" space* + "\\(?:[][a-z_+*/%^?&|!~<>,:=-]+" + "\\|()\\|\"\"" + "\\)" space* + "\\)")) + + (name-exp ; matches foo or (* foo), etc. + (concat "\\(?:(" space* "[*&]+" space* id-:: space* "[][()]*" ")" + "\\|\\(?:[*&]+" space* "\\)?" id-:: + "\\)" space*)) + (type-suffix-modifier* (concat "\\(?:" + (regexp-opt + '("auto" "const" "noexcept" + "requires" "throw" "volatile") + 'words) + space+ "\\)*")) + (post-paren-modifier* (concat "\\(?:" + (regexp-opt + '("const" "final" "override" + "mutable") + 'words) + space* "\\)*"))) + + (concat template-exp\? + "\\(?:" ad-hoc-requires-clause "\\)?" + type-exp + type-mid-modifier* + "\\(?:" operator-exp "\\|" name-exp "\\)" + type-suffix-modifier* + paren-exp space* + "\\(?:->" space* type-exp "\\)?" + post-paren-modifier* + "{"))) + (defconst hui-java-defun-prompt-regexp (let* ((space* "[ \t\n\r\f]*") (space+ "[ \t\n\r\f]+") @@ -221,15 +305,15 @@ Used to include a final line when marking indented code.") (concat "^[ \t]*" modifier* "\\(?:" generic-exp space* "\\)?" - ids-with-dot-\[\] space+ ; first part of type + ids-with-dot-\[\] space+ ; first part of type "\\(?:" ids-with-dot-\[\] space+ "\\)?" ; optional second part of type. "\\(?:[_a-zA-Z][^][ \t:;.,{}()=<>]*" ; defun name - "\\|" ids-with-dots + "\\|" ids-with-dots "\\)" space* paren-exp "\\(?:" space* "]\\)*" ; What's this for? "\\(?:" space* "\\" space* ids-with-dot-\[\] - "\\(?:," space* ids-with-dot-\[\] "\\)*" + "\\(?:," space* ids-with-dot-\[\] "\\)*" "\\)?" space*))) @@ -402,12 +486,8 @@ Also, add language-specific syntax setups to aid in thing selection." (var:add-and-run-hook 'java-mode-hook (lambda () (setq defun-prompt-regexp hui-java-defun-prompt-regexp))) - ;; !! TODO: defun selection regexp is disabled in C++ until regexp is - ;; rewritten as it can hang Emacs; reported in Emacs bug#61436 in - ;; 2023 and gh#rswgnu/hyperbole/issue-518 in 2024. - ;; (var:add-and-run-hook 'c++-mode-hook (lambda () - ;; (setq defun-prompt-regexp - ;; "^[ \t]*\\(template\\s-*<[^>;.{}]+>\\s-*\\)?\\(\\(\\(auto\\|const\\|explicit\\|extern\\s-+\"[^\"]+\"\\|extern\\|friend\\|inline\\|mutable\\|overload\\|register\\|static\\|typedef\\|virtual\\)\\s-+\\)*\\(\\([[a-zA-Z0-9 ,]+>\\s-*[*&]*\\|[[a-zA-Z0-9]*\\(::[[a-zA-Z0-9]+\\)?\\s-*[*&]*\\)[*& \t\n\r]+\\)\\)?\\(\\(::\\|[[;{}]+>\\s-*[*&]*::\\|[[a-zA-Z0-9]*\\s-*[*&]*::\\)\\s-*\\)?\\(operator\\s-*[^ \t\n\r:;.,?~{}]+\\(\\s-*\\[\\]\\)?\\|[_~;{}]+[ \t\n\r>]*>\\|[_~a-zA-Z0-9]*\\)\\)\\s-*\\(([^{;]*)\\(\\(\\s-+const\\|\\s-+mutable\\)?\\(\\s-*[=:][^;{]+\\)?\\)?\\)\\s-*"))) + (var:add-and-run-hook 'c++-mode-hook (lambda () + (setq defun-prompt-regexp hui-c++-defun-prompt-regexp))) ;; ;; Match to Lisp symbols with : in their names, often included in help buffers. (var:add-and-run-hook 'help-mode-hook (lambda () (modify-syntax-entry ?: "_" help-mode-syntax-table)))