ELisp: Line Number Problem

By Xah Lee. Date: . Last updated: .

in emacs, the cursor position is the number of chars from beginning of file or buffer. A position is considered to be between characters. Count start at 1.

To get the position, use point

In most other editors, cursor position is specified as line number and column number. (at least in user interface. Am not sure if line/column number is used in implementation, or if it uses count of character same as emacs.)

in emacs, you can also get line number and column number, however, the functions doing that is not native. Meaning, much slowier.

The particular problem is getting the line number.

there are these functions to get line number:

they all call count-lines.

count-lines is fairly complex. It works by counting the number of newline character, but involves narrow-to-region, save-restriction, and save-excursion.

(defun count-lines (start end)
  "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."
  (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)))))))

obviously, you don't want to call count-lines frequently, such as on every line.

this seems kinda slow and bloated. I wonder how other editors do it.

here's function to get cursor position and column number:

here's functions to jump to by position, line number, column number: