aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGregory Heytings2022-08-04 21:19:36 +0200
committerGregory Heytings2022-08-04 21:19:36 +0200
commit5a79bb2aed617f5b0ecf8e20ec958682e72fcc75 (patch)
tree78f8f67e887cefc78d026b5ac775aceebde315ff /src
parentb335e1a0469105bb55b9741ae3106dc0a6023ce2 (diff)
parenta95c5baa6a556059a434b9973a4454d414c15928 (diff)
downloademacs-5a79bb2aed617f5b0ecf8e20ec958682e72fcc75.tar.gz
emacs-5a79bb2aed617f5b0ecf8e20ec958682e72fcc75.zip
Merge branch 'feature/long-lines-improvements'
Diffstat (limited to 'src')
-rw-r--r--src/buffer.c5
-rw-r--r--src/composite.c20
-rw-r--r--src/dispextern.h2
-rw-r--r--src/keyboard.c54
-rw-r--r--src/lisp.h1
-rw-r--r--src/xdisp.c36
6 files changed, 88 insertions, 30 deletions
diff --git a/src/buffer.c b/src/buffer.c
index a07194aef72..e5601af5051 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -6431,12 +6431,15 @@ will run for `clone-indirect-buffer' calls as well. */);
6431 6431
6432 DEFVAR_LISP ("long-line-threshold", Vlong_line_threshold, 6432 DEFVAR_LISP ("long-line-threshold", Vlong_line_threshold,
6433 doc: /* Line length above which to use redisplay shortcuts. 6433 doc: /* Line length above which to use redisplay shortcuts.
6434
6434The value should be a positive integer or nil. 6435The value should be a positive integer or nil.
6435If the value is an integer, shortcuts in the display code intended 6436If the value is an integer, shortcuts in the display code intended
6436to speed up redisplay for long lines will automatically be enabled 6437to speed up redisplay for long lines will automatically be enabled
6437in buffers which contain one or more lines whose length is above 6438in buffers which contain one or more lines whose length is above
6438this threshold. 6439this threshold.
6439If nil, these display shortcuts will always remain disabled. */); 6440If nil, these display shortcuts will always remain disabled.
6441
6442There is no reason to change that value except for debugging purposes. */);
6440 XSETFASTINT (Vlong_line_threshold, 10000); 6443 XSETFASTINT (Vlong_line_threshold, 10000);
6441 6444
6442 defsubr (&Sbuffer_live_p); 6445 defsubr (&Sbuffer_live_p);
diff --git a/src/composite.c b/src/composite.c
index 0f90b92a785..a13839939b8 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -1021,7 +1021,11 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos,
1021 /* But we don't know where to stop the searching. */ 1021 /* But we don't know where to stop the searching. */
1022 endpos = NILP (string) ? BEGV - 1 : -1; 1022 endpos = NILP (string) ? BEGV - 1 : -1;
1023 /* Usually we don't reach ENDPOS because we stop searching 1023 /* Usually we don't reach ENDPOS because we stop searching
1024 at an uncomposable character (NL, LRE, etc). */ 1024 at an uncomposable character (NL, LRE, etc). In buffers
1025 with long lines, however, NL might be far away, so
1026 pretend that the buffer is smaller. */
1027 if (current_buffer->long_line_optimizations_p)
1028 endpos = get_closer_narrowed_begv (cmp_it->parent_it->w, charpos);
1025 } 1029 }
1026 } 1030 }
1027 cmp_it->id = -1; 1031 cmp_it->id = -1;
@@ -1580,7 +1584,6 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, ptrdiff_t backlim,
1580 Lisp_Object window; 1584 Lisp_Object window;
1581 struct window *w; 1585 struct window *w;
1582 bool need_adjustment = 0; 1586 bool need_adjustment = 0;
1583 ptrdiff_t narrowed_begv;
1584 1587
1585 window = Fget_buffer_window (Fcurrent_buffer (), Qnil); 1588 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
1586 if (NILP (window)) 1589 if (NILP (window))
@@ -1597,11 +1600,14 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, ptrdiff_t backlim,
1597 } 1600 }
1598 else 1601 else
1599 head = backlim; 1602 head = backlim;
1600 /* In buffers with very long lines, this function becomes very 1603 if (current_buffer->long_line_optimizations_p)
1601 slow. Pretend that the buffer is narrowed to make it fast. */ 1604 {
1602 narrowed_begv = get_narrowed_begv (w, window_point (w)); 1605 /* In buffers with very long lines, this function becomes very
1603 if (narrowed_begv && pos > narrowed_begv) 1606 slow. Pretend that the buffer is narrowed to make it fast. */
1604 head = narrowed_begv; 1607 ptrdiff_t begv = get_closer_narrowed_begv (w, window_point (w));
1608 if (pos > begv)
1609 head = begv;
1610 }
1605 tail = ZV; 1611 tail = ZV;
1606 stop = GPT; 1612 stop = GPT;
1607 cur.pos_byte = CHAR_TO_BYTE (cur.pos); 1613 cur.pos_byte = CHAR_TO_BYTE (cur.pos);
diff --git a/src/dispextern.h b/src/dispextern.h
index 037e02ff58f..12ba927261f 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2287,6 +2287,8 @@ struct composition_it
2287 reverse order, and thus the grapheme clusters must be rendered 2287 reverse order, and thus the grapheme clusters must be rendered
2288 from the last to the first. */ 2288 from the last to the first. */
2289 bool reversed_p; 2289 bool reversed_p;
2290 /* Parent iterator. */
2291 struct it *parent_it;
2290 2292
2291 /** The following members contain information about the current 2293 /** The following members contain information about the current
2292 grapheme cluster. */ 2294 grapheme cluster. */
diff --git a/src/keyboard.c b/src/keyboard.c
index 2863058d633..02e02448ff8 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1295,7 +1295,8 @@ command_loop_1 (void)
1295 /* Note that the value cell will never directly contain nil 1295 /* Note that the value cell will never directly contain nil
1296 if the symbol is a local variable. */ 1296 if the symbol is a local variable. */
1297 if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks)) 1297 if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))
1298 safe_run_hooks (Qpost_command_hook); 1298 safe_run_hooks_maybe_narrowed (Qpost_command_hook,
1299 XWINDOW (selected_window));
1299 1300
1300 /* If displaying a message, resize the echo area window to fit 1301 /* If displaying a message, resize the echo area window to fit
1301 that message's size exactly. */ 1302 that message's size exactly. */
@@ -1461,7 +1462,9 @@ command_loop_1 (void)
1461 } 1462 }
1462 Vthis_command = cmd; 1463 Vthis_command = cmd;
1463 Vreal_this_command = cmd; 1464 Vreal_this_command = cmd;
1464 safe_run_hooks (Qpre_command_hook); 1465
1466 safe_run_hooks_maybe_narrowed (Qpre_command_hook,
1467 XWINDOW (selected_window));
1465 1468
1466 already_adjusted = 0; 1469 already_adjusted = 0;
1467 1470
@@ -1513,7 +1516,8 @@ command_loop_1 (void)
1513 } 1516 }
1514 kset_last_prefix_arg (current_kboard, Vcurrent_prefix_arg); 1517 kset_last_prefix_arg (current_kboard, Vcurrent_prefix_arg);
1515 1518
1516 safe_run_hooks (Qpost_command_hook); 1519 safe_run_hooks_maybe_narrowed (Qpost_command_hook,
1520 XWINDOW (selected_window));
1517 1521
1518 /* If displaying a message, resize the echo area window to fit 1522 /* If displaying a message, resize the echo area window to fit
1519 that message's size exactly. Do this only if the echo area 1523 that message's size exactly. Do this only if the echo area
@@ -1895,6 +1899,22 @@ safe_run_hooks (Lisp_Object hook)
1895 unbind_to (count, Qnil); 1899 unbind_to (count, Qnil);
1896} 1900}
1897 1901
1902void
1903safe_run_hooks_maybe_narrowed (Lisp_Object hook, struct window *w)
1904{
1905 specpdl_ref count = SPECPDL_INDEX ();
1906
1907 specbind (Qinhibit_quit, Qt);
1908
1909 if (current_buffer->long_line_optimizations_p)
1910 narrow_to_region_internal (make_fixnum (get_narrowed_begv (w, PT)),
1911 make_fixnum (get_narrowed_zv (w, PT)),
1912 true);
1913
1914 run_hook_with_args (2, ((Lisp_Object []) {hook, hook}), safe_run_hook_funcall);
1915 unbind_to (count, Qnil);
1916}
1917
1898 1918
1899/* Nonzero means polling for input is temporarily suppressed. */ 1919/* Nonzero means polling for input is temporarily suppressed. */
1900 1920
@@ -12622,23 +12642,39 @@ Buffer modification stores t in this variable. */);
12622 12642
12623 DEFVAR_LISP ("pre-command-hook", Vpre_command_hook, 12643 DEFVAR_LISP ("pre-command-hook", Vpre_command_hook,
12624 doc: /* Normal hook run before each command is executed. 12644 doc: /* Normal hook run before each command is executed.
12625If an unhandled error happens in running this hook, 12645
12626the function in which the error occurred is unconditionally removed, since 12646If an unhandled error happens in running this hook, the function in
12627otherwise the error might happen repeatedly and make Emacs nonfunctional. 12647which the error occurred is unconditionally removed, since otherwise
12648the error might happen repeatedly and make Emacs nonfunctional.
12649
12650Note that, when the current buffer contains one or more lines whose
12651length is above `long-line-threshold', these hook functions are called
12652with the buffer narrowed to a small portion around point, and the
12653narrowing is locked (see `narrow-to-region'), so that these hook
12654functions cannot use `widen' to gain access to other portions of
12655buffer text.
12628 12656
12629See also `post-command-hook'. */); 12657See also `post-command-hook'. */);
12630 Vpre_command_hook = Qnil; 12658 Vpre_command_hook = Qnil;
12631 12659
12632 DEFVAR_LISP ("post-command-hook", Vpost_command_hook, 12660 DEFVAR_LISP ("post-command-hook", Vpost_command_hook,
12633 doc: /* Normal hook run after each command is executed. 12661 doc: /* Normal hook run after each command is executed.
12634If an unhandled error happens in running this hook, 12662
12635the function in which the error occurred is unconditionally removed, since 12663If an unhandled error happens in running this hook, the function in
12636otherwise the error might happen repeatedly and make Emacs nonfunctional. 12664which the error occurred is unconditionally removed, since otherwise
12665the error might happen repeatedly and make Emacs nonfunctional.
12637 12666
12638It is a bad idea to use this hook for expensive processing. If 12667It is a bad idea to use this hook for expensive processing. If
12639unavoidable, wrap your code in `(while-no-input (redisplay) CODE)' to 12668unavoidable, wrap your code in `(while-no-input (redisplay) CODE)' to
12640avoid making Emacs unresponsive while the user types. 12669avoid making Emacs unresponsive while the user types.
12641 12670
12671Note that, when the current buffer contains one or more lines whose
12672length is above `long-line-threshold', these hook functions are called
12673with the buffer narrowed to a small portion around point, and the
12674narrowing is locked (see `narrow-to-region'), so that these hook
12675functions cannot use `widen' to gain access to other portions of
12676buffer text.
12677
12642See also `pre-command-hook'. */); 12678See also `pre-command-hook'. */);
12643 Vpost_command_hook = Qnil; 12679 Vpost_command_hook = Qnil;
12644 12680
diff --git a/src/lisp.h b/src/lisp.h
index c8ad0bc56f5..8e36620fe53 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4830,6 +4830,7 @@ extern bool detect_input_pending (void);
4830extern bool detect_input_pending_ignore_squeezables (void); 4830extern bool detect_input_pending_ignore_squeezables (void);
4831extern bool detect_input_pending_run_timers (bool); 4831extern bool detect_input_pending_run_timers (bool);
4832extern void safe_run_hooks (Lisp_Object); 4832extern void safe_run_hooks (Lisp_Object);
4833extern void safe_run_hooks_maybe_narrowed (Lisp_Object, struct window *);
4833extern void cmd_error_internal (Lisp_Object, const char *); 4834extern void cmd_error_internal (Lisp_Object, const char *);
4834extern Lisp_Object command_loop_2 (Lisp_Object); 4835extern Lisp_Object command_loop_2 (Lisp_Object);
4835extern Lisp_Object read_menu_command (void); 4836extern Lisp_Object read_menu_command (void);
diff --git a/src/xdisp.c b/src/xdisp.c
index 2bedf1c7847..099efed2db1 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -3229,6 +3229,7 @@ init_iterator (struct it *it, struct window *w,
3229 it->f = XFRAME (w->frame); 3229 it->f = XFRAME (w->frame);
3230 3230
3231 it->cmp_it.id = -1; 3231 it->cmp_it.id = -1;
3232 it->cmp_it.parent_it = it;
3232 3233
3233 if (max_redisplay_ticks > 0) 3234 if (max_redisplay_ticks > 0)
3234 update_redisplay_ticks (0, w); 3235 update_redisplay_ticks (0, w);
@@ -3413,12 +3414,6 @@ init_iterator (struct it *it, struct window *w,
3413 } 3414 }
3414 } 3415 }
3415 3416
3416 if (current_buffer->long_line_optimizations_p)
3417 {
3418 it->narrowed_begv = get_narrowed_begv (w, window_point (w));
3419 it->narrowed_zv = get_narrowed_zv (w, window_point (w));
3420 }
3421
3422 /* If a buffer position was specified, set the iterator there, 3417 /* If a buffer position was specified, set the iterator there,
3423 getting overlays and face properties from that position. */ 3418 getting overlays and face properties from that position. */
3424 if (charpos >= BUF_BEG (current_buffer)) 3419 if (charpos >= BUF_BEG (current_buffer))
@@ -3478,6 +3473,9 @@ init_iterator (struct it *it, struct window *w,
3478 &it->bidi_it); 3473 &it->bidi_it);
3479 } 3474 }
3480 3475
3476 if (current_buffer->long_line_optimizations_p)
3477 it->narrowed_begv = 0;
3478
3481 /* Compute faces etc. */ 3479 /* Compute faces etc. */
3482 reseat (it, it->current.pos, true); 3480 reseat (it, it->current.pos, true);
3483 } 3481 }
@@ -3510,9 +3508,7 @@ ptrdiff_t
3510get_narrowed_begv (struct window *w, ptrdiff_t pos) 3508get_narrowed_begv (struct window *w, ptrdiff_t pos)
3511{ 3509{
3512 int len = get_narrowed_len (w); 3510 int len = get_narrowed_len (w);
3513 ptrdiff_t begv; 3511 return max ((pos / len - 1) * len, BEGV);
3514 begv = max ((pos / len - 1) * len, BEGV);
3515 return begv == BEGV ? 0 : begv;
3516} 3512}
3517 3513
3518ptrdiff_t 3514ptrdiff_t
@@ -4397,13 +4393,12 @@ handle_fontified_prop (struct it *it)
4397 4393
4398 if (current_buffer->long_line_optimizations_p) 4394 if (current_buffer->long_line_optimizations_p)
4399 { 4395 {
4400 ptrdiff_t begv = it->narrowed_begv ? it->narrowed_begv : BEGV; 4396 ptrdiff_t begv = it->narrowed_begv;
4401 ptrdiff_t zv = it->narrowed_zv; 4397 ptrdiff_t zv = it->narrowed_zv;
4402 ptrdiff_t charpos = IT_CHARPOS (*it); 4398 ptrdiff_t charpos = IT_CHARPOS (*it);
4403 if (charpos < begv || charpos > zv) 4399 if (charpos < begv || charpos > zv)
4404 { 4400 {
4405 begv = get_narrowed_begv (it->w, charpos); 4401 begv = get_narrowed_begv (it->w, charpos);
4406 if (!begv) begv = BEGV;
4407 zv = get_narrowed_zv (it->w, charpos); 4402 zv = get_narrowed_zv (it->w, charpos);
4408 } 4403 }
4409 narrow_to_region_internal (make_fixnum (begv), make_fixnum (zv), true); 4404 narrow_to_region_internal (make_fixnum (begv), make_fixnum (zv), true);
@@ -7533,6 +7528,21 @@ reseat (struct it *it, struct text_pos pos, bool force_p)
7533 7528
7534 reseat_1 (it, pos, false); 7529 reseat_1 (it, pos, false);
7535 7530
7531 if (current_buffer->long_line_optimizations_p)
7532 {
7533 if (!it->narrowed_begv)
7534 {
7535 it->narrowed_begv = get_narrowed_begv (it->w, window_point (it->w));
7536 it->narrowed_zv = get_narrowed_zv (it->w, window_point (it->w));
7537 }
7538 else if ((pos.charpos < it->narrowed_begv || pos.charpos > it->narrowed_zv)
7539 && (!redisplaying_p || it->line_wrap == TRUNCATE))
7540 {
7541 it->narrowed_begv = get_narrowed_begv (it->w, pos.charpos);
7542 it->narrowed_zv = get_narrowed_zv (it->w, pos.charpos);
7543 }
7544 }
7545
7536 /* Determine where to check text properties. Avoid doing it 7546 /* Determine where to check text properties. Avoid doing it
7537 where possible because text property lookup is very expensive. */ 7547 where possible because text property lookup is very expensive. */
7538 if (force_p 7548 if (force_p
@@ -8838,7 +8848,7 @@ get_visually_first_element (struct it *it)
8838 8848
8839 SET_WITH_NARROWED_BEGV (it, bob, 8849 SET_WITH_NARROWED_BEGV (it, bob,
8840 string_p ? 0 : 8850 string_p ? 0 :
8841 IT_BYTEPOS (*it) < BEGV ? obegv : BEGV, 8851 IT_CHARPOS (*it) < BEGV ? obegv : BEGV,
8842 it->narrowed_begv); 8852 it->narrowed_begv);
8843 8853
8844 if (STRINGP (it->string)) 8854 if (STRINGP (it->string))
@@ -10773,7 +10783,7 @@ move_it_vertically_backward (struct it *it, int dy)
10773 dec_both (&cp, &bp); 10783 dec_both (&cp, &bp);
10774 SET_WITH_NARROWED_BEGV (it, cp, 10784 SET_WITH_NARROWED_BEGV (it, cp,
10775 find_newline_no_quit (cp, bp, -1, NULL), 10785 find_newline_no_quit (cp, bp, -1, NULL),
10776 it->narrowed_begv); 10786 get_closer_narrowed_begv (it->w, IT_CHARPOS (*it)));
10777 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS); 10787 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
10778 } 10788 }
10779 bidi_unshelve_cache (it3data, true); 10789 bidi_unshelve_cache (it3data, true);