loop.el --- friendly imperative loop structures for Emacs lisp
Emacs lisp is missing loop structures familiar to users of newer languages. This library adds a selection of popular loop structures as well as break and continue.
loop.el also has full unit tests.
Table of Contents
Contents
loop-while
Repeatedly evaluate BODY while CONDITION is non-nil.
loop-while
(condition body...)
Example:
(let ((x 0)
(sum 0))
;; sum the numbers 0 to 9
(loop-while (< x 10)
(setq sum (+ sum x))
(setq x (1+ x))))
loop-do-while
Evaluate BODY, then repeatedly BODY while CONDITION is non-nil.
loop-do-while
(condition body...)
Example:
(let ((x 0)
(sum 0))
;; our condition is false on the first iteration
(loop-do-while (and (> x 0) (< x 10))
(setq sum (+ sum x))
(setq x (1+ x))))
loop-until
Repeatedly evaluate BODY until CONDITION is non-nil.
loop-until
(condition body...)
Example:
(let ((x 0)
(sum 0))
;; sum the numbers 0 to 9
(loop-until (= x 10)
(setq sum (+ sum x))
(setq x (1+ x))))
loop-for-each
For every item in LIST, evaluate BODY with VAR bound to that item.
loop-for-each
(var list body...)
Example:
(let ((sum 0))
(loop-for-each x (list 1 2 3 4 5 6 7 8 9)
(setq sum (+ sum x))))
loop-for-each-line
For every line in the buffer, put point at the start of the line and execute BODY.
loop-for-each-loop
(body...)
Example:
;; Count headings in a markdown buffer.
(let ((heading-count 0))
(loop-for-each-line
(when (looking-at "#")
(setq heading-count (+ heading 1))))
loop-break
Terminate evaluation of a loop-while
, loop-do-while
,
loop-for-each
, or loop-for-each-line
block. If there are nested
loops, breaks out of the innermost loop.
loop-break
()
Example:
(let ((sum 0))
;; sum the numbers 1 to 5
(loop-for-each x (list 1 2 3 4 5 6 7 8 9)
(setq sum (+ sum x))
(when (= x 5)
(loop-break)))
sum)
loop-continue
Skip the rest of the current loop-while
, loop-do-while
, or
loop-for-each
block and continue to the next iteration. If there
are nested loops, applies to the innermost loop.
loop-continue
()
Example:
(let ((sum 0))
;; sum the numbers 1, 3, 4, 5
(loop-for-each x (list 1 2 3 4 5)
(when (= x 2)
(loop-continue))
(setq sum (+ sum x))))
Alternatives
while
anddolist
are built-in loop structures- The
cl-loop
macro incl-lib
-each
in dash.el
Changelog
- v1.3
loop-for-each-line
now works even if point moves around. Insideloop-for-each-line
,it
is now set to the current line. Addedloop-return
. - v1.2 Added
loop-for-each-line
. Also added edebug support, so you can step through loops in loop.el. - v1.1 Added
loop-continue
- v1.0
loop-for-each
now takes three arguments:(VAR LIST BODY...)
- v0.3 Added
loop-until
- v0.2 Basic working implementation
Running the tests
M-x loop-run-tests