diff options
| author | Eli Zaretskii | 2017-05-18 23:18:29 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2017-05-18 23:18:29 +0300 |
| commit | 064b92d6e5a80f5435e2d941ec400ff9bd63d127 (patch) | |
| tree | 1a0ccdcc27c3d2cb3a525343df1b9101943f37ba | |
| parent | f6816a659c61d26d2d3328f34e43280b4ae1cf09 (diff) | |
| download | emacs-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/NEWS | 6 | ||||
| -rw-r--r-- | src/xdisp.c | 133 |
2 files changed, 97 insertions, 42 deletions
| @@ -357,6 +357,12 @@ you may set this variable to nil. (Behind the scenes, there is now a | |||
| 357 | new mode line construct, '%C', which operates exactly as '%c' does | 357 | new mode line construct, '%C', which operates exactly as '%c' does |
| 358 | except that it counts from one.) | 358 | except that it counts from one.) |
| 359 | 359 | ||
| 360 | ** New single-line horizontal scrolling mode. | ||
| 361 | The 'auto-hscroll-mode' variable can now have a new special value, | ||
| 362 | 'current-line', which causes only the line where the cursor is | ||
| 363 | displayed to be horizontally scrolled when lines are truncated on | ||
| 364 | display 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); | |||
| 832 | static bool update_menu_bar (struct frame *, bool, bool); | 832 | static bool update_menu_bar (struct frame *, bool, bool); |
| 833 | static bool try_window_reusing_current_matrix (struct window *); | 833 | static bool try_window_reusing_current_matrix (struct window *); |
| 834 | static int try_window_id (struct window *); | 834 | static int try_window_id (struct window *); |
| 835 | static bool display_line (struct it *); | 835 | static bool display_line (struct it *, int); |
| 836 | static int display_mode_lines (struct window *); | 836 | static int display_mode_lines (struct window *); |
| 837 | static int display_mode_line (struct window *, enum face_id, Lisp_Object); | 837 | static int display_mode_line (struct window *, enum face_id, Lisp_Object); |
| 838 | static int display_mode_element (struct it *, int, int, int, Lisp_Object, | 838 | static 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 | ||
| 2516 | static bool | ||
| 2517 | hscrolling_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 | ||
| 20623 | static bool | 20655 | static bool |
| 20624 | display_line (struct it *it) | 20656 | display_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, | |||
| 31906 | the frame's other specifications determine how to blink the cursor off. */); | 31952 | the 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. |
| 31911 | If non-nil, windows are automatically scrolled horizontally to make | 31957 | The value `current-line' means the line displaying point in each window |
| 31912 | point visible. */); | 31958 | is automatically scrolled horizontally to make point visible. |
| 31913 | automatic_hscrolling_p = true; | 31959 | Any other non-nil value means all the lines in a window are automatically |
| 31960 | scrolled 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 |