diff options
| author | Elías Gabriel Pérez | 2025-11-18 11:02:24 -0600 |
|---|---|---|
| committer | Juri Linkov | 2025-11-19 09:20:00 +0200 |
| commit | bfa0cb81ddae6ce3e37f4cc4da4725a2f396d784 (patch) | |
| tree | ee082497832992766c8fa9c182e529edf06f3ee0 | |
| parent | 4532f5ae8f690f1e663706aea265461061f6b522 (diff) | |
| download | emacs-bfa0cb81ddae6ce3e37f4cc4da4725a2f396d784.tar.gz emacs-bfa0cb81ddae6ce3e37f4cc4da4725a2f396d784.zip | |
hideshow: Fix regressions. (Bug#79857)
* lisp/progmodes/hideshow.el (hs-block-positions): Exit the
function if 'hs-forward-sexp' fails.
(hs-hide-level-recursive): Fix infloop.
* test/lisp/progmodes/hideshow-tests.el (hideshow-hide-level-1):
(hideshow-hide-level-2): Update tests.
| -rw-r--r-- | lisp/progmodes/hideshow.el | 66 | ||||
| -rw-r--r-- | test/lisp/progmodes/hideshow-tests.el | 8 |
2 files changed, 45 insertions, 29 deletions
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el index 62bbbe40164..78990993449 100644 --- a/lisp/progmodes/hideshow.el +++ b/lisp/progmodes/hideshow.el | |||
| @@ -794,34 +794,39 @@ to call with the newly initialized overlay." | |||
| 794 | This returns a list with the current code block beginning and end | 794 | This returns a list with the current code block beginning and end |
| 795 | positions. This does nothing if there is not a code block at current | 795 | positions. This does nothing if there is not a code block at current |
| 796 | point." | 796 | point." |
| 797 | (save-match-data | 797 | ;; `catch' is used here if the search fails due unbalanced parentheses |
| 798 | (save-excursion | 798 | ;; or any other unknown error caused in `hs-forward-sexp'. |
| 799 | (when (funcall hs-looking-at-block-start-predicate) | 799 | (catch 'hs-sexp-error |
| 800 | (let ((mdata (match-data t)) | 800 | (save-match-data |
| 801 | (header-end (match-end 0)) | 801 | (save-excursion |
| 802 | block-beg block-end) | 802 | (when (funcall hs-looking-at-block-start-predicate) |
| 803 | ;; `block-start' is the point at the end of the block | 803 | (let ((mdata (match-data t)) |
| 804 | ;; beginning, which may need to be adjusted | 804 | (header-end (match-end 0)) |
| 805 | (save-excursion | 805 | block-beg block-end) |
| 806 | (when hs-adjust-block-beginning-function | 806 | ;; `block-start' is the point at the end of the block |
| 807 | (goto-char (funcall hs-adjust-block-beginning-function header-end))) | 807 | ;; beginning, which may need to be adjusted |
| 808 | (setq block-beg (line-end-position))) | 808 | (save-excursion |
| 809 | ;; `block-end' is the point at the end of the block | 809 | (when hs-adjust-block-beginning-function |
| 810 | (hs-forward-sexp mdata 1) | 810 | (goto-char (funcall hs-adjust-block-beginning-function header-end))) |
| 811 | (setq block-end | 811 | (setq block-beg (line-end-position))) |
| 812 | (cond ((and (stringp hs-block-end-regexp) | 812 | ;; `block-end' is the point at the end of the block |
| 813 | (looking-back hs-block-end-regexp nil)) | 813 | (condition-case _ |
| 814 | (match-beginning 0)) | 814 | (hs-forward-sexp mdata 1) |
| 815 | ((functionp hs-block-end-regexp) | 815 | (scan-error (throw 'hs-sexp-error nil))) |
| 816 | (funcall hs-block-end-regexp) | ||
| 817 | (match-beginning 0)) | ||
| 818 | (t (point)))) | ||
| 819 | ;; adjust block end (if needed) | ||
| 820 | (when hs-adjust-block-end-function | ||
| 821 | (setq block-end | 816 | (setq block-end |
| 822 | (or (funcall hs-adjust-block-end-function block-beg) | 817 | (cond ((and (stringp hs-block-end-regexp) |
| 823 | block-end))) | 818 | (looking-back hs-block-end-regexp nil)) |
| 824 | (list block-beg block-end)))))) | 819 | (match-beginning 0)) |
| 820 | ((functionp hs-block-end-regexp) | ||
| 821 | (funcall hs-block-end-regexp) | ||
| 822 | (match-beginning 0)) | ||
| 823 | (t (point)))) | ||
| 824 | ;; adjust block end (if needed) | ||
| 825 | (when hs-adjust-block-end-function | ||
| 826 | (setq block-end | ||
| 827 | (or (funcall hs-adjust-block-end-function block-beg) | ||
| 828 | block-end))) | ||
| 829 | (list block-beg block-end))))))) | ||
| 825 | 830 | ||
| 826 | (defun hs--make-indicators-overlays (beg) | 831 | (defun hs--make-indicators-overlays (beg) |
| 827 | "Helper function to make the indicators overlays." | 832 | "Helper function to make the indicators overlays." |
| @@ -1177,8 +1182,11 @@ region (point MAXP)." | |||
| 1177 | (not (nth 8 (syntax-ppss)))) ; not inside comments or strings | 1182 | (not (nth 8 (syntax-ppss)))) ; not inside comments or strings |
| 1178 | (if (> arg 1) | 1183 | (if (> arg 1) |
| 1179 | (hs-hide-level-recursive (1- arg) minp maxp) | 1184 | (hs-hide-level-recursive (1- arg) minp maxp) |
| 1180 | (goto-char (match-beginning hs-block-start-mdata-select)) | 1185 | ;; `hs-hide-block-at-point' already moves the cursor, but if it |
| 1181 | (hs-hide-block-at-point t)))) | 1186 | ;; fails, return to the previous position where we were. |
| 1187 | (unless (and (goto-char (match-beginning hs-block-start-mdata-select)) | ||
| 1188 | (hs-hide-block-at-point t)) | ||
| 1189 | (goto-char (match-end hs-block-start-mdata-select)))))) | ||
| 1182 | (goto-char maxp)) | 1190 | (goto-char maxp)) |
| 1183 | 1191 | ||
| 1184 | (defmacro hs-life-goes-on (&rest body) | 1192 | (defmacro hs-life-goes-on (&rest body) |
diff --git a/test/lisp/progmodes/hideshow-tests.el b/test/lisp/progmodes/hideshow-tests.el index a6b3ecfbd3d..9cf60c1ec84 100644 --- a/test/lisp/progmodes/hideshow-tests.el +++ b/test/lisp/progmodes/hideshow-tests.el | |||
| @@ -254,6 +254,8 @@ sub() | |||
| 254 | Comments | 254 | Comments |
| 255 | */ | 255 | */ |
| 256 | 256 | ||
| 257 | \"String\" | ||
| 258 | |||
| 257 | int | 259 | int |
| 258 | main(int argc, char **argv) | 260 | main(int argc, char **argv) |
| 259 | { | 261 | { |
| @@ -270,6 +272,8 @@ main(int argc, char **argv) | |||
| 270 | Comments | 272 | Comments |
| 271 | */ | 273 | */ |
| 272 | 274 | ||
| 275 | \"String\" | ||
| 276 | |||
| 273 | int | 277 | int |
| 274 | main(int argc, char **argv) | 278 | main(int argc, char **argv) |
| 275 | {} | 279 | {} |
| @@ -284,6 +288,8 @@ main(int argc, char **argv) | |||
| 284 | Comments | 288 | Comments |
| 285 | */ | 289 | */ |
| 286 | 290 | ||
| 291 | \"String\" | ||
| 292 | |||
| 287 | int | 293 | int |
| 288 | main(int argc, char **argv) | 294 | main(int argc, char **argv) |
| 289 | { | 295 | { |
| @@ -300,6 +306,8 @@ main(int argc, char **argv) | |||
| 300 | Comments | 306 | Comments |
| 301 | */ | 307 | */ |
| 302 | 308 | ||
| 309 | \"String\" | ||
| 310 | |||
| 303 | int | 311 | int |
| 304 | main(int argc, char **argv) | 312 | main(int argc, char **argv) |
| 305 | { | 313 | { |