summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Ingebrigtsen <larsi@gnus.org>2021-02-07 16:02:56 +0100
committerLars Ingebrigtsen <larsi@gnus.org>2021-02-07 16:03:02 +0100
commit094a109b8eefbabbc99dba925ebec9887c101a91 (patch)
treede1959ee43a6a1b8bda4de6b4ec781a8eccdd0a3
parent4e8d36fdaadade020f0bcadc70d617d8b07b739c (diff)
downloademacs-094a109b8eefbabbc99dba925ebec9887c101a91.tar.gz
Add a new function 'line-number-at-position'
* doc/lispref/positions.texi (Text Lines): Document it. * lisp/simple.el (count-lines): Use it. (line-number-at-pos): Ditto. * src/fns.c (Fline_number_at_position): New function (bug#22763).
-rw-r--r--doc/lispref/positions.texi18
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/simple.el17
-rw-r--r--src/fns.c18
-rw-r--r--test/src/fns-tests.el8
5 files changed, 46 insertions, 19 deletions
diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi
index dc0c7442d8d..9adce21baec 100644
--- a/doc/lispref/positions.texi
+++ b/doc/lispref/positions.texi
@@ -437,16 +437,18 @@ prints a message reporting the number of lines, words, and characters
in the buffer, or in the region if the region is active.
@end deffn
+@defun line-number-at-position pos
+This function returns the line number in the current buffer
+corresponding to the buffer position @var{pos}. If narrowing is in
+effect, this is the line number in the visible part of the buffer.
+@end defun
+
@defun line-number-at-pos &optional pos absolute
@cindex line number
-This function returns the line number in the current buffer
-corresponding to the buffer position @var{pos}. If @var{pos} is
-@code{nil} or omitted, the current buffer position is used. If
-@var{absolute} is @code{nil}, the default, counting starts at
-@code{(point-min)}, so the value refers to the contents of the
-accessible portion of the (potentially narrowed) buffer. If
-@var{absolute} is non-@code{nil}, ignore any narrowing and return
-the absolute line number.
+This function is like @code{line-number-at-position}, but if @var{pos}
+is @code{nil} or omitted, the current buffer position is used. In
+addition, if @var{absolute} is non-@code{nil}, ignore any narrowing
+and return the absolute line number.
@end defun
@ignore
diff --git a/etc/NEWS b/etc/NEWS
index 0faed3e5aa2..93a60bf14cf 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2192,6 +2192,10 @@ back in Emacs 23.1. The affected functions are: 'make-obsolete',
* Lisp Changes in Emacs 28.1
++++
+** New function 'line-number-at-position'.
+This returns the line number in the visible portion of the buffer.
+
---
** New variable 'indent-line-ignored-functions'.
This allows modes to cycle through a set of indentation functions
diff --git a/lisp/simple.el b/lisp/simple.el
index e4a363a9a59..eab2ac25691 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1472,7 +1472,7 @@ included in the count."
(assq prop buffer-invisibility-spec)))
(setq invisible-count (1+ invisible-count))))
invisible-count))))
- (t (- (buffer-size) (forward-line (buffer-size))))))))
+ (t (1- (line-number-at-position (point-max))))))))
(defun line-number-at-pos (&optional pos absolute)
"Return buffer line number at position POS.
@@ -1483,16 +1483,11 @@ at (point-min), so the value refers to the contents of the
accessible portion of the (potentially narrowed) buffer. If
ABSOLUTE is non-nil, ignore any narrowing and return the
absolute line number."
- (save-restriction
- (when absolute
- (widen))
- (let ((opoint (or pos (point))) start)
- (save-excursion
- (goto-char (point-min))
- (setq start (point))
- (goto-char opoint)
- (forward-line 0)
- (1+ (count-lines start (point)))))))
+ (if absolute
+ (save-restriction
+ (widen)
+ (line-number-at-position (or pos (point))))
+ (line-number-at-position (or pos (point)))))
(defcustom what-cursor-show-names nil
"Whether to show character names in `what-cursor-position'."
diff --git a/src/fns.c b/src/fns.c
index bd4afa0c4e9..479a5975ce7 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -5758,6 +5758,23 @@ in OBJECT. */)
traverse_intervals (intervals, 0, collect_interval, collector);
return CDR (collector);
}
+
+DEFUN ("line-number-at-position", Fline_number_at_position,
+ Sline_number_at_position, 1, 1, 0,
+ doc: /* Return the line number at POSITION.
+If the buffer is narrowed, the position returned is the position in the
+visible part of the buffer. */)
+ (register Lisp_Object position)
+{
+ CHECK_FIXNUM (position);
+ ptrdiff_t pos = XFIXNUM (position);
+
+ /* Check that POSITION is n the visible range of the buffer. */
+ if (pos < BEGV || pos > ZV)
+ args_out_of_range (make_int (BEGV), make_int (ZV));
+
+ return make_int (count_lines (BEGV_BYTE, CHAR_TO_BYTE (pos)) + 1);
+}
void
@@ -5800,6 +5817,7 @@ syms_of_fns (void)
defsubr (&Sdefine_hash_table_test);
defsubr (&Sstring_search);
defsubr (&Sobject_intervals);
+ defsubr (&Sline_number_at_position);
/* Crypto and hashing stuff. */
DEFSYM (Qiv_auto, "iv-auto");
diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el
index e0aed2a71b6..3a43142106b 100644
--- a/test/src/fns-tests.el
+++ b/test/src/fns-tests.el
@@ -1098,3 +1098,11 @@
(goto-char (point-max))
(insert "fóo")
(should (approx-equal (buffer-line-statistics) '(1002 50 49.9)))))
+
+(ert-deftest test-line-number-at-position ()
+ (with-temp-buffer
+ (insert (make-string 10 ?\n))
+ (should (= (line-number-at-position (point)) 11))
+ (should-error (line-number-at-position nil))
+ (should-error (line-number-at-position -1))
+ (should-error (line-number-at-position 100))))