]> git.eshelyaron.com Git - emacs.git/commitdiff
Implement line numbers that disregard narrowing
authorEli Zaretskii <eliz@gnu.org>
Thu, 6 Jul 2017 17:22:16 +0000 (20:22 +0300)
committerEli Zaretskii <eliz@gnu.org>
Thu, 6 Jul 2017 17:22:16 +0000 (20:22 +0300)
* src/xdisp.c (display_count_lines_logically): New function,
counts line numbers disregarding narrowing.  Suggested by Andy
Moreton <andrewjmoreton@gmail.com>.
(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) <display-line-numbers-widen>: 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.

doc/emacs/display.texi
lisp/cus-start.el
lisp/frame.el
src/xdisp.c

index 61ca7e24f84919aac745d71e4e621830b92369e7..083fcdf97a64c85479a0e550f90ed6dae2643038 100644 (file)
@@ -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
index a89d5dff0cd7edae71bfcc7695f286ffe283e079..017e7f9fa55f43717a8a1992b71b6753be5baeeb 100644 (file)
@@ -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
index 8f51afa2a9a2d08d4e18cb857fe20884f5e45252..f3e59edb2f5ab8ed0302497f19a6833ac8586bca 100644 (file)
@@ -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))
 
index 312ee10f280f1c172a580251b5d5d1aab25826bf..92ce1451867f7153290721f85b4b413e530f3374 100644 (file)
@@ -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;