aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGregory Heytings2022-07-08 21:22:52 +0000
committerGregory Heytings2022-07-08 23:36:58 +0200
commit1792cbaddc33772c344e45fb9478bee85fee66e7 (patch)
tree6bc87aa85e8c14091ef00433a52d28b99d9d0d32 /src
parent60e51595c8a89ffc34dbe0d36c75d1c119a7d5c5 (diff)
downloademacs-1792cbaddc33772c344e45fb9478bee85fee66e7.tar.gz
emacs-1792cbaddc33772c344e45fb9478bee85fee66e7.zip
Actually fix the long lines display bug (bug#56393).
* src/dispextern.h (struct it): New 'narrowed_begv' field. * src/dispextern.h (WITH_NARROWED_BEGV): New macro. * src/xdisp.c (get_narrowed_begv): New function. (init_iterator): Initilize the 'narrowed_begv' field. (back_to_previous_line_start, get_visually_first_element, move_it_vertically_backward): Use the new macro. * src/dispextern.h: Prototype of 'get_narrowed_begv'. * src/window.c (window_body_height): Make it externally visible. * src/window.h: Prototype of 'window_body_height'. * src/composite.c (find_automatic_composition): Optimize display in buffers with very long lines with 'get_narrowed_begv'. * lisp/obsolete/longlines.el: Reobsolete longlines-mode. * etc/NEWS: Announce the new minor mode, and remove the unobsoletion indication for 'longlines-mode'. * doc/emacs/trouble.texi (Long Lines): Remove the section. (Lossage): Remove the entry for the Long Lines section. * doc/emacs/emacs.texi (Top): Remove the entry for the Long Lines section.
Diffstat (limited to 'src')
-rw-r--r--src/composite.c6
-rw-r--r--src/dispextern.h17
-rw-r--r--src/window.c2
-rw-r--r--src/window.h1
-rw-r--r--src/xdisp.c31
5 files changed, 50 insertions, 7 deletions
diff --git a/src/composite.c b/src/composite.c
index 4d69702171f..d8998b5a1f3 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -1576,6 +1576,7 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, ptrdiff_t backlim,
1576 Lisp_Object window; 1576 Lisp_Object window;
1577 struct window *w; 1577 struct window *w;
1578 bool need_adjustment = 0; 1578 bool need_adjustment = 0;
1579 ptrdiff_t narrowed_begv;
1579 1580
1580 window = Fget_buffer_window (Fcurrent_buffer (), Qnil); 1581 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
1581 if (NILP (window)) 1582 if (NILP (window))
@@ -1586,6 +1587,11 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, ptrdiff_t backlim,
1586 if (NILP (string)) 1587 if (NILP (string))
1587 { 1588 {
1588 head = backlim < 0 ? BEGV : backlim, tail = ZV, stop = GPT; 1589 head = backlim < 0 ? BEGV : backlim, tail = ZV, stop = GPT;
1590 /* In buffers with very long lines, this function becomes very
1591 slow. Pretend that the buffer is narrowed to make it fast. */
1592 narrowed_begv = get_narrowed_begv (w);
1593 if (pos > narrowed_begv)
1594 head = narrowed_begv;
1589 cur.pos_byte = CHAR_TO_BYTE (cur.pos); 1595 cur.pos_byte = CHAR_TO_BYTE (cur.pos);
1590 cur.p = BYTE_POS_ADDR (cur.pos_byte); 1596 cur.p = BYTE_POS_ADDR (cur.pos_byte);
1591 } 1597 }
diff --git a/src/dispextern.h b/src/dispextern.h
index ca7834dec55..2edf4b73f81 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2332,6 +2332,10 @@ struct it
2332 with which display_string was called. */ 2332 with which display_string was called. */
2333 ptrdiff_t end_charpos; 2333 ptrdiff_t end_charpos;
2334 2334
2335 /* Alternate begin position of the buffer, which is used to optimize
2336 display (see the WITH_NARROWED_BEGV macro below). */
2337 ptrdiff_t narrowed_begv;
2338
2335 /* C string to iterate over. Non-null means get characters from 2339 /* C string to iterate over. Non-null means get characters from
2336 this string, otherwise characters are read from current_buffer 2340 this string, otherwise characters are read from current_buffer
2337 or it->string. */ 2341 or it->string. */
@@ -2813,6 +2817,18 @@ struct it
2813 reset_box_start_end_flags ((IT)); \ 2817 reset_box_start_end_flags ((IT)); \
2814 } while (false) 2818 } while (false)
2815 2819
2820/* Execute STATEMENT with a temporarily narrowed buffer. */
2821
2822#define WITH_NARROWED_BEGV(STATEMENT) \
2823 do { \
2824 ptrdiff_t obegv = BEGV; \
2825 if (it->narrowed_begv) \
2826 SET_BUF_BEGV (current_buffer, it->narrowed_begv); \
2827 STATEMENT; \
2828 if (it->narrowed_begv) \
2829 SET_BUF_BEGV (current_buffer, obegv); \
2830 } while (0)
2831
2816/* Bit-flags indicating what operation move_it_to should perform. */ 2832/* Bit-flags indicating what operation move_it_to should perform. */
2817 2833
2818enum move_operation_enum 2834enum move_operation_enum
@@ -3396,6 +3412,7 @@ void mark_window_display_accurate (Lisp_Object, bool);
3396void redisplay_preserve_echo_area (int); 3412void redisplay_preserve_echo_area (int);
3397void init_iterator (struct it *, struct window *, ptrdiff_t, 3413void init_iterator (struct it *, struct window *, ptrdiff_t,
3398 ptrdiff_t, struct glyph_row *, enum face_id); 3414 ptrdiff_t, struct glyph_row *, enum face_id);
3415ptrdiff_t get_narrowed_begv (struct window *w);
3399void init_iterator_to_row_start (struct it *, struct window *, 3416void init_iterator_to_row_start (struct it *, struct window *,
3400 struct glyph_row *); 3417 struct glyph_row *);
3401void start_display (struct it *, struct window *, struct text_pos); 3418void start_display (struct it *, struct window *, struct text_pos);
diff --git a/src/window.c b/src/window.c
index af463b90ce6..61ca9feb64d 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1028,7 +1028,7 @@ window_body_unit_from_symbol (Lisp_Object unit)
1028/* Return the number of lines/pixels of W's body. Don't count any mode 1028/* Return the number of lines/pixels of W's body. Don't count any mode
1029 or header line or horizontal divider of W. Rounds down to nearest 1029 or header line or horizontal divider of W. Rounds down to nearest
1030 integer when not working pixelwise. */ 1030 integer when not working pixelwise. */
1031static int 1031int
1032window_body_height (struct window *w, enum window_body_unit pixelwise) 1032window_body_height (struct window *w, enum window_body_unit pixelwise)
1033{ 1033{
1034 int height = (w->pixel_height 1034 int height = (w->pixel_height
diff --git a/src/window.h b/src/window.h
index 298a80a5366..c63b1b24d4f 100644
--- a/src/window.h
+++ b/src/window.h
@@ -1193,6 +1193,7 @@ enum window_body_unit
1193 WINDOW_BODY_IN_REMAPPED_CHARS 1193 WINDOW_BODY_IN_REMAPPED_CHARS
1194 }; 1194 };
1195extern int window_body_width (struct window *w, enum window_body_unit); 1195extern int window_body_width (struct window *w, enum window_body_unit);
1196extern int window_body_height (struct window *w, enum window_body_unit);
1196enum margin_unit { MARGIN_IN_LINES, MARGIN_IN_PIXELS }; 1197enum margin_unit { MARGIN_IN_LINES, MARGIN_IN_PIXELS };
1197extern int window_scroll_margin (struct window *, enum margin_unit); 1198extern int window_scroll_margin (struct window *, enum margin_unit);
1198extern void temp_output_buffer_show (Lisp_Object); 1199extern void temp_output_buffer_show (Lisp_Object);
diff --git a/src/xdisp.c b/src/xdisp.c
index 4089525e10f..e130b23d9a1 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -3425,6 +3425,8 @@ init_iterator (struct it *it, struct window *w,
3425 } 3425 }
3426 } 3426 }
3427 3427
3428 it->narrowed_begv = get_narrowed_begv (w);
3429
3428 /* If a buffer position was specified, set the iterator there, 3430 /* If a buffer position was specified, set the iterator there,
3429 getting overlays and face properties from that position. */ 3431 getting overlays and face properties from that position. */
3430 if (charpos >= BUF_BEG (current_buffer)) 3432 if (charpos >= BUF_BEG (current_buffer))
@@ -3491,6 +3493,19 @@ init_iterator (struct it *it, struct window *w,
3491 CHECK_IT (it); 3493 CHECK_IT (it);
3492} 3494}
3493 3495
3496/* Compute a suitable value for BEGV that can be used temporarily, to
3497 optimize display, for the buffer in window W. */
3498
3499ptrdiff_t
3500get_narrowed_begv (struct window *w)
3501{
3502 int len, begv;
3503 len = (1 + ((window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS) *
3504 window_body_height (w, WINDOW_BODY_IN_CANONICAL_CHARS)) /
3505 10000)) * 10000;
3506 begv = max ((PT / len - 2) * len, BEGV);
3507 return begv == BEGV ? 0 : begv;
3508}
3494 3509
3495/* Initialize IT for the display of window W with window start POS. */ 3510/* Initialize IT for the display of window W with window start POS. */
3496 3511
@@ -6992,7 +7007,8 @@ back_to_previous_line_start (struct it *it)
6992 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it); 7007 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6993 7008
6994 dec_both (&cp, &bp); 7009 dec_both (&cp, &bp);
6995 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it)); 7010 WITH_NARROWED_BEGV (IT_CHARPOS (*it) =
7011 find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it)));
6996} 7012}
6997 7013
6998 7014
@@ -8623,7 +8639,9 @@ get_visually_first_element (struct it *it)
8623{ 8639{
8624 bool string_p = STRINGP (it->string) || it->s; 8640 bool string_p = STRINGP (it->string) || it->s;
8625 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV); 8641 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
8626 ptrdiff_t bob = (string_p ? 0 : BEGV); 8642 ptrdiff_t bob;
8643
8644 WITH_NARROWED_BEGV (bob = (string_p ? 0 : BEGV));
8627 8645
8628 if (STRINGP (it->string)) 8646 if (STRINGP (it->string))
8629 { 8647 {
@@ -8663,9 +8681,10 @@ get_visually_first_element (struct it *it)
8663 if (string_p) 8681 if (string_p)
8664 it->bidi_it.charpos = it->bidi_it.bytepos = 0; 8682 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
8665 else 8683 else
8666 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it), 8684 WITH_NARROWED_BEGV (it->bidi_it.charpos =
8667 IT_BYTEPOS (*it), -1, 8685 find_newline_no_quit (IT_CHARPOS (*it),
8668 &it->bidi_it.bytepos); 8686 IT_BYTEPOS (*it), -1,
8687 &it->bidi_it.bytepos));
8669 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true); 8688 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
8670 do 8689 do
8671 { 8690 {
@@ -10583,7 +10602,7 @@ move_it_vertically_backward (struct it *it, int dy)
10583 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it); 10602 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
10584 10603
10585 dec_both (&cp, &bp); 10604 dec_both (&cp, &bp);
10586 cp = find_newline_no_quit (cp, bp, -1, NULL); 10605 WITH_NARROWED_BEGV (cp = find_newline_no_quit (cp, bp, -1, NULL));
10587 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS); 10606 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
10588 } 10607 }
10589 bidi_unshelve_cache (it3data, true); 10608 bidi_unshelve_cache (it3data, true);