All About Processing Lines in Emacs Lisp

Perm url with updates: http://xahlee.org/emacs/elisp_all_about_lines.html

All About Processing Lines in Emacs Lisp

Xah Lee, 2010-06-08

This page discuss issues about which emacs lisp functions to use for processing lines. e.g. move cursor to 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:

line-beginning-position
line-end-position
move-beginning-of-line
move-end-of-line
forward-line
next-line
previous-line
(search-forward "\n")
(search-backward "\n")
(thing-at-point 'line)
line-move-visual

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

  • Is a line defined by End Of Line (EOL) char or screen line?
  • When grabbing a line, does it includes the EOL?
  • What happens if the line is at end of buffer, or beginning?
  • Which is faster?

If you are not sure, this article helps.

Moving to Beginning/End of a Line

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

(goto-char (line-beginning-position))
(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")”. 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 more for interactive use.

Moving to Previous/Next Line

To move by line, use

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

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

Grabbing 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)”, because thing-at-point have problems when the line is at the end of buffer. 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, it makes you do extra work to detect special cases. Also, thing-at-point is complex elisp code and is slower.

Get All Lines In a File Into a List

See: How To Process A File Line By Line In Elisp.

Screen Lines

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

next-line
previous-line
line-move-visual

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 line endings 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.

See also: Emacs Line Return and Windows, Unix, Mac, All That ^M ^J ^L.

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

Popular posts from this blog

11 Years of Writing About Emacs

does md5 creates more randomness?

Google Code shutting down, future of ErgoEmacs