aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2023-05-13 06:36:25 -0400
committerEli Zaretskii2023-05-13 06:36:25 -0400
commitea986a64b234c3e946d4577dc2ccfd261855c60b (patch)
tree1690bace8274024ea6287535ecac8cb0dcc143a5 /src
parentbfc07100d28d0f687da0a1dd5fdfa42a92a93f88 (diff)
parent7acae22f42f1b2df2042d5d77a0839f0ca9c02e7 (diff)
downloademacs-ea986a64b234c3e946d4577dc2ccfd261855c60b.tar.gz
emacs-ea986a64b234c3e946d4577dc2ccfd261855c60b.zip
Merge from origin/emacs-29
7acae22f42f Fix auto-filling in Texinfo mode 4bda9627349 ; * admin/git-bisect-start: Update failing commits dcf8c011028 Merge branch 'scratch/long-lines-cleanup' into 'emacs-29' 1e3a66df459 Add an assertion in, and a commentary for, 'get_nearby_bo... f0f08eeb05c Fix the return type of 'labeled_restrictions_get_bound' acf4763417e Fix mouse highlight with some fonts in Cairo builds 32b42b333ca ; * etc/NEWS: Fix wording in last change. 09d6070e56e ; Improve and update documentation of built-in package up... ba2c76fa2bc Ensure that package menu respects 'package-install-upgrad... 6fa9332e7cd Ensure that EXTRA-DATA are always written when generating... 60d5a015d1f Update to Transient v0.4.0 b8bcd42cabc Revert "Don't have nntp-report signal an error" ef1f4068f6f ; * lisp/wid-edit.el (widget-specify-insert): Fix debug s... 09bf4768360 Make c-emacs-features use the proper binding of parse-sex... c9e2a5ec26c ; * lisp/obsolete/autoload.el (make-directory-autoloads):... 346f4ac3bf5 ; Fix example in ELisp manual 91fff05ae35 ; Fix wording in Emacs manual 2438fa2e6cc ; Fix minor documentation issue ion replace.el 93005cd9dc2 with-display-message: Workaround for bug#63253 6924c81a6d2 ; Don't use literal non-ASCII characters in Texinfo f1675df3d0c Fido-mode: never shadow 'external' completion style 56d2949d44c ; * lisp/leim/quail/persian.el: Fix a typo in last commit. d94ea9efca6 Avoid crashes in --without-all build trying to scale non-... 387ddc0ccc1 Improve instructions for dealing with Emacs crashes e6b4784a37f Improved transliterations + improved bidi insertion suppo... c1363a04bb2 Fix crash when creating a child frame in NS (bug#63107) 7d6855c9ab6 Fix outgoing mime type regression (Bug#62815) e920dd2b6f9 define-minor-mode: sanitize mode function messages 910a7b30dfd Fix beginning/end-of-defun with tree-sitter e205f68717e Fix indent for enums in csharp-mode dfde902f3b9 ; Expand 'package-vc-install' documentation 71337843036 Teach c-ts-mode about the 'restrict' keyword 15e06260ae8 * lisp/x-dnd.el (x-dnd-after-move-frame): Skip dead frame... a081b6625bd ; Updated Elispref-Manual: `nil' cannot be defun'ed 97b818a4fb9 Fix doc strings of 'mark-sexp' and 'mark-word' 6f910ad9322 ; * etc/EGLOT-NEWS: Fix misspellings. 9b775ddc057 ; * etc/EGLOT-NEWS: Fix wording of last change. 79a886ba368 (package-upgrade): Don't remove the package from 'package... c0ab4e9ca93 Eglot: re-rename eglot-upgrade to eglot-upgrade-eglot b4e90070f96 Fix arguments of xml.c functions as displayed in Help buf... b1bda8228e5 More fixes for NetBSD/vax a2d4cd06f45 Improve VHDL mode highlighting 2f3a514b6db Clarify documentation wrt floating point division by zero... 94e984e6700 Make loaddefs-generate slightly more tolerant aba41d2c4bb ; Minor doc cleanups in go-ts-mode.el b42ccb2e5c1 ; Minor grammar fix in treesit manual. ab44c8a6f9d Fix order of rcirc-connect arguments 8eb6e33691d Fix rcirc messages printing in the wrong place 2901a3443c7 Prevent unnecessary modifications of 'package-vc-selected... eaad302bd6f Rename eglot-update to eglot-upgrade eaf25b9c6ae go-ts-mode: Use iota query only if supported (Bug#63086) cc090294d77 (rng-complete-tag): Add the (ignored) argument to the :co... 21ec6c1d5cc Update to Transient v0.3.7-219-g3ded15b 8d5aa8df4ad Fix inserting selection data into Mozilla programs 57562c3fd0a Recognize defstruct slot names in various eieio functions b93eb68cc30 Use 'calendar-buffer' instead of fixed string e338a8ac41d Handle point not at EOB in minibuffer-choose-completion fceaf230b06 Note that Emacs pauses when handling sentinel errors 46392c1623b Fix vertical-motion when tab-line is displayed in a window 0e52beeacea Update to Org 9.6.5-3-g2993f4 dd21003878d Prevent generating empty autoload files 2bcf11d0efe * lisp/org/org-macs.el (org--inhibit-version-check): Fix ... ca43435816b Fix redisplay of mode line after its format changes from nil 610a7657e0a Fix c-ts-mode--emacs-c-range-query 7f94558b775 Improve documentation of warnings 5a3f0e2c558 ; Doc fix in c-ts-mode.el 21361d05635 Fix FOR_EACH_TAIL fontification (bug#62951) d0df3404fde ; * etc/EGLOT-NEWS: chsharp-le -> csharp-ls c229e83c3ce ; * etc/EGLOT-NEWS (https): Elglot -> Eglot. b4f2f499783 Fix documentation of libxml-parse-* functions 5dd784961d1 ; * src/treesit.c (syms_of_treesit): Fix error messages. ddfa0d8da9a ; Remove some leftover text 212e30f6789 ; Fix byte-compilation warnings in c-ts-mode.el 1f2214dabd0 Skip over whitespace in annotation-top-cont check (bug#63... 7e136c51f6f Update zh-CN tutorial translation d3ca0b3aa2e ; * lisp/progmodes/c-ts-mode.el: Fix comments and doc str... c6f15c24862 ; Fix last change. b9e06330f75 ; * etc/NEWS: Followup to bug#62720. b33d25f5967 ; Minor improvements in doc strings of package-upgrade co... c3a61870b94 Fix eglot.texi a40f1816237 Fix two crashes upon startup 44ebd9cbd56 Eglot: explain how to update Eglot in manual (bug#62720) 941ef044f2e Eglot: fix edge case when deleting inlay hint overlays a365984d9e1 package-upgrade[-all]: Expand docstrings to note the curr... f965f35b33b Rename all functions called package-*-update-* to package... 31b58161bb5 Fix FOR_EACH_TAIL in c-ts-mode (bug#62951) 0cf6e0998ba * Makefile.in (distclean): Remove the 'native-lisp' direc... 933705d61e5 Improve greek-ibycus4 input method c46e93b1f50 Explain ERC 5.5 regressions in new version 5.5.0.29.1 af43f0a2954 * doc/misc/erc.texi: Elaborate on upgrading via ELPA. 10948948c12 Improve outline-default-state docstring b5ace2eed80 Document problems with /bin/sh on Solaris 10 7b2ad8f199e ; Add missing <<inserted by help-with-tutorial>> line to ... 524e161a536 Followup to addition of TUTORIAL.fa 76f50df1539 Add Farsi/Persian translation of the tutorial 8eacfaea6d8 Add Mongolian language environments fe8efbb8f75 Document the 'end-session' event on MS-Windows d80f959bede Update to Org 9.6.4-9-g8eb209 98c6cfcbe4a Don't support versioned grammar libraries on MS-Windows 8f71c1546df Accept versioned tree-sitter language grammar files 99add09d5e1 tab-bar-new-tab: inhibit side-window checks 087e8181947 * etc/NEWS: Fix outline level. (Bug#63042) d7f38558c4c ; Improve font selection for Traditional Mongolian 965c5e0231c Fix rendering of Traditional Mongolian script 9a0f10b5f88 Fix line-number-at-pos when POSITION is out of narrowing 4e0f4292aaf ; * etc/tutorials/TUTORIAL: Fix punctuation. dec2ac0c657 Fix exiting Emacs after saving a tutorial 44145bf07e2 Add indentation style setting for c-ts-mode in .dir-local... e7db6c59cc6 ; * .dir-locals.el (c-ts-mode): Add settings. d041f01b02f ; Minor fix in Emacs Lisp Intro manual 3899acbb336 ; * src/fringe.c: Fix description of large circle. (Bug#... 2b10e1827d3 sql: add missing postgresql types 9ac12592781 Fix display of menu-bar bindings of commands in *Help* bu... ecdd3a9efac Improve Completion Example section in the Emacs manual 626e1ac62b2 Improve 'message-server-alist' docstring 327986936c3 Add index entry for fallback modes 1c4783c3300 ; * etc/NEWS: Copyedits and grammar fixes. 3d6f7553319 xref-search-program-alist: Fix searching larger file list... 1b8b2cf61bd Fix typo and inaccuracy in the ELisp Reference manual df17682ebf1 ; Support 'dart-ts-mode' in Eglot e0dc60e0780 ; Fix typos in gdb-mi.el 60560cc7adf Fix description of lexical environment's internals 1456adf4248 ; Eglot: fix a typo in a customization type 2f59595f5f4 ; * etc/NEWS: Grammar fixes. 596b780ab71 Update to Org 9.6.4-2-g0f6ae7 a0b04a22479 Documentation copyedits for 'package-install-upgrade-buil... 580d8278c5f Allow upgrading built-in packages with 'package-install' 329304c23fa ; * src/term.c (init_tty): Fix last change. (Bug#62877) 200dbf7d302 Minor changes in c-ts-mode.el's support of DEFUNs 9686b015a0d Fix strike-through attribute support on TTY frames 39035fbfc5f Avoid crashes in 'describe-keymap' due to shadowing b7023da6627 Make image-map bindings available on image links d9e96c029bb * CONTRIBUTE: Fix a typo 3f71a2a0cf6 ; * lisp/progmodes/c-ts-mode.el (treesit-node-next-siblin... adf9c956c28 Add to Eglot support for additional language-servers. b3603b84bd9 Partial support for DEFUN in c-ts-mode (bug#62825) 14e809ddff1 Fix style and unwinding code in treesit.c 759cdf1e510 Catch signals produced by PRED in tree-sitter search func... 864a4dc2363 Fix compilation of w32.c with old MinGW system headers a22eb9ae0f9 ruby-add-log-current-method: Reduce the use of 'nreverse' 17d803d0a75 Fix detection of WebP images by their signature 43290391ce2 ; Eglot: make version parseable by version-to-list 6e6e8b5c974 Add more documentation for the keys of `package-vc-select... 7972b76c2c7 ; vc-checkout: Wrap var lookup in 'bound-and-true-p' e9fef1d70ff vc-checkout: Try to use the vc-dir's backend first 372e024accd ; Fix wallpaper-tests on XFCE 7055fd8e43e Improve documentation related to 'ispell-complete-word' 61fd017abde * configure.ac: Add -lbsd on Haiku. 05971c4d9a4 Add menu to 'c-ts-mode' and 'c++-ts-mode' 954e2d96a92 Update manual about `sort` c62afb10cf0 Fix wallpaper-tests on MS-Windows f2d212c6966 Fix a couple of eglot-tests 338b3718b6c Fix visiting RPM files b4afee03193 Fix ff-quiet-mode doc 2445100d7d6 ; Improve documentation of 'match-buffers' d4d0da96f0b ; Update make-tarball.txt for Emacs 29. 9b0bf694da4 ; Fix ldefs-boot.el. 0cb86a348c7 ; Update ChangeLog.4. 5e039d5a6e9 * lisp/ldefs-boot.el: Regenerate. 671abd0cc40 Merge branch 'emacs-29' of git.sv.gnu.org:/srv/git/emacs ... 4bc678ec9f4 Bump Emacs version to 29.0.90 db8f207e52f Fix some cases of incomplete code's indentation [c/c++-ts... 589959fb09d project-search: Pipe the list of files through 'file-regu... 2b91567bf61 Update ChangeLog and AUTHORS for Emacs 29 d6af1f14982 ; doc/lispref/windows.texi: Fix @pxref paren. 57490fff6ec ; Backport: Eglot: fix misplaced parenthesis in last comm... 2a62273f3bf Backport: Eglot: no more tests based on Pylsp (bug#62694) 5ef7ff05736 ; Start a new ChangeLog.4 file. 11126c6d30a Fix 'C-h k' for "Paste from Kill Menu" in context menus 74ddfe811f9 ; * doc/misc/calc.texi (Rewrites Tutorial): Fix a typo (b... 08cda286c3f Improve the documentation of the XDS support 14d1c00e806 Allow reindentation of images inserted by 'mm-inline-image' b63a9eda01c Fix "C-h k" and "C-h c" with Paste from Kill Menu b36c21e27dc Change cursor color on NS port when it matches the face b... 96714c106b7 Improve documentation of image-related commands 6a2863ca016 Fix handling of sliced images 5be79fd05a5 ; * etc/NEWS: Announce 'cyrillic-mongolian' IM. ca1a0fda98a ; Fix last change. ce63462dbda Add cyrillic-mongolian input method 58801792706 ; Minor addition to the Emacs FAQ 88847dee125 Jsonrpc: don't bind inhibit-read-only to t so early cb8c87a423a Allow active region when IM is used 305246d9726 Add emoji-zoom-reset 470d269ec1f Make emoji-zoom-{increase,decrease} set text properties c... 63d4a86f8d1 Fix transforming sliced images 5e1953a8f85 ; * etc/NEWS: Minor copyedits of entry for 'keymap-*' fun... 6b9f9df9454 ; Improve documentation of 'declare-function' 81d1f46d0fe ; Avoid compiler warning in eglot.el. 38cdfcb2128 ; Fix description of new 'keymap-*' functions 257090b8728 Adapt EMBA scripts. 90c07d3fdd2 Another terminology fix in ELisp reference manual a832bc7090c Correct terminology in Elisp Reference Manual db308233cb3 Comment out GNUSTEP jobs on EMBA (again) 8c1b1022439 ; * lisp/image.el (put-image): Doc fix. eda88c63adf ; * doc/emacs/trouble.texi (Checklist): Minor grammar fix. 728bc09cf3c Fix regexp string escaping mistake in vhdl-mode.el (bug#6... 479626dbac9 Update to Org 9.6.3-2-gf2949d 5a1c9aace70 ; Add a bit more docstring to tsx-ts-mode (bug#62429) 86cf9fd932c Eglot: don't watch directories that don't exist 82d0b6c64ea ; * lisp/subr.el (use-dialog-box-p): Fix last change. 3619663f982 Preserve peer information for web page in eww-readable cb8d6ab648f * lisp/subr.el (use-dialog-box-p): Fix conditions for GUI... fb2c4409207 ; * lisp/progmodes/c-ts-mode.el (c++-ts-mode): Add some n... c0b9530862c Another final fix to last changes 0cc8d6826ad Three final fixes to last changes 89e337c3fc9 ; Make sure 'eshell-command' tests don't prompt the user 097c5ee8f55 Two further fixes to last changes b39c3cd1125 ; * etc/NEWS: Fix typos. dce08cf05cc Improve and fix last changes 89ac5ba11c7 Fix ModelSim error regexp in vhdl-mode 24ed9c7ae78 ; * doc/emacs/trouble.texi (Checklist): Minor copyedits (... d1d39a0f09c Document enhancements in handling of echo-area messages 46209b2453b ; Fix last change 21a4ee209c1 Fix new Eshell tests on MS-Windows e2ebf3995d0 ; Auto-commit of loaddefs files. 6419d78fa6f Fix using background commands in 'eshell-command' 3bdbb66efb9 ; CONTRIBUTE: Minor stylistic changes. d0eb12e8d3c Fix typo in section 14.1 of Emacs Manual b2fbec37f39 ; * etc/EGLOT-NEWS: Clarify scope of topmost section 131ec049db0 Eglot: unbreak eglot-extend-to-xref on w32 0622e1f29f6 Eglot: ensure server shutdown turns off eglot-inlay-hints... 59f66ea3027 ; * lisp/emacs-lisp/package-vc.el: Remove completed item ... d23dc3dd7e3 ; * lisp/emacs-lisp/package-vc.el (package-vc): Fix manua... 4508a024e81 ; Clarify documentation of 'cursor' text property d2e82817a3f Add two typescript-ts-mode faces (bug#62429) 10918fc9d24 Fix scrolling window when point moves up 9b32bc134c4 Improve documentation of 'defcustom's :set keyword ab4273056e0 Comp fix calls to redefined primtives with op-bytecode (b... c98929c7e18 ; Fix last change a14c3f62a67 ; Fix last change 09fece5722f Fix duplicate defcustom in eww.el 2093e010dc1 Fix cursor motion in character-only terminals e45bd10a3d9 Fix indentation regression in 'C-h l' 46fd10a7600 * doc/misc/tramp.texi (Remote shell setup): Clarify use o... 974e4f33333 Make get_medium_narrowing_begv/zv static afc2c6c13cb Improve accuracy of cursor motion commands in long lines 7e26a5c774e Remove labeled restrictions before calling Fwiden 85ed1c9ca6b Code cleanup for long line optimizations # Conflicts: # etc/NEWS
Diffstat (limited to 'src')
-rw-r--r--src/buffer.c1
-rw-r--r--src/callproc.c1
-rw-r--r--src/composite.c4
-rw-r--r--src/dispextern.h37
-rw-r--r--src/editfns.c347
-rw-r--r--src/fileio.c1
-rw-r--r--src/ftcrfont.c1
-rw-r--r--src/indent.c1
-rw-r--r--src/keyboard.c12
-rw-r--r--src/lisp.h6
-rw-r--r--src/lread.c1
-rw-r--r--src/xdisp.c209
12 files changed, 389 insertions, 232 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 3e3be805a6d..399460c47da 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2386,6 +2386,7 @@ Any narrowing restriction in effect (see `narrow-to-region') is removed,
2386so the buffer is truly empty after this. */) 2386so the buffer is truly empty after this. */)
2387 (void) 2387 (void)
2388{ 2388{
2389 labeled_restrictions_remove_in_current_buffer ();
2389 Fwiden (); 2390 Fwiden ();
2390 2391
2391 del_range (BEG, Z); 2392 del_range (BEG, Z);
diff --git a/src/callproc.c b/src/callproc.c
index 5e1e1a8cc0a..6f3d4fad9be 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -1113,6 +1113,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1113 { 1113 {
1114 /* No need to save restrictions since we delete everything 1114 /* No need to save restrictions since we delete everything
1115 anyway. */ 1115 anyway. */
1116 labeled_restrictions_remove_in_current_buffer ();
1116 Fwiden (); 1117 Fwiden ();
1117 del_range (BEG, Z); 1118 del_range (BEG, Z);
1118 } 1119 }
diff --git a/src/composite.c b/src/composite.c
index 34f369d167a..9332c1cb9a3 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -1077,7 +1077,7 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos,
1077 with long lines, however, NL might be far away, so 1077 with long lines, however, NL might be far away, so
1078 pretend that the buffer is smaller. */ 1078 pretend that the buffer is smaller. */
1079 if (current_buffer->long_line_optimizations_p) 1079 if (current_buffer->long_line_optimizations_p)
1080 endpos = get_closer_narrowed_begv (cmp_it->parent_it->w, charpos); 1080 endpos = get_small_narrowing_begv (cmp_it->parent_it->w, charpos);
1081 } 1081 }
1082 } 1082 }
1083 cmp_it->id = -1; 1083 cmp_it->id = -1;
@@ -1660,7 +1660,7 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, ptrdiff_t backlim,
1660 { 1660 {
1661 /* In buffers with very long lines, this function becomes very 1661 /* In buffers with very long lines, this function becomes very
1662 slow. Pretend that the buffer is narrowed to make it fast. */ 1662 slow. Pretend that the buffer is narrowed to make it fast. */
1663 ptrdiff_t begv = get_closer_narrowed_begv (w, window_point (w)); 1663 ptrdiff_t begv = get_small_narrowing_begv (w, window_point (w));
1664 if (pos > begv) 1664 if (pos > begv)
1665 head = begv; 1665 head = begv;
1666 } 1666 }
diff --git a/src/dispextern.h b/src/dispextern.h
index 4dcab113ea2..ece128949f5 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2334,21 +2334,20 @@ struct it
2334 with which display_string was called. */ 2334 with which display_string was called. */
2335 ptrdiff_t end_charpos; 2335 ptrdiff_t end_charpos;
2336 2336
2337 /* Alternate begin position of the buffer that may be used to 2337 /* Alternate begin and end positions of the buffer that are used to
2338 optimize display (see the SET_WITH_NARROWED_BEGV macro). */ 2338 optimize display of buffers with long lines. These two fields
2339 ptrdiff_t narrowed_begv; 2339 hold the return value of the 'get_medium_narrowing_begv' and
2340 2340 'get_medium_narrowing_zv' functions. */
2341 /* Alternate end position of the buffer that may be used to 2341 ptrdiff_t medium_narrowing_begv;
2342 optimize display. */ 2342 ptrdiff_t medium_narrowing_zv;
2343 ptrdiff_t narrowed_zv; 2343
2344 2344 /* Alternate begin and end positions of the buffer that are used for
2345 /* Begin position of the buffer for the locked narrowing around 2345 labeled narrowings around low-level hooks in buffers with long
2346 low-level hooks. */ 2346 lines. These two fields hold the return value of the
2347 ptrdiff_t locked_narrowing_begv; 2347 'get_large_narrowing_begv' and 'get_large_narrowing_zv'
2348 2348 functions. */
2349 /* End position of the buffer for the locked narrowing around 2349 ptrdiff_t large_narrowing_begv;
2350 low-level hooks. */ 2350 ptrdiff_t large_narrowing_zv;
2351 ptrdiff_t locked_narrowing_zv;
2352 2351
2353 /* C string to iterate over. Non-null means get characters from 2352 /* C string to iterate over. Non-null means get characters from
2354 this string, otherwise characters are read from current_buffer 2353 this string, otherwise characters are read from current_buffer
@@ -3410,11 +3409,9 @@ void mark_window_display_accurate (Lisp_Object, bool);
3410void redisplay_preserve_echo_area (int); 3409void redisplay_preserve_echo_area (int);
3411void init_iterator (struct it *, struct window *, ptrdiff_t, 3410void init_iterator (struct it *, struct window *, ptrdiff_t,
3412 ptrdiff_t, struct glyph_row *, enum face_id); 3411 ptrdiff_t, struct glyph_row *, enum face_id);
3413ptrdiff_t get_narrowed_begv (struct window *, ptrdiff_t); 3412ptrdiff_t get_small_narrowing_begv (struct window *, ptrdiff_t);
3414ptrdiff_t get_narrowed_zv (struct window *, ptrdiff_t); 3413ptrdiff_t get_large_narrowing_begv (ptrdiff_t);
3415ptrdiff_t get_closer_narrowed_begv (struct window *, ptrdiff_t); 3414ptrdiff_t get_large_narrowing_zv (ptrdiff_t);
3416ptrdiff_t get_locked_narrowing_begv (ptrdiff_t);
3417ptrdiff_t get_locked_narrowing_zv (ptrdiff_t);
3418void init_iterator_to_row_start (struct it *, struct window *, 3415void init_iterator_to_row_start (struct it *, struct window *,
3419 struct glyph_row *); 3416 struct glyph_row *);
3420void start_display (struct it *, struct window *, struct text_pos); 3417void start_display (struct it *, struct window *, struct text_pos);
diff --git a/src/editfns.c b/src/editfns.c
index f83c5c7259b..d02cce4aef3 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -2653,182 +2653,203 @@ DEFUN ("delete-and-extract-region", Fdelete_and_extract_region,
2653 return del_range_1 (XFIXNUM (start), XFIXNUM (end), 1, 1); 2653 return del_range_1 (XFIXNUM (start), XFIXNUM (end), 1, 1);
2654} 2654}
2655 2655
2656/* Alist of buffers in which locked narrowing is used. The car of 2656/* Alist of buffers in which labeled restrictions are used. The car
2657 each list element is a buffer, the cdr is a list of triplets (tag 2657 of each list element is a buffer, the cdr is a list of triplets
2658 begv-marker zv-marker). The last element of that list always uses 2658 (label begv-marker zv-marker). The last triplet of that list
2659 the (uninterned) Qoutermost_narrowing tag and records the narrowing 2659 always uses the (uninterned) Qoutermost_restriction label, and
2660 bounds that were set by the user and that are visible on display. 2660 records the restriction bounds that were current when the first
2661 This alist is used internally by narrow-to-region, widen, 2661 labeled restriction was entered (which may be a narrowing that was
2662 internal--lock-narrowing, internal--unlock-narrowing and 2662 set by the user and is visible on display). This alist is used
2663 save-restriction. For efficiency reasons, an alist is used instead 2663 internally by narrow-to-region, widen, internal--label-restriction,
2664 of a buffer-local variable: otherwise reset_outermost_narrowings, 2664 internal--unlabel-restriction and save-restriction. For efficiency
2665 which is called during each redisplay cycle, would have to loop 2665 reasons, an alist is used instead of a buffer-local variable:
2666 through all live buffers. */ 2666 otherwise reset_outermost_restrictions, which is called during each
2667static Lisp_Object narrowing_locks; 2667 redisplay cycle, would have to loop through all live buffers. */
2668 2668static Lisp_Object labeled_restrictions;
2669/* Add BUF with its LOCKS in the narrowing_locks alist. */ 2669
2670/* Add BUF with its list of labeled RESTRICTIONS in the
2671 labeled_restrictions alist. */
2670static void 2672static void
2671narrowing_locks_add (Lisp_Object buf, Lisp_Object locks) 2673labeled_restrictions_add (Lisp_Object buf, Lisp_Object restrictions)
2672{ 2674{
2673 narrowing_locks = nconc2 (list1 (list2 (buf, locks)), narrowing_locks); 2675 labeled_restrictions = nconc2 (list1 (list2 (buf, restrictions)),
2676 labeled_restrictions);
2674} 2677}
2675 2678
2676/* Remove BUF and its locks from the narrowing_locks alist. Do 2679/* Remove BUF and its list of labeled restrictions from the
2677 nothing if BUF is not present in narrowing_locks. */ 2680 labeled_restrictions alist. Do nothing if BUF is not present in
2681 labeled_restrictions. */
2678static void 2682static void
2679narrowing_locks_remove (Lisp_Object buf) 2683labeled_restrictions_remove (Lisp_Object buf)
2680{ 2684{
2681 narrowing_locks = Fdelq (Fassoc (buf, narrowing_locks, Qnil), 2685 labeled_restrictions = Fdelq (Fassoc (buf, labeled_restrictions, Qnil),
2682 narrowing_locks); 2686 labeled_restrictions);
2683} 2687}
2684 2688
2685/* Retrieve one of the BEGV/ZV bounds of a narrowing in BUF from the 2689/* Retrieve one of the labeled restriction bounds in BUF from the
2686 narrowing_locks alist, as a pointer to a struct Lisp_Marker, or 2690 labeled_restrictions alist, as a marker, or return nil if BUF is
2687 NULL if BUF is not in narrowing_locks or is a killed buffer. When 2691 not in labeled_restrictions or is a killed buffer. When OUTERMOST
2688 OUTERMOST is true, the bounds that were set by the user and that 2692 is true, the restriction bounds that were current when the first
2689 are visible on display are returned. Otherwise the innermost 2693 labeled restriction was entered are returned. Otherwise the bounds
2690 locked narrowing bounds are returned. */ 2694 of the innermost labeled restriction are returned. */
2691static struct Lisp_Marker * 2695static Lisp_Object
2692narrowing_lock_get_bound (Lisp_Object buf, bool begv, bool outermost) 2696labeled_restrictions_get_bound (Lisp_Object buf, bool begv, bool outermost)
2693{ 2697{
2694 if (NILP (Fbuffer_live_p (buf))) 2698 if (NILP (Fbuffer_live_p (buf)))
2695 return NULL; 2699 return Qnil;
2696 Lisp_Object buffer_locks = assq_no_quit (buf, narrowing_locks); 2700 Lisp_Object restrictions = assq_no_quit (buf, labeled_restrictions);
2697 if (NILP (buffer_locks)) 2701 if (NILP (restrictions))
2698 return NULL; 2702 return Qnil;
2699 buffer_locks = XCAR (XCDR (buffer_locks)); 2703 restrictions = XCAR (XCDR (restrictions));
2700 Lisp_Object bounds 2704 Lisp_Object bounds
2701 = outermost 2705 = outermost
2702 ? XCDR (assq_no_quit (Qoutermost_narrowing, buffer_locks)) 2706 ? XCDR (assq_no_quit (Qoutermost_restriction, restrictions))
2703 : XCDR (XCAR (buffer_locks)); 2707 : XCDR (XCAR (restrictions));
2704 eassert (! NILP (bounds)); 2708 eassert (! NILP (bounds));
2705 Lisp_Object marker = begv ? XCAR (bounds) : XCAR (XCDR (bounds)); 2709 Lisp_Object marker = begv ? XCAR (bounds) : XCAR (XCDR (bounds));
2706 eassert (EQ (Fmarker_buffer (marker), buf)); 2710 eassert (EQ (Fmarker_buffer (marker), buf));
2707 return XMARKER (marker); 2711 return marker;
2708} 2712}
2709 2713
2710/* Retrieve the tag of the innermost narrowing in BUF. Return nil if 2714/* Retrieve the label of the innermost labeled restriction in BUF.
2711 BUF is not in narrowing_locks or is a killed buffer. */ 2715 Return nil if BUF is not in labeled_restrictions or is a killed
2716 buffer. */
2712static Lisp_Object 2717static Lisp_Object
2713narrowing_lock_peek_tag (Lisp_Object buf) 2718labeled_restrictions_peek_label (Lisp_Object buf)
2714{ 2719{
2715 if (NILP (Fbuffer_live_p (buf))) 2720 if (NILP (Fbuffer_live_p (buf)))
2716 return Qnil; 2721 return Qnil;
2717 Lisp_Object buffer_locks = assq_no_quit (buf, narrowing_locks); 2722 Lisp_Object restrictions = assq_no_quit (buf, labeled_restrictions);
2718 if (NILP (buffer_locks)) 2723 if (NILP (restrictions))
2719 return Qnil; 2724 return Qnil;
2720 Lisp_Object tag = XCAR (XCAR (XCAR (XCDR (buffer_locks)))); 2725 Lisp_Object label = XCAR (XCAR (XCAR (XCDR (restrictions))));
2721 eassert (! NILP (tag)); 2726 eassert (! NILP (label));
2722 return tag; 2727 return label;
2723} 2728}
2724 2729
2725/* Add a LOCK for BUF in the narrowing_locks alist. */ 2730/* Add a labeled RESTRICTION for BUF in the labeled_restrictions
2731 alist. */
2726static void 2732static void
2727narrowing_lock_push (Lisp_Object buf, Lisp_Object lock) 2733labeled_restrictions_push (Lisp_Object buf, Lisp_Object restriction)
2728{ 2734{
2729 Lisp_Object buffer_locks = assq_no_quit (buf, narrowing_locks); 2735 Lisp_Object restrictions = assq_no_quit (buf, labeled_restrictions);
2730 if (NILP (buffer_locks)) 2736 if (NILP (restrictions))
2731 narrowing_locks_add (buf, list1 (lock)); 2737 labeled_restrictions_add (buf, list1 (restriction));
2732 else 2738 else
2733 XSETCDR (buffer_locks, list1 (nconc2 (list1 (lock), 2739 XSETCDR (restrictions, list1 (nconc2 (list1 (restriction),
2734 XCAR (XCDR (buffer_locks))))); 2740 XCAR (XCDR (restrictions)))));
2735} 2741}
2736 2742
2737/* Remove the innermost lock in BUF from the narrowing_locks alist. 2743/* Remove the innermost labeled restriction in BUF from the
2738 Do nothing if BUF is not present in narrowing_locks. */ 2744 labeled_restrictions alist. Do nothing if BUF is not present in
2745 labeled_restrictions. */
2739static void 2746static void
2740narrowing_lock_pop (Lisp_Object buf) 2747labeled_restrictions_pop (Lisp_Object buf)
2741{ 2748{
2742 Lisp_Object buffer_locks = assq_no_quit (buf, narrowing_locks); 2749 Lisp_Object restrictions = assq_no_quit (buf, labeled_restrictions);
2743 if (NILP (buffer_locks)) 2750 if (NILP (restrictions))
2744 return; 2751 return;
2745 if (EQ (narrowing_lock_peek_tag (buf), Qoutermost_narrowing)) 2752 if (EQ (labeled_restrictions_peek_label (buf), Qoutermost_restriction))
2746 narrowing_locks_remove (buf); 2753 labeled_restrictions_remove (buf);
2747 else 2754 else
2748 XSETCDR (buffer_locks, list1 (XCDR (XCAR (XCDR (buffer_locks))))); 2755 XSETCDR (restrictions, list1 (XCDR (XCAR (XCDR (restrictions)))));
2756}
2757
2758/* Unconditionally remove all labeled restrictions in current_buffer. */
2759void
2760labeled_restrictions_remove_in_current_buffer (void)
2761{
2762 labeled_restrictions_remove (Fcurrent_buffer ());
2749} 2763}
2750 2764
2751static void 2765static void
2752unwind_reset_outermost_narrowing (Lisp_Object buf) 2766unwind_reset_outermost_restriction (Lisp_Object buf)
2753{ 2767{
2754 struct Lisp_Marker *begv = narrowing_lock_get_bound (buf, true, false); 2768 Lisp_Object begv = labeled_restrictions_get_bound (buf, true, false);
2755 struct Lisp_Marker *zv = narrowing_lock_get_bound (buf, false, false); 2769 Lisp_Object zv = labeled_restrictions_get_bound (buf, false, false);
2756 if (begv != NULL && zv != NULL) 2770 if (! NILP (begv) && ! NILP (zv))
2757 { 2771 {
2758 SET_BUF_BEGV_BOTH (XBUFFER (buf), begv->charpos, begv->bytepos); 2772 SET_BUF_BEGV_BOTH (XBUFFER (buf),
2759 SET_BUF_ZV_BOTH (XBUFFER (buf), zv->charpos, zv->bytepos); 2773 marker_position (begv), marker_byte_position (begv));
2774 SET_BUF_ZV_BOTH (XBUFFER (buf),
2775 marker_position (zv), marker_byte_position (zv));
2760 } 2776 }
2761 else 2777 else
2762 narrowing_locks_remove (buf); 2778 labeled_restrictions_remove (buf);
2763} 2779}
2764 2780
2765/* Restore the narrowing bounds that were set by the user, and restore 2781/* Restore the restriction bounds that were current when the first
2766 the bounds of the locked narrowing upon return. 2782 labeled restriction was entered, and restore the bounds of the
2783 innermost labeled restriction upon return.
2767 In particular, this function is called when redisplay starts, so 2784 In particular, this function is called when redisplay starts, so
2768 that if a Lisp function executed during redisplay calls (redisplay) 2785 that if a Lisp function executed during redisplay calls (redisplay)
2769 while a locked narrowing is in effect, the locked narrowing will 2786 while labeled restrictions are in effect, these restrictions will
2770 not be visible on display. 2787 not become visible on display.
2771 See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=57207#140 and 2788 See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=57207#140 and
2772 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=57207#254 for example 2789 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=57207#254 for example
2773 recipes that demonstrate why this is necessary. */ 2790 recipes that demonstrate why this is necessary. */
2774void 2791void
2775reset_outermost_narrowings (void) 2792reset_outermost_restrictions (void)
2776{ 2793{
2777 Lisp_Object val, buf; 2794 Lisp_Object val, buf;
2778 for (val = narrowing_locks; CONSP (val); val = XCDR (val)) 2795 for (val = labeled_restrictions; CONSP (val); val = XCDR (val))
2779 { 2796 {
2780 buf = XCAR (XCAR (val)); 2797 buf = XCAR (XCAR (val));
2781 eassert (BUFFERP (buf)); 2798 eassert (BUFFERP (buf));
2782 struct Lisp_Marker *begv = narrowing_lock_get_bound (buf, true, true); 2799 Lisp_Object begv = labeled_restrictions_get_bound (buf, true, true);
2783 struct Lisp_Marker *zv = narrowing_lock_get_bound (buf, false, true); 2800 Lisp_Object zv = labeled_restrictions_get_bound (buf, false, true);
2784 if (begv != NULL && zv != NULL) 2801 if (! NILP (begv) && ! NILP (zv))
2785 { 2802 {
2786 SET_BUF_BEGV_BOTH (XBUFFER (buf), begv->charpos, begv->bytepos); 2803 SET_BUF_BEGV_BOTH (XBUFFER (buf),
2787 SET_BUF_ZV_BOTH (XBUFFER (buf), zv->charpos, zv->bytepos); 2804 marker_position (begv), marker_byte_position (begv));
2788 record_unwind_protect (unwind_reset_outermost_narrowing, buf); 2805 SET_BUF_ZV_BOTH (XBUFFER (buf),
2806 marker_position (zv), marker_byte_position (zv));
2807 record_unwind_protect (unwind_reset_outermost_restriction, buf);
2789 } 2808 }
2790 else 2809 else
2791 narrowing_locks_remove (buf); 2810 labeled_restrictions_remove (buf);
2792 } 2811 }
2793} 2812}
2794 2813
2795/* Helper functions to save and restore the narrowing locks of the 2814/* Helper functions to save and restore the labeled restrictions of
2796 current buffer in Fsave_restriction. */ 2815 the current buffer in Fsave_restriction. */
2797static Lisp_Object 2816static Lisp_Object
2798narrowing_locks_save (void) 2817labeled_restrictions_save (void)
2799{ 2818{
2800 Lisp_Object buf = Fcurrent_buffer (); 2819 Lisp_Object buf = Fcurrent_buffer ();
2801 Lisp_Object locks = assq_no_quit (buf, narrowing_locks); 2820 Lisp_Object restrictions = assq_no_quit (buf, labeled_restrictions);
2802 if (!NILP (locks)) 2821 if (! NILP (restrictions))
2803 locks = XCAR (XCDR (locks)); 2822 restrictions = XCAR (XCDR (restrictions));
2804 return Fcons (buf, Fcopy_sequence (locks)); 2823 return Fcons (buf, Fcopy_sequence (restrictions));
2805} 2824}
2806 2825
2807static void 2826static void
2808narrowing_locks_restore (Lisp_Object buf_and_saved_locks) 2827labeled_restrictions_restore (Lisp_Object buf_and_restrictions)
2809{ 2828{
2810 Lisp_Object buf = XCAR (buf_and_saved_locks); 2829 Lisp_Object buf = XCAR (buf_and_restrictions);
2811 Lisp_Object saved_locks = XCDR (buf_and_saved_locks); 2830 Lisp_Object restrictions = XCDR (buf_and_restrictions);
2812 narrowing_locks_remove (buf); 2831 labeled_restrictions_remove (buf);
2813 if (!NILP (saved_locks)) 2832 if (! NILP (restrictions))
2814 narrowing_locks_add (buf, saved_locks); 2833 labeled_restrictions_add (buf, restrictions);
2815} 2834}
2816 2835
2817static void 2836static void
2818unwind_narrow_to_region_locked (Lisp_Object tag) 2837unwind_labeled_narrow_to_region (Lisp_Object label)
2819{ 2838{
2820 Finternal__unlock_narrowing (tag); 2839 Finternal__unlabel_restriction (label);
2821 Fwiden (); 2840 Fwiden ();
2822} 2841}
2823 2842
2824/* Narrow current_buffer to BEGV-ZV with a narrowing locked with TAG. */ 2843/* Narrow current_buffer to BEGV-ZV with a restriction labeled with
2844 LABEL. */
2825void 2845void
2826narrow_to_region_locked (Lisp_Object begv, Lisp_Object zv, Lisp_Object tag) 2846labeled_narrow_to_region (Lisp_Object begv, Lisp_Object zv,
2847 Lisp_Object label)
2827{ 2848{
2828 Fnarrow_to_region (begv, zv); 2849 Fnarrow_to_region (begv, zv);
2829 Finternal__lock_narrowing (tag); 2850 Finternal__label_restriction (label);
2830 record_unwind_protect (restore_point_unwind, Fpoint_marker ()); 2851 record_unwind_protect (restore_point_unwind, Fpoint_marker ());
2831 record_unwind_protect (unwind_narrow_to_region_locked, tag); 2852 record_unwind_protect (unwind_labeled_narrow_to_region, label);
2832} 2853}
2833 2854
2834DEFUN ("widen", Fwiden, Swiden, 0, 0, "", 2855DEFUN ("widen", Fwiden, Swiden, 0, 0, "",
@@ -2842,11 +2863,11 @@ To gain access to other portions of the buffer, use
2842`without-restriction' with the same label. */) 2863`without-restriction' with the same label. */)
2843 (void) 2864 (void)
2844{ 2865{
2845 Fset (Qoutermost_narrowing, Qnil); 2866 Fset (Qoutermost_restriction, Qnil);
2846 Lisp_Object buf = Fcurrent_buffer (); 2867 Lisp_Object buf = Fcurrent_buffer ();
2847 Lisp_Object tag = narrowing_lock_peek_tag (buf); 2868 Lisp_Object label = labeled_restrictions_peek_label (buf);
2848 2869
2849 if (NILP (tag)) 2870 if (NILP (label))
2850 { 2871 {
2851 if (BEG != BEGV || Z != ZV) 2872 if (BEG != BEGV || Z != ZV)
2852 current_buffer->clip_changed = 1; 2873 current_buffer->clip_changed = 1;
@@ -2856,19 +2877,23 @@ To gain access to other portions of the buffer, use
2856 } 2877 }
2857 else 2878 else
2858 { 2879 {
2859 struct Lisp_Marker *begv = narrowing_lock_get_bound (buf, true, false); 2880 Lisp_Object begv = labeled_restrictions_get_bound (buf, true, false);
2860 struct Lisp_Marker *zv = narrowing_lock_get_bound (buf, false, false); 2881 Lisp_Object zv = labeled_restrictions_get_bound (buf, false, false);
2861 eassert (begv != NULL && zv != NULL); 2882 eassert (! NILP (begv) && ! NILP (zv));
2862 if (begv->charpos != BEGV || zv->charpos != ZV) 2883 ptrdiff_t begv_charpos = marker_position (begv);
2884 ptrdiff_t zv_charpos = marker_position (zv);
2885 if (begv_charpos != BEGV || zv_charpos != ZV)
2863 current_buffer->clip_changed = 1; 2886 current_buffer->clip_changed = 1;
2864 SET_BUF_BEGV_BOTH (current_buffer, begv->charpos, begv->bytepos); 2887 SET_BUF_BEGV_BOTH (current_buffer,
2865 SET_BUF_ZV_BOTH (current_buffer, zv->charpos, zv->bytepos); 2888 begv_charpos, marker_byte_position (begv));
2866 /* If the only remaining bounds in narrowing_locks for 2889 SET_BUF_ZV_BOTH (current_buffer,
2890 zv_charpos, marker_byte_position (zv));
2891 /* If the only remaining bounds in labeled_restrictions for
2867 current_buffer are the bounds that were set by the user, no 2892 current_buffer are the bounds that were set by the user, no
2868 locked narrowing is in effect in current_buffer anymore: 2893 labeled restriction is in effect in current_buffer anymore:
2869 remove it from the narrowing_locks alist. */ 2894 remove it from the labeled_restrictions alist. */
2870 if (EQ (tag, Qoutermost_narrowing)) 2895 if (EQ (label, Qoutermost_restriction))
2871 narrowing_lock_pop (buf); 2896 labeled_restrictions_pop (buf);
2872 } 2897 }
2873 /* Changing the buffer bounds invalidates any recorded current column. */ 2898 /* Changing the buffer bounds invalidates any recorded current column. */
2874 invalidate_current_column (); 2899 invalidate_current_column ();
@@ -2905,25 +2930,27 @@ argument. To gain access to other portions of the buffer, use
2905 args_out_of_range (start, end); 2930 args_out_of_range (start, end);
2906 2931
2907 Lisp_Object buf = Fcurrent_buffer (); 2932 Lisp_Object buf = Fcurrent_buffer ();
2908 if (! NILP (narrowing_lock_peek_tag (buf))) 2933 if (! NILP (labeled_restrictions_peek_label (buf)))
2909 { 2934 {
2910 struct Lisp_Marker *begv = narrowing_lock_get_bound (buf, true, false); 2935 /* Limit the start and end positions to those of the innermost
2911 struct Lisp_Marker *zv = narrowing_lock_get_bound (buf, false, false); 2936 labeled restriction. */
2912 eassert (begv != NULL && zv != NULL); 2937 Lisp_Object begv = labeled_restrictions_get_bound (buf, true, false);
2913 /* Limit the start and end positions to those of the locked 2938 Lisp_Object zv = labeled_restrictions_get_bound (buf, false, false);
2914 narrowing. */ 2939 eassert (! NILP (begv) && ! NILP (zv));
2915 if (s < begv->charpos) s = begv->charpos; 2940 ptrdiff_t begv_charpos = marker_position (begv);
2916 if (s > zv->charpos) s = zv->charpos; 2941 ptrdiff_t zv_charpos = marker_position (zv);
2917 if (e < begv->charpos) e = begv->charpos; 2942 if (s < begv_charpos) s = begv_charpos;
2918 if (e > zv->charpos) e = zv->charpos; 2943 if (s > zv_charpos) s = zv_charpos;
2944 if (e < begv_charpos) e = begv_charpos;
2945 if (e > zv_charpos) e = zv_charpos;
2919 } 2946 }
2920 2947
2921 /* Record the accessible range of the buffer when narrow-to-region 2948 /* Record the accessible range of the buffer when narrow-to-region
2922 is called, that is, before applying the narrowing. It is used 2949 is called, that is, before applying the narrowing. That
2923 only by internal--lock-narrowing. */ 2950 information is used only by internal--label-restriction. */
2924 Fset (Qoutermost_narrowing, list3 (Qoutermost_narrowing, 2951 Fset (Qoutermost_restriction, list3 (Qoutermost_restriction,
2925 Fpoint_min_marker (), 2952 Fpoint_min_marker (),
2926 Fpoint_max_marker ())); 2953 Fpoint_max_marker ()));
2927 2954
2928 if (BEGV != s || ZV != e) 2955 if (BEGV != s || ZV != e)
2929 current_buffer->clip_changed = 1; 2956 current_buffer->clip_changed = 1;
@@ -2940,38 +2967,38 @@ argument. To gain access to other portions of the buffer, use
2940 return Qnil; 2967 return Qnil;
2941} 2968}
2942 2969
2943DEFUN ("internal--lock-narrowing", Finternal__lock_narrowing, 2970DEFUN ("internal--label-restriction", Finternal__label_restriction,
2944 Sinternal__lock_narrowing, 1, 1, 0, 2971 Sinternal__label_restriction, 1, 1, 0,
2945 doc: /* Lock the current narrowing with LABEL. 2972 doc: /* Label the current restriction with LABEL.
2946 2973
2947This is an internal function used by `with-restriction'. */) 2974This is an internal function used by `with-restriction'. */)
2948 (Lisp_Object tag) 2975 (Lisp_Object label)
2949{ 2976{
2950 Lisp_Object buf = Fcurrent_buffer (); 2977 Lisp_Object buf = Fcurrent_buffer ();
2951 Lisp_Object outermost_narrowing 2978 Lisp_Object outermost_restriction
2952 = buffer_local_value (Qoutermost_narrowing, buf); 2979 = buffer_local_value (Qoutermost_restriction, buf);
2953 /* If internal--lock-narrowing is ever called without being preceded 2980 /* If internal--label-restriction is ever called without being
2954 by narrow-to-region, do nothing. */ 2981 preceded by narrow-to-region, do nothing. */
2955 if (NILP (outermost_narrowing)) 2982 if (NILP (outermost_restriction))
2956 return Qnil; 2983 return Qnil;
2957 if (NILP (narrowing_lock_peek_tag (buf))) 2984 if (NILP (labeled_restrictions_peek_label (buf)))
2958 narrowing_lock_push (buf, outermost_narrowing); 2985 labeled_restrictions_push (buf, outermost_restriction);
2959 narrowing_lock_push (buf, list3 (tag, 2986 labeled_restrictions_push (buf, list3 (label,
2960 Fpoint_min_marker (), 2987 Fpoint_min_marker (),
2961 Fpoint_max_marker ())); 2988 Fpoint_max_marker ()));
2962 return Qnil; 2989 return Qnil;
2963} 2990}
2964 2991
2965DEFUN ("internal--unlock-narrowing", Finternal__unlock_narrowing, 2992DEFUN ("internal--unlabel-restriction", Finternal__unlabel_restriction,
2966 Sinternal__unlock_narrowing, 1, 1, 0, 2993 Sinternal__unlabel_restriction, 1, 1, 0,
2967 doc: /* Unlock a narrowing locked with LABEL. 2994 doc: /* If the current restriction is labeled with LABEL, remove its label.
2968 2995
2969This is an internal function used by `without-restriction'. */) 2996This is an internal function used by `without-restriction'. */)
2970 (Lisp_Object tag) 2997 (Lisp_Object label)
2971{ 2998{
2972 Lisp_Object buf = Fcurrent_buffer (); 2999 Lisp_Object buf = Fcurrent_buffer ();
2973 if (EQ (narrowing_lock_peek_tag (buf), tag)) 3000 if (EQ (labeled_restrictions_peek_label (buf), label))
2974 narrowing_lock_pop (buf); 3001 labeled_restrictions_pop (buf);
2975 return Qnil; 3002 return Qnil;
2976} 3003}
2977 3004
@@ -3071,15 +3098,15 @@ save_restriction_restore_1 (Lisp_Object data)
3071Lisp_Object 3098Lisp_Object
3072save_restriction_save (void) 3099save_restriction_save (void)
3073{ 3100{
3074 Lisp_Object restr = save_restriction_save_1 (); 3101 Lisp_Object restriction = save_restriction_save_1 ();
3075 Lisp_Object locks = narrowing_locks_save (); 3102 Lisp_Object labeled_restrictions = labeled_restrictions_save ();
3076 return Fcons (restr, locks); 3103 return Fcons (restriction, labeled_restrictions);
3077} 3104}
3078 3105
3079void 3106void
3080save_restriction_restore (Lisp_Object data) 3107save_restriction_restore (Lisp_Object data)
3081{ 3108{
3082 narrowing_locks_restore (XCDR (data)); 3109 labeled_restrictions_restore (XCDR (data));
3083 save_restriction_restore_1 (XCAR (data)); 3110 save_restriction_restore_1 (XCAR (data));
3084} 3111}
3085 3112
@@ -4748,7 +4775,7 @@ syms_of_editfns (void)
4748 DEFSYM (Qwall, "wall"); 4775 DEFSYM (Qwall, "wall");
4749 DEFSYM (Qpropertize, "propertize"); 4776 DEFSYM (Qpropertize, "propertize");
4750 4777
4751 staticpro (&narrowing_locks); 4778 staticpro (&labeled_restrictions);
4752 4779
4753 DEFVAR_LISP ("inhibit-field-text-motion", Vinhibit_field_text_motion, 4780 DEFVAR_LISP ("inhibit-field-text-motion", Vinhibit_field_text_motion,
4754 doc: /* Non-nil means text motion commands don't notice fields. */); 4781 doc: /* Non-nil means text motion commands don't notice fields. */);
@@ -4809,12 +4836,12 @@ This variable is experimental; email 32252@debbugs.gnu.org if you need
4809it to be non-nil. */); 4836it to be non-nil. */);
4810 binary_as_unsigned = false; 4837 binary_as_unsigned = false;
4811 4838
4812 DEFVAR_LISP ("outermost-narrowing", Voutermost_narrowing, 4839 DEFVAR_LISP ("outermost-restriction", Voutermost_restriction,
4813 doc: /* Outermost narrowing bounds, if any. Internal use only. */); 4840 doc: /* Outermost narrowing bounds, if any. Internal use only. */);
4814 Voutermost_narrowing = Qnil; 4841 Voutermost_restriction = Qnil;
4815 Fmake_variable_buffer_local (Qoutermost_narrowing); 4842 Fmake_variable_buffer_local (Qoutermost_restriction);
4816 DEFSYM (Qoutermost_narrowing, "outermost-narrowing"); 4843 DEFSYM (Qoutermost_restriction, "outermost-restriction");
4817 Funintern (Qoutermost_narrowing, Qnil); 4844 Funintern (Qoutermost_restriction, Qnil);
4818 4845
4819 defsubr (&Spropertize); 4846 defsubr (&Spropertize);
4820 defsubr (&Schar_equal); 4847 defsubr (&Schar_equal);
@@ -4907,8 +4934,8 @@ it to be non-nil. */);
4907 defsubr (&Sdelete_and_extract_region); 4934 defsubr (&Sdelete_and_extract_region);
4908 defsubr (&Swiden); 4935 defsubr (&Swiden);
4909 defsubr (&Snarrow_to_region); 4936 defsubr (&Snarrow_to_region);
4910 defsubr (&Sinternal__lock_narrowing); 4937 defsubr (&Sinternal__label_restriction);
4911 defsubr (&Sinternal__unlock_narrowing); 4938 defsubr (&Sinternal__unlabel_restriction);
4912 defsubr (&Ssave_restriction); 4939 defsubr (&Ssave_restriction);
4913 defsubr (&Stranspose_regions); 4940 defsubr (&Stranspose_regions);
4914} 4941}
diff --git a/src/fileio.c b/src/fileio.c
index b80f8d61de4..a364aa2ea33 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -5246,6 +5246,7 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
5246 } 5246 }
5247 5247
5248 record_unwind_protect (save_restriction_restore, save_restriction_save ()); 5248 record_unwind_protect (save_restriction_restore, save_restriction_save ());
5249 labeled_restrictions_remove_in_current_buffer ();
5249 5250
5250 /* Special kludge to simplify auto-saving. */ 5251 /* Special kludge to simplify auto-saving. */
5251 if (NILP (start)) 5252 if (NILP (start))
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index c9a4de8137b..49564692b75 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -590,7 +590,6 @@ ftcrfont_draw (struct glyph_string *s,
590 GREEN_FROM_ULONG (col) / 255.0, 590 GREEN_FROM_ULONG (col) / 255.0,
591 BLUE_FROM_ULONG (col) / 255.0); 591 BLUE_FROM_ULONG (col) / 255.0);
592#endif 592#endif
593 s->background_filled_p = 1;
594 cairo_rectangle (cr, x, y - FONT_BASE (s->font), 593 cairo_rectangle (cr, x, y - FONT_BASE (s->font),
595 s->width, FONT_HEIGHT (s->font)); 594 s->width, FONT_HEIGHT (s->font));
596 cairo_fill (cr); 595 cairo_fill (cr);
diff --git a/src/indent.c b/src/indent.c
index 16285ce84e2..c3cbc49c81b 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -2065,6 +2065,7 @@ line_number_display_width (struct window *w, int *width, int *pixel_width)
2065 { 2065 {
2066 record_unwind_protect (save_restriction_restore, 2066 record_unwind_protect (save_restriction_restore,
2067 save_restriction_save ()); 2067 save_restriction_save ());
2068 labeled_restrictions_remove_in_current_buffer ();
2068 Fwiden (); 2069 Fwiden ();
2069 saved_restriction = true; 2070 saved_restriction = true;
2070 } 2071 }
diff --git a/src/keyboard.c b/src/keyboard.c
index f7aa496bb81..b1ccf4acde4 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -318,6 +318,8 @@ static Lisp_Object command_loop (void);
318static void echo_now (void); 318static void echo_now (void);
319static ptrdiff_t echo_length (void); 319static ptrdiff_t echo_length (void);
320 320
321static void safe_run_hooks_maybe_narrowed (Lisp_Object, struct window *);
322
321/* Incremented whenever a timer is run. */ 323/* Incremented whenever a timer is run. */
322unsigned timers_run; 324unsigned timers_run;
323 325
@@ -1909,7 +1911,7 @@ safe_run_hooks (Lisp_Object hook)
1909 unbind_to (count, Qnil); 1911 unbind_to (count, Qnil);
1910} 1912}
1911 1913
1912void 1914static void
1913safe_run_hooks_maybe_narrowed (Lisp_Object hook, struct window *w) 1915safe_run_hooks_maybe_narrowed (Lisp_Object hook, struct window *w)
1914{ 1916{
1915 specpdl_ref count = SPECPDL_INDEX (); 1917 specpdl_ref count = SPECPDL_INDEX ();
@@ -1919,11 +1921,11 @@ safe_run_hooks_maybe_narrowed (Lisp_Object hook, struct window *w)
1919 if (current_buffer->long_line_optimizations_p 1921 if (current_buffer->long_line_optimizations_p
1920 && long_line_optimizations_region_size > 0) 1922 && long_line_optimizations_region_size > 0)
1921 { 1923 {
1922 ptrdiff_t begv = get_locked_narrowing_begv (PT); 1924 ptrdiff_t begv = get_large_narrowing_begv (PT);
1923 ptrdiff_t zv = get_locked_narrowing_zv (PT); 1925 ptrdiff_t zv = get_large_narrowing_zv (PT);
1924 if (begv != BEG || zv != Z) 1926 if (begv != BEG || zv != Z)
1925 narrow_to_region_locked (make_fixnum (begv), make_fixnum (zv), 1927 labeled_narrow_to_region (make_fixnum (begv), make_fixnum (zv),
1926 Qlong_line_optimizations_in_command_hooks); 1928 Qlong_line_optimizations_in_command_hooks);
1927 } 1929 }
1928 1930
1929 run_hook_with_args (2, ((Lisp_Object []) {hook, hook}), 1931 run_hook_with_args (2, ((Lisp_Object []) {hook, hook}),
diff --git a/src/lisp.h b/src/lisp.h
index ab66109d5df..72d2c1a8f91 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4680,8 +4680,9 @@ extern void save_restriction_restore (Lisp_Object);
4680extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool); 4680extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool);
4681extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, 4681extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t,
4682 ptrdiff_t, bool); 4682 ptrdiff_t, bool);
4683extern void narrow_to_region_locked (Lisp_Object, Lisp_Object, Lisp_Object); 4683extern void labeled_narrow_to_region (Lisp_Object, Lisp_Object, Lisp_Object);
4684extern void reset_outermost_narrowings (void); 4684extern void reset_outermost_restrictions (void);
4685extern void labeled_restrictions_remove_in_current_buffer (void);
4685extern void init_editfns (void); 4686extern void init_editfns (void);
4686extern void syms_of_editfns (void); 4687extern void syms_of_editfns (void);
4687 4688
@@ -4850,7 +4851,6 @@ extern bool detect_input_pending (void);
4850extern bool detect_input_pending_ignore_squeezables (void); 4851extern bool detect_input_pending_ignore_squeezables (void);
4851extern bool detect_input_pending_run_timers (bool); 4852extern bool detect_input_pending_run_timers (bool);
4852extern void safe_run_hooks (Lisp_Object); 4853extern void safe_run_hooks (Lisp_Object);
4853extern void safe_run_hooks_maybe_narrowed (Lisp_Object, struct window *);
4854extern void safe_run_hooks_2 (Lisp_Object, Lisp_Object, Lisp_Object); 4854extern void safe_run_hooks_2 (Lisp_Object, Lisp_Object, Lisp_Object);
4855extern void cmd_error_internal (Lisp_Object, const char *); 4855extern void cmd_error_internal (Lisp_Object, const char *);
4856extern Lisp_Object command_loop_2 (Lisp_Object); 4856extern Lisp_Object command_loop_2 (Lisp_Object);
diff --git a/src/lread.c b/src/lread.c
index 67cd7185d04..4f1d29d80b2 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -2255,6 +2255,7 @@ readevalloop (Lisp_Object readcharfun,
2255 record_unwind_protect_excursion (); 2255 record_unwind_protect_excursion ();
2256 /* Save ZV in it. */ 2256 /* Save ZV in it. */
2257 record_unwind_protect (save_restriction_restore, save_restriction_save ()); 2257 record_unwind_protect (save_restriction_restore, save_restriction_save ());
2258 labeled_restrictions_remove_in_current_buffer ();
2258 /* Those get unbound after we read one expression. */ 2259 /* Those get unbound after we read one expression. */
2259 2260
2260 /* Set point and ZV around stuff to be read. */ 2261 /* Set point and ZV around stuff to be read. */
diff --git a/src/xdisp.c b/src/xdisp.c
index 28f8e8128c5..982e1b3c103 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -3482,7 +3482,7 @@ init_iterator (struct it *it, struct window *w,
3482 3482
3483 /* This is set only when long_line_optimizations_p is non-zero 3483 /* This is set only when long_line_optimizations_p is non-zero
3484 for the current buffer. */ 3484 for the current buffer. */
3485 it->narrowed_begv = 0; 3485 it->medium_narrowing_begv = 0;
3486 3486
3487 /* Compute faces etc. */ 3487 /* Compute faces etc. */
3488 reseat (it, it->current.pos, true); 3488 reseat (it, it->current.pos, true);
@@ -3491,17 +3491,104 @@ init_iterator (struct it *it, struct window *w,
3491 CHECK_IT (it); 3491 CHECK_IT (it);
3492} 3492}
3493 3493
3494/* Compute a suitable alternate value for BEGV and ZV that may be used 3494/* How Emacs deals with long lines.
3495 temporarily to optimize display if the buffer in window W contains 3495
3496 long lines. */ 3496 (1) When a buffer is about to be (re)displayed, 'redisplay_window'
3497 detects, with a heuristic, whether it contains long lines.
3498
3499 This happens in 'redisplay_window' because it is only displaying
3500 buffers with long lines that is problematic. In other words, none
3501 of the optimizations described below is ever used in buffers that
3502 are never displayed.
3503
3504 This happens with a heuristic, which checks whether a buffer
3505 contains long lines, each time its contents have changed "enough"
3506 between two redisplay cycles, because a buffer without long lines
3507 can become a buffer with long lines at any time, for example after
3508 a yank command, or after a replace command, or while the output of
3509 an external process is inserted in a buffer.
3510
3511 When Emacs has detected that a buffer contains long lines, the
3512 buffer-local variable 'long_line_optimizations_p' (in 'struct
3513 buffer') is set, and Emacs does not try to detect whether the
3514 buffer does or does not contain long lines anymore.
3515
3516 What a long line is depends on the variable 'long-line-threshold',
3517 whose default value is 50000 (characters).
3518
3519 (2) When a buffer with long lines is (re)displayed, the amount of
3520 data that the display routines consider is, in a few well-chosen
3521 places, limited with a temporary restriction, whose bounds are
3522 calculated with the functions below.
3523
3524 (2.1) 'get_small_narrowing_begv' is used to create a restriction
3525 which starts a few hundred characters before point. The exact
3526 number of characters depends on the width of the window in which
3527 the buffer is displayed.
3528
3529 There is no corresponding 'get_small_narrowing_zv' function,
3530 because it is not necessary to set the end limit of that
3531 restriction.
3532
3533 This restriction is used in four places, namely:
3534 'back_to_previous_line_start' and 'move_it_vertically_backward'
3535 (with the 'SET_WITH_NARROWED_BEGV' macro), and in
3536 'composition_compute_stop_pos' and 'find_automatic_composition' (in
3537 a conditional statement depending on 'long_line_optimizations_p').
3538
3539 (2.2) 'get_medium_narrowing_begv' is used to create a restriction
3540 which starts a few thousand characters before point. The exact
3541 number of characters depends on the size (width and height) of the
3542 window in which the buffer is displayed. For performance reasons,
3543 the return value of that function is cached in 'struct it', in the
3544 'medium_narrowing_begv' field.
3545
3546 The corresponding function 'get_medium_narrowing_zv' (and
3547 'medium_narrowing_zv' field in 'struct it') is not used to set the
3548 end limit of the restriction, which is again unnecessary, but to
3549 determine, in 'reseat', whether the iterator has moved far enough
3550 from its original position, and whether the start position of the
3551 restriction must be computed anew.
3552
3553 This restriction is used in a single place:
3554 'get_visually_first_element', with the 'SET_WITH_NARROWED_BEGV'
3555 macro.
3556
3557 (2.3) 'get_large_narrowing_begv' and 'get_large_narrowing_zv' are
3558 used to create a restriction which starts a few hundred thousand
3559 characters before point and ends a few hundred thousand characters
3560 after point. The size of that restriction depends on the variable
3561 'long-line-optimizations-region-size', whose default value is
3562 500000 (characters); it can be adjusted by a few hundred characters
3563 depending on 'long-line-optimizations-bol-search-limit', whose
3564 default value is 128 (characters).
3565
3566 For performance reasons again, the return values of these functions
3567 are stored in the 'large_narrowing_begv' and 'large_narrowing_zv'
3568 fields in 'struct it'.
3569
3570 The restriction defined by these values is used around three
3571 low-level hooks: around 'fontification-functions', in
3572 'handle_fontified_prop', and around 'pre-command-hook' and
3573 'post-command-hook', in 'safe_run_hooks_maybe_narrowed', which is
3574 called in 'command_loop_1'. These restrictions are set around
3575 these hooks with 'labeled_narrow_to_region'; the restrictions are
3576 labeled, and cannot be removed with a call to 'widen', but can be
3577 removed with 'without-restriction' with a :label argument.
3578*/
3497 3579
3498static int 3580static int
3499get_narrowed_width (struct window *w) 3581get_narrowed_width (struct window *w)
3500{ 3582{
3501 /* In a character-only terminal, only one font size is used, so we 3583 /* In a character-only terminal, only one font size is used, so we
3502 can use a smaller factor. */ 3584 can use a smaller factor. */
3503 int fact = EQ (Fterminal_live_p (Qnil), Qt) ? 2 : 3; 3585 int fact = FRAME_WINDOW_P (XFRAME (w->frame)) ? 3 : 2;
3504 int width = window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS); 3586 /* If the window has no fringes (in a character-only terminal or in
3587 a GUI frame without fringes), subtract 1 from the width for the
3588 '\' line wrapping character. */
3589 int width = window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS)
3590 - ((WINDOW_RIGHT_FRINGE_WIDTH (w) == 0
3591 || WINDOW_LEFT_FRINGE_WIDTH (w) == 0) ? 1 : 0);
3505 return fact * max (1, width); 3592 return fact * max (1, width);
3506} 3593}
3507 3594
@@ -3512,29 +3599,63 @@ get_narrowed_len (struct window *w)
3512 return get_narrowed_width (w) * max (1, height); 3599 return get_narrowed_width (w) * max (1, height);
3513} 3600}
3514 3601
3515ptrdiff_t 3602static ptrdiff_t
3516get_narrowed_begv (struct window *w, ptrdiff_t pos) 3603get_medium_narrowing_begv (struct window *w, ptrdiff_t pos)
3517{ 3604{
3518 int len = get_narrowed_len (w); 3605 int len = get_narrowed_len (w);
3519 return max ((pos / len - 1) * len, BEGV); 3606 return max ((pos / len - 1) * len, BEGV);
3520} 3607}
3521 3608
3522ptrdiff_t 3609static ptrdiff_t
3523get_narrowed_zv (struct window *w, ptrdiff_t pos) 3610get_medium_narrowing_zv (struct window *w, ptrdiff_t pos)
3524{ 3611{
3525 int len = get_narrowed_len (w); 3612 int len = get_narrowed_len (w);
3526 return min ((pos / len + 1) * len, ZV); 3613 return min ((pos / len + 1) * len, ZV);
3527} 3614}
3528 3615
3616/* Find the position of the last BOL before POS, unless it is too far
3617 away. The buffer portion in which the search occurs is gradually
3618 enlarged: [POS-500..POS], [POS-5500..POS-500],
3619 [POS-55500..POS-5500], and finally [POS-555500..POS-55500]. Return
3620 BEGV-1 if no BOL was found in [POS-555500..POS]. */
3621static ptrdiff_t
3622get_nearby_bol_pos (ptrdiff_t pos)
3623{
3624 ptrdiff_t start, pos_bytepos, cur, next, found, bol = BEGV - 1, init_pos = pos;
3625 int dist;
3626 for (dist = 500; dist <= 500000; dist *= 10)
3627 {
3628 pos_bytepos = pos == BEGV ? BEGV_BYTE : CHAR_TO_BYTE (pos);
3629 start = pos - dist < BEGV ? BEGV : pos - dist;
3630 for (cur = start; cur < pos; cur = next)
3631 {
3632 next = find_newline1 (cur, CHAR_TO_BYTE (cur),
3633 pos, pos_bytepos,
3634 1, &found, NULL, false);
3635 if (found)
3636 bol = next;
3637 else
3638 break;
3639 }
3640 if (bol >= BEGV || start == BEGV)
3641 break;
3642 else
3643 pos = pos - dist < BEGV ? BEGV : pos - dist;
3644 }
3645 eassert (bol <= init_pos);
3646 return bol;
3647}
3648
3529ptrdiff_t 3649ptrdiff_t
3530get_closer_narrowed_begv (struct window *w, ptrdiff_t pos) 3650get_small_narrowing_begv (struct window *w, ptrdiff_t pos)
3531{ 3651{
3532 int len = get_narrowed_width (w); 3652 int len = get_narrowed_width (w);
3533 return max ((pos / len - 1) * len, BEGV); 3653 ptrdiff_t bol_pos = max (get_nearby_bol_pos (pos), BEGV);
3654 return max (bol_pos + ((pos - bol_pos) / len - 1) * len, BEGV);
3534} 3655}
3535 3656
3536ptrdiff_t 3657ptrdiff_t
3537get_locked_narrowing_begv (ptrdiff_t pos) 3658get_large_narrowing_begv (ptrdiff_t pos)
3538{ 3659{
3539 if (long_line_optimizations_region_size <= 0) 3660 if (long_line_optimizations_region_size <= 0)
3540 return BEGV; 3661 return BEGV;
@@ -3552,7 +3673,7 @@ get_locked_narrowing_begv (ptrdiff_t pos)
3552} 3673}
3553 3674
3554ptrdiff_t 3675ptrdiff_t
3555get_locked_narrowing_zv (ptrdiff_t pos) 3676get_large_narrowing_zv (ptrdiff_t pos)
3556{ 3677{
3557 if (long_line_optimizations_region_size <= 0) 3678 if (long_line_optimizations_region_size <= 0)
3558 return ZV; 3679 return ZV;
@@ -3571,7 +3692,7 @@ unwind_narrowed_begv (Lisp_Object point_min)
3571 3692
3572#define SET_WITH_NARROWED_BEGV(IT,DST,EXPR,BV) \ 3693#define SET_WITH_NARROWED_BEGV(IT,DST,EXPR,BV) \
3573 do { \ 3694 do { \
3574 if (IT->narrowed_begv) \ 3695 if (IT->medium_narrowing_begv) \
3575 { \ 3696 { \
3576 specpdl_ref count = SPECPDL_INDEX (); \ 3697 specpdl_ref count = SPECPDL_INDEX (); \
3577 record_unwind_protect (unwind_narrowed_begv, Fpoint_min ()); \ 3698 record_unwind_protect (unwind_narrowed_begv, Fpoint_min ()); \
@@ -4410,17 +4531,17 @@ handle_fontified_prop (struct it *it)
4410 if (current_buffer->long_line_optimizations_p 4531 if (current_buffer->long_line_optimizations_p
4411 && long_line_optimizations_region_size > 0) 4532 && long_line_optimizations_region_size > 0)
4412 { 4533 {
4413 ptrdiff_t begv = it->locked_narrowing_begv; 4534 ptrdiff_t begv = it->large_narrowing_begv;
4414 ptrdiff_t zv = it->locked_narrowing_zv; 4535 ptrdiff_t zv = it->large_narrowing_zv;
4415 ptrdiff_t charpos = IT_CHARPOS (*it); 4536 ptrdiff_t charpos = IT_CHARPOS (*it);
4416 if (charpos < begv || charpos > zv) 4537 if (charpos < begv || charpos > zv)
4417 { 4538 {
4418 begv = get_locked_narrowing_begv (charpos); 4539 begv = get_large_narrowing_begv (charpos);
4419 zv = get_locked_narrowing_zv (charpos); 4540 zv = get_large_narrowing_zv (charpos);
4420 } 4541 }
4421 if (begv != BEG || zv != Z) 4542 if (begv != BEG || zv != Z)
4422 narrow_to_region_locked (make_fixnum (begv), make_fixnum (zv), 4543 labeled_narrow_to_region (make_fixnum (begv), make_fixnum (zv),
4423 Qlong_line_optimizations_in_fontification_functions); 4544 Qlong_line_optimizations_in_fontification_functions);
4424 } 4545 }
4425 4546
4426 /* Don't allow Lisp that runs from 'fontification-functions' 4547 /* Don't allow Lisp that runs from 'fontification-functions'
@@ -7055,7 +7176,7 @@ back_to_previous_line_start (struct it *it)
7055 dec_both (&cp, &bp); 7176 dec_both (&cp, &bp);
7056 SET_WITH_NARROWED_BEGV (it, IT_CHARPOS (*it), 7177 SET_WITH_NARROWED_BEGV (it, IT_CHARPOS (*it),
7057 find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it)), 7178 find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it)),
7058 get_closer_narrowed_begv (it->w, IT_CHARPOS (*it))); 7179 get_small_narrowing_begv (it->w, IT_CHARPOS (*it)));
7059} 7180}
7060 7181
7061/* Find in the current buffer the first display or overlay string 7182/* Find in the current buffer the first display or overlay string
@@ -7359,7 +7480,7 @@ back_to_previous_visible_line_start (struct it *it)
7359 it->continuation_lines_width = 0; 7480 it->continuation_lines_width = 0;
7360 7481
7361 eassert (IT_CHARPOS (*it) >= BEGV); 7482 eassert (IT_CHARPOS (*it) >= BEGV);
7362 eassert (it->narrowed_begv > 0 /* long-line optimizations: all bets off */ 7483 eassert (it->medium_narrowing_begv > 0 /* long-line optimizations: all bets off */
7363 || IT_CHARPOS (*it) == BEGV 7484 || IT_CHARPOS (*it) == BEGV
7364 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n'); 7485 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
7365 CHECK_IT (it); 7486 CHECK_IT (it);
@@ -7477,24 +7598,29 @@ reseat (struct it *it, struct text_pos pos, bool force_p)
7477 7598
7478 if (current_buffer->long_line_optimizations_p) 7599 if (current_buffer->long_line_optimizations_p)
7479 { 7600 {
7480 if (!it->narrowed_begv) 7601 if (!it->medium_narrowing_begv)
7481 { 7602 {
7482 it->narrowed_begv = get_narrowed_begv (it->w, window_point (it->w)); 7603 it->medium_narrowing_begv
7483 it->narrowed_zv = get_narrowed_zv (it->w, window_point (it->w)); 7604 = get_medium_narrowing_begv (it->w, window_point (it->w));
7484 it->locked_narrowing_begv 7605 it->medium_narrowing_zv
7485 = get_locked_narrowing_begv (window_point (it->w)); 7606 = get_medium_narrowing_zv (it->w, window_point (it->w));
7486 it->locked_narrowing_zv 7607 it->large_narrowing_begv
7487 = get_locked_narrowing_zv (window_point (it->w)); 7608 = get_large_narrowing_begv (window_point (it->w));
7609 it->large_narrowing_zv
7610 = get_large_narrowing_zv (window_point (it->w));
7488 } 7611 }
7489 else if ((pos.charpos < it->narrowed_begv || pos.charpos > it->narrowed_zv) 7612 else if ((pos.charpos < it->medium_narrowing_begv
7613 || pos.charpos > it->medium_narrowing_zv)
7490 && (!redisplaying_p || it->line_wrap == TRUNCATE)) 7614 && (!redisplaying_p || it->line_wrap == TRUNCATE))
7491 { 7615 {
7492 it->narrowed_begv = get_narrowed_begv (it->w, pos.charpos); 7616 it->medium_narrowing_begv
7493 it->narrowed_zv = get_narrowed_zv (it->w, pos.charpos); 7617 = get_medium_narrowing_begv (it->w, pos.charpos);
7494 it->locked_narrowing_begv 7618 it->medium_narrowing_zv
7495 = get_locked_narrowing_begv (window_point (it->w)); 7619 = get_medium_narrowing_zv (it->w, pos.charpos);
7496 it->locked_narrowing_zv 7620 it->large_narrowing_begv
7497 = get_locked_narrowing_zv (window_point (it->w)); 7621 = get_large_narrowing_begv (window_point (it->w));
7622 it->large_narrowing_zv
7623 = get_large_narrowing_zv (window_point (it->w));
7498 } 7624 }
7499 } 7625 }
7500 7626
@@ -8804,7 +8930,7 @@ get_visually_first_element (struct it *it)
8804 SET_WITH_NARROWED_BEGV (it, bob, 8930 SET_WITH_NARROWED_BEGV (it, bob,
8805 string_p ? 0 : 8931 string_p ? 0 :
8806 IT_CHARPOS (*it) < BEGV ? obegv : BEGV, 8932 IT_CHARPOS (*it) < BEGV ? obegv : BEGV,
8807 it->narrowed_begv); 8933 it->medium_narrowing_begv);
8808 8934
8809 if (STRINGP (it->string)) 8935 if (STRINGP (it->string))
8810 { 8936 {
@@ -8848,7 +8974,7 @@ get_visually_first_element (struct it *it)
8848 find_newline_no_quit (IT_CHARPOS (*it), 8974 find_newline_no_quit (IT_CHARPOS (*it),
8849 IT_BYTEPOS (*it), -1, 8975 IT_BYTEPOS (*it), -1,
8850 &it->bidi_it.bytepos), 8976 &it->bidi_it.bytepos),
8851 it->narrowed_begv); 8977 it->medium_narrowing_begv);
8852 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true); 8978 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
8853 do 8979 do
8854 { 8980 {
@@ -10737,7 +10863,7 @@ move_it_vertically_backward (struct it *it, int dy)
10737 dec_both (&cp, &bp); 10863 dec_both (&cp, &bp);
10738 SET_WITH_NARROWED_BEGV (it, cp, 10864 SET_WITH_NARROWED_BEGV (it, cp,
10739 find_newline_no_quit (cp, bp, -1, NULL), 10865 find_newline_no_quit (cp, bp, -1, NULL),
10740 get_closer_narrowed_begv (it->w, IT_CHARPOS (*it))); 10866 get_small_narrowing_begv (it->w, IT_CHARPOS (*it)));
10741 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS); 10867 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
10742 } 10868 }
10743 bidi_unshelve_cache (it3data, true); 10869 bidi_unshelve_cache (it3data, true);
@@ -16417,7 +16543,7 @@ redisplay_internal (void)
16417 FOR_EACH_FRAME (tail, frame) 16543 FOR_EACH_FRAME (tail, frame)
16418 XFRAME (frame)->already_hscrolled_p = false; 16544 XFRAME (frame)->already_hscrolled_p = false;
16419 16545
16420 reset_outermost_narrowings (); 16546 reset_outermost_restrictions ();
16421 16547
16422 retry: 16548 retry:
16423 /* Remember the currently selected window. */ 16549 /* Remember the currently selected window. */
@@ -24144,6 +24270,7 @@ display_count_lines_logically (ptrdiff_t start_byte, ptrdiff_t limit_byte,
24144 ptrdiff_t val; 24270 ptrdiff_t val;
24145 specpdl_ref pdl_count = SPECPDL_INDEX (); 24271 specpdl_ref pdl_count = SPECPDL_INDEX ();
24146 record_unwind_protect (save_restriction_restore, save_restriction_save ()); 24272 record_unwind_protect (save_restriction_restore, save_restriction_save ());
24273 labeled_restrictions_remove_in_current_buffer ();
24147 Fwiden (); 24274 Fwiden ();
24148 val = display_count_lines (start_byte, limit_byte, count, byte_pos_ptr); 24275 val = display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
24149 unbind_to (pdl_count, Qnil); 24276 unbind_to (pdl_count, Qnil);