diff options
| author | Eli Zaretskii | 2017-06-17 17:42:44 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2017-06-17 17:42:44 +0300 |
| commit | 7277c0fca7dab9f1b311c3eba5c42fd17acc3593 (patch) | |
| tree | 6426512a85cc8a16bd274bb93eaf857f440e40db | |
| parent | daf78963ee96484df1ecb0c10e7c0040d7b544a5 (diff) | |
| download | emacs-7277c0fca7dab9f1b311c3eba5c42fd17acc3593.tar.gz emacs-7277c0fca7dab9f1b311c3eba5c42fd17acc3593.zip | |
Finish up native display of line numbers
* src/xdisp.c (maybe_produce_line_number): Produce a blank before
the number, for R2L rows. Increment 'g' in the loop even if
glyph_row is NULL. Accept 2nd argument FORCE and produce the
line-number glyphs if it is non-zero.
(move_it_in_display_line_to): Account for the space taken by the
line-number glyphs. Call maybe_produce_line_number with 2nd
argument non-zero.
(set_cursor_from_row): Fix calculation of cursor X coordinate in
R2L rows with display-produced glyphs at the beginning.
(syms_of_xdisp) <line-number>: New face symbol.
<relative, display-line-width>: New symbols.
(maybe_produce_line_number): Use the line-number face for
displaying line numbers. Support relative line-number display.
Support user-defined width for displaying line numbers.
(try_cursor_movement, try_window_id): Disable these optimizations
when displaying relative line numbers.
* src/dispextern.h (struct it): New member 'pt_lnum'.
* lisp/faces.el (line-number): New face.
* lisp/cus-start.el (standard): Provide customization forms for
display-line-numbers and display-line-width.
* lisp/menu-bar.el (menu-bar-showhide-menu): Add menu-bar item to
turn display-line-numbers on and off.
* etc/NEWS: Document the new feature.
| -rw-r--r-- | etc/NEWS | 21 | ||||
| -rw-r--r-- | lisp/cus-start.el | 16 | ||||
| -rw-r--r-- | lisp/faces.el | 8 | ||||
| -rw-r--r-- | lisp/menu-bar.el | 19 | ||||
| -rw-r--r-- | src/dispextern.h | 3 | ||||
| -rw-r--r-- | src/xdisp.c | 126 |
6 files changed, 162 insertions, 31 deletions
| @@ -377,6 +377,27 @@ display of raw bytes from octal to hex. | |||
| 377 | ** You can now provide explicit field numbers in format specifiers. | 377 | ** You can now provide explicit field numbers in format specifiers. |
| 378 | For example, '(format "%2$s %1$s" "X" "Y")' produces "Y X". | 378 | For example, '(format "%2$s %1$s" "X" "Y")' produces "Y X". |
| 379 | 379 | ||
| 380 | ** Emacs now supports optional display of line numbers in the buffer. | ||
| 381 | This is similar to what linum-mode provides, but much faster and | ||
| 382 | doesn't usurp the display margin for the line numbers. Customize the | ||
| 383 | buffer-local variable 'display-line-numbers' to activate this optional | ||
| 384 | display. If set to t, Emacs will display the number of each line | ||
| 385 | before the line. If set to 'relative', Emacs will display the line | ||
| 386 | number relative to the line showing point. The default is nil, which | ||
| 387 | doesn't display the line numbers. | ||
| 388 | |||
| 389 | You can also customize the new variable 'display-lines-width' to | ||
| 390 | specify a fixed minimal with of the area allocated to line-number | ||
| 391 | display. The default is nil, meaning that Emacs will dynamically | ||
| 392 | calculate the area width, enlarging it as needed. Setting it to a | ||
| 393 | non-negative integer specifies that as the minimal width; selecting a | ||
| 394 | value that is large enough to display all line numbers in a buffer | ||
| 395 | will keep the line-number display area of constant width. | ||
| 396 | |||
| 397 | Linum mode and all similar packages are henceforth becoming obsolete. | ||
| 398 | Users and developers are encouraged to switch to this new feature | ||
| 399 | instead. | ||
| 400 | |||
| 380 | 401 | ||
| 381 | * Editing Changes in Emacs 26.1 | 402 | * Editing Changes in Emacs 26.1 |
| 382 | 403 | ||
diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 744fe7f69ee..0fe41d7c3ea 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el | |||
| @@ -584,6 +584,22 @@ since it could result in memory overflow and make Emacs crash." | |||
| 584 | (const :tag "Grow only" :value grow-only)) | 584 | (const :tag "Grow only" :value grow-only)) |
| 585 | "25.1") | 585 | "25.1") |
| 586 | (display-raw-bytes-as-hex display boolean "26.1") | 586 | (display-raw-bytes-as-hex display boolean "26.1") |
| 587 | (display-line-numbers display | ||
| 588 | (choice | ||
| 589 | (const :tag "Off (nil)" :value nil) | ||
| 590 | (const :tag "Absolute line numbers" | ||
| 591 | :value t) | ||
| 592 | (const :tag "Relative line numbers" | ||
| 593 | :value relative)) | ||
| 594 | "26.1") | ||
| 595 | (display-line-width display | ||
| 596 | (choice | ||
| 597 | (const :tag "Dynamically computed" | ||
| 598 | :value nil) | ||
| 599 | (integer :menu-tag "Fixed number of columns" | ||
| 600 | :value 2 | ||
| 601 | :format "%v")) | ||
| 602 | "26.1") | ||
| 587 | ;; xfaces.c | 603 | ;; xfaces.c |
| 588 | (scalable-fonts-allowed display boolean "22.1") | 604 | (scalable-fonts-allowed display boolean "22.1") |
| 589 | ;; xfns.c | 605 | ;; xfns.c |
diff --git a/lisp/faces.el b/lisp/faces.el index 9a8a1344caf..ac2d210a32f 100644 --- a/lisp/faces.el +++ b/lisp/faces.el | |||
| @@ -2465,6 +2465,14 @@ If you set `term-file-prefix' to nil, this function does nothing." | |||
| 2465 | :version "21.1" | 2465 | :version "21.1" |
| 2466 | :group 'basic-faces) | 2466 | :group 'basic-faces) |
| 2467 | 2467 | ||
| 2468 | ;; Definition stolen from linum.el. | ||
| 2469 | (defface line-number | ||
| 2470 | '((t :inherit (shadow default))) | ||
| 2471 | "Face for displaying line numbers. | ||
| 2472 | This face is used when `display-line-numbers' is non-nil." | ||
| 2473 | :version "26.1" | ||
| 2474 | :group 'basic-faces) | ||
| 2475 | |||
| 2468 | (defface escape-glyph | 2476 | (defface escape-glyph |
| 2469 | '((((background dark)) :foreground "cyan") | 2477 | '((((background dark)) :foreground "cyan") |
| 2470 | ;; See the comment in minibuffer-prompt for | 2478 | ;; See the comment in minibuffer-prompt for |
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index 9c7bcffbaab..06f8c7872b7 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el | |||
| @@ -1101,17 +1101,32 @@ The selected font will be the default on both the existing and future frames." | |||
| 1101 | :button (:radio . (eq tool-bar-mode nil)))) | 1101 | :button (:radio . (eq tool-bar-mode nil)))) |
| 1102 | menu))) | 1102 | menu))) |
| 1103 | 1103 | ||
| 1104 | (defun toggle-display-line-numbers () | ||
| 1105 | (interactive) | ||
| 1106 | (if display-line-numbers | ||
| 1107 | (setq display-line-numbers nil) | ||
| 1108 | (setq display-line-numbers t)) | ||
| 1109 | (force-mode-line-update)) | ||
| 1110 | |||
| 1104 | (defvar menu-bar-showhide-menu | 1111 | (defvar menu-bar-showhide-menu |
| 1105 | (let ((menu (make-sparse-keymap "Show/Hide"))) | 1112 | (let ((menu (make-sparse-keymap "Show/Hide"))) |
| 1106 | 1113 | ||
| 1114 | (bindings--define-key menu [display-line-numbers] | ||
| 1115 | `(menu-item "Line Numbers for all lines" | ||
| 1116 | ,(lambda () | ||
| 1117 | (interactive) | ||
| 1118 | (toggle-display-line-numbers)) | ||
| 1119 | :help "Show the line number alongside each line" | ||
| 1120 | :button (:toggle . display-line-numbers))) | ||
| 1121 | |||
| 1107 | (bindings--define-key menu [column-number-mode] | 1122 | (bindings--define-key menu [column-number-mode] |
| 1108 | (menu-bar-make-mm-toggle column-number-mode | 1123 | (menu-bar-make-mm-toggle column-number-mode |
| 1109 | "Column Numbers" | 1124 | "Column Numbers in Mode Line" |
| 1110 | "Show the current column number in the mode line")) | 1125 | "Show the current column number in the mode line")) |
| 1111 | 1126 | ||
| 1112 | (bindings--define-key menu [line-number-mode] | 1127 | (bindings--define-key menu [line-number-mode] |
| 1113 | (menu-bar-make-mm-toggle line-number-mode | 1128 | (menu-bar-make-mm-toggle line-number-mode |
| 1114 | "Line Numbers" | 1129 | "Line Numbers in Mode Line" |
| 1115 | "Show the current line number in the mode line")) | 1130 | "Show the current line number in the mode line")) |
| 1116 | 1131 | ||
| 1117 | (bindings--define-key menu [size-indication-mode] | 1132 | (bindings--define-key menu [size-indication-mode] |
diff --git a/src/dispextern.h b/src/dispextern.h index 050c68b8e08..08e5caa893b 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -2671,6 +2671,9 @@ struct it | |||
| 2671 | zero if not computed. */ | 2671 | zero if not computed. */ |
| 2672 | int lnum_width; | 2672 | int lnum_width; |
| 2673 | 2673 | ||
| 2674 | /* The line number of point's line, or zero if not computed yet. */ | ||
| 2675 | ptrdiff_t pt_lnum; | ||
| 2676 | |||
| 2674 | /* Left fringe bitmap number (enum fringe_bitmap_type). */ | 2677 | /* Left fringe bitmap number (enum fringe_bitmap_type). */ |
| 2675 | unsigned left_user_fringe_bitmap : FRINGE_ID_BITS; | 2678 | unsigned left_user_fringe_bitmap : FRINGE_ID_BITS; |
| 2676 | 2679 | ||
diff --git a/src/xdisp.c b/src/xdisp.c index dcef242966e..ebf5edc4d05 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -833,6 +833,7 @@ static bool cursor_row_fully_visible_p (struct window *, bool, bool); | |||
| 833 | static bool update_menu_bar (struct frame *, bool, bool); | 833 | static bool update_menu_bar (struct frame *, bool, bool); |
| 834 | static bool try_window_reusing_current_matrix (struct window *); | 834 | static bool try_window_reusing_current_matrix (struct window *); |
| 835 | static int try_window_id (struct window *); | 835 | static int try_window_id (struct window *); |
| 836 | static void maybe_produce_line_number (struct it *, bool); | ||
| 836 | static bool display_line (struct it *, int); | 837 | static bool display_line (struct it *, int); |
| 837 | static int display_mode_lines (struct window *); | 838 | static int display_mode_lines (struct window *); |
| 838 | static int display_mode_line (struct window *, enum face_id, Lisp_Object); | 839 | static int display_mode_line (struct window *, enum face_id, Lisp_Object); |
| @@ -8652,9 +8653,16 @@ move_it_in_display_line_to (struct it *it, | |||
| 8652 | || (it->method == GET_FROM_DISPLAY_VECTOR \ | 8653 | || (it->method == GET_FROM_DISPLAY_VECTOR \ |
| 8653 | && it->dpvec + it->current.dpvec_index + 1 >= it->dpend))) | 8654 | && it->dpvec + it->current.dpvec_index + 1 >= it->dpend))) |
| 8654 | 8655 | ||
| 8655 | /* If there's a line-/wrap-prefix, handle it. */ | 8656 | if (it->hpos == 0) |
| 8656 | if (it->hpos == 0 && it->method == GET_FROM_BUFFER) | 8657 | { |
| 8657 | handle_line_prefix (it); | 8658 | /* If line numbers are being displayed, produce a line number. */ |
| 8659 | if (!NILP (Vdisplay_line_numbers) | ||
| 8660 | && it->current_x == it->first_visible_x) | ||
| 8661 | maybe_produce_line_number (it, true); | ||
| 8662 | /* If there's a line-/wrap-prefix, handle it. */ | ||
| 8663 | if (it->method == GET_FROM_BUFFER) | ||
| 8664 | handle_line_prefix (it); | ||
| 8665 | } | ||
| 8658 | 8666 | ||
| 8659 | if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) | 8667 | if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) |
| 8660 | SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it)); | 8668 | SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it)); |
| @@ -14787,15 +14795,12 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, | |||
| 14787 | while (glyph > end + 1 | 14795 | while (glyph > end + 1 |
| 14788 | && NILP (glyph->object) | 14796 | && NILP (glyph->object) |
| 14789 | && glyph->charpos < 0) | 14797 | && glyph->charpos < 0) |
| 14790 | { | 14798 | --glyph; |
| 14791 | --glyph; | ||
| 14792 | x -= glyph->pixel_width; | ||
| 14793 | } | ||
| 14794 | if (NILP (glyph->object) && glyph->charpos < 0) | 14799 | if (NILP (glyph->object) && glyph->charpos < 0) |
| 14795 | --glyph; | 14800 | --glyph; |
| 14796 | /* By default, in reversed rows we put the cursor on the | 14801 | /* By default, in reversed rows we put the cursor on the |
| 14797 | rightmost (first in the reading order) glyph. */ | 14802 | rightmost (first in the reading order) glyph. */ |
| 14798 | for (g = end + 1; g < glyph; g++) | 14803 | for (x = 0, g = end + 1; g < glyph; g++) |
| 14799 | x += g->pixel_width; | 14804 | x += g->pixel_width; |
| 14800 | while (end < glyph | 14805 | while (end < glyph |
| 14801 | && NILP ((end + 1)->object) | 14806 | && NILP ((end + 1)->object) |
| @@ -15932,6 +15937,9 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, | |||
| 15932 | && !windows_or_buffers_changed | 15937 | && !windows_or_buffers_changed |
| 15933 | && !f->cursor_type_changed | 15938 | && !f->cursor_type_changed |
| 15934 | && NILP (Vshow_trailing_whitespace) | 15939 | && NILP (Vshow_trailing_whitespace) |
| 15940 | /* When display-line-numbers is in relative mode, moving point | ||
| 15941 | requires to redraw the entire window. */ | ||
| 15942 | && !EQ (Vdisplay_line_numbers, Qrelative) | ||
| 15935 | /* This code is not used for mini-buffer for the sake of the case | 15943 | /* This code is not used for mini-buffer for the sake of the case |
| 15936 | of redisplaying to replace an echo area message; since in | 15944 | of redisplaying to replace an echo area message; since in |
| 15937 | that case the mini-buffer contents per se are usually | 15945 | that case the mini-buffer contents per se are usually |
| @@ -18433,6 +18441,10 @@ try_window_id (struct window *w) | |||
| 18433 | if (!NILP (BVAR (XBUFFER (w->contents), extra_line_spacing))) | 18441 | if (!NILP (BVAR (XBUFFER (w->contents), extra_line_spacing))) |
| 18434 | GIVE_UP (23); | 18442 | GIVE_UP (23); |
| 18435 | 18443 | ||
| 18444 | /* Give up if display-line-numbers is in relative mode. */ | ||
| 18445 | if (EQ (Vdisplay_line_numbers, Qrelative)) | ||
| 18446 | GIVE_UP (24); | ||
| 18447 | |||
| 18436 | /* Make sure beg_unchanged and end_unchanged are up to date. Do it | 18448 | /* Make sure beg_unchanged and end_unchanged are up to date. Do it |
| 18437 | only if buffer has really changed. The reason is that the gap is | 18449 | only if buffer has really changed. The reason is that the gap is |
| 18438 | initially at Z for freshly visited files. The code below would | 18450 | initially at Z for freshly visited files. The code below would |
| @@ -20679,8 +20691,13 @@ find_row_edges (struct it *it, struct glyph_row *row, | |||
| 20679 | row->maxpos = it->current.pos; | 20691 | row->maxpos = it->current.pos; |
| 20680 | } | 20692 | } |
| 20681 | 20693 | ||
| 20694 | /* Produce the line-number glyphs for the current glyph_row. If | ||
| 20695 | IT->glyph_row is non-NULL, populate the row with the produced | ||
| 20696 | glyphs. FORCE non-zero means produce the glyphs even if the line | ||
| 20697 | number didn't change since the last time this function was called; | ||
| 20698 | this is used by move_it_in_display_line_to. */ | ||
| 20682 | static void | 20699 | static void |
| 20683 | maybe_produce_line_number (struct it *it) | 20700 | maybe_produce_line_number (struct it *it, bool force) |
| 20684 | { | 20701 | { |
| 20685 | ptrdiff_t last_line = it->lnum; | 20702 | ptrdiff_t last_line = it->lnum; |
| 20686 | ptrdiff_t start_from, bytepos; | 20703 | ptrdiff_t start_from, bytepos; |
| @@ -20709,9 +20726,12 @@ maybe_produce_line_number (struct it *it) | |||
| 20709 | eassert (this_line > 0 || (this_line == 0 && start_from == BEGV_BYTE)); | 20726 | eassert (this_line > 0 || (this_line == 0 && start_from == BEGV_BYTE)); |
| 20710 | eassert (bytepos == IT_BYTEPOS (*it)); | 20727 | eassert (bytepos == IT_BYTEPOS (*it)); |
| 20711 | 20728 | ||
| 20712 | /* If this is a new logical line, produce the glyphs for the line | 20729 | /* Produce the glyphs for the line number if needed. */ |
| 20713 | number. */ | 20730 | if (force |
| 20714 | if (this_line != last_line || !last_line || it->continuation_lines_width > 0) | 20731 | || !last_line |
| 20732 | || this_line != last_line | ||
| 20733 | || it->continuation_lines_width > 0 | ||
| 20734 | || (EQ (Vdisplay_line_numbers, Qrelative) && PT != it->w->last_point)) | ||
| 20715 | { | 20735 | { |
| 20716 | if (this_line != last_line || !last_line) | 20736 | if (this_line != last_line || !last_line) |
| 20717 | { | 20737 | { |
| @@ -20723,19 +20743,51 @@ maybe_produce_line_number (struct it *it) | |||
| 20723 | struct it tem_it; | 20743 | struct it tem_it; |
| 20724 | char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1]; | 20744 | char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1]; |
| 20725 | bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE ? true : false; | 20745 | bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE ? true : false; |
| 20746 | ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */ | ||
| 20747 | /* Compute point's line number if needed. */ | ||
| 20748 | if (EQ (Vdisplay_line_numbers, Qrelative) && !it->pt_lnum) | ||
| 20749 | { | ||
| 20750 | ptrdiff_t ignored; | ||
| 20751 | if (PT_BYTE > it->lnum_bytepos) | ||
| 20752 | it->pt_lnum = | ||
| 20753 | this_line + display_count_lines (it->lnum_bytepos, PT_BYTE, PT, | ||
| 20754 | &ignored); | ||
| 20755 | else | ||
| 20756 | it->pt_lnum = display_count_lines (BEGV_BYTE, PT_BYTE, PT, | ||
| 20757 | &ignored); | ||
| 20758 | } | ||
| 20726 | /* Compute the required width if needed. */ | 20759 | /* Compute the required width if needed. */ |
| 20727 | if (!it->lnum_width) | 20760 | if (!it->lnum_width) |
| 20728 | { | 20761 | { |
| 20729 | /* Max line number to be displayed cannot be more than the | 20762 | if (NATNUMP (Vdisplay_line_width)) |
| 20730 | one corresponding to the last row of the desired | 20763 | it->lnum_width = XFASTINT (Vdisplay_line_width); |
| 20731 | matrix. */ | 20764 | else |
| 20732 | ptrdiff_t max_lnum = | 20765 | { |
| 20733 | this_line + it->w->desired_matrix->nrows - 1 - it->vpos; | 20766 | /* Max line number to be displayed cannot be more than |
| 20734 | it->lnum_width = log10 (max_lnum) + 1; | 20767 | the one corresponding to the last row of the desired |
| 20768 | matrix. */ | ||
| 20769 | ptrdiff_t max_lnum; | ||
| 20770 | |||
| 20771 | if (EQ (Vdisplay_line_numbers, Qrelative)) | ||
| 20772 | /* We subtract one more because the current line is | ||
| 20773 | always zero under relative line-number display. */ | ||
| 20774 | max_lnum = it->w->desired_matrix->nrows - 2; | ||
| 20775 | else | ||
| 20776 | max_lnum = | ||
| 20777 | this_line + it->w->desired_matrix->nrows - 1 - it->vpos; | ||
| 20778 | it->lnum_width = log10 (max_lnum) + 1; | ||
| 20779 | } | ||
| 20735 | eassert (it->lnum_width > 0); | 20780 | eassert (it->lnum_width > 0); |
| 20736 | } | 20781 | } |
| 20737 | pint2str (lnum_buf, it->lnum_width, this_line + 1); | 20782 | if (EQ (Vdisplay_line_numbers, Qrelative)) |
| 20738 | /* Append a blank. */ | 20783 | lnum_offset = it->pt_lnum; |
| 20784 | |||
| 20785 | /* In L2R rows we need to append the blank separator, in R2L | ||
| 20786 | rows we need to prepend it. But this function is usually | ||
| 20787 | called when no display elements were produced from the | ||
| 20788 | following line, so the paragraph direction might be unknown. | ||
| 20789 | Therefore we cheat and add 2 blanks, one on either side. */ | ||
| 20790 | pint2str (lnum_buf, it->lnum_width + 1, eabs (this_line - lnum_offset)); | ||
| 20739 | strcat (lnum_buf, " "); | 20791 | strcat (lnum_buf, " "); |
| 20740 | 20792 | ||
| 20741 | /* Setup for producing the glyphs. */ | 20793 | /* Setup for producing the glyphs. */ |
| @@ -20745,12 +20797,12 @@ maybe_produce_line_number (struct it *it) | |||
| 20745 | scratch_glyph_row.reversed_p = false; | 20797 | scratch_glyph_row.reversed_p = false; |
| 20746 | scratch_glyph_row.used[TEXT_AREA] = 0; | 20798 | scratch_glyph_row.used[TEXT_AREA] = 0; |
| 20747 | SET_TEXT_POS (tem_it.position, 0, 0); | 20799 | SET_TEXT_POS (tem_it.position, 0, 0); |
| 20800 | tem_it.face_id = merge_faces (it->f, Qline_number, 0, DEFAULT_FACE_ID); | ||
| 20748 | tem_it.bidi_it.type = WEAK_EN; | 20801 | tem_it.bidi_it.type = WEAK_EN; |
| 20749 | /* According to UAX#9, EN goes up 2 levels in L2R paragraph and | 20802 | /* According to UAX#9, EN goes up 2 levels in L2R paragraph and |
| 20750 | 1 level in R2L paragraphs. Emulate that. */ | 20803 | 1 level in R2L paragraphs. Emulate that, assuming we are in |
| 20804 | an L2R paragraph. */ | ||
| 20751 | tem_it.bidi_it.resolved_level = 2; | 20805 | tem_it.bidi_it.resolved_level = 2; |
| 20752 | if (it->glyph_row && it->glyph_row->reversed_p) | ||
| 20753 | tem_it.bidi_it.resolved_level = 1; | ||
| 20754 | 20806 | ||
| 20755 | /* Produce glyphs for the line number in a scratch glyph_row. */ | 20807 | /* Produce glyphs for the line number in a scratch glyph_row. */ |
| 20756 | int n_glyphs_before; | 20808 | int n_glyphs_before; |
| @@ -20784,13 +20836,17 @@ maybe_produce_line_number (struct it *it) | |||
| 20784 | struct glyph *p = it->glyph_row ? it->glyph_row->glyphs[TEXT_AREA] : NULL; | 20836 | struct glyph *p = it->glyph_row ? it->glyph_row->glyphs[TEXT_AREA] : NULL; |
| 20785 | short *u = it->glyph_row ? &it->glyph_row->used[TEXT_AREA] : NULL; | 20837 | short *u = it->glyph_row ? &it->glyph_row->used[TEXT_AREA] : NULL; |
| 20786 | 20838 | ||
| 20787 | while (g < e) | 20839 | for ( ; g < e; g++) |
| 20788 | { | 20840 | { |
| 20789 | it->current_x += g->pixel_width; | 20841 | it->current_x += g->pixel_width; |
| 20790 | it->hpos++; | 20842 | /* The following is important when this function is called |
| 20843 | from move_it_in_display_line_to: HPOS is incremented only | ||
| 20844 | when we are in the visible portion of the glyph row. */ | ||
| 20845 | if (it->current_x > it->first_visible_x) | ||
| 20846 | it->hpos++; | ||
| 20791 | if (p) | 20847 | if (p) |
| 20792 | { | 20848 | { |
| 20793 | *p++ = *g++; | 20849 | *p++ = *g; |
| 20794 | (*u)++; | 20850 | (*u)++; |
| 20795 | } | 20851 | } |
| 20796 | } | 20852 | } |
| @@ -20922,13 +20978,13 @@ display_line (struct it *it, int cursor_vpos) | |||
| 20922 | 20978 | ||
| 20923 | /* Produce line number, if needed. */ | 20979 | /* Produce line number, if needed. */ |
| 20924 | if (!NILP (Vdisplay_line_numbers)) | 20980 | if (!NILP (Vdisplay_line_numbers)) |
| 20925 | maybe_produce_line_number (it); | 20981 | maybe_produce_line_number (it, false); |
| 20926 | } | 20982 | } |
| 20927 | else if (it->area == TEXT_AREA) | 20983 | else if (it->area == TEXT_AREA) |
| 20928 | { | 20984 | { |
| 20929 | /* Line numbers should precede the line-prefix or wrap-prefix. */ | 20985 | /* Line numbers should precede the line-prefix or wrap-prefix. */ |
| 20930 | if (!NILP (Vdisplay_line_numbers)) | 20986 | if (!NILP (Vdisplay_line_numbers)) |
| 20931 | maybe_produce_line_number (it); | 20987 | maybe_produce_line_number (it, false); |
| 20932 | 20988 | ||
| 20933 | /* We only do this when not calling move_it_in_display_line_to | 20989 | /* We only do this when not calling move_it_in_display_line_to |
| 20934 | above, because that function calls itself handle_line_prefix. */ | 20990 | above, because that function calls itself handle_line_prefix. */ |
| @@ -21090,7 +21146,7 @@ display_line (struct it *it, int cursor_vpos) | |||
| 21090 | { | 21146 | { |
| 21091 | /* Line numbers should precede the line-prefix or wrap-prefix. */ | 21147 | /* Line numbers should precede the line-prefix or wrap-prefix. */ |
| 21092 | if (!NILP (Vdisplay_line_numbers)) | 21148 | if (!NILP (Vdisplay_line_numbers)) |
| 21093 | maybe_produce_line_number (it); | 21149 | maybe_produce_line_number (it, false); |
| 21094 | 21150 | ||
| 21095 | pending_handle_line_prefix = false; | 21151 | pending_handle_line_prefix = false; |
| 21096 | handle_line_prefix (it); | 21152 | handle_line_prefix (it); |
| @@ -31778,6 +31834,9 @@ They are still logged to the *Messages* buffer. */); | |||
| 31778 | /* Name of the face used to highlight trailing whitespace. */ | 31834 | /* Name of the face used to highlight trailing whitespace. */ |
| 31779 | DEFSYM (Qtrailing_whitespace, "trailing-whitespace"); | 31835 | DEFSYM (Qtrailing_whitespace, "trailing-whitespace"); |
| 31780 | 31836 | ||
| 31837 | /* Name of the face used to display line numbers. */ | ||
| 31838 | DEFSYM (Qline_number, "line-number"); | ||
| 31839 | |||
| 31781 | /* Name and number of the face used to highlight escape glyphs. */ | 31840 | /* Name and number of the face used to highlight escape glyphs. */ |
| 31782 | DEFSYM (Qescape_glyph, "escape-glyph"); | 31841 | DEFSYM (Qescape_glyph, "escape-glyph"); |
| 31783 | 31842 | ||
| @@ -32297,6 +32356,15 @@ after each newline that comes from buffer text. */); | |||
| 32297 | Vdisplay_line_numbers = Qnil; | 32356 | Vdisplay_line_numbers = Qnil; |
| 32298 | DEFSYM (Qdisplay_line_numbers, "display-line-numbers"); | 32357 | DEFSYM (Qdisplay_line_numbers, "display-line-numbers"); |
| 32299 | Fmake_variable_buffer_local (Qdisplay_line_numbers); | 32358 | Fmake_variable_buffer_local (Qdisplay_line_numbers); |
| 32359 | DEFSYM (Qrelative, "relative"); | ||
| 32360 | |||
| 32361 | DEFVAR_LISP ("display-line-width", Vdisplay_line_width, | ||
| 32362 | doc: /* Minimum width of space reserved for line number display. | ||
| 32363 | A positive number means reserve that many columns for line numbers, | ||
| 32364 | even if the actual number needs less space. | ||
| 32365 | The default value of nil means compute the space dynamically. | ||
| 32366 | Any other value is treated as nil. */); | ||
| 32367 | Vdisplay_line_width = Qnil; | ||
| 32300 | 32368 | ||
| 32301 | DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay, | 32369 | DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay, |
| 32302 | doc: /* Non-nil means don't eval Lisp during redisplay. */); | 32370 | doc: /* Non-nil means don't eval Lisp during redisplay. */); |