comparison lisp/emacs-lisp/ewoc.el @ 70956:5fd02ab03d96

(ewoc--current-dll): New var. (ewoc--node-next, ewoc--node-prev, ewoc--node-nth): Don't take DLL arg. Instead, use `ewoc--current-dll'. Update all callers. (ewoc--set-buffer-bind-dll-let*): Bind `ewoc--current-dll', not `dll'. (ewoc--adjust): Use `ewoc--current-dll'. (ewoc-next, ewoc-prev, ewoc-nth): Bind `ewoc--current-dll'.
author Thien-Thi Nguyen <ttn@gnuvola.org>
date Fri, 26 May 2006 08:29:13 +0000
parents 9119e54a8121
children c54570f9431a
comparison
equal deleted inserted replaced
70955:d42f132da9a8 70956:5fd02ab03d96
132 132
133 (eval-when-compile (require 'cl)) ;because of CL compiler macros 133 (eval-when-compile (require 'cl)) ;because of CL compiler macros
134 134
135 ;; The doubly linked list is implemented as a circular list 135 ;; The doubly linked list is implemented as a circular list
136 ;; with a dummy node first and last. The dummy node is used as 136 ;; with a dummy node first and last. The dummy node is used as
137 ;; "the dll" (or rather is the dll handle passed around). 137 ;; "the dll" (or rather the dynamically bound `ewoc--current-dll').
138
139 (defvar ewoc--current-dll)
138 140
139 (defstruct (ewoc--node 141 (defstruct (ewoc--node
140 (:type vector) ;required for ewoc--node-branch hack 142 (:type vector) ;required for ewoc--node-branch hack
141 (:constructor ewoc--node-create (start-marker data))) 143 (:constructor ewoc--node-create (start-marker data)))
142 left right data start-marker) 144 left right data start-marker)
144 (defalias 'ewoc--node-branch 'aref 146 (defalias 'ewoc--node-branch 'aref
145 "Get the left (CHILD=0) or right (CHILD=1) child of the NODE. 147 "Get the left (CHILD=0) or right (CHILD=1) child of the NODE.
146 148
147 \(fn NODE CHILD)") 149 \(fn NODE CHILD)")
148 150
149 (defun ewoc--node-next (dll node) 151 (defun ewoc--node-next (node)
150 "Return the node after NODE, or nil if NODE is the last node." 152 "Return the node after NODE, or nil if NODE is the last node."
151 (unless (eq (ewoc--node-right node) dll) (ewoc--node-right node))) 153 (let ((R (ewoc--node-right node)))
152 154 (unless (eq ewoc--current-dll R) R)))
153 (defun ewoc--node-prev (dll node) 155
156 (defun ewoc--node-prev (node)
154 "Return the node before NODE, or nil if NODE is the first node." 157 "Return the node before NODE, or nil if NODE is the first node."
155 (unless (eq (ewoc--node-left node) dll) (ewoc--node-left node))) 158 (let ((L (ewoc--node-left node)))
156 159 (unless (eq ewoc--current-dll L) L)))
157 (defun ewoc--node-nth (dll n) 160
158 "Return the Nth node from the doubly linked list DLL. 161 (defun ewoc--node-nth (n)
159 N counts from zero. If DLL is not that long, nil is returned. 162 "Return the Nth node from the doubly linked list `ewoc--current-dll'.
160 If N is negative, return the -(N+1)th last element. 163 N counts from zero. If N is negative, return the -(N+1)th last element.
161 Thus, (ewoc--node-nth dll 0) returns the first node, 164 If N is out of range, return nil.
162 and (ewoc--node-nth dll -1) returns the last node." 165 Thus, (ewoc--node-nth 0) returns the first node,
166 and (ewoc--node-nth -1) returns the last node."
163 ;; Branch 0 ("follow left pointer") is used when n is negative. 167 ;; Branch 0 ("follow left pointer") is used when n is negative.
164 ;; Branch 1 ("follow right pointer") is used otherwise. 168 ;; Branch 1 ("follow right pointer") is used otherwise.
165 (let* ((branch (if (< n 0) 0 1)) 169 (let* ((branch (if (< n 0) 0 1))
166 (node (ewoc--node-branch dll branch))) 170 (node (ewoc--node-branch ewoc--current-dll branch)))
167 (if (< n 0) (setq n (- -1 n))) 171 (if (< n 0) (setq n (- -1 n)))
168 (while (and (not (eq dll node)) (> n 0)) 172 (while (and (not (eq ewoc--current-dll node)) (> n 0))
169 (setq node (ewoc--node-branch node branch)) 173 (setq node (ewoc--node-branch node branch))
170 (setq n (1- n))) 174 (setq n (1- n)))
171 (unless (eq dll node) node))) 175 (unless (eq ewoc--current-dll node) node)))
172 176
173 (defun ewoc-location (node) 177 (defun ewoc-location (node)
174 "Return the start location of NODE." 178 "Return the start location of NODE."
175 (ewoc--node-start-marker node)) 179 (ewoc--node-start-marker node))
176 180
184 (:conc-name ewoc--)) 188 (:conc-name ewoc--))
185 buffer pretty-printer header footer dll last-node) 189 buffer pretty-printer header footer dll last-node)
186 190
187 (defmacro ewoc--set-buffer-bind-dll-let* (ewoc varlist &rest forms) 191 (defmacro ewoc--set-buffer-bind-dll-let* (ewoc varlist &rest forms)
188 "Execute FORMS with ewoc--buffer selected as current buffer, 192 "Execute FORMS with ewoc--buffer selected as current buffer,
189 dll bound to ewoc--dll, and VARLIST bound as in a let*. 193 `ewoc--current-dll' bound to the dll, and VARLIST bound as in a let*.
190 dll will be bound when VARLIST is initialized, but the current 194 `ewoc--current-dll' will be bound when VARLIST is initialized, but
191 buffer will *not* have been changed. 195 the current buffer will *not* have been changed.
192 Return value of last form in FORMS." 196 Return value of last form in FORMS."
193 (let ((hnd (make-symbol "ewoc"))) 197 (let ((hnd (make-symbol "ewoc")))
194 `(let* ((,hnd ,ewoc) 198 `(let* ((,hnd ,ewoc)
195 (dll (ewoc--dll ,hnd)) 199 (ewoc--current-dll (ewoc--dll ,hnd))
196 ,@varlist) 200 ,@varlist)
197 (with-current-buffer (ewoc--buffer ,hnd) 201 (with-current-buffer (ewoc--buffer ,hnd)
198 ,@forms)))) 202 ,@forms))))
199 203
200 (defmacro ewoc--set-buffer-bind-dll (ewoc &rest forms) 204 (defmacro ewoc--set-buffer-bind-dll (ewoc &rest forms)
211 ;; "Manually reseat" markers for NODE and its successors (including footer 215 ;; "Manually reseat" markers for NODE and its successors (including footer
212 ;; and dll), in the case where they originally shared start position with 216 ;; and dll), in the case where they originally shared start position with
213 ;; BEG, to END. BEG and END are buffer positions describing NODE's left 217 ;; BEG, to END. BEG and END are buffer positions describing NODE's left
214 ;; neighbor. This operation is functionally equivalent to temporarily 218 ;; neighbor. This operation is functionally equivalent to temporarily
215 ;; setting these nodes' markers' insertion type to t around the pretty-print 219 ;; setting these nodes' markers' insertion type to t around the pretty-print
216 ;; call that precedes the call to `ewoc-adjust', and then changing them back 220 ;; call that precedes the call to `ewoc--adjust', and then changing them back
217 ;; to nil. 221 ;; to nil.
218 (when (< beg end) 222 (when (< beg end)
219 (let (m) 223 (let (m)
220 (while (and (= beg (setq m (ewoc--node-start-marker node))) 224 (while (and (= beg (setq m (ewoc--node-start-marker node)))
221 (progn 225 (progn
222 (set-marker m end) 226 (set-marker m end)
223 (not (eq dll node)))) 227 (not (eq ewoc--current-dll node))))
224 (setq node (ewoc--node-right node)))))) 228 (setq node (ewoc--node-right node))))))
225 229
226 (defun ewoc--insert-new-node (node data pretty-printer) 230 (defun ewoc--insert-new-node (node data pretty-printer)
227 "Insert before NODE a new node for DATA, displayed by PRETTY-PRINTER. 231 "Insert before NODE a new node for DATA, displayed by PRETTY-PRINTER.
228 Call PRETTY-PRINTER with point at NODE's start, thus pushing back 232 Call PRETTY-PRINTER with point at NODE's start, thus pushing back
304 308
305 (defun ewoc-enter-first (ewoc data) 309 (defun ewoc-enter-first (ewoc data)
306 "Enter DATA first in EWOC. 310 "Enter DATA first in EWOC.
307 Return the new node." 311 Return the new node."
308 (ewoc--set-buffer-bind-dll ewoc 312 (ewoc--set-buffer-bind-dll ewoc
309 (ewoc-enter-after ewoc (ewoc--node-nth dll 0) data))) 313 (ewoc-enter-after ewoc (ewoc--node-nth 0) data)))
310 314
311 (defun ewoc-enter-last (ewoc data) 315 (defun ewoc-enter-last (ewoc data)
312 "Enter DATA last in EWOC. 316 "Enter DATA last in EWOC.
313 Return the new node." 317 Return the new node."
314 (ewoc--set-buffer-bind-dll ewoc 318 (ewoc--set-buffer-bind-dll ewoc
315 (ewoc-enter-before ewoc (ewoc--node-nth dll -1) data))) 319 (ewoc-enter-before ewoc (ewoc--node-nth -1) data)))
316 320
317 321
318 (defun ewoc-enter-after (ewoc node data) 322 (defun ewoc-enter-after (ewoc node data)
319 "Enter a new element DATA after NODE in EWOC. 323 "Enter a new element DATA after NODE in EWOC.
320 Return the new node." 324 Return the new node."
321 (ewoc--set-buffer-bind-dll ewoc 325 (ewoc--set-buffer-bind-dll ewoc
322 (ewoc-enter-before ewoc (ewoc--node-next dll node) data))) 326 (ewoc-enter-before ewoc (ewoc--node-next node) data)))
323 327
324 (defun ewoc-enter-before (ewoc node data) 328 (defun ewoc-enter-before (ewoc node data)
325 "Enter a new element DATA before NODE in EWOC. 329 "Enter a new element DATA before NODE in EWOC.
326 Return the new node." 330 Return the new node."
327 (ewoc--set-buffer-bind-dll ewoc 331 (ewoc--set-buffer-bind-dll ewoc
330 (defun ewoc-next (ewoc node) 334 (defun ewoc-next (ewoc node)
331 "Return the node in EWOC that follows NODE. 335 "Return the node in EWOC that follows NODE.
332 Return nil if NODE is nil or the last element." 336 Return nil if NODE is nil or the last element."
333 (when node 337 (when node
334 (ewoc--filter-hf-nodes 338 (ewoc--filter-hf-nodes
335 ewoc (ewoc--node-next (ewoc--dll ewoc) node)))) 339 ewoc (let ((ewoc--current-dll (ewoc--dll ewoc)))
340 (ewoc--node-next node)))))
336 341
337 (defun ewoc-prev (ewoc node) 342 (defun ewoc-prev (ewoc node)
338 "Return the node in EWOC that precedes NODE. 343 "Return the node in EWOC that precedes NODE.
339 Return nil if NODE is nil or the first element." 344 Return nil if NODE is nil or the first element."
340 (when node 345 (when node
341 (ewoc--filter-hf-nodes 346 (ewoc--filter-hf-nodes
342 ewoc 347 ewoc (let ((ewoc--current-dll (ewoc--dll ewoc)))
343 (ewoc--node-prev (ewoc--dll ewoc) node)))) 348 (ewoc--node-prev node)))))
344 349
345 350
346 (defun ewoc-nth (ewoc n) 351 (defun ewoc-nth (ewoc n)
347 "Return the Nth node. 352 "Return the Nth node.
348 N counts from zero. Return nil if there is less than N elements. 353 N counts from zero. Return nil if there is less than N elements.
349 If N is negative, return the -(N+1)th last element. 354 If N is negative, return the -(N+1)th last element.
350 Thus, (ewoc-nth dll 0) returns the first node, 355 Thus, (ewoc-nth ewoc 0) returns the first node,
351 and (ewoc-nth dll -1) returns the last node. 356 and (ewoc-nth ewoc -1) returns the last node.
352 Use `ewoc-data' to extract the data from the node." 357 Use `ewoc-data' to extract the data from the node."
353 ;; Skip the header (or footer, if n is negative). 358 ;; Skip the header (or footer, if n is negative).
354 (setq n (if (< n 0) (1- n) (1+ n))) 359 (setq n (if (< n 0) (1- n) (1+ n)))
355 (ewoc--filter-hf-nodes ewoc 360 (ewoc--filter-hf-nodes ewoc
356 (ewoc--node-nth (ewoc--dll ewoc) n))) 361 (let ((ewoc--current-dll (ewoc--dll ewoc)))
362 (ewoc--node-nth n))))
357 363
358 (defun ewoc-map (map-function ewoc &rest args) 364 (defun ewoc-map (map-function ewoc &rest args)
359 "Apply MAP-FUNCTION to all elements in EWOC. 365 "Apply MAP-FUNCTION to all elements in EWOC.
360 MAP-FUNCTION is applied to the first element first. 366 MAP-FUNCTION is applied to the first element first.
361 If MAP-FUNCTION returns non-nil the element will be refreshed (its 367 If MAP-FUNCTION returns non-nil the element will be refreshed (its
368 If more than two arguments are given, the remaining 374 If more than two arguments are given, the remaining
369 arguments will be passed to MAP-FUNCTION." 375 arguments will be passed to MAP-FUNCTION."
370 (ewoc--set-buffer-bind-dll-let* ewoc 376 (ewoc--set-buffer-bind-dll-let* ewoc
371 ((footer (ewoc--footer ewoc)) 377 ((footer (ewoc--footer ewoc))
372 (pp (ewoc--pretty-printer ewoc)) 378 (pp (ewoc--pretty-printer ewoc))
373 (node (ewoc--node-nth dll 1))) 379 (node (ewoc--node-nth 1)))
374 (save-excursion 380 (save-excursion
375 (while (not (eq node footer)) 381 (while (not (eq node footer))
376 (if (apply map-function (ewoc--node-data node) args) 382 (if (apply map-function (ewoc--node-data node) args)
377 (ewoc--refresh-node pp node)) 383 (ewoc--refresh-node pp node))
378 (setq node (ewoc--node-next dll node)))))) 384 (setq node (ewoc--node-next node))))))
379 385
380 (defun ewoc-delete (ewoc &rest nodes) 386 (defun ewoc-delete (ewoc &rest nodes)
381 "Delete NODES from EWOC." 387 "Delete NODES from EWOC."
382 (ewoc--set-buffer-bind-dll-let* ewoc 388 (ewoc--set-buffer-bind-dll-let* ewoc
383 ((L nil) (R nil)) 389 ((L nil) (R nil))
385 ;; If we are about to delete the node pointed at by last-node, 391 ;; If we are about to delete the node pointed at by last-node,
386 ;; set last-node to nil. 392 ;; set last-node to nil.
387 (if (eq (ewoc--last-node ewoc) node) 393 (if (eq (ewoc--last-node ewoc) node)
388 (setf (ewoc--last-node ewoc) nil)) 394 (setf (ewoc--last-node ewoc) nil))
389 (delete-region (ewoc--node-start-marker node) 395 (delete-region (ewoc--node-start-marker node)
390 (ewoc--node-start-marker (ewoc--node-next dll node))) 396 (ewoc--node-start-marker (ewoc--node-next node)))
391 (set-marker (ewoc--node-start-marker node) nil) 397 (set-marker (ewoc--node-start-marker node) nil)
392 (setf L (ewoc--node-left node) 398 (setf L (ewoc--node-left node)
393 R (ewoc--node-right node) 399 R (ewoc--node-right node)
394 ;; Link neighbors to each other. 400 ;; Link neighbors to each other.
395 (ewoc--node-right L) R 401 (ewoc--node-right L) R
404 is called. PREDICATE must restore the current buffer before it returns 410 is called. PREDICATE must restore the current buffer before it returns
405 if it changes it. 411 if it changes it.
406 The PREDICATE is called with the element as its first argument. If any 412 The PREDICATE is called with the element as its first argument. If any
407 ARGS are given they will be passed to the PREDICATE." 413 ARGS are given they will be passed to the PREDICATE."
408 (ewoc--set-buffer-bind-dll-let* ewoc 414 (ewoc--set-buffer-bind-dll-let* ewoc
409 ((node (ewoc--node-nth dll 1)) 415 ((node (ewoc--node-nth 1))
410 (footer (ewoc--footer ewoc)) 416 (footer (ewoc--footer ewoc))
411 (goodbye nil) 417 (goodbye nil)
412 (inhibit-read-only t)) 418 (inhibit-read-only t))
413 (while (not (eq node footer)) 419 (while (not (eq node footer))
414 (unless (apply predicate (ewoc--node-data node) args) 420 (unless (apply predicate (ewoc--node-data node) args)
415 (push node goodbye)) 421 (push node goodbye))
416 (setq node (ewoc--node-next dll node))) 422 (setq node (ewoc--node-next node)))
417 (apply 'ewoc-delete ewoc goodbye))) 423 (apply 'ewoc-delete ewoc goodbye)))
418 424
419 (defun ewoc-locate (ewoc &optional pos guess) 425 (defun ewoc-locate (ewoc &optional pos guess)
420 "Return the node that POS (a buffer position) is within. 426 "Return the node that POS (a buffer position) is within.
421 POS may be a marker or an integer. It defaults to point. 427 POS may be a marker or an integer. It defaults to point.
428 (ewoc--set-buffer-bind-dll-let* ewoc 434 (ewoc--set-buffer-bind-dll-let* ewoc
429 ((footer (ewoc--footer ewoc))) 435 ((footer (ewoc--footer ewoc)))
430 436
431 (cond 437 (cond
432 ;; Nothing present? 438 ;; Nothing present?
433 ((eq (ewoc--node-nth dll 1) (ewoc--node-nth dll -1)) 439 ((eq (ewoc--node-nth 1) (ewoc--node-nth -1))
434 nil) 440 nil)
435 441
436 ;; Before second elem? 442 ;; Before second elem?
437 ((< pos (ewoc--node-start-marker (ewoc--node-nth dll 2))) 443 ((< pos (ewoc--node-start-marker (ewoc--node-nth 2)))
438 (ewoc--node-nth dll 1)) 444 (ewoc--node-nth 1))
439 445
440 ;; After one-before-last elem? 446 ;; After one-before-last elem?
441 ((>= pos (ewoc--node-start-marker (ewoc--node-nth dll -2))) 447 ((>= pos (ewoc--node-start-marker (ewoc--node-nth -2)))
442 (ewoc--node-nth dll -2)) 448 (ewoc--node-nth -2))
443 449
444 ;; We now know that pos is within a elem. 450 ;; We now know that pos is within a elem.
445 (t 451 (t
446 ;; Make an educated guess about which of the three known 452 ;; Make an educated guess about which of the three known
447 ;; node'es (the first, the last, or GUESS) is nearest. 453 ;; node'es (the first, the last, or GUESS) is nearest.
448 (let* ((best-guess (ewoc--node-nth dll 1)) 454 (let* ((best-guess (ewoc--node-nth 1))
449 (distance (abs (- pos (ewoc--node-start-marker best-guess))))) 455 (distance (abs (- pos (ewoc--node-start-marker best-guess)))))
450 (when guess 456 (when guess
451 (let ((d (abs (- pos (ewoc--node-start-marker guess))))) 457 (let ((d (abs (- pos (ewoc--node-start-marker guess)))))
452 (when (< d distance) 458 (when (< d distance)
453 (setq distance d) 459 (setq distance d)
454 (setq best-guess guess)))) 460 (setq best-guess guess))))
455 461
456 (let* ((g (ewoc--node-nth dll -1)) ;Check the last elem 462 (let* ((g (ewoc--node-nth -1)) ;Check the last elem
457 (d (abs (- pos (ewoc--node-start-marker g))))) 463 (d (abs (- pos (ewoc--node-start-marker g)))))
458 (when (< d distance) 464 (when (< d distance)
459 (setq distance d) 465 (setq distance d)
460 (setq best-guess g))) 466 (setq best-guess g)))
461 467
462 (when (ewoc--last-node ewoc) ;Check "previous". 468 (when (ewoc--last-node ewoc) ;Check "previous".
463 (let* ((g (ewoc--last-node ewoc)) 469 (let* ((g (ewoc--last-node ewoc))
464 (d (abs (- pos (ewoc--node-start-marker g))))) 470 (d (abs (- pos (ewoc--node-start-marker g)))))
465 (when (< d distance) 471 (when (< d distance)
466 (setq distance d) 472 (setq distance d)
467 (setq best-guess g)))) 473 (setq best-guess g))))
474 ;; Is pos after the guess? 480 ;; Is pos after the guess?
475 ((>= pos 481 ((>= pos
476 (ewoc--node-start-marker best-guess)) 482 (ewoc--node-start-marker best-guess))
477 ;; Loop until we are exactly one node too far down... 483 ;; Loop until we are exactly one node too far down...
478 (while (>= pos (ewoc--node-start-marker best-guess)) 484 (while (>= pos (ewoc--node-start-marker best-guess))
479 (setq best-guess (ewoc--node-next dll best-guess))) 485 (setq best-guess (ewoc--node-next best-guess)))
480 ;; ...and return the previous node. 486 ;; ...and return the previous node.
481 (ewoc--node-prev dll best-guess)) 487 (ewoc--node-prev best-guess))
482 488
483 ;; Pos is before best-guess 489 ;; Pos is before best-guess
484 (t 490 (t
485 (while (< pos (ewoc--node-start-marker best-guess)) 491 (while (< pos (ewoc--node-start-marker best-guess))
486 (setq best-guess (ewoc--node-prev dll best-guess))) 492 (setq best-guess (ewoc--node-prev best-guess)))
487 best-guess))))))) 493 best-guess)))))))
488 494
489 (defun ewoc-invalidate (ewoc &rest nodes) 495 (defun ewoc-invalidate (ewoc &rest nodes)
490 "Call EWOC's pretty-printer for each element in NODES. 496 "Call EWOC's pretty-printer for each element in NODES.
491 Delete current text first, thus effecting a \"refresh\"." 497 Delete current text first, thus effecting a \"refresh\"."
505 ;; If we were past the last element, first jump to it. 511 ;; If we were past the last element, first jump to it.
506 (when (>= (point) (ewoc--node-start-marker (ewoc--node-right node))) 512 (when (>= (point) (ewoc--node-start-marker (ewoc--node-right node)))
507 (setq arg (1- arg))) 513 (setq arg (1- arg)))
508 (while (and node (> arg 0)) 514 (while (and node (> arg 0))
509 (setq arg (1- arg)) 515 (setq arg (1- arg))
510 (setq node (ewoc--node-prev dll node))) 516 (setq node (ewoc--node-prev node)))
511 ;; Never step above the first element. 517 ;; Never step above the first element.
512 (unless (ewoc--filter-hf-nodes ewoc node) 518 (unless (ewoc--filter-hf-nodes ewoc node)
513 (setq node (ewoc--node-nth dll 1))) 519 (setq node (ewoc--node-nth 1)))
514 (ewoc-goto-node ewoc node)))) 520 (ewoc-goto-node ewoc node))))
515 521
516 (defun ewoc-goto-next (ewoc arg) 522 (defun ewoc-goto-next (ewoc arg)
517 "Move point to the ARGth next element in EWOC. 523 "Move point to the ARGth next element in EWOC.
518 Return the node (or nil if we just passed the last node)." 524 Return the node (or nil if we just passed the last node)."
519 (ewoc--set-buffer-bind-dll-let* ewoc 525 (ewoc--set-buffer-bind-dll-let* ewoc
520 ((node (ewoc-locate ewoc (point)))) 526 ((node (ewoc-locate ewoc (point))))
521 (while (and node (> arg 0)) 527 (while (and node (> arg 0))
522 (setq arg (1- arg)) 528 (setq arg (1- arg))
523 (setq node (ewoc--node-next dll node))) 529 (setq node (ewoc--node-next node)))
524 ;; Never step below the first element. 530 ;; Never step below the first element.
525 ;; (unless (ewoc--filter-hf-nodes ewoc node) 531 ;; (unless (ewoc--filter-hf-nodes ewoc node)
526 ;; (setq node (ewoc--node-nth dll -2))) 532 ;; (setq node (ewoc--node-nth -2)))
527 (ewoc-goto-node ewoc node))) 533 (ewoc-goto-node ewoc node)))
528 534
529 (defun ewoc-goto-node (ewoc node) 535 (defun ewoc-goto-node (ewoc node)
530 "Move point to NODE in EWOC." 536 "Move point to NODE in EWOC."
531 (ewoc--set-buffer-bind-dll ewoc 537 (ewoc--set-buffer-bind-dll ewoc
540 Note that `ewoc-invalidate' is more efficient if only a small 546 Note that `ewoc-invalidate' is more efficient if only a small
541 number of elements needs to be refreshed." 547 number of elements needs to be refreshed."
542 (ewoc--set-buffer-bind-dll-let* ewoc 548 (ewoc--set-buffer-bind-dll-let* ewoc
543 ((footer (ewoc--footer ewoc))) 549 ((footer (ewoc--footer ewoc)))
544 (let ((inhibit-read-only t)) 550 (let ((inhibit-read-only t))
545 (delete-region (ewoc--node-start-marker (ewoc--node-nth dll 1)) 551 (delete-region (ewoc--node-start-marker (ewoc--node-nth 1))
546 (ewoc--node-start-marker footer)) 552 (ewoc--node-start-marker footer))
547 (goto-char (ewoc--node-start-marker footer)) 553 (goto-char (ewoc--node-start-marker footer))
548 (let ((pp (ewoc--pretty-printer ewoc)) 554 (let ((pp (ewoc--pretty-printer ewoc))
549 (node (ewoc--node-nth dll 1))) 555 (node (ewoc--node-nth 1)))
550 (while (not (eq node footer)) 556 (while (not (eq node footer))
551 (set-marker (ewoc--node-start-marker node) (point)) 557 (set-marker (ewoc--node-start-marker node) (point))
552 (funcall pp (ewoc--node-data node)) 558 (funcall pp (ewoc--node-data node))
553 (setq node (ewoc--node-next dll node))))) 559 (setq node (ewoc--node-next node)))))
554 (set-marker (ewoc--node-start-marker footer) (point)))) 560 (set-marker (ewoc--node-start-marker footer) (point))))
555 561
556 (defun ewoc-collect (ewoc predicate &rest args) 562 (defun ewoc-collect (ewoc predicate &rest args)
557 "Select elements from EWOC using PREDICATE. 563 "Select elements from EWOC using PREDICATE.
558 Return a list of all selected data elements. 564 Return a list of all selected data elements.
565 changes it. 571 changes it.
566 If more than two arguments are given the 572 If more than two arguments are given the
567 remaining arguments will be passed to PREDICATE." 573 remaining arguments will be passed to PREDICATE."
568 (ewoc--set-buffer-bind-dll-let* ewoc 574 (ewoc--set-buffer-bind-dll-let* ewoc
569 ((header (ewoc--header ewoc)) 575 ((header (ewoc--header ewoc))
570 (node (ewoc--node-nth dll -2)) 576 (node (ewoc--node-nth -2))
571 result) 577 result)
572 (while (not (eq node header)) 578 (while (not (eq node header))
573 (if (apply predicate (ewoc--node-data node) args) 579 (if (apply predicate (ewoc--node-data node) args)
574 (push (ewoc--node-data node) result)) 580 (push (ewoc--node-data node) result))
575 (setq node (ewoc--node-prev dll node))) 581 (setq node (ewoc--node-prev node)))
576 (nreverse result))) 582 (nreverse result)))
577 583
578 (defun ewoc-buffer (ewoc) 584 (defun ewoc-buffer (ewoc)
579 "Return the buffer that is associated with EWOC. 585 "Return the buffer that is associated with EWOC.
580 Return nil if the buffer has been deleted." 586 Return nil if the buffer has been deleted."