ErgoEmacsEmacsLispBlogEmacsLispBuy Tutorial
Web Hosting by 1&1

All About Processing Lines in Emacs Lisp

Xah Lee,

This page discuss issues about which emacs lisp functions to use for processing lines. ⁖ move cursor to end of line, to next line, grabbing the current line, etc. If you don't know elisp, first take a look at Emacs Lisp Basics.

In emacs, there are lots of ways to move or grab lines. In particular, in the first few years of my elisp experience, i find it confusing. Here are some functions or variables that are related to lines:

Do you know the differences? Also, there are issues such as:

Get Line Beginning/Ending Position

To get the position of line beginning/ending position, use:

(setq p1 (line-beginning-position) )
(setq p2 (line-end-position) )

These are written in C.

Move to Beginning/End of a Line

To move cursor to beginning or end of a line, use:

(beginning-of-line) ; better than (goto-char (line-beginning-position))
(end-of-line)       ; better than (goto-char (line-end-position))

These are written in C. So, they are much faster than other functions that are written in elisp.

They don't have problems when the line is at the beginning of buffer or end.

They work by EOL (end of line) character. That is, not screen line.

Do not use (search-forward "\n") for moving cursor to end of line. Because you'll have special cases if the line is at the end of buffer and doesn't have a EOL. It is also slower.

Do not use move-beginning-of-line or move-end-of-line. Because these are designed for interactive use.

Move to Previous/Next Line

To move by line, use:

(forward-line 1)
(forward-line -1)

These are written in C. They put the cursor to the beginning of previous/next line.

Do not use next-line or previous-line. Because these are for interactive use. Their behavior changes depending on the variable line-move-visual.

Grab the Current Line

To grab current line, use:

(let (p1 p2 myLine)
  (setq p1 (line-beginning-position) )
  (setq p2 (line-end-position) )
  (setq myLine (buffer-substring-no-properties p1 p2))
)

Do not use (thing-at-point 'line). Normally, thing-at-point will include the EOL char, but if the line is at the end of buffer, then it won't. So, if you use it, you have to do extra work to detect special cases. Also, thing-at-point is complex elisp code and is slower. 〔☛ Emacs thing-at-point and Chaining Functions

Get All Lines in a File into a List

To read a whole file into a list of lines, you can use this code:

(defun read-lines (file)
  "Return a list of lines in FILE."
  (with-temp-buffer
    (insert-file-contents file)
    (split-string
     (buffer-string) "\n" t)
    ) )

See also: Process a File line-by-line in Emacs Lisp.

Screen Lines

If you want to move cursor across lines as defined by the screen, you can use these.

line-move-visual is a variable that controls whether next-line and previous-line move by EOL or screen.

Misc

Note that in emacs buffer, all EOL are represented by "\n". So, if you need to use (search-forward "\n"), you don't have to worry about whether the file uses unix or Windows line endings. 〔☛ Emacs: Newline Representations ^M ^J ^L

Thanks to Uday S Reddy and Alan Mackenzie for some tips.

blog comments powered by Disqus