From: Eli Zaretskii Date: Thu, 6 Jul 2017 17:22:16 +0000 (+0300) Subject: Implement line numbers that disregard narrowing X-Git-Tag: emacs-26.0.90~518^2~156^2~2 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=25bc3911615d1160d47287c023545c6e0587739f;p=emacs.git Implement line numbers that disregard narrowing * src/xdisp.c (display_count_lines_logically): New function, counts line numbers disregarding narrowing. Suggested by Andy Moreton . (maybe_produce_line_number): Call display_count_lines_logically instead of display_count_lines. Adapt BEGV, ZV, etc. to display-line-numbers-widen. (syms_of_xdisp) : New buffer-local variable. * lisp/cus-start.el (standard): Provide a customization form for display-line-numbers-widen. * lisp/frame.el: Add display-line-numbers-widen, display-line-numbers-current-absolute, and display-line-number-width to the list of variables that should trigger redisplay of the current buffer. * doc/emacs/display.texi (Display Custom): Document display-line-numbers-widen. --- diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi index 61ca7e24f84..083fcdf97a6 100644 --- a/doc/emacs/display.texi +++ b/doc/emacs/display.texi @@ -1756,6 +1756,14 @@ zero. This is handy if you don't care about the number of the current line, and want to leave more horizontal space for text in large buffers. +@vindex display-line-numbers-widen +In a narrowed buffer (@pxref{Narrowing}) lines are normally numbered +starting at the beginning of the narrowing. However, if you customize +the variable @code{display-line-numbers-widen} to a non-@code{nil} +value, line numbers will disregard any narrowing and will start at the +first character of the buffer. + +@cindex line-number face The line numbers are displayed in a special face @code{line-number}. The current line number is displayed in a different face, @code{line-number-current-line}, so you can make the current line's diff --git a/lisp/cus-start.el b/lisp/cus-start.el index a89d5dff0cd..017e7f9fa55 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -608,7 +608,14 @@ since it could result in memory overflow and make Emacs crash." :value t) (const :tag "Display zero as number of current line" :value nil)) - "26.1") + "26.1") + (display-line-numbers-widen display + (choice + (const :tag "Disregard narrowing when calculating line numbers" + :value t) + (const :tag "Count lines from beinning of narrowed region" + :value nil)) + "26.1") ;; xfaces.c (scalable-fonts-allowed display boolean "22.1") ;; xfns.c diff --git a/lisp/frame.el b/lisp/frame.el index 8f51afa2a9a..f3e59edb2f5 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -2435,6 +2435,9 @@ See also `toggle-frame-maximized'." wrap-prefix truncate-lines display-line-numbers + display-line-number-width + display-line-numbers-current-absolute + display-line-numbers-widen bidi-paragraph-direction bidi-display-reordering)) diff --git a/src/xdisp.c b/src/xdisp.c index 312ee10f280..92ce1451867 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -20749,6 +20749,24 @@ find_row_edges (struct it *it, struct glyph_row *row, row->maxpos = it->current.pos; } +/* Like display_count_lines, but capable of counting outside of the + current narrowed region. */ +static ptrdiff_t +display_count_lines_logically (ptrdiff_t start_byte, ptrdiff_t limit_byte, + ptrdiff_t count, ptrdiff_t *byte_pos_ptr) +{ + if (!display_line_numbers_widen || (BEGV == BEG && ZV == Z)) + return display_count_lines (start_byte, limit_byte, count, byte_pos_ptr); + + ptrdiff_t val; + ptrdiff_t pdl_count = SPECPDL_INDEX (); + record_unwind_protect (save_restriction_restore, save_restriction_save ()); + Fwiden (); + val = display_count_lines (start_byte, limit_byte, count, byte_pos_ptr); + unbind_to (pdl_count, Qnil); + return val; +} + /* Count the number of screen lines in window IT->w between character position IT_CHARPOS(*IT) and the line showing that window's point. */ static ptrdiff_t @@ -20806,6 +20824,9 @@ maybe_produce_line_number (struct it *it) ptrdiff_t start_from, bytepos; ptrdiff_t this_line; bool first_time = false; + ptrdiff_t beg = display_line_numbers_widen ? BEG : BEGV; + ptrdiff_t beg_byte = display_line_numbers_widen ? BEG_BYTE : BEGV_BYTE; + ptrdiff_t z_byte = display_line_numbers_widen ? Z_BYTE : ZV_BYTE; void *itdata = bidi_shelve_cache (); if (EQ (Vdisplay_line_numbers, Qvisual)) @@ -20815,7 +20836,7 @@ maybe_produce_line_number (struct it *it) if (!last_line) { /* FIXME: Maybe reuse the data in it->w->base_line_number. */ - start_from = BEGV; + start_from = beg; if (!it->lnum_bytepos) first_time = true; } @@ -20825,17 +20846,17 @@ maybe_produce_line_number (struct it *it) /* Paranoia: what if someone changes the narrowing since the last time display_line was called? Shouldn't really happen, but who knows what some crazy Lisp invoked by :eval could do? */ - if (!(BEGV_BYTE <= start_from && start_from < ZV_BYTE)) + if (!(beg_byte <= start_from && start_from < z_byte)) { last_line = 0; - start_from = BEGV_BYTE; + start_from = beg_byte; } this_line = - last_line + display_count_lines (start_from, - IT_BYTEPOS (*it), IT_CHARPOS (*it), - &bytepos); - eassert (this_line > 0 || (this_line == 0 && start_from == BEGV_BYTE)); + last_line + display_count_lines_logically (start_from, + IT_BYTEPOS (*it), + IT_CHARPOS (*it), &bytepos); + eassert (this_line > 0 || (this_line == 0 && start_from == beg_byte)); eassert (bytepos == IT_BYTEPOS (*it)); } @@ -20863,11 +20884,11 @@ maybe_produce_line_number (struct it *it) ptrdiff_t ignored; if (PT_BYTE > it->lnum_bytepos && !EQ (Vdisplay_line_numbers, Qvisual)) it->pt_lnum = - this_line + display_count_lines (it->lnum_bytepos, PT_BYTE, PT, - &ignored); + this_line + display_count_lines_logically (it->lnum_bytepos, PT_BYTE, + PT, &ignored); else - it->pt_lnum = display_count_lines (BEGV_BYTE, PT_BYTE, PT, - &ignored); + it->pt_lnum = display_count_lines_logically (beg_byte, PT_BYTE, PT, + &ignored); } /* Compute the required width if needed. */ if (!it->lnum_width) @@ -32604,6 +32625,12 @@ This variable has effect only when `display-line-numbers' is either `relative' or `visual'. */); Vdisplay_line_numbers_current_absolute = Qt; + DEFVAR_BOOL ("display-line-numbers-widen", display_line_numbers_widen, + doc: /* Non-nil means display line numbers disregarding any narrowing. */); + display_line_numbers_widen = false; + DEFSYM (Qdisplay_line_numbers_widen, "display-line-numbers-widen"); + Fmake_variable_buffer_local (Qdisplay_line_numbers_widen); + DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay, doc: /* Non-nil means don't eval Lisp during redisplay. */); inhibit_eval_during_redisplay = false;