1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
# 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.
<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-generate-toc again -->
**Table of Contents**
- [loop.el --- friendly imperative loop structures for Emacs lisp](#loopel-----friendly-imperative-loop-structures-for-emacs-lisp)
- [Contents](#contents)
- [loop-while](#loop-while)
- [loop-do-while](#loop-do-while)
- [loop-until](#loop-until)
- [loop-for-each](#loop-for-each)
- [loop-for-each-line](#loop-for-each-line)
- [loop-break](#loop-break)
- [loop-continue](#loop-continue)
- [Alternatives](#alternatives)
- [Changelog](#changelog)
- [Running the tests](#running-the-tests)
<!-- markdown-toc end -->
## Contents
### loop-while
Repeatedly evaluate BODY while CONDITION is non-nil.
`loop-while` `(condition body...)`
Example:
``` lisp
(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:
``` lisp
(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:
``` lisp
(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:
``` lisp
(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:
``` lisp
;; 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:
``` lisp
(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))))
```
### 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:
``` lisp
(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` and `dolist` are built-in loop structures
* The `cl-loop` macro in `cl-lib`
* `-each` in [dash.el](https://github.com/magnars/dash.el)
## Changelog
* v1.3 `loop-for-each-line` now works even if point moves
around. Inside `loop-for-each-line`, `it` is now set to the current
line. Added `loop-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
|