Mercurial > emacs
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." |