aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2017-05-18 23:18:29 +0300
committerEli Zaretskii2017-05-18 23:18:29 +0300
commit064b92d6e5a80f5435e2d941ec400ff9bd63d127 (patch)
tree1a0ccdcc27c3d2cb3a525343df1b9101943f37ba
parentf6816a659c61d26d2d3328f34e43280b4ae1cf09 (diff)
downloademacs-064b92d6e5a80f5435e2d941ec400ff9bd63d127.tar.gz
emacs-064b92d6e5a80f5435e2d941ec400ff9bd63d127.zip
Support hscrolling only the current line
* src/xdisp.c (hscrolling_current_line_p): New function. (init_iterator): If auto-hscrolling just the current line, don't increment the iterator's first_visible_x and last_visible_x variables. (hscroll_window_tree): Recompute window's hscroll when moving vertically to another screen line. (redisplay_window): If we are hscrolling only the current line, disable the optimizations that rely on the current matrix being up-to-date. (display_line): Accept an additional argument CURSOR_VPOS, the vertical position of the current screen line which might need hscrolling; all callers changed. Compute first_visible_x and last_visible_x specially when auto-hscrolling current line, by repeating the calculation that is done in init_iterator in other modes. (syms_of_xdisp) <auto-hscroll-mode>: No longer boolean, it can now accept a 3rd value 'current-line, to turn on the mode where only the current line is hscrolled. * etc/NEWS: Mention the new auto-hscroll-mode value.
-rw-r--r--etc/NEWS6
-rw-r--r--src/xdisp.c133
2 files changed, 97 insertions, 42 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 6851dc9a0e4..4121c44b0c2 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -357,6 +357,12 @@ you may set this variable to nil. (Behind the scenes, there is now a
357new mode line construct, '%C', which operates exactly as '%c' does 357new mode line construct, '%C', which operates exactly as '%c' does
358except that it counts from one.) 358except that it counts from one.)
359 359
360** New single-line horizontal scrolling mode.
361The 'auto-hscroll-mode' variable can now have a new special value,
362'current-line', which causes only the line where the cursor is
363displayed to be horizontally scrolled when lines are truncated on
364display and point moves outside the left or right window margin.
365
360+++ 366+++
361** Two new user options 'list-matching-lines-jump-to-current-line' and 367** Two new user options 'list-matching-lines-jump-to-current-line' and
362'list-matching-lines-current-line-face' to show highlighted the current 368'list-matching-lines-current-line-face' to show highlighted the current
diff --git a/src/xdisp.c b/src/xdisp.c
index cdea20993c7..96bc1a5e032 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -832,7 +832,7 @@ static bool cursor_row_fully_visible_p (struct window *, bool, bool);
832static bool update_menu_bar (struct frame *, bool, bool); 832static bool update_menu_bar (struct frame *, bool, bool);
833static bool try_window_reusing_current_matrix (struct window *); 833static bool try_window_reusing_current_matrix (struct window *);
834static int try_window_id (struct window *); 834static int try_window_id (struct window *);
835static bool display_line (struct it *); 835static bool display_line (struct it *, int);
836static int display_mode_lines (struct window *); 836static int display_mode_lines (struct window *);
837static int display_mode_line (struct window *, enum face_id, Lisp_Object); 837static int display_mode_line (struct window *, enum face_id, Lisp_Object);
838static int display_mode_element (struct it *, int, int, int, Lisp_Object, 838static int display_mode_element (struct it *, int, int, int, Lisp_Object,
@@ -2513,6 +2513,14 @@ adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
2513 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix); 2513 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
2514} 2514}
2515 2515
2516static bool
2517hscrolling_current_line_p (struct window *w)
2518{
2519 return (!w->suspend_auto_hscroll
2520 && EQ (Fbuffer_local_value (Qauto_hscroll_mode, w->contents),
2521 Qcurrent_line));
2522}
2523
2516/*********************************************************************** 2524/***********************************************************************
2517 Lisp form evaluation 2525 Lisp form evaluation
2518 ***********************************************************************/ 2526 ***********************************************************************/
@@ -2882,8 +2890,11 @@ init_iterator (struct it *it, struct window *w,
2882 } 2890 }
2883 else 2891 else
2884 { 2892 {
2885 it->first_visible_x 2893 if (hscrolling_current_line_p (w))
2886 = window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f); 2894 it->first_visible_x = 0;
2895 else
2896 it->first_visible_x =
2897 window_hscroll_limited (w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2887 it->last_visible_x = (it->first_visible_x 2898 it->last_visible_x = (it->first_visible_x
2888 + window_box_width (w, TEXT_AREA)); 2899 + window_box_width (w, TEXT_AREA));
2889 2900
@@ -13031,6 +13042,7 @@ hscroll_window_tree (Lisp_Object window)
13031 cursor_row = bottom_row - 1; 13042 cursor_row = bottom_row - 1;
13032 } 13043 }
13033 bool row_r2l_p = cursor_row->reversed_p; 13044 bool row_r2l_p = cursor_row->reversed_p;
13045 bool hscl = hscrolling_current_line_p (w);
13034 13046
13035 text_area_width = window_box_width (w, TEXT_AREA); 13047 text_area_width = window_box_width (w, TEXT_AREA);
13036 13048
@@ -13081,7 +13093,13 @@ hscroll_window_tree (Lisp_Object window)
13081 && cursor_row->truncated_on_right_p 13093 && cursor_row->truncated_on_right_p
13082 && w->cursor.x <= h_margin) 13094 && w->cursor.x <= h_margin)
13083 || (w->hscroll 13095 || (w->hscroll
13084 && (w->cursor.x >= text_area_width - h_margin)))))) 13096 && (w->cursor.x >= text_area_width - h_margin))))
13097 /* This last condition is needed when moving
13098 vertically from an hscrolled line to a short line
13099 that doesn't need to be hscrolled. If we omit
13100 this condition, the line from which we move will
13101 remain hscrolled. */
13102 || (hscl && w->hscroll && !cursor_row->truncated_on_left_p)))
13085 { 13103 {
13086 struct it it; 13104 struct it it;
13087 ptrdiff_t hscroll; 13105 ptrdiff_t hscroll;
@@ -13101,6 +13119,9 @@ hscroll_window_tree (Lisp_Object window)
13101 /* Move iterator to pt starting at cursor_row->start in 13119 /* Move iterator to pt starting at cursor_row->start in
13102 a line with infinite width. */ 13120 a line with infinite width. */
13103 init_to_row_start (&it, w, cursor_row); 13121 init_to_row_start (&it, w, cursor_row);
13122 if (hscl)
13123 it.first_visible_x = window_hscroll_limited (w, it.f)
13124 * FRAME_COLUMN_WIDTH (it.f);
13104 it.last_visible_x = INFINITY; 13125 it.last_visible_x = INFINITY;
13105 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS); 13126 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
13106 /* If the line ends in an overlay string with a newline, 13127 /* If the line ends in an overlay string with a newline,
@@ -13112,6 +13133,9 @@ hscroll_window_tree (Lisp_Object window)
13112 if (it.method == GET_FROM_STRING && pt > 1) 13133 if (it.method == GET_FROM_STRING && pt > 1)
13113 { 13134 {
13114 init_to_row_start (&it, w, cursor_row); 13135 init_to_row_start (&it, w, cursor_row);
13136 if (hscl)
13137 it.first_visible_x = (window_hscroll_limited (w, it.f)
13138 * FRAME_COLUMN_WIDTH (it.f));
13115 move_it_in_display_line_to (&it, pt - 1, -1, MOVE_TO_POS); 13139 move_it_in_display_line_to (&it, pt - 1, -1, MOVE_TO_POS);
13116 } 13140 }
13117 current_buffer = saved_current_buffer; 13141 current_buffer = saved_current_buffer;
@@ -13153,7 +13177,12 @@ hscroll_window_tree (Lisp_Object window)
13153 /* Don't prevent redisplay optimizations if hscroll 13177 /* Don't prevent redisplay optimizations if hscroll
13154 hasn't changed, as it will unnecessarily slow down 13178 hasn't changed, as it will unnecessarily slow down
13155 redisplay. */ 13179 redisplay. */
13156 if (w->hscroll != hscroll) 13180 if (w->hscroll != hscroll
13181 /* When hscrolling only the current line, we need to
13182 report hscroll even if its value is equal to the
13183 previous one, because the new line might need a
13184 different value. */
13185 || (hscl && w->last_cursor_vpos != w->cursor.vpos))
13157 { 13186 {
13158 struct buffer *b = XBUFFER (w->contents); 13187 struct buffer *b = XBUFFER (w->contents);
13159 b->prevent_redisplay_optimizations_p = true; 13188 b->prevent_redisplay_optimizations_p = true;
@@ -13921,7 +13950,7 @@ redisplay_internal (void)
13921 it.vpos = this_line_vpos; 13950 it.vpos = this_line_vpos;
13922 it.current_y = this_line_y; 13951 it.current_y = this_line_y;
13923 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos); 13952 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13924 display_line (&it); 13953 display_line (&it, -1);
13925 13954
13926 /* If line contains point, is not continued, 13955 /* If line contains point, is not continued,
13927 and ends at same distance from eob as before, we win. */ 13956 and ends at same distance from eob as before, we win. */
@@ -16431,7 +16460,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
16431 = (w->window_end_valid 16460 = (w->window_end_valid
16432 && !current_buffer->clip_changed 16461 && !current_buffer->clip_changed
16433 && !current_buffer->prevent_redisplay_optimizations_p 16462 && !current_buffer->prevent_redisplay_optimizations_p
16434 && !window_outdated (w)); 16463 && !window_outdated (w)
16464 && !hscrolling_current_line_p (w));
16435 16465
16436 /* Run the window-text-change-functions 16466 /* Run the window-text-change-functions
16437 if it is possible that the text on the screen has changed 16467 if it is possible that the text on the screen has changed
@@ -17408,6 +17438,7 @@ try_window (Lisp_Object window, struct text_pos pos, int flags)
17408 struct it it; 17438 struct it it;
17409 struct glyph_row *last_text_row = NULL; 17439 struct glyph_row *last_text_row = NULL;
17410 struct frame *f = XFRAME (w->frame); 17440 struct frame *f = XFRAME (w->frame);
17441 int cursor_vpos = w->cursor.vpos;
17411 17442
17412 /* Make POS the new window start. */ 17443 /* Make POS the new window start. */
17413 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos)); 17444 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
@@ -17423,7 +17454,7 @@ try_window (Lisp_Object window, struct text_pos pos, int flags)
17423 /* Display all lines of W. */ 17454 /* Display all lines of W. */
17424 while (it.current_y < it.last_visible_y) 17455 while (it.current_y < it.last_visible_y)
17425 { 17456 {
17426 if (display_line (&it)) 17457 if (display_line (&it, cursor_vpos))
17427 last_text_row = it.glyph_row - 1; 17458 last_text_row = it.glyph_row - 1;
17428 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE)) 17459 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
17429 return 0; 17460 return 0;
@@ -17599,7 +17630,7 @@ try_window_reusing_current_matrix (struct window *w)
17599 break; 17630 break;
17600 17631
17601 it.glyph_row->reversed_p = false; 17632 it.glyph_row->reversed_p = false;
17602 if (display_line (&it)) 17633 if (display_line (&it, -1))
17603 last_text_row = it.glyph_row - 1; 17634 last_text_row = it.glyph_row - 1;
17604 17635
17605 } 17636 }
@@ -17778,7 +17809,7 @@ try_window_reusing_current_matrix (struct window *w)
17778 w->cursor.vpos = -1; 17809 w->cursor.vpos = -1;
17779 last_text_row = NULL; 17810 last_text_row = NULL;
17780 while (it.current_y < it.last_visible_y && !f->fonts_changed) 17811 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17781 if (display_line (&it)) 17812 if (display_line (&it, w->cursor.vpos))
17782 last_text_row = it.glyph_row - 1; 17813 last_text_row = it.glyph_row - 1;
17783 17814
17784 /* If point is in a reused row, adjust y and vpos of the cursor 17815 /* If point is in a reused row, adjust y and vpos of the cursor
@@ -18634,7 +18665,7 @@ try_window_id (struct window *w)
18634 && (first_unchanged_at_end_row == NULL 18665 && (first_unchanged_at_end_row == NULL
18635 || IT_CHARPOS (it) < stop_pos)) 18666 || IT_CHARPOS (it) < stop_pos))
18636 { 18667 {
18637 if (display_line (&it)) 18668 if (display_line (&it, -1))
18638 last_text_row = it.glyph_row - 1; 18669 last_text_row = it.glyph_row - 1;
18639 } 18670 }
18640 18671
@@ -18900,7 +18931,7 @@ try_window_id (struct window *w)
18900 displayed invalid in the current matrix by setting their 18931 displayed invalid in the current matrix by setting their
18901 enabled_p flag to false. */ 18932 enabled_p flag to false. */
18902 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, it.vpos, false); 18933 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, it.vpos, false);
18903 if (display_line (&it)) 18934 if (display_line (&it, w->cursor.vpos))
18904 last_text_row_at_end = it.glyph_row - 1; 18935 last_text_row_at_end = it.glyph_row - 1;
18905 } 18936 }
18906 } 18937 }
@@ -20618,10 +20649,11 @@ find_row_edges (struct it *it, struct glyph_row *row,
20618 IT->w from text at the current position of IT. See dispextern.h 20649 IT->w from text at the current position of IT. See dispextern.h
20619 for an overview of struct it. Value is true if 20650 for an overview of struct it. Value is true if
20620 IT->glyph_row displays text, as opposed to a line displaying ZV 20651 IT->glyph_row displays text, as opposed to a line displaying ZV
20621 only. */ 20652 only. CURSOR_VPOS is the window-relative vertical position of
20653 the glyph row displaying the cursor, or -1 if unknown. */
20622 20654
20623static bool 20655static bool
20624display_line (struct it *it) 20656display_line (struct it *it, int cursor_vpos)
20625{ 20657{
20626 struct glyph_row *row = it->glyph_row; 20658 struct glyph_row *row = it->glyph_row;
20627 Lisp_Object overlay_arrow_string; 20659 Lisp_Object overlay_arrow_string;
@@ -20639,6 +20671,8 @@ display_line (struct it *it)
20639 ptrdiff_t min_pos = ZV + 1, max_pos = 0; 20671 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
20640 ptrdiff_t min_bpos UNINIT, max_bpos UNINIT; 20672 ptrdiff_t min_bpos UNINIT, max_bpos UNINIT;
20641 bool pending_handle_line_prefix = false; 20673 bool pending_handle_line_prefix = false;
20674 int first_visible_x = it->first_visible_x;
20675 int last_visible_x = it->last_visible_x;
20642 20676
20643 /* We always start displaying at hpos zero even if hscrolled. */ 20677 /* We always start displaying at hpos zero even if hscrolled. */
20644 eassert (it->hpos == 0 && it->current_x == 0); 20678 eassert (it->hpos == 0 && it->current_x == 0);
@@ -20668,26 +20702,38 @@ display_line (struct it *it)
20668 recenter_overlay_lists but the first will be pretty cheap. */ 20702 recenter_overlay_lists but the first will be pretty cheap. */
20669 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it)); 20703 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
20670 20704
20705 /* If we are going to display the cursor's line, account for the
20706 hscroll of that line. */
20707 if (cursor_vpos >= 0 && it->vpos == cursor_vpos
20708 && hscrolling_current_line_p (it->w))
20709 {
20710 int x_incr =
20711 window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
20712
20713 first_visible_x += x_incr;
20714 last_visible_x += x_incr;
20715 }
20716
20671 /* Move over display elements that are not visible because we are 20717 /* Move over display elements that are not visible because we are
20672 hscrolled. This may stop at an x-position < IT->first_visible_x 20718 hscrolled. This may stop at an x-position < first_visible_x
20673 if the first glyph is partially visible or if we hit a line end. */ 20719 if the first glyph is partially visible or if we hit a line end. */
20674 if (it->current_x < it->first_visible_x) 20720 if (it->current_x < first_visible_x)
20675 { 20721 {
20676 enum move_it_result move_result; 20722 enum move_it_result move_result;
20677 20723
20678 this_line_min_pos = row->start.pos; 20724 this_line_min_pos = row->start.pos;
20679 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x, 20725 move_result = move_it_in_display_line_to (it, ZV, first_visible_x,
20680 MOVE_TO_POS | MOVE_TO_X); 20726 MOVE_TO_POS | MOVE_TO_X);
20681 /* If we are under a large hscroll, move_it_in_display_line_to 20727 /* If we are under a large hscroll, move_it_in_display_line_to
20682 could hit the end of the line without reaching 20728 could hit the end of the line without reaching
20683 it->first_visible_x. Pretend that we did reach it. This is 20729 first_visible_x. Pretend that we did reach it. This is
20684 especially important on a TTY, where we will call 20730 especially important on a TTY, where we will call
20685 extend_face_to_end_of_line, which needs to know how many 20731 extend_face_to_end_of_line, which needs to know how many
20686 blank glyphs to produce. */ 20732 blank glyphs to produce. */
20687 if (it->current_x < it->first_visible_x 20733 if (it->current_x < first_visible_x
20688 && (move_result == MOVE_NEWLINE_OR_CR 20734 && (move_result == MOVE_NEWLINE_OR_CR
20689 || move_result == MOVE_POS_MATCH_OR_ZV)) 20735 || move_result == MOVE_POS_MATCH_OR_ZV))
20690 it->current_x = it->first_visible_x; 20736 it->current_x = first_visible_x;
20691 20737
20692 /* Record the smallest positions seen while we moved over 20738 /* Record the smallest positions seen while we moved over
20693 display elements that are not visible. This is needed by 20739 display elements that are not visible. This is needed by
@@ -20881,7 +20927,7 @@ display_line (struct it *it)
20881 if (/* Not a newline. */ 20927 if (/* Not a newline. */
20882 nglyphs > 0 20928 nglyphs > 0
20883 /* Glyphs produced fit entirely in the line. */ 20929 /* Glyphs produced fit entirely in the line. */
20884 && it->current_x < it->last_visible_x) 20930 && it->current_x < last_visible_x)
20885 { 20931 {
20886 it->hpos += nglyphs; 20932 it->hpos += nglyphs;
20887 row->ascent = max (row->ascent, it->max_ascent); 20933 row->ascent = max (row->ascent, it->max_ascent);
@@ -20891,13 +20937,13 @@ display_line (struct it *it)
20891 it->max_phys_ascent + it->max_phys_descent); 20937 it->max_phys_ascent + it->max_phys_descent);
20892 row->extra_line_spacing = max (row->extra_line_spacing, 20938 row->extra_line_spacing = max (row->extra_line_spacing,
20893 it->max_extra_line_spacing); 20939 it->max_extra_line_spacing);
20894 if (it->current_x - it->pixel_width < it->first_visible_x 20940 if (it->current_x - it->pixel_width < first_visible_x
20895 /* In R2L rows, we arrange in extend_face_to_end_of_line 20941 /* In R2L rows, we arrange in extend_face_to_end_of_line
20896 to add a right offset to the line, by a suitable 20942 to add a right offset to the line, by a suitable
20897 change to the stretch glyph that is the leftmost 20943 change to the stretch glyph that is the leftmost
20898 glyph of the line. */ 20944 glyph of the line. */
20899 && !row->reversed_p) 20945 && !row->reversed_p)
20900 row->x = x - it->first_visible_x; 20946 row->x = x - first_visible_x;
20901 /* Record the maximum and minimum buffer positions seen so 20947 /* Record the maximum and minimum buffer positions seen so
20902 far in glyphs that will be displayed by this row. */ 20948 far in glyphs that will be displayed by this row. */
20903 if (it->bidi_p) 20949 if (it->bidi_p)
@@ -20922,9 +20968,9 @@ display_line (struct it *it)
20922 if (/* Lines are continued. */ 20968 if (/* Lines are continued. */
20923 it->line_wrap != TRUNCATE 20969 it->line_wrap != TRUNCATE
20924 && (/* Glyph doesn't fit on the line. */ 20970 && (/* Glyph doesn't fit on the line. */
20925 new_x > it->last_visible_x 20971 new_x > last_visible_x
20926 /* Or it fits exactly on a window system frame. */ 20972 /* Or it fits exactly on a window system frame. */
20927 || (new_x == it->last_visible_x 20973 || (new_x == last_visible_x
20928 && FRAME_WINDOW_P (it->f) 20974 && FRAME_WINDOW_P (it->f)
20929 && (row->reversed_p 20975 && (row->reversed_p
20930 ? WINDOW_LEFT_FRINGE_WIDTH (it->w) 20976 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
@@ -20933,7 +20979,7 @@ display_line (struct it *it)
20933 /* End of a continued line. */ 20979 /* End of a continued line. */
20934 20980
20935 if (it->hpos == 0 20981 if (it->hpos == 0
20936 || (new_x == it->last_visible_x 20982 || (new_x == last_visible_x
20937 && FRAME_WINDOW_P (it->f) 20983 && FRAME_WINDOW_P (it->f)
20938 && (row->reversed_p 20984 && (row->reversed_p
20939 ? WINDOW_LEFT_FRINGE_WIDTH (it->w) 20985 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
@@ -21076,10 +21122,10 @@ display_line (struct it *it)
21076 ? WINDOW_LEFT_FRINGE_WIDTH (it->w) 21122 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21077 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0) 21123 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21078 produce_special_glyphs (it, IT_CONTINUATION); 21124 produce_special_glyphs (it, IT_CONTINUATION);
21079 it->continuation_lines_width += it->last_visible_x; 21125 it->continuation_lines_width += last_visible_x;
21080 row->ends_in_middle_of_char_p = true; 21126 row->ends_in_middle_of_char_p = true;
21081 row->continued_p = true; 21127 row->continued_p = true;
21082 glyph->pixel_width = it->last_visible_x - x; 21128 glyph->pixel_width = last_visible_x - x;
21083 it->starts_in_middle_of_char_p = true; 21129 it->starts_in_middle_of_char_p = true;
21084 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0 21130 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21085 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0) 21131 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
@@ -21123,7 +21169,7 @@ display_line (struct it *it)
21123 21169
21124 break; 21170 break;
21125 } 21171 }
21126 else if (new_x > it->first_visible_x) 21172 else if (new_x > first_visible_x)
21127 { 21173 {
21128 /* Increment number of glyphs actually displayed. */ 21174 /* Increment number of glyphs actually displayed. */
21129 ++it->hpos; 21175 ++it->hpos;
@@ -21134,14 +21180,14 @@ display_line (struct it *it)
21134 if (it->bidi_p) 21180 if (it->bidi_p)
21135 RECORD_MAX_MIN_POS (it); 21181 RECORD_MAX_MIN_POS (it);
21136 21182
21137 if (x < it->first_visible_x && !row->reversed_p) 21183 if (x < first_visible_x && !row->reversed_p)
21138 /* Glyph is partially visible, i.e. row starts at 21184 /* Glyph is partially visible, i.e. row starts at
21139 negative X position. Don't do that in R2L 21185 negative X position. Don't do that in R2L
21140 rows, where we arrange to add a right offset to 21186 rows, where we arrange to add a right offset to
21141 the line in extend_face_to_end_of_line, by a 21187 the line in extend_face_to_end_of_line, by a
21142 suitable change to the stretch glyph that is 21188 suitable change to the stretch glyph that is
21143 the leftmost glyph of the line. */ 21189 the leftmost glyph of the line. */
21144 row->x = x - it->first_visible_x; 21190 row->x = x - first_visible_x;
21145 /* When the last glyph of an R2L row only fits 21191 /* When the last glyph of an R2L row only fits
21146 partially on the line, we need to set row->x to a 21192 partially on the line, we need to set row->x to a
21147 negative offset, so that the leftmost glyph is 21193 negative offset, so that the leftmost glyph is
@@ -21149,12 +21195,12 @@ display_line (struct it *it)
21149 going to produce the truncation glyph, this will 21195 going to produce the truncation glyph, this will
21150 be taken care of in produce_special_glyphs. */ 21196 be taken care of in produce_special_glyphs. */
21151 if (row->reversed_p 21197 if (row->reversed_p
21152 && new_x > it->last_visible_x 21198 && new_x > last_visible_x
21153 && !(it->line_wrap == TRUNCATE 21199 && !(it->line_wrap == TRUNCATE
21154 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)) 21200 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
21155 { 21201 {
21156 eassert (FRAME_WINDOW_P (it->f)); 21202 eassert (FRAME_WINDOW_P (it->f));
21157 row->x = it->last_visible_x - new_x; 21203 row->x = last_visible_x - new_x;
21158 } 21204 }
21159 } 21205 }
21160 else 21206 else
@@ -21164,7 +21210,7 @@ display_line (struct it *it)
21164 move_it_in_display_line at the start of this 21210 move_it_in_display_line at the start of this
21165 function, unless the text display area of the 21211 function, unless the text display area of the
21166 window is empty. */ 21212 window is empty. */
21167 eassert (it->first_visible_x <= it->last_visible_x); 21213 eassert (first_visible_x <= last_visible_x);
21168 } 21214 }
21169 } 21215 }
21170 /* Even if this display element produced no glyphs at all, 21216 /* Even if this display element produced no glyphs at all,
@@ -21233,8 +21279,8 @@ display_line (struct it *it)
21233 ? WINDOW_LEFT_FRINGE_WIDTH (it->w) 21279 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21234 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) 21280 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))
21235 || it->what == IT_IMAGE)) 21281 || it->what == IT_IMAGE))
21236 ? (it->current_x >= it->last_visible_x) 21282 ? (it->current_x >= last_visible_x)
21237 : (it->current_x > it->last_visible_x))) 21283 : (it->current_x > last_visible_x)))
21238 { 21284 {
21239 /* Maybe add truncation glyphs. */ 21285 /* Maybe add truncation glyphs. */
21240 if (!FRAME_WINDOW_P (it->f) 21286 if (!FRAME_WINDOW_P (it->f)
@@ -21268,7 +21314,7 @@ display_line (struct it *it)
21268 /* produce_special_glyphs overwrites the last glyph, so 21314 /* produce_special_glyphs overwrites the last glyph, so
21269 we don't want that if we want to keep that last 21315 we don't want that if we want to keep that last
21270 glyph, which means it's an image. */ 21316 glyph, which means it's an image. */
21271 if (it->current_x > it->last_visible_x) 21317 if (it->current_x > last_visible_x)
21272 { 21318 {
21273 it->current_x = x_before; 21319 it->current_x = x_before;
21274 if (!FRAME_WINDOW_P (it->f)) 21320 if (!FRAME_WINDOW_P (it->f))
@@ -21329,7 +21375,7 @@ display_line (struct it *it)
21329 21375
21330 /* If line is not empty and hscrolled, maybe insert truncation glyphs 21376 /* If line is not empty and hscrolled, maybe insert truncation glyphs
21331 at the left window margin. */ 21377 at the left window margin. */
21332 if (it->first_visible_x 21378 if (first_visible_x
21333 && IT_CHARPOS (*it) != CHARPOS (row->start.pos)) 21379 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
21334 { 21380 {
21335 if (!FRAME_WINDOW_P (it->f) 21381 if (!FRAME_WINDOW_P (it->f)
@@ -31906,12 +31952,15 @@ If a frame's ON-STATE has no entry in this list,
31906the frame's other specifications determine how to blink the cursor off. */); 31952the frame's other specifications determine how to blink the cursor off. */);
31907 Vblink_cursor_alist = Qnil; 31953 Vblink_cursor_alist = Qnil;
31908 31954
31909 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p, 31955 DEFVAR_LISP ("auto-hscroll-mode", automatic_hscrolling,
31910 doc: /* Allow or disallow automatic horizontal scrolling of windows. 31956 doc: /* Allow or disallow automatic horizontal scrolling of windows.
31911If non-nil, windows are automatically scrolled horizontally to make 31957The value `current-line' means the line displaying point in each window
31912point visible. */); 31958is automatically scrolled horizontally to make point visible.
31913 automatic_hscrolling_p = true; 31959Any other non-nil value means all the lines in a window are automatically
31960scrolled horizontally to make point visible. */);
31961 automatic_hscrolling = Qt;
31914 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode"); 31962 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
31963 DEFSYM (Qcurrent_line, "current-line");
31915 31964
31916 DEFVAR_INT ("hscroll-margin", hscroll_margin, 31965 DEFVAR_INT ("hscroll-margin", hscroll_margin,
31917 doc: /* How many columns away from the window edge point is allowed to get 31966 doc: /* How many columns away from the window edge point is allowed to get