emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 4d4d3e4: Allow count-lines to ignore invisible lines


From: Lars Ingebrigtsen
Subject: master 4d4d3e4: Allow count-lines to ignore invisible lines
Date: Tue, 11 Aug 2020 10:52:27 -0400 (EDT)

branch: master
commit 4d4d3e42caca5d823dd66b62f25a1bdd833ba484
Author: Robert Weiner <rsw@gnu.org>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    Allow count-lines to ignore invisible lines
    
    * doc/lispref/positions.texi (Text Lines): Document it (bug#23675).
    
    * lisp/simple.el (count-lines): Add an optional parameter to
    ignore invisible lines (bug#23675).
---
 doc/lispref/positions.texi |  5 ++++-
 etc/NEWS                   |  4 ++++
 lisp/simple.el             | 53 +++++++++++++++++++++++++++++++---------------
 3 files changed, 44 insertions(+), 18 deletions(-)

diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi
index d7856ce..9141970 100644
--- a/doc/lispref/positions.texi
+++ b/doc/lispref/positions.texi
@@ -411,7 +411,7 @@ function counts that line as one line successfully moved.
 In an interactive call, @var{count} is the numeric prefix argument.
 @end deffn
 
-@defun count-lines start end
+@defun count-lines start end &optional ignore-invisible-lines
 @cindex lines in region
 @anchor{Definition of count-lines}
 This function returns the number of lines between the positions
@@ -420,6 +420,9 @@ This function returns the number of lines between the 
positions
 1, even if @var{start} and @var{end} are on the same line.  This is
 because the text between them, considered in isolation, must contain at
 least one line unless it is empty.
+
+If the optional @var{ignore-invisible-lines} is non-@code{nil},
+invisible lines will not be included in the count.
 @end defun
 
 @deffn Command count-words start end
diff --git a/etc/NEWS b/etc/NEWS
index f914e1b..5c44c97 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -868,6 +868,10 @@ have now been removed.
 
 * Lisp Changes in Emacs 28.1
 
++++
+** The 'count-lines' function now takes an optional parameter to
+ignore invisible lines.
+
 ---
 ** New function 'custom-add-choice'.
 This function can be used by modes to add elements to the
diff --git a/lisp/simple.el b/lisp/simple.el
index 4d59108..6f72c3b 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1366,28 +1366,47 @@ END, without printing any message."
          (message "line %d (narrowed line %d)"
                   (+ n (line-number-at-pos start) -1) n))))))
 
-(defun count-lines (start end)
+(defun count-lines (start end &optional ignore-invisible-lines)
   "Return number of lines between START and END.
-This is usually the number of newlines between them,
-but can be one more if START is not equal to END
-and the greater of them is not at the start of a line."
+This is usually the number of newlines between them, but can be
+one more if START is not equal to END and the greater of them is
+not at the start of a line.
+
+When IGNORE-INVISIBLE-LINES is non-nil, invisible lines are not
+included in the count."
   (save-excursion
     (save-restriction
       (narrow-to-region start end)
       (goto-char (point-min))
-      (if (eq selective-display t)
-         (save-match-data
-           (let ((done 0))
-                     (while (re-search-forward "[\n\C-m]" nil t 40)
-                       (setq done (+ 40 done)))
-                     (while (re-search-forward "[\n\C-m]" nil t 1)
-                       (setq done (+ 1 done)))
-                     (goto-char (point-max))
-                     (if (and (/= start end)
-                      (not (bolp)))
-                 (1+ done)
-               done)))
-       (- (buffer-size) (forward-line (buffer-size)))))))
+      (cond ((and (not ignore-invisible-lines)
+                  (eq selective-display t))
+            (save-match-data
+              (let ((done 0))
+                (while (re-search-forward "\n\\|\r[^\n]" nil t 40)
+                  (setq done (+ 40 done)))
+                (while (re-search-forward "\n\\|\r[^\n]" nil t 1)
+                  (setq done (+ 1 done)))
+                (goto-char (point-max))
+                (if (and (/= start end)
+                         (not (bolp)))
+                    (1+ done)
+                  done))))
+           (ignore-invisible-lines
+            (save-match-data
+              (- (buffer-size)
+                  (forward-line (buffer-size))
+                 (let ((invisible-count 0)
+                       prop)
+                   (goto-char (point-min))
+                   (while (re-search-forward "\n\\|\r[^\n]" nil t)
+                     (setq prop (get-char-property (1- (point)) 'invisible))
+                     (if (if (eq buffer-invisibility-spec t)
+                             prop
+                           (or (memq prop buffer-invisibility-spec)
+                               (assq prop buffer-invisibility-spec)))
+                         (setq invisible-count (1+ invisible-count))))
+                   invisible-count))))
+           (t (- (buffer-size) (forward-line (buffer-size))))))))
 
 (defun line-number-at-pos (&optional pos absolute)
   "Return buffer line number at position POS.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]