From: Lars Ingebrigtsen Date: Sun, 7 Feb 2021 15:02:56 +0000 (+0100) Subject: Add a new function 'line-number-at-position' X-Git-Tag: emacs-28.0.90~3889 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=094a109b8eefbabbc99dba925ebec9887c101a91;p=emacs.git 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). --- 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))))