aboutsummaryrefslogtreecommitdiffstats
path: root/src/buffer.c
diff options
context:
space:
mode:
authorYuan Fu2022-08-29 11:41:10 -0700
committerYuan Fu2022-08-29 11:41:10 -0700
commit77d5a0cf9fc4a6dc44f0c6ee5e3295e0eea08273 (patch)
tree969937ec44ce5ddf9447b074aa15314e0b9e8e95 /src/buffer.c
parente98b4715bb986524bde9356b62429af9786ae716 (diff)
parentdf2f6fb7fc4b79834ae40db8be2ccdc1e4a273f1 (diff)
downloademacs-77d5a0cf9fc4a6dc44f0c6ee5e3295e0eea08273.tar.gz
emacs-77d5a0cf9fc4a6dc44f0c6ee5e3295e0eea08273.zip
Merge remote-tracking branch 'origin/master' into feature/tree-sitter
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c112
1 files changed, 80 insertions, 32 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 97e9e227386..be7c2f2161e 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -604,6 +604,7 @@ even if it is dead. The return value is never nil. */)
604 set_buffer_intervals (b, NULL); 604 set_buffer_intervals (b, NULL);
605 BUF_UNCHANGED_MODIFIED (b) = 1; 605 BUF_UNCHANGED_MODIFIED (b) = 1;
606 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = 1; 606 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = 1;
607 BUF_CHARS_UNCHANGED_MODIFIED (b) = 1;
607 BUF_END_UNCHANGED (b) = 0; 608 BUF_END_UNCHANGED (b) = 0;
608 BUF_BEG_UNCHANGED (b) = 0; 609 BUF_BEG_UNCHANGED (b) = 0;
609 *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */ 610 *(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */
@@ -918,7 +919,8 @@ does not run the hooks `kill-buffer-hook',
918 set_buffer_internal_1 (b); 919 set_buffer_internal_1 (b);
919 Fset (intern ("buffer-save-without-query"), Qnil); 920 Fset (intern ("buffer-save-without-query"), Qnil);
920 Fset (intern ("buffer-file-number"), Qnil); 921 Fset (intern ("buffer-file-number"), Qnil);
921 Fset (intern ("buffer-stale-function"), Qnil); 922 if (!NILP (Flocal_variable_p (Qbuffer_stale_function, base_buffer)))
923 Fkill_local_variable (Qbuffer_stale_function);
922 /* Cloned buffers need extra setup, to do things such as deep 924 /* Cloned buffers need extra setup, to do things such as deep
923 variable copies for list variables that might be mangled due 925 variable copies for list variables that might be mangled due
924 to destructive operations in the indirect buffer. */ 926 to destructive operations in the indirect buffer. */
@@ -991,6 +993,7 @@ reset_buffer (register struct buffer *b)
991 /* It is more conservative to start out "changed" than "unchanged". */ 993 /* It is more conservative to start out "changed" than "unchanged". */
992 b->clip_changed = 0; 994 b->clip_changed = 0;
993 b->prevent_redisplay_optimizations_p = 1; 995 b->prevent_redisplay_optimizations_p = 1;
996 b->long_line_optimizations_p = 0;
994 bset_backed_up (b, Qnil); 997 bset_backed_up (b, Qnil);
995 bset_local_minor_modes (b, Qnil); 998 bset_local_minor_modes (b, Qnil);
996 BUF_AUTOSAVE_MODIFF (b) = 0; 999 BUF_AUTOSAVE_MODIFF (b) = 0;
@@ -1075,7 +1078,7 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too)
1075 eassert (XSYMBOL (sym)->u.s.redirect == SYMBOL_LOCALIZED); 1078 eassert (XSYMBOL (sym)->u.s.redirect == SYMBOL_LOCALIZED);
1076 /* Need not do anything if some other buffer's binding is 1079 /* Need not do anything if some other buffer's binding is
1077 now cached. */ 1080 now cached. */
1078 if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer)) 1081 if (BASE_EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer))
1079 { 1082 {
1080 /* Symbol is set up for this buffer's old local value: 1083 /* Symbol is set up for this buffer's old local value:
1081 swap it out! */ 1084 swap it out! */
@@ -1168,7 +1171,8 @@ is first appended to NAME, to speed up finding a non-existent buffer. */)
1168 genbase = name; 1171 genbase = name;
1169 else 1172 else
1170 { 1173 {
1171 char number[sizeof "-999999"]; 1174 enum { bug_52711 = true }; /* https://bugs.gnu.org/57211 */
1175 char number[bug_52711 ? INT_BUFSIZE_BOUND (int) + 1 : sizeof "-999999"];
1172 EMACS_INT r = get_random (); 1176 EMACS_INT r = get_random ();
1173 eassume (0 <= r); 1177 eassume (0 <= r);
1174 int i = r % 1000000; 1178 int i = r % 1000000;
@@ -1510,7 +1514,7 @@ state of the current buffer. Use with care. */)
1510 decrease SAVE_MODIFF and auto_save_modified or increase 1514 decrease SAVE_MODIFF and auto_save_modified or increase
1511 MODIFF. */ 1515 MODIFF. */
1512 if (SAVE_MODIFF >= MODIFF) 1516 if (SAVE_MODIFF >= MODIFF)
1513 SAVE_MODIFF = modiff_incr (&MODIFF); 1517 SAVE_MODIFF = modiff_incr (&MODIFF, 1);
1514 if (EQ (flag, Qautosaved)) 1518 if (EQ (flag, Qautosaved))
1515 BUF_AUTOSAVE_MODIFF (b) = MODIFF; 1519 BUF_AUTOSAVE_MODIFF (b) = MODIFF;
1516 } 1520 }
@@ -1570,6 +1574,7 @@ This does not change the name of the visited file (if any). */)
1570 (register Lisp_Object newname, Lisp_Object unique) 1574 (register Lisp_Object newname, Lisp_Object unique)
1571{ 1575{
1572 register Lisp_Object tem, buf; 1576 register Lisp_Object tem, buf;
1577 Lisp_Object requestedname = newname;
1573 1578
1574 CHECK_STRING (newname); 1579 CHECK_STRING (newname);
1575 1580
@@ -1586,7 +1591,8 @@ This does not change the name of the visited file (if any). */)
1586 if (NILP (unique) && XBUFFER (tem) == current_buffer) 1591 if (NILP (unique) && XBUFFER (tem) == current_buffer)
1587 return BVAR (current_buffer, name); 1592 return BVAR (current_buffer, name);
1588 if (!NILP (unique)) 1593 if (!NILP (unique))
1589 newname = Fgenerate_new_buffer_name (newname, BVAR (current_buffer, name)); 1594 newname = Fgenerate_new_buffer_name (newname,
1595 BVAR (current_buffer, name));
1590 else 1596 else
1591 error ("Buffer name `%s' is in use", SDATA (newname)); 1597 error ("Buffer name `%s' is in use", SDATA (newname));
1592 } 1598 }
@@ -1606,7 +1612,7 @@ This does not change the name of the visited file (if any). */)
1606 run_buffer_list_update_hook (current_buffer); 1612 run_buffer_list_update_hook (current_buffer);
1607 1613
1608 call2 (intern ("uniquify--rename-buffer-advice"), 1614 call2 (intern ("uniquify--rename-buffer-advice"),
1609 BVAR (current_buffer, name), unique); 1615 requestedname, unique);
1610 1616
1611 /* Refetch since that last call may have done GC. */ 1617 /* Refetch since that last call may have done GC. */
1612 return BVAR (current_buffer, name); 1618 return BVAR (current_buffer, name);
@@ -1617,7 +1623,7 @@ This does not change the name of the visited file (if any). */)
1617static bool 1623static bool
1618candidate_buffer (Lisp_Object b, Lisp_Object buffer) 1624candidate_buffer (Lisp_Object b, Lisp_Object buffer)
1619{ 1625{
1620 return (BUFFERP (b) && !EQ (b, buffer) 1626 return (BUFFERP (b) && !BASE_EQ (b, buffer)
1621 && BUFFER_LIVE_P (XBUFFER (b)) 1627 && BUFFER_LIVE_P (XBUFFER (b))
1622 && !BUFFER_HIDDEN_P (XBUFFER (b))); 1628 && !BUFFER_HIDDEN_P (XBUFFER (b)));
1623} 1629}
@@ -1819,10 +1825,12 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1819 /* Query if the buffer is still modified. */ 1825 /* Query if the buffer is still modified. */
1820 if (INTERACTIVE && modified) 1826 if (INTERACTIVE && modified)
1821 { 1827 {
1822 AUTO_STRING (format, "Buffer %s modified; kill anyway? "); 1828 /* Ask whether to kill the buffer, and exit if the user says
1823 tem = do_yes_or_no_p (CALLN (Fformat, format, BVAR (b, name))); 1829 "no". */
1824 if (NILP (tem)) 1830 if (NILP (call1 (Qkill_buffer__possibly_save, buffer)))
1825 return unbind_to (count, Qnil); 1831 return unbind_to (count, Qnil);
1832 /* Recheck modified. */
1833 modified = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
1826 } 1834 }
1827 1835
1828 /* Delete the autosave file, if requested. */ 1836 /* Delete the autosave file, if requested. */
@@ -1861,7 +1869,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1861 since anything can happen within do_yes_or_no_p. */ 1869 since anything can happen within do_yes_or_no_p. */
1862 1870
1863 /* Don't kill the minibuffer now current. */ 1871 /* Don't kill the minibuffer now current. */
1864 if (EQ (buffer, XWINDOW (minibuf_window)->contents)) 1872 if (BASE_EQ (buffer, XWINDOW (minibuf_window)->contents))
1865 return Qnil; 1873 return Qnil;
1866 1874
1867 /* When we kill an ordinary buffer which shares its buffer text 1875 /* When we kill an ordinary buffer which shares its buffer text
@@ -1905,7 +1913,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1905 is the sole other buffer give up. */ 1913 is the sole other buffer give up. */
1906 XSETBUFFER (tem, current_buffer); 1914 XSETBUFFER (tem, current_buffer);
1907 if (EQ (tem, XWINDOW (minibuf_window)->contents) 1915 if (EQ (tem, XWINDOW (minibuf_window)->contents)
1908 && EQ (buffer, Fother_buffer (buffer, Qnil, Qnil))) 1916 && BASE_EQ (buffer, Fother_buffer (buffer, Qnil, Qnil)))
1909 return Qnil; 1917 return Qnil;
1910 1918
1911 /* Now there is no question: we can kill the buffer. */ 1919 /* Now there is no question: we can kill the buffer. */
@@ -2453,6 +2461,7 @@ results, see Info node `(elisp)Swapping Text'. */)
2453 swapfield (bidi_paragraph_cache, struct region_cache *); 2461 swapfield (bidi_paragraph_cache, struct region_cache *);
2454 current_buffer->prevent_redisplay_optimizations_p = 1; 2462 current_buffer->prevent_redisplay_optimizations_p = 1;
2455 other_buffer->prevent_redisplay_optimizations_p = 1; 2463 other_buffer->prevent_redisplay_optimizations_p = 1;
2464 swapfield (long_line_optimizations_p, bool_bf);
2456 swapfield (overlays_before, struct Lisp_Overlay *); 2465 swapfield (overlays_before, struct Lisp_Overlay *);
2457 swapfield (overlays_after, struct Lisp_Overlay *); 2466 swapfield (overlays_after, struct Lisp_Overlay *);
2458 swapfield (overlay_center, ptrdiff_t); 2467 swapfield (overlay_center, ptrdiff_t);
@@ -2472,12 +2481,12 @@ results, see Info node `(elisp)Swapping Text'. */)
2472 bset_point_before_scroll (current_buffer, Qnil); 2481 bset_point_before_scroll (current_buffer, Qnil);
2473 bset_point_before_scroll (other_buffer, Qnil); 2482 bset_point_before_scroll (other_buffer, Qnil);
2474 2483
2475 modiff_incr (&current_buffer->text->modiff); 2484 modiff_incr (&current_buffer->text->modiff, 1);
2476 modiff_incr (&other_buffer->text->modiff); 2485 modiff_incr (&other_buffer->text->modiff, 1);
2477 modiff_incr (&current_buffer->text->chars_modiff); 2486 modiff_incr (&current_buffer->text->chars_modiff, 1);
2478 modiff_incr (&other_buffer->text->chars_modiff); 2487 modiff_incr (&other_buffer->text->chars_modiff, 1);
2479 modiff_incr (&current_buffer->text->overlay_modiff); 2488 modiff_incr (&current_buffer->text->overlay_modiff, 1);
2480 modiff_incr (&other_buffer->text->overlay_modiff); 2489 modiff_incr (&other_buffer->text->overlay_modiff, 1);
2481 current_buffer->text->beg_unchanged = current_buffer->text->gpt; 2490 current_buffer->text->beg_unchanged = current_buffer->text->gpt;
2482 current_buffer->text->end_unchanged = current_buffer->text->gpt; 2491 current_buffer->text->end_unchanged = current_buffer->text->gpt;
2483 other_buffer->text->beg_unchanged = other_buffer->text->gpt; 2492 other_buffer->text->beg_unchanged = other_buffer->text->gpt;
@@ -2511,23 +2520,23 @@ results, see Info node `(elisp)Swapping Text'. */)
2511 { 2520 {
2512 ws = Fcons (w, ws); 2521 ws = Fcons (w, ws);
2513 if (MARKERP (XWINDOW (w)->pointm) 2522 if (MARKERP (XWINDOW (w)->pointm)
2514 && (EQ (XWINDOW (w)->contents, buf1) 2523 && (BASE_EQ (XWINDOW (w)->contents, buf1)
2515 || EQ (XWINDOW (w)->contents, buf2))) 2524 || BASE_EQ (XWINDOW (w)->contents, buf2)))
2516 Fset_marker (XWINDOW (w)->pointm, 2525 Fset_marker (XWINDOW (w)->pointm,
2517 make_fixnum 2526 make_fixnum
2518 (BUF_BEGV (XBUFFER (XWINDOW (w)->contents))), 2527 (BUF_BEGV (XBUFFER (XWINDOW (w)->contents))),
2519 XWINDOW (w)->contents); 2528 XWINDOW (w)->contents);
2520 /* Blindly copied from pointm part. */ 2529 /* Blindly copied from pointm part. */
2521 if (MARKERP (XWINDOW (w)->old_pointm) 2530 if (MARKERP (XWINDOW (w)->old_pointm)
2522 && (EQ (XWINDOW (w)->contents, buf1) 2531 && (BASE_EQ (XWINDOW (w)->contents, buf1)
2523 || EQ (XWINDOW (w)->contents, buf2))) 2532 || BASE_EQ (XWINDOW (w)->contents, buf2)))
2524 Fset_marker (XWINDOW (w)->old_pointm, 2533 Fset_marker (XWINDOW (w)->old_pointm,
2525 make_fixnum 2534 make_fixnum
2526 (BUF_BEGV (XBUFFER (XWINDOW (w)->contents))), 2535 (BUF_BEGV (XBUFFER (XWINDOW (w)->contents))),
2527 XWINDOW (w)->contents); 2536 XWINDOW (w)->contents);
2528 if (MARKERP (XWINDOW (w)->start) 2537 if (MARKERP (XWINDOW (w)->start)
2529 && (EQ (XWINDOW (w)->contents, buf1) 2538 && (BASE_EQ (XWINDOW (w)->contents, buf1)
2530 || EQ (XWINDOW (w)->contents, buf2))) 2539 || BASE_EQ (XWINDOW (w)->contents, buf2)))
2531 Fset_marker (XWINDOW (w)->start, 2540 Fset_marker (XWINDOW (w)->start,
2532 make_fixnum 2541 make_fixnum
2533 (XBUFFER (XWINDOW (w)->contents)->last_window_start), 2542 (XBUFFER (XWINDOW (w)->contents)->last_window_start),
@@ -2537,10 +2546,11 @@ results, see Info node `(elisp)Swapping Text'. */)
2537 } 2546 }
2538 2547
2539 if (current_buffer->text->intervals) 2548 if (current_buffer->text->intervals)
2540 (eassert (EQ (current_buffer->text->intervals->up.obj, buffer)), 2549 (eassert (BASE_EQ (current_buffer->text->intervals->up.obj, buffer)),
2541 XSETBUFFER (current_buffer->text->intervals->up.obj, current_buffer)); 2550 XSETBUFFER (current_buffer->text->intervals->up.obj, current_buffer));
2542 if (other_buffer->text->intervals) 2551 if (other_buffer->text->intervals)
2543 (eassert (EQ (other_buffer->text->intervals->up.obj, Fcurrent_buffer ())), 2552 (eassert (BASE_EQ (other_buffer->text->intervals->up.obj,
2553 Fcurrent_buffer ())),
2544 XSETBUFFER (other_buffer->text->intervals->up.obj, other_buffer)); 2554 XSETBUFFER (other_buffer->text->intervals->up.obj, other_buffer));
2545 2555
2546 return Qnil; 2556 return Qnil;
@@ -3950,9 +3960,9 @@ for the rear of the overlay advance when text is inserted there
3950 else 3960 else
3951 CHECK_BUFFER (buffer); 3961 CHECK_BUFFER (buffer);
3952 3962
3953 if (MARKERP (beg) && !EQ (Fmarker_buffer (beg), buffer)) 3963 if (MARKERP (beg) && !BASE_EQ (Fmarker_buffer (beg), buffer))
3954 signal_error ("Marker points into wrong buffer", beg); 3964 signal_error ("Marker points into wrong buffer", beg);
3955 if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer)) 3965 if (MARKERP (end) && !BASE_EQ (Fmarker_buffer (end), buffer))
3956 signal_error ("Marker points into wrong buffer", end); 3966 signal_error ("Marker points into wrong buffer", end);
3957 3967
3958 CHECK_FIXNUM_COERCE_MARKER (beg); 3968 CHECK_FIXNUM_COERCE_MARKER (beg);
@@ -4015,7 +4025,7 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
4015 4025
4016 bset_redisplay (buf); 4026 bset_redisplay (buf);
4017 4027
4018 modiff_incr (&BUF_OVERLAY_MODIFF (buf)); 4028 modiff_incr (&BUF_OVERLAY_MODIFF (buf), 1);
4019} 4029}
4020 4030
4021/* Remove OVERLAY from LIST. */ 4031/* Remove OVERLAY from LIST. */
@@ -4070,9 +4080,9 @@ buffer. */)
4070 if (NILP (Fbuffer_live_p (buffer))) 4080 if (NILP (Fbuffer_live_p (buffer)))
4071 error ("Attempt to move overlay to a dead buffer"); 4081 error ("Attempt to move overlay to a dead buffer");
4072 4082
4073 if (MARKERP (beg) && !EQ (Fmarker_buffer (beg), buffer)) 4083 if (MARKERP (beg) && !BASE_EQ (Fmarker_buffer (beg), buffer))
4074 signal_error ("Marker points into wrong buffer", beg); 4084 signal_error ("Marker points into wrong buffer", beg);
4075 if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer)) 4085 if (MARKERP (end) && !BASE_EQ (Fmarker_buffer (end), buffer))
4076 signal_error ("Marker points into wrong buffer", end); 4086 signal_error ("Marker points into wrong buffer", end);
4077 4087
4078 CHECK_FIXNUM_COERCE_MARKER (beg); 4088 CHECK_FIXNUM_COERCE_MARKER (beg);
@@ -5622,7 +5632,7 @@ used. */);
5622 5632
5623 DEFVAR_PER_BUFFER ("mode-line-format", &BVAR (current_buffer, mode_line_format), 5633 DEFVAR_PER_BUFFER ("mode-line-format", &BVAR (current_buffer, mode_line_format),
5624 Qnil, 5634 Qnil,
5625 doc: /* Template for displaying mode line for current buffer. 5635 doc: /* Template for displaying mode line for a window's buffer.
5626 5636
5627The value may be nil, a string, a symbol or a list. 5637The value may be nil, a string, a symbol or a list.
5628 5638
@@ -5635,6 +5645,9 @@ For any symbol other than t or nil, the symbol's value is processed as
5635 `risky-local-variable' property, all properties in any strings, as 5645 `risky-local-variable' property, all properties in any strings, as
5636 well as all :eval and :propertize forms in the value, are ignored. 5646 well as all :eval and :propertize forms in the value, are ignored.
5637 5647
5648When the value is processed, the window's buffer is temporarily the
5649current buffer.
5650
5638A list whose car is a string or list is processed by processing each 5651A list whose car is a string or list is processed by processing each
5639 of the list elements recursively, as separate mode line constructs, 5652 of the list elements recursively, as separate mode line constructs,
5640 and concatenating the results. 5653 and concatenating the results.
@@ -6436,6 +6449,37 @@ Since `clone-indirect-buffer' calls `make-indirect-buffer', this hook
6436will run for `clone-indirect-buffer' calls as well. */); 6449will run for `clone-indirect-buffer' calls as well. */);
6437 Vclone_indirect_buffer_hook = Qnil; 6450 Vclone_indirect_buffer_hook = Qnil;
6438 6451
6452 DEFVAR_LISP ("long-line-threshold", Vlong_line_threshold,
6453 doc: /* Line length above which to use redisplay shortcuts.
6454
6455The value should be a positive integer or nil.
6456If the value is an integer, shortcuts in the display code intended
6457to speed up redisplay for long lines will automatically be enabled
6458in buffers which contain one or more lines whose length is above
6459this threshold.
6460If nil, these display shortcuts will always remain disabled.
6461
6462There is no reason to change that value except for debugging purposes. */);
6463 XSETFASTINT (Vlong_line_threshold, 10000);
6464
6465 DEFVAR_INT ("large-hscroll-threshold", large_hscroll_threshold,
6466 doc: /* Horizontal scroll of truncated lines above which to use redisplay shortcuts.
6467
6468The value should be a positive integer.
6469
6470Shortcuts in the display code intended to speed up redisplay for long
6471and truncated lines will automatically be enabled when a line's
6472horizontal scroll amount is or about to become larger than the value
6473of this variable.
6474
6475This variable has effect only in buffers which contain one or more
6476lines whose length is above `long-line-threshold', which see.
6477To disable redisplay shortcuts for long truncated line, set this
6478variable to `most-positive-fixnum'.
6479
6480There is no reason to change that value except for debugging purposes. */);
6481 large_hscroll_threshold = 10000;
6482
6439 defsubr (&Sbuffer_live_p); 6483 defsubr (&Sbuffer_live_p);
6440 defsubr (&Sbuffer_list); 6484 defsubr (&Sbuffer_list);
6441 defsubr (&Sget_buffer); 6485 defsubr (&Sget_buffer);
@@ -6489,5 +6533,9 @@ will run for `clone-indirect-buffer' calls as well. */);
6489 6533
6490 DEFSYM (Qautosaved, "autosaved"); 6534 DEFSYM (Qautosaved, "autosaved");
6491 6535
6536 DEFSYM (Qkill_buffer__possibly_save, "kill-buffer--possibly-save");
6537
6538 DEFSYM (Qbuffer_stale_function, "buffer-stale-function");
6539
6492 Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt); 6540 Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt);
6493} 6541}