diff options
| author | Gregory Heytings | 2022-08-04 21:19:36 +0200 |
|---|---|---|
| committer | Gregory Heytings | 2022-08-04 21:19:36 +0200 |
| commit | 5a79bb2aed617f5b0ecf8e20ec958682e72fcc75 (patch) | |
| tree | 78f8f67e887cefc78d026b5ac775aceebde315ff | |
| parent | b335e1a0469105bb55b9741ae3106dc0a6023ce2 (diff) | |
| parent | a95c5baa6a556059a434b9973a4454d414c15928 (diff) | |
| download | emacs-5a79bb2aed617f5b0ecf8e20ec958682e72fcc75.tar.gz emacs-5a79bb2aed617f5b0ecf8e20ec958682e72fcc75.zip | |
Merge branch 'feature/long-lines-improvements'
| -rw-r--r-- | src/buffer.c | 5 | ||||
| -rw-r--r-- | src/composite.c | 20 | ||||
| -rw-r--r-- | src/dispextern.h | 2 | ||||
| -rw-r--r-- | src/keyboard.c | 54 | ||||
| -rw-r--r-- | src/lisp.h | 1 | ||||
| -rw-r--r-- | src/xdisp.c | 36 |
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 | |||
| 6434 | The value should be a positive integer or nil. | 6435 | The value should be a positive integer or nil. |
| 6435 | If the value is an integer, shortcuts in the display code intended | 6436 | If the value is an integer, shortcuts in the display code intended |
| 6436 | to speed up redisplay for long lines will automatically be enabled | 6437 | to speed up redisplay for long lines will automatically be enabled |
| 6437 | in buffers which contain one or more lines whose length is above | 6438 | in buffers which contain one or more lines whose length is above |
| 6438 | this threshold. | 6439 | this threshold. |
| 6439 | If nil, these display shortcuts will always remain disabled. */); | 6440 | If nil, these display shortcuts will always remain disabled. |
| 6441 | |||
| 6442 | There 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 | ||
| 1902 | void | ||
| 1903 | safe_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. |
| 12625 | If an unhandled error happens in running this hook, | 12645 | |
| 12626 | the function in which the error occurred is unconditionally removed, since | 12646 | If an unhandled error happens in running this hook, the function in |
| 12627 | otherwise the error might happen repeatedly and make Emacs nonfunctional. | 12647 | which the error occurred is unconditionally removed, since otherwise |
| 12648 | the error might happen repeatedly and make Emacs nonfunctional. | ||
| 12649 | |||
| 12650 | Note that, when the current buffer contains one or more lines whose | ||
| 12651 | length is above `long-line-threshold', these hook functions are called | ||
| 12652 | with the buffer narrowed to a small portion around point, and the | ||
| 12653 | narrowing is locked (see `narrow-to-region'), so that these hook | ||
| 12654 | functions cannot use `widen' to gain access to other portions of | ||
| 12655 | buffer text. | ||
| 12628 | 12656 | ||
| 12629 | See also `post-command-hook'. */); | 12657 | See 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. |
| 12634 | If an unhandled error happens in running this hook, | 12662 | |
| 12635 | the function in which the error occurred is unconditionally removed, since | 12663 | If an unhandled error happens in running this hook, the function in |
| 12636 | otherwise the error might happen repeatedly and make Emacs nonfunctional. | 12664 | which the error occurred is unconditionally removed, since otherwise |
| 12665 | the error might happen repeatedly and make Emacs nonfunctional. | ||
| 12637 | 12666 | ||
| 12638 | It is a bad idea to use this hook for expensive processing. If | 12667 | It is a bad idea to use this hook for expensive processing. If |
| 12639 | unavoidable, wrap your code in `(while-no-input (redisplay) CODE)' to | 12668 | unavoidable, wrap your code in `(while-no-input (redisplay) CODE)' to |
| 12640 | avoid making Emacs unresponsive while the user types. | 12669 | avoid making Emacs unresponsive while the user types. |
| 12641 | 12670 | ||
| 12671 | Note that, when the current buffer contains one or more lines whose | ||
| 12672 | length is above `long-line-threshold', these hook functions are called | ||
| 12673 | with the buffer narrowed to a small portion around point, and the | ||
| 12674 | narrowing is locked (see `narrow-to-region'), so that these hook | ||
| 12675 | functions cannot use `widen' to gain access to other portions of | ||
| 12676 | buffer text. | ||
| 12677 | |||
| 12642 | See also `pre-command-hook'. */); | 12678 | See 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); | |||
| 4830 | extern bool detect_input_pending_ignore_squeezables (void); | 4830 | extern bool detect_input_pending_ignore_squeezables (void); |
| 4831 | extern bool detect_input_pending_run_timers (bool); | 4831 | extern bool detect_input_pending_run_timers (bool); |
| 4832 | extern void safe_run_hooks (Lisp_Object); | 4832 | extern void safe_run_hooks (Lisp_Object); |
| 4833 | extern void safe_run_hooks_maybe_narrowed (Lisp_Object, struct window *); | ||
| 4833 | extern void cmd_error_internal (Lisp_Object, const char *); | 4834 | extern void cmd_error_internal (Lisp_Object, const char *); |
| 4834 | extern Lisp_Object command_loop_2 (Lisp_Object); | 4835 | extern Lisp_Object command_loop_2 (Lisp_Object); |
| 4835 | extern Lisp_Object read_menu_command (void); | 4836 | extern 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 | |||
| 3510 | get_narrowed_begv (struct window *w, ptrdiff_t pos) | 3508 | get_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 | ||
| 3518 | ptrdiff_t | 3514 | ptrdiff_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); |