comparison lisp/emacs-lisp/ewoc.el @ 71052:529644115612

(ewoc--current-dll): Remove. Basically undo the change of 2006-05-26: use extra arguments instead of dynamic scoping. (ewoc-locate): Remove unused var `footer'.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Mon, 29 May 2006 04:39:46 +0000
parents bf1f0ff1e25e
children 1d4b1a32fd66 a8190f7e546e
comparison
equal deleted inserted replaced
71051:bf1f0ff1e25e 71052:529644115612
99 99
100 ;;; Code: 100 ;;; Code:
101 101
102 (eval-when-compile (require 'cl)) 102 (eval-when-compile (require 'cl))
103 103
104 ;; The doubly linked list is implemented as a circular list 104 ;; The doubly linked list is implemented as a circular list with a dummy
105 ;; with a dummy node first and last. The dummy node is used as 105 ;; node first and last. The dummy node is used as "the dll".
106 ;; "the dll" (or rather the dynamically bound `ewoc--current-dll').
107
108 (defvar ewoc--current-dll)
109
110 (defstruct (ewoc--node 106 (defstruct (ewoc--node
111 (:type vector) ;ewoc--node-nth needs this 107 (:type vector) ;ewoc--node-nth needs this
112 (:constructor nil) 108 (:constructor nil)
113 (:constructor ewoc--node-create (start-marker data))) 109 (:constructor ewoc--node-create (start-marker data)))
114 left right data start-marker) 110 left right data start-marker)
115 111
116 (defun ewoc--node-next (node) 112 (defun ewoc--node-next (dll node)
117 "Return the node after NODE, or nil if NODE is the last node." 113 "Return the node after NODE, or nil if NODE is the last node."
118 (let ((R (ewoc--node-right node))) 114 (let ((R (ewoc--node-right node)))
119 (unless (eq ewoc--current-dll R) R))) 115 (unless (eq dll R) R)))
120 116
121 (defun ewoc--node-prev (node) 117 (defun ewoc--node-prev (dll node)
122 "Return the node before NODE, or nil if NODE is the first node." 118 "Return the node before NODE, or nil if NODE is the first node."
123 (let ((L (ewoc--node-left node))) 119 (let ((L (ewoc--node-left node)))
124 (unless (eq ewoc--current-dll L) L))) 120 (unless (eq dll L) L)))
125 121
126 (defun ewoc--node-nth (n) 122 (defun ewoc--node-nth (dll n)
127 "Return the Nth node from the doubly linked list `ewoc--current-dll'. 123 "Return the Nth node from the doubly linked list `dll'.
128 N counts from zero. If N is negative, return the -(N+1)th last element. 124 N counts from zero. If N is negative, return the -(N+1)th last element.
129 If N is out of range, return nil. 125 If N is out of range, return nil.
130 Thus, (ewoc--node-nth 0) returns the first node, 126 Thus, (ewoc--node-nth dll 0) returns the first node,
131 and (ewoc--node-nth -1) returns the last node." 127 and (ewoc--node-nth dll -1) returns the last node."
132 ;; Presuming a node is ":type vector", starting with `left' and `right': 128 ;; Presuming a node is ":type vector", starting with `left' and `right':
133 ;; Branch 0 ("follow left pointer") is used when n is negative. 129 ;; Branch 0 ("follow left pointer") is used when n is negative.
134 ;; Branch 1 ("follow right pointer") is used otherwise. 130 ;; Branch 1 ("follow right pointer") is used otherwise.
135 (let* ((branch (if (< n 0) 0 1)) 131 (let* ((branch (if (< n 0) 0 1))
136 (node (aref ewoc--current-dll branch))) 132 (node (aref dll branch)))
137 (if (< n 0) (setq n (- -1 n))) 133 (if (< n 0) (setq n (- -1 n)))
138 (while (and (not (eq ewoc--current-dll node)) (> n 0)) 134 (while (and (not (eq dll node)) (> n 0))
139 (setq node (aref node branch)) 135 (setq node (aref node branch))
140 (setq n (1- n))) 136 (setq n (1- n)))
141 (unless (eq ewoc--current-dll node) node))) 137 (unless (eq dll node) node)))
142 138
143 (defun ewoc-location (node) 139 (defun ewoc-location (node)
144 "Return the start location of NODE." 140 "Return the start location of NODE."
145 (ewoc--node-start-marker node)) 141 (ewoc--node-start-marker node))
146 142
153 (:conc-name ewoc--)) 149 (:conc-name ewoc--))
154 buffer pretty-printer header footer dll last-node hf-pp) 150 buffer pretty-printer header footer dll last-node hf-pp)
155 151
156 (defmacro ewoc--set-buffer-bind-dll-let* (ewoc varlist &rest forms) 152 (defmacro ewoc--set-buffer-bind-dll-let* (ewoc varlist &rest forms)
157 "Execute FORMS with ewoc--buffer selected as current buffer, 153 "Execute FORMS with ewoc--buffer selected as current buffer,
158 `ewoc--current-dll' bound to the dll, and VARLIST bound as in a let*. 154 `dll' bound to the dll, and VARLIST bound as in a let*.
159 `ewoc--current-dll' will be bound when VARLIST is initialized, but 155 `dll' will be bound when VARLIST is initialized, but
160 the current buffer will *not* have been changed. 156 the current buffer will *not* have been changed.
161 Return value of last form in FORMS." 157 Return value of last form in FORMS."
162 (let ((hnd (make-symbol "ewoc"))) 158 (let ((hnd (make-symbol "ewoc")))
163 `(let* ((,hnd ,ewoc) 159 `(let* ((,hnd ,ewoc)
164 (ewoc--current-dll (ewoc--dll ,hnd)) 160 (dll (ewoc--dll ,hnd))
165 ,@varlist) 161 ,@varlist)
166 (with-current-buffer (ewoc--buffer ,hnd) 162 (with-current-buffer (ewoc--buffer ,hnd)
167 ,@forms)))) 163 ,@forms))))
168 164
169 (defmacro ewoc--set-buffer-bind-dll (ewoc &rest forms) 165 (defmacro ewoc--set-buffer-bind-dll (ewoc &rest forms)
174 BUT if it is the header or the footer in EWOC return nil instead." 170 BUT if it is the header or the footer in EWOC return nil instead."
175 (unless (or (eq node (ewoc--header ewoc)) 171 (unless (or (eq node (ewoc--header ewoc))
176 (eq node (ewoc--footer ewoc))) 172 (eq node (ewoc--footer ewoc)))
177 node)) 173 node))
178 174
179 (defun ewoc--adjust (beg end node) 175 (defun ewoc--adjust (beg end node dll)
180 ;; "Manually reseat" markers for NODE and its successors (including footer 176 ;; "Manually reseat" markers for NODE and its successors (including footer
181 ;; and dll), in the case where they originally shared start position with 177 ;; and dll), in the case where they originally shared start position with
182 ;; BEG, to END. BEG and END are buffer positions describing NODE's left 178 ;; BEG, to END. BEG and END are buffer positions describing NODE's left
183 ;; neighbor. This operation is functionally equivalent to temporarily 179 ;; neighbor. This operation is functionally equivalent to temporarily
184 ;; setting these nodes' markers' insertion type to t around the pretty-print 180 ;; setting these nodes' markers' insertion type to t around the pretty-print
185 ;; call that precedes the call to `ewoc--adjust', and then changing them back 181 ;; call that precedes the call to `ewoc--adjust', and then changing them back
186 ;; to nil. 182 ;; to nil.
187 (when (< beg end) 183 (when (< beg end)
188 (let (m) 184 (let (m)
189 (while (and (= beg (setq m (ewoc--node-start-marker node))) 185 (while (and (= beg (setq m (ewoc--node-start-marker node)))
186 ;; The "dummy" node `dll' actually holds the marker that
187 ;; points to the end of the footer, so we check `dll'
188 ;; *after* reseating the marker.
190 (progn 189 (progn
191 (set-marker m end) 190 (set-marker m end)
192 (not (eq ewoc--current-dll node)))) 191 (not (eq dll node))))
193 (setq node (ewoc--node-right node)))))) 192 (setq node (ewoc--node-right node))))))
194 193
195 (defun ewoc--insert-new-node (node data pretty-printer) 194 (defun ewoc--insert-new-node (node data pretty-printer)
196 "Insert before NODE a new node for DATA, displayed by PRETTY-PRINTER. 195 "Insert before NODE a new node for DATA, displayed by PRETTY-PRINTER.
197 Call PRETTY-PRINTER with point at NODE's start, thus pushing back 196 Call PRETTY-PRINTER with point at NODE's start, thus pushing back
201 (copy-marker (ewoc--node-start-marker node)) data))) 200 (copy-marker (ewoc--node-start-marker node)) data)))
202 (setf (ewoc--node-left elemnode) (ewoc--node-left node) 201 (setf (ewoc--node-left elemnode) (ewoc--node-left node)
203 (ewoc--node-right elemnode) node 202 (ewoc--node-right elemnode) node
204 (ewoc--node-right (ewoc--node-left node)) elemnode 203 (ewoc--node-right (ewoc--node-left node)) elemnode
205 (ewoc--node-left node) elemnode) 204 (ewoc--node-left node) elemnode)
206 (ewoc--refresh-node pretty-printer elemnode) 205 (ewoc--refresh-node pretty-printer elemnode dll)
207 elemnode))) 206 elemnode)))
208 207
209 (defun ewoc--refresh-node (pp node) 208 (defun ewoc--refresh-node (pp node dll)
210 "Redisplay the element represented by NODE using the pretty-printer PP." 209 "Redisplay the element represented by NODE using the pretty-printer PP."
211 (let ((inhibit-read-only t) 210 (let ((inhibit-read-only t)
212 (m (ewoc--node-start-marker node)) 211 (m (ewoc--node-start-marker node))
213 (R (ewoc--node-right node))) 212 (R (ewoc--node-right node)))
214 ;; First, remove the string from the buffer: 213 ;; First, remove the string from the buffer:
215 (delete-region m (ewoc--node-start-marker R)) 214 (delete-region m (ewoc--node-start-marker R))
216 ;; Calculate and insert the string. 215 ;; Calculate and insert the string.
217 (goto-char m) 216 (goto-char m)
218 (funcall pp (ewoc--node-data node)) 217 (funcall pp (ewoc--node-data node))
219 (ewoc--adjust m (point) R))) 218 (ewoc--adjust m (point) R dll)))
220 219
221 (defun ewoc--wrap (func) 220 (defun ewoc--wrap (func)
222 (lexical-let ((ewoc--user-pp func)) 221 (lexical-let ((ewoc--user-pp func))
223 (lambda (data) 222 (lambda (data)
224 (funcall ewoc--user-pp data) 223 (funcall ewoc--user-pp data)
282 281
283 (defun ewoc-enter-first (ewoc data) 282 (defun ewoc-enter-first (ewoc data)
284 "Enter DATA first in EWOC. 283 "Enter DATA first in EWOC.
285 Return the new node." 284 Return the new node."
286 (ewoc--set-buffer-bind-dll ewoc 285 (ewoc--set-buffer-bind-dll ewoc
287 (ewoc-enter-after ewoc (ewoc--node-nth 0) data))) 286 (ewoc-enter-after ewoc (ewoc--node-nth dll 0) data)))
288 287
289 (defun ewoc-enter-last (ewoc data) 288 (defun ewoc-enter-last (ewoc data)
290 "Enter DATA last in EWOC. 289 "Enter DATA last in EWOC.
291 Return the new node." 290 Return the new node."
292 (ewoc--set-buffer-bind-dll ewoc 291 (ewoc--set-buffer-bind-dll ewoc
293 (ewoc-enter-before ewoc (ewoc--node-nth -1) data))) 292 (ewoc-enter-before ewoc (ewoc--node-nth dll -1) data)))
294 293
295 (defun ewoc-enter-after (ewoc node data) 294 (defun ewoc-enter-after (ewoc node data)
296 "Enter a new element DATA after NODE in EWOC. 295 "Enter a new element DATA after NODE in EWOC.
297 Return the new node." 296 Return the new node."
298 (ewoc--set-buffer-bind-dll ewoc 297 (ewoc--set-buffer-bind-dll ewoc
299 (ewoc-enter-before ewoc (ewoc--node-next node) data))) 298 (ewoc-enter-before ewoc (ewoc--node-next dll node) data)))
300 299
301 (defun ewoc-enter-before (ewoc node data) 300 (defun ewoc-enter-before (ewoc node data)
302 "Enter a new element DATA before NODE in EWOC. 301 "Enter a new element DATA before NODE in EWOC.
303 Return the new node." 302 Return the new node."
304 (ewoc--set-buffer-bind-dll ewoc 303 (ewoc--set-buffer-bind-dll ewoc
307 (defun ewoc-next (ewoc node) 306 (defun ewoc-next (ewoc node)
308 "Return the node in EWOC that follows NODE. 307 "Return the node in EWOC that follows NODE.
309 Return nil if NODE is nil or the last element." 308 Return nil if NODE is nil or the last element."
310 (when node 309 (when node
311 (ewoc--filter-hf-nodes 310 (ewoc--filter-hf-nodes
312 ewoc (let ((ewoc--current-dll (ewoc--dll ewoc))) 311 ewoc (ewoc--node-next (ewoc--dll ewoc) node))))
313 (ewoc--node-next node)))))
314 312
315 (defun ewoc-prev (ewoc node) 313 (defun ewoc-prev (ewoc node)
316 "Return the node in EWOC that precedes NODE. 314 "Return the node in EWOC that precedes NODE.
317 Return nil if NODE is nil or the first element." 315 Return nil if NODE is nil or the first element."
318 (when node 316 (when node
319 (ewoc--filter-hf-nodes 317 (ewoc--filter-hf-nodes
320 ewoc (let ((ewoc--current-dll (ewoc--dll ewoc))) 318 ewoc (ewoc--node-prev (ewoc--dll ewoc) node))))
321 (ewoc--node-prev node)))))
322 319
323 (defun ewoc-nth (ewoc n) 320 (defun ewoc-nth (ewoc n)
324 "Return the Nth node. 321 "Return the Nth node.
325 N counts from zero. Return nil if there is less than N elements. 322 N counts from zero. Return nil if there is less than N elements.
326 If N is negative, return the -(N+1)th last element. 323 If N is negative, return the -(N+1)th last element.
328 and (ewoc-nth ewoc -1) returns the last node. 325 and (ewoc-nth ewoc -1) returns the last node.
329 Use `ewoc-data' to extract the data from the node." 326 Use `ewoc-data' to extract the data from the node."
330 ;; Skip the header (or footer, if n is negative). 327 ;; Skip the header (or footer, if n is negative).
331 (setq n (if (< n 0) (1- n) (1+ n))) 328 (setq n (if (< n 0) (1- n) (1+ n)))
332 (ewoc--filter-hf-nodes ewoc 329 (ewoc--filter-hf-nodes ewoc
333 (let ((ewoc--current-dll (ewoc--dll ewoc))) 330 (ewoc--node-nth (ewoc--dll ewoc) n)))
334 (ewoc--node-nth n))))
335 331
336 (defun ewoc-map (map-function ewoc &rest args) 332 (defun ewoc-map (map-function ewoc &rest args)
337 "Apply MAP-FUNCTION to all elements in EWOC. 333 "Apply MAP-FUNCTION to all elements in EWOC.
338 MAP-FUNCTION is applied to the first element first. 334 MAP-FUNCTION is applied to the first element first.
339 If MAP-FUNCTION returns non-nil the element will be refreshed (its 335 If MAP-FUNCTION returns non-nil the element will be refreshed (its
346 If more than two arguments are given, the remaining 342 If more than two arguments are given, the remaining
347 arguments will be passed to MAP-FUNCTION." 343 arguments will be passed to MAP-FUNCTION."
348 (ewoc--set-buffer-bind-dll-let* ewoc 344 (ewoc--set-buffer-bind-dll-let* ewoc
349 ((footer (ewoc--footer ewoc)) 345 ((footer (ewoc--footer ewoc))
350 (pp (ewoc--pretty-printer ewoc)) 346 (pp (ewoc--pretty-printer ewoc))
351 (node (ewoc--node-nth 1))) 347 (node (ewoc--node-nth dll 1)))
352 (save-excursion 348 (save-excursion
353 (while (not (eq node footer)) 349 (while (not (eq node footer))
354 (if (apply map-function (ewoc--node-data node) args) 350 (if (apply map-function (ewoc--node-data node) args)
355 (ewoc--refresh-node pp node)) 351 (ewoc--refresh-node pp node dll))
356 (setq node (ewoc--node-next node)))))) 352 (setq node (ewoc--node-next dll node))))))
357 353
358 (defun ewoc-delete (ewoc &rest nodes) 354 (defun ewoc-delete (ewoc &rest nodes)
359 "Delete NODES from EWOC." 355 "Delete NODES from EWOC."
360 (ewoc--set-buffer-bind-dll-let* ewoc 356 (ewoc--set-buffer-bind-dll-let* ewoc
361 ((L nil) (R nil) (last (ewoc--last-node ewoc))) 357 ((L nil) (R nil) (last (ewoc--last-node ewoc)))
363 ;; If we are about to delete the node pointed at by last-node, 359 ;; If we are about to delete the node pointed at by last-node,
364 ;; set last-node to nil. 360 ;; set last-node to nil.
365 (when (eq last node) 361 (when (eq last node)
366 (setf last nil (ewoc--last-node ewoc) nil)) 362 (setf last nil (ewoc--last-node ewoc) nil))
367 (delete-region (ewoc--node-start-marker node) 363 (delete-region (ewoc--node-start-marker node)
368 (ewoc--node-start-marker (ewoc--node-next node))) 364 (ewoc--node-start-marker (ewoc--node-next dll node)))
369 (set-marker (ewoc--node-start-marker node) nil) 365 (set-marker (ewoc--node-start-marker node) nil)
370 (setf L (ewoc--node-left node) 366 (setf L (ewoc--node-left node)
371 R (ewoc--node-right node) 367 R (ewoc--node-right node)
372 ;; Link neighbors to each other. 368 ;; Link neighbors to each other.
373 (ewoc--node-right L) R 369 (ewoc--node-right L) R
382 is called. PREDICATE must restore the current buffer before it returns 378 is called. PREDICATE must restore the current buffer before it returns
383 if it changes it. 379 if it changes it.
384 The PREDICATE is called with the element as its first argument. If any 380 The PREDICATE is called with the element as its first argument. If any
385 ARGS are given they will be passed to the PREDICATE." 381 ARGS are given they will be passed to the PREDICATE."
386 (ewoc--set-buffer-bind-dll-let* ewoc 382 (ewoc--set-buffer-bind-dll-let* ewoc
387 ((node (ewoc--node-nth 1)) 383 ((node (ewoc--node-nth dll 1))
388 (footer (ewoc--footer ewoc)) 384 (footer (ewoc--footer ewoc))
389 (goodbye nil) 385 (goodbye nil)
390 (inhibit-read-only t)) 386 (inhibit-read-only t))
391 (while (not (eq node footer)) 387 (while (not (eq node footer))
392 (unless (apply predicate (ewoc--node-data node) args) 388 (unless (apply predicate (ewoc--node-data node) args)
393 (push node goodbye)) 389 (push node goodbye))
394 (setq node (ewoc--node-next node))) 390 (setq node (ewoc--node-next dll node)))
395 (apply 'ewoc-delete ewoc goodbye))) 391 (apply 'ewoc-delete ewoc goodbye)))
396 392
397 (defun ewoc-locate (ewoc &optional pos guess) 393 (defun ewoc-locate (ewoc &optional pos guess)
398 "Return the node that POS (a buffer position) is within. 394 "Return the node that POS (a buffer position) is within.
399 POS may be a marker or an integer. It defaults to point. 395 POS may be a marker or an integer. It defaults to point.
401 397
402 If POS points before the first element, the first node is returned. 398 If POS points before the first element, the first node is returned.
403 If POS points after the last element, the last node is returned. 399 If POS points after the last element, the last node is returned.
404 If the EWOC is empty, nil is returned." 400 If the EWOC is empty, nil is returned."
405 (unless pos (setq pos (point))) 401 (unless pos (setq pos (point)))
406 (ewoc--set-buffer-bind-dll-let* ewoc 402 (ewoc--set-buffer-bind-dll ewoc
407 ((footer (ewoc--footer ewoc)))
408 403
409 (cond 404 (cond
410 ;; Nothing present? 405 ;; Nothing present?
411 ((eq (ewoc--node-nth 1) (ewoc--node-nth -1)) 406 ((eq (ewoc--node-nth dll 1) (ewoc--node-nth dll -1))
412 nil) 407 nil)
413 408
414 ;; Before second elem? 409 ;; Before second elem?
415 ((< pos (ewoc--node-start-marker (ewoc--node-nth 2))) 410 ((< pos (ewoc--node-start-marker (ewoc--node-nth dll 2)))
416 (ewoc--node-nth 1)) 411 (ewoc--node-nth dll 1))
417 412
418 ;; After one-before-last elem? 413 ;; After one-before-last elem?
419 ((>= pos (ewoc--node-start-marker (ewoc--node-nth -2))) 414 ((>= pos (ewoc--node-start-marker (ewoc--node-nth dll -2)))
420 (ewoc--node-nth -2)) 415 (ewoc--node-nth dll -2))
421 416
422 ;; We now know that pos is within a elem. 417 ;; We now know that pos is within a elem.
423 (t 418 (t
424 ;; Make an educated guess about which of the three known 419 ;; Make an educated guess about which of the three known
425 ;; node'es (the first, the last, or GUESS) is nearest. 420 ;; node'es (the first, the last, or GUESS) is nearest.
426 (let* ((best-guess (ewoc--node-nth 1)) 421 (let* ((best-guess (ewoc--node-nth dll 1))
427 (distance (abs (- pos (ewoc--node-start-marker best-guess))))) 422 (distance (abs (- pos (ewoc--node-start-marker best-guess)))))
428 (when guess 423 (when guess
429 (let ((d (abs (- pos (ewoc--node-start-marker guess))))) 424 (let ((d (abs (- pos (ewoc--node-start-marker guess)))))
430 (when (< d distance) 425 (when (< d distance)
431 (setq distance d) 426 (setq distance d)
432 (setq best-guess guess)))) 427 (setq best-guess guess))))
433 428
434 (let* ((g (ewoc--node-nth -1)) ;Check the last elem 429 (let* ((g (ewoc--node-nth dll -1)) ;Check the last elem
435 (d (abs (- pos (ewoc--node-start-marker g))))) 430 (d (abs (- pos (ewoc--node-start-marker g)))))
436 (when (< d distance) 431 (when (< d distance)
437 (setq distance d) 432 (setq distance d)
438 (setq best-guess g))) 433 (setq best-guess g)))
439 434
452 ;; Is pos after the guess? 447 ;; Is pos after the guess?
453 ((>= pos 448 ((>= pos
454 (ewoc--node-start-marker best-guess)) 449 (ewoc--node-start-marker best-guess))
455 ;; Loop until we are exactly one node too far down... 450 ;; Loop until we are exactly one node too far down...
456 (while (>= pos (ewoc--node-start-marker best-guess)) 451 (while (>= pos (ewoc--node-start-marker best-guess))
457 (setq best-guess (ewoc--node-next best-guess))) 452 (setq best-guess (ewoc--node-next dll best-guess)))
458 ;; ...and return the previous node. 453 ;; ...and return the previous node.
459 (ewoc--node-prev best-guess)) 454 (ewoc--node-prev dll best-guess))
460 455
461 ;; Pos is before best-guess 456 ;; Pos is before best-guess
462 (t 457 (t
463 (while (< pos (ewoc--node-start-marker best-guess)) 458 (while (< pos (ewoc--node-start-marker best-guess))
464 (setq best-guess (ewoc--node-prev best-guess))) 459 (setq best-guess (ewoc--node-prev dll best-guess)))
465 best-guess))))))) 460 best-guess)))))))
466 461
467 (defun ewoc-invalidate (ewoc &rest nodes) 462 (defun ewoc-invalidate (ewoc &rest nodes)
468 "Call EWOC's pretty-printer for each element in NODES. 463 "Call EWOC's pretty-printer for each element in NODES.
469 Delete current text first, thus effecting a \"refresh\"." 464 Delete current text first, thus effecting a \"refresh\"."
470 (ewoc--set-buffer-bind-dll-let* ewoc 465 (ewoc--set-buffer-bind-dll-let* ewoc
471 ((pp (ewoc--pretty-printer ewoc))) 466 ((pp (ewoc--pretty-printer ewoc)))
472 (save-excursion 467 (save-excursion
473 (dolist (node nodes) 468 (dolist (node nodes)
474 (ewoc--refresh-node pp node))))) 469 (ewoc--refresh-node pp node dll)))))
475 470
476 (defun ewoc-goto-prev (ewoc arg) 471 (defun ewoc-goto-prev (ewoc arg)
477 "Move point to the ARGth previous element in EWOC. 472 "Move point to the ARGth previous element in EWOC.
478 Don't move if we are at the first element, or if EWOC is empty. 473 Don't move if we are at the first element, or if EWOC is empty.
479 Return the node we moved to." 474 Return the node we moved to."
483 ;; If we were past the last element, first jump to it. 478 ;; If we were past the last element, first jump to it.
484 (when (>= (point) (ewoc--node-start-marker (ewoc--node-right node))) 479 (when (>= (point) (ewoc--node-start-marker (ewoc--node-right node)))
485 (setq arg (1- arg))) 480 (setq arg (1- arg)))
486 (while (and node (> arg 0)) 481 (while (and node (> arg 0))
487 (setq arg (1- arg)) 482 (setq arg (1- arg))
488 (setq node (ewoc--node-prev node))) 483 (setq node (ewoc--node-prev dll node)))
489 ;; Never step above the first element. 484 ;; Never step above the first element.
490 (unless (ewoc--filter-hf-nodes ewoc node) 485 (unless (ewoc--filter-hf-nodes ewoc node)
491 (setq node (ewoc--node-nth 1))) 486 (setq node (ewoc--node-nth dll 1)))
492 (ewoc-goto-node ewoc node)))) 487 (ewoc-goto-node ewoc node))))
493 488
494 (defun ewoc-goto-next (ewoc arg) 489 (defun ewoc-goto-next (ewoc arg)
495 "Move point to the ARGth next element in EWOC. 490 "Move point to the ARGth next element in EWOC.
496 Return the node (or nil if we just passed the last node)." 491 Return the node (or nil if we just passed the last node)."
497 (ewoc--set-buffer-bind-dll-let* ewoc 492 (ewoc--set-buffer-bind-dll-let* ewoc
498 ((node (ewoc-locate ewoc (point)))) 493 ((node (ewoc-locate ewoc (point))))
499 (while (and node (> arg 0)) 494 (while (and node (> arg 0))
500 (setq arg (1- arg)) 495 (setq arg (1- arg))
501 (setq node (ewoc--node-next node))) 496 (setq node (ewoc--node-next dll node)))
502 ;; Never step below the first element. 497 ;; Never step below the first element.
503 ;; (unless (ewoc--filter-hf-nodes ewoc node) 498 ;; (unless (ewoc--filter-hf-nodes ewoc node)
504 ;; (setq node (ewoc--node-nth -2))) 499 ;; (setq node (ewoc--node-nth dll -2)))
505 (ewoc-goto-node ewoc node))) 500 (ewoc-goto-node ewoc node)))
506 501
507 (defun ewoc-goto-node (ewoc node) 502 (defun ewoc-goto-node (ewoc node)
508 "Move point to NODE in EWOC." 503 "Move point to NODE in EWOC."
509 (ewoc--set-buffer-bind-dll ewoc 504 (ewoc--set-buffer-bind-dll ewoc
518 Note that `ewoc-invalidate' is more efficient if only a small 513 Note that `ewoc-invalidate' is more efficient if only a small
519 number of elements needs to be refreshed." 514 number of elements needs to be refreshed."
520 (ewoc--set-buffer-bind-dll-let* ewoc 515 (ewoc--set-buffer-bind-dll-let* ewoc
521 ((footer (ewoc--footer ewoc))) 516 ((footer (ewoc--footer ewoc)))
522 (let ((inhibit-read-only t)) 517 (let ((inhibit-read-only t))
523 (delete-region (ewoc--node-start-marker (ewoc--node-nth 1)) 518 (delete-region (ewoc--node-start-marker (ewoc--node-nth dll 1))
524 (ewoc--node-start-marker footer)) 519 (ewoc--node-start-marker footer))
525 (goto-char (ewoc--node-start-marker footer)) 520 (goto-char (ewoc--node-start-marker footer))
526 (let ((pp (ewoc--pretty-printer ewoc)) 521 (let ((pp (ewoc--pretty-printer ewoc))
527 (node (ewoc--node-nth 1))) 522 (node (ewoc--node-nth dll 1)))
528 (while (not (eq node footer)) 523 (while (not (eq node footer))
529 (set-marker (ewoc--node-start-marker node) (point)) 524 (set-marker (ewoc--node-start-marker node) (point))
530 (funcall pp (ewoc--node-data node)) 525 (funcall pp (ewoc--node-data node))
531 (setq node (ewoc--node-next node))))) 526 (setq node (ewoc--node-next dll node)))))
532 (set-marker (ewoc--node-start-marker footer) (point)))) 527 (set-marker (ewoc--node-start-marker footer) (point))))
533 528
534 (defun ewoc-collect (ewoc predicate &rest args) 529 (defun ewoc-collect (ewoc predicate &rest args)
535 "Select elements from EWOC using PREDICATE. 530 "Select elements from EWOC using PREDICATE.
536 Return a list of all selected data elements. 531 Return a list of all selected data elements.
543 changes it. 538 changes it.
544 If more than two arguments are given the 539 If more than two arguments are given the
545 remaining arguments will be passed to PREDICATE." 540 remaining arguments will be passed to PREDICATE."
546 (ewoc--set-buffer-bind-dll-let* ewoc 541 (ewoc--set-buffer-bind-dll-let* ewoc
547 ((header (ewoc--header ewoc)) 542 ((header (ewoc--header ewoc))
548 (node (ewoc--node-nth -2)) 543 (node (ewoc--node-nth dll -2))
549 result) 544 result)
550 (while (not (eq node header)) 545 (while (not (eq node header))
551 (if (apply predicate (ewoc--node-data node) args) 546 (if (apply predicate (ewoc--node-data node) args)
552 (push (ewoc--node-data node) result)) 547 (push (ewoc--node-data node) result))
553 (setq node (ewoc--node-prev node))) 548 (setq node (ewoc--node-prev dll node)))
554 (nreverse result))) 549 (nreverse result)))
555 550
556 (defun ewoc-buffer (ewoc) 551 (defun ewoc-buffer (ewoc)
557 "Return the buffer that is associated with EWOC. 552 "Return the buffer that is associated with EWOC.
558 Return nil if the buffer has been deleted." 553 Return nil if the buffer has been deleted."
571 (foot (ewoc--footer ewoc)) 566 (foot (ewoc--footer ewoc))
572 (hf-pp (ewoc--hf-pp ewoc))) 567 (hf-pp (ewoc--hf-pp ewoc)))
573 (setf (ewoc--node-data head) header 568 (setf (ewoc--node-data head) header
574 (ewoc--node-data foot) footer) 569 (ewoc--node-data foot) footer)
575 (save-excursion 570 (save-excursion
576 (ewoc--refresh-node hf-pp head) 571 (ewoc--refresh-node hf-pp head dll)
577 (ewoc--refresh-node hf-pp foot)))) 572 (ewoc--refresh-node hf-pp foot dll))))
578 573
579 574
580 (provide 'ewoc) 575 (provide 'ewoc)
581 576
582 ;; Local Variables: 577 ;; Local Variables: