>From 68fb034a60f74ea3cab9acd8e35bdf52ba9d5024 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Thu, 3 Aug 2023 22:24:57 -0700 Subject: [PATCH] [POC] Honor invisible text-prop list values in count-lines * lisp/simple.el (count-lines): Use `invisible-p' when `ignore-invisible-lines' parameter is non-nil. * test/lisp/simple-tests.el (simple-tests-count-lines/invisible/interval, simple-tests-count-lines/invisible/list/single, simple-tests-count-lines/invisible/list/tail): Add tests. (Bug#23675) --- lisp/simple.el | 19 ++++-------- test/lisp/simple-tests.el | 62 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 14 deletions(-) diff --git a/lisp/simple.el b/lisp/simple.el index 6dc08ff0eb0..5c414fb364f 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1782,20 +1782,11 @@ count-lines done)))) (ignore-invisible-lines (goto-char (point-min)) - (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)))) + (let ((count (if (eobp) 0 1))) + (while (and (zerop (forward-line)) (not (eobp))) + (unless (invisible-p (1- (point))) + (cl-incf count))) + count)) (t (goto-char (point-max)) (if (bolp) diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el index 7dabb735522..e8e83c9a5cd 100644 --- a/test/lisp/simple-tests.el +++ b/test/lisp/simple-tests.el @@ -67,6 +67,68 @@ simple-test-count-lines/ignore-invisible-lines (insert (propertize "\nbar\nbaz\nzut" 'invisible t)) (should (= (count-lines (point-min) (point-max) t) 2)))) +(ert-deftest simple-tests-count-lines/invisible/interval () + (with-current-buffer (get-buffer-create "*count-lines/invisible/interval*") + (should (= 0 (count-lines (point-min) (point-max) t))) ; invisible + (insert "pre\n" + "before\n" + (propertize "0\n" 'invisible t) + (propertize "1\n" 'invisible t) + (propertize "2\n" 'invisible t) + (propertize "3\n" 'invisible t) + "after\n" + "post\n") + (should (equal buffer-invisibility-spec 't)) + (with-restriction 5 (- (point-max) 5) + (goto-char (point-min)) + (should (looking-at "before")) + (goto-char (point-max)) + (should (looking-back "after\n"))) + (should (= 6 (count-lines 5 (- (point-max) 5)))) + (should (= 2 (count-lines 5 (- (point-max) 5) t))) ; invisible + (when noninteractive (kill-buffer)))) + +(ert-deftest simple-tests-count-lines/invisible/list/single () + (with-current-buffer (get-buffer-create "*count-lines/invisible/list/head*") + (insert "before\n" + (propertize "0\n" 'invisible '(0)) + (propertize "1\n" 'invisible '(1)) + (propertize "2\n" 'invisible '(2)) + (propertize "3\n" 'invisible '(3)) + "after\n") + (setq buffer-invisibility-spec '(0 1 (2 . t) 3 t)) + (should (= 6 (count-lines (point-min) (point-max)))) + (should (= 2 (count-lines (point-min) (point-max) t))) ; invisible + (when noninteractive (kill-buffer))) + + (with-current-buffer (get-buffer-create "*count-lines/invisible/list/alt*") + (insert "before\n" + (propertize "0\n" 'invisible '(0)) + "a\n" + (propertize "1\n" 'invisible '(1)) + "b\n" + (propertize "2\n" 'invisible '(2)) + "c\n" + (propertize "3\n" 'invisible '(3)) + "after\n") + (setq buffer-invisibility-spec '(0 1 (2 . t) 3 t)) + (should (= 9 (count-lines (point-min) (point-max)))) + (should (= 5 (count-lines (point-min) (point-max) t))) ; invisible + (when noninteractive (kill-buffer)))) + +(ert-deftest simple-tests-count-lines/invisible/list/tail () + (with-current-buffer (get-buffer-create "*count-lines/invisible/list/tail*") + (insert "before\n" + (propertize "0\n" 'invisible '(x 0)) + (propertize "1\n" 'invisible '(x 1)) + (propertize "2\n" 'invisible '(x 2)) + (propertize "3\n" 'invisible '(x 3)) + "after\n") + (setq buffer-invisibility-spec '(0 (1 . t) 2 3 t)) + (should (= 6 (count-lines (point-min) (point-max)))) + (should (= 2 (count-lines (point-min) (point-max) t))) ; invisible + (when noninteractive (kill-buffer)))) + (ert-deftest simple-text-count-lines-non-ascii () (with-temp-buffer (insert "あ\nい\nう\nえ\nお\n") -- 2.41.0