comparison lisp/emacs-lisp/ewoc.el @ 90399:a5812696f7bf unicode-pre-font-backend

Merge from emacs--devo--0 Patches applied: * emacs--devo--0 (patch 274-284) - Update from CVS - Update etc/MORE.STUFF. - Merge from gnus--rel--5.10 * gnus--rel--5.10 (patch 101) - Update from CVS Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-62
author Miles Bader <miles@gnu.org>
date Wed, 17 May 2006 07:46:49 +0000
parents 146cd8369025 308a4824e11b
children a8190f7e546e
comparison
equal deleted inserted replaced
90398:1f8d5cd37cf0 90399:a5812696f7bf
142 (defalias 'ewoc--node-branch 'aref 142 (defalias 'ewoc--node-branch 'aref
143 "Get the left (CHILD=0) or right (CHILD=1) child of the NODE. 143 "Get the left (CHILD=0) or right (CHILD=1) child of the NODE.
144 144
145 \(fn NODE CHILD)") 145 \(fn NODE CHILD)")
146 146
147 (defun ewoc--node-enter-before (node elemnode)
148 "Insert ELEMNODE before NODE in a DLL."
149 (assert (and (null (ewoc--node-left elemnode)) (null (ewoc--node-right elemnode))))
150 (setf (ewoc--node-left elemnode) (ewoc--node-left node))
151 (setf (ewoc--node-right elemnode) node)
152 (setf (ewoc--node-right (ewoc--node-left node)) elemnode)
153 (setf (ewoc--node-left node) elemnode))
154
155 (defun ewoc--node-next (dll node) 147 (defun ewoc--node-next (dll node)
156 "Return the node after NODE, or nil if NODE is the last node." 148 "Return the node after NODE, or nil if NODE is the last node."
157 (unless (eq (ewoc--node-right node) dll) (ewoc--node-right node))) 149 (unless (eq (ewoc--node-right node) dll) (ewoc--node-right node)))
158 150
159 (defun ewoc--node-prev (dll node) 151 (defun ewoc--node-prev (dll node)
211 BUT if it is the header or the footer in EWOC return nil instead." 203 BUT if it is the header or the footer in EWOC return nil instead."
212 (unless (or (eq node (ewoc--header ewoc)) 204 (unless (or (eq node (ewoc--header ewoc))
213 (eq node (ewoc--footer ewoc))) 205 (eq node (ewoc--footer ewoc)))
214 node)) 206 node))
215 207
216 208 (defun ewoc--insert-new-node (node data pretty-printer)
217 (defun ewoc--create-node (data pretty-printer pos) 209 "Insert before NODE a new node for DATA, displayed by PRETTY-PRINTER.
218 "Call PRETTY-PRINTER with point set at POS in current buffer. 210 Call PRETTY-PRINTER with point at NODE's start, thus pushing back
219 Remember the start position. Create a wrapper containing that 211 NODE and leaving the new node's start there. Return the new node."
220 start position and the element DATA."
221 (save-excursion 212 (save-excursion
222 ;; Remember the position as a number so that it doesn't move 213 (let* ((inhibit-read-only t)
223 ;; when we insert the string. 214 (m (copy-marker (ewoc--node-start-marker node)))
224 (when (markerp pos) (setq pos (marker-position pos))) 215 (pos (marker-position m))
225 (goto-char pos) 216 (elemnode (ewoc--node-create m data)))
226 (let ((inhibit-read-only t)) 217 (goto-char pos)
227 ;; Insert the trailing newline using insert-before-markers 218 ;; Insert the trailing newline using insert-before-markers
228 ;; so that the start position for the next element is updated. 219 ;; so that the start position for the next element is updated.
229 (insert-before-markers ?\n) 220 (insert-before-markers ?\n)
230 ;; Move back, and call the pretty-printer. 221 ;; Move back, and call the pretty-printer.
231 (backward-char 1) 222 (backward-char 1)
232 (funcall pretty-printer data) 223 (funcall pretty-printer data)
233 (ewoc--node-create (copy-marker pos) data)))) 224 (setf (marker-position m) pos
225 (ewoc--node-left elemnode) (ewoc--node-left node)
226 (ewoc--node-right elemnode) node
227 (ewoc--node-right (ewoc--node-left node)) elemnode
228 (ewoc--node-left node) elemnode)
229 elemnode)))
234 230
235 (defun ewoc--refresh-node (pp node) 231 (defun ewoc--refresh-node (pp node)
236 "Redisplay the element represented by NODE using the pretty-printer PP." 232 "Redisplay the element represented by NODE using the pretty-printer PP."
237 (let ((inhibit-read-only t)) 233 (let ((inhibit-read-only t))
238 (save-excursion 234 ;; First, remove the string from the buffer:
239 ;; First, remove the string from the buffer: 235 (delete-region (ewoc--node-start-marker node)
240 (delete-region (ewoc--node-start-marker node) 236 (1- (marker-position
241 (1- (marker-position 237 (ewoc--node-start-marker (ewoc--node-right node)))))
242 (ewoc--node-start-marker (ewoc--node-right node))))) 238 ;; Calculate and insert the string.
243 ;; Calculate and insert the string. 239 (goto-char (ewoc--node-start-marker node))
244 (goto-char (ewoc--node-start-marker node)) 240 (funcall pp (ewoc--node-data node))))
245 (funcall pp (ewoc--node-data node)))))
246 241
247 ;;; =========================================================================== 242 ;;; ===========================================================================
248 ;;; Public members of the Ewoc package 243 ;;; Public members of the Ewoc package
249 244
250 245
269 (setf (ewoc--node-left dummy-node) dummy-node) 264 (setf (ewoc--node-left dummy-node) dummy-node)
270 dummy-node)) 265 dummy-node))
271 (new-ewoc 266 (new-ewoc
272 (ewoc--create (current-buffer) 267 (ewoc--create (current-buffer)
273 pretty-printer nil nil dll)) 268 pretty-printer nil nil dll))
274 (pos (point))) 269 (pos (point))
270 head foot)
275 (ewoc--set-buffer-bind-dll new-ewoc 271 (ewoc--set-buffer-bind-dll new-ewoc
276 ;; Set default values 272 ;; Set default values
277 (unless header (setq header "")) 273 (unless header (setq header ""))
278 (unless footer (setq footer "")) 274 (unless footer (setq footer ""))
279 (setf (ewoc--node-start-marker dll) (copy-marker pos)) 275 (setf (ewoc--node-start-marker dll) (copy-marker pos)
280 (let ((foot (ewoc--create-node footer 'insert pos)) 276 foot (ewoc--insert-new-node dll footer 'insert)
281 (head (ewoc--create-node header 'insert pos))) 277 head (ewoc--insert-new-node foot header 'insert)
282 (ewoc--node-enter-before (ewoc--node-right dll) head) 278 (ewoc--footer new-ewoc) foot
283 (ewoc--node-enter-before dll foot) 279 (ewoc--header new-ewoc) head))
284 (setf (ewoc--header new-ewoc) head)
285 (setf (ewoc--footer new-ewoc) foot)))
286 ;; Return the ewoc 280 ;; Return the ewoc
287 new-ewoc)) 281 new-ewoc))
288 282
289 (defalias 'ewoc-data 'ewoc--node-data) 283 (defalias 'ewoc-data 'ewoc--node-data
284 "Extract the data encapsulated by NODE and return it.
285
286 \(fn NODE)")
290 287
291 (defun ewoc-enter-first (ewoc data) 288 (defun ewoc-enter-first (ewoc data)
292 "Enter DATA first in EWOC. 289 "Enter DATA first in EWOC.
293 Return the new node." 290 Return the new node."
294 (ewoc--set-buffer-bind-dll ewoc 291 (ewoc--set-buffer-bind-dll ewoc
309 306
310 (defun ewoc-enter-before (ewoc node data) 307 (defun ewoc-enter-before (ewoc node data)
311 "Enter a new element DATA before NODE in EWOC. 308 "Enter a new element DATA before NODE in EWOC.
312 Return the new node." 309 Return the new node."
313 (ewoc--set-buffer-bind-dll ewoc 310 (ewoc--set-buffer-bind-dll ewoc
314 (ewoc--node-enter-before 311 (ewoc--insert-new-node node data (ewoc--pretty-printer ewoc))))
315 node
316 (ewoc--create-node
317 data
318 (ewoc--pretty-printer ewoc)
319 (ewoc--node-start-marker node)))))
320 312
321 (defun ewoc-next (ewoc node) 313 (defun ewoc-next (ewoc node)
322 "Return the node in EWOC that follows NODE. 314 "Return the node in EWOC that follows NODE.
323 Return nil if NODE is nil or the last element." 315 Return nil if NODE is nil or the last element."
324 (when node 316 (when node
338 "Return the Nth node. 330 "Return the Nth node.
339 N counts from zero. Return nil if there is less than N elements. 331 N counts from zero. Return nil if there is less than N elements.
340 If N is negative, return the -(N+1)th last element. 332 If N is negative, return the -(N+1)th last element.
341 Thus, (ewoc-nth dll 0) returns the first node, 333 Thus, (ewoc-nth dll 0) returns the first node,
342 and (ewoc-nth dll -1) returns the last node. 334 and (ewoc-nth dll -1) returns the last node.
343 Use `ewoc--node-data' to extract the data from the node." 335 Use `ewoc-data' to extract the data from the node."
344 ;; Skip the header (or footer, if n is negative). 336 ;; Skip the header (or footer, if n is negative).
345 (setq n (if (< n 0) (1- n) (1+ n))) 337 (setq n (if (< n 0) (1- n) (1+ n)))
346 (ewoc--filter-hf-nodes ewoc 338 (ewoc--filter-hf-nodes ewoc
347 (ewoc--node-nth (ewoc--dll ewoc) n))) 339 (ewoc--node-nth (ewoc--dll ewoc) n)))
348 340
359 If more than two arguments are given, the remaining 351 If more than two arguments are given, the remaining
360 arguments will be passed to MAP-FUNCTION." 352 arguments will be passed to MAP-FUNCTION."
361 (ewoc--set-buffer-bind-dll-let* ewoc 353 (ewoc--set-buffer-bind-dll-let* ewoc
362 ((footer (ewoc--footer ewoc)) 354 ((footer (ewoc--footer ewoc))
363 (node (ewoc--node-nth dll 1))) 355 (node (ewoc--node-nth dll 1)))
364 (while (not (eq node footer)) 356 (save-excursion
365 (if (apply map-function (ewoc--node-data node) args) 357 (while (not (eq node footer))
366 (ewoc--refresh-node (ewoc--pretty-printer ewoc) node)) 358 (if (apply map-function (ewoc--node-data node) args)
367 (setq node (ewoc--node-next dll node))))) 359 (ewoc--refresh-node (ewoc--pretty-printer ewoc) node))
360 (setq node (ewoc--node-next dll node))))))
368 361
369 (defun ewoc-filter (ewoc predicate &rest args) 362 (defun ewoc-filter (ewoc predicate &rest args)
370 "Remove all elements in EWOC for which PREDICATE returns nil. 363 "Remove all elements in EWOC for which PREDICATE returns nil.
371 Note that the buffer for EWOC will be current-buffer when PREDICATE 364 Note that the buffer for EWOC will be current-buffer when PREDICATE
372 is called. PREDICATE must restore the current buffer before it returns 365 is called. PREDICATE must restore the current buffer before it returns
471 464
472 (defun ewoc-invalidate (ewoc &rest nodes) 465 (defun ewoc-invalidate (ewoc &rest nodes)
473 "Call EWOC's pretty-printer for each element in NODES. 466 "Call EWOC's pretty-printer for each element in NODES.
474 Delete current text first, thus effecting a \"refresh\"." 467 Delete current text first, thus effecting a \"refresh\"."
475 (ewoc--set-buffer-bind-dll ewoc 468 (ewoc--set-buffer-bind-dll ewoc
476 (dolist (node nodes) 469 (save-excursion
477 (ewoc--refresh-node (ewoc--pretty-printer ewoc) node)))) 470 (dolist (node nodes)
471 (ewoc--refresh-node (ewoc--pretty-printer ewoc) node)))))
478 472
479 (defun ewoc-goto-prev (ewoc arg) 473 (defun ewoc-goto-prev (ewoc arg)
480 "Move point to the ARGth previous element in EWOC. 474 "Move point to the ARGth previous element in EWOC.
481 Don't move if we are at the first element, or if EWOC is empty. 475 Don't move if we are at the first element, or if EWOC is empty.
482 Return the node we moved to." 476 Return the node we moved to."
524 ((footer (ewoc--footer ewoc))) 518 ((footer (ewoc--footer ewoc)))
525 (let ((inhibit-read-only t)) 519 (let ((inhibit-read-only t))
526 (delete-region (ewoc--node-start-marker (ewoc--node-nth dll 1)) 520 (delete-region (ewoc--node-start-marker (ewoc--node-nth dll 1))
527 (ewoc--node-start-marker footer)) 521 (ewoc--node-start-marker footer))
528 (goto-char (ewoc--node-start-marker footer)) 522 (goto-char (ewoc--node-start-marker footer))
529 (let ((node (ewoc--node-nth dll 1))) 523 (let ((pp (ewoc--pretty-printer ewoc))
524 (node (ewoc--node-nth dll 1)))
530 (while (not (eq node footer)) 525 (while (not (eq node footer))
531 (set-marker (ewoc--node-start-marker node) (point)) 526 (set-marker (ewoc--node-start-marker node) (point))
532 (funcall (ewoc--pretty-printer ewoc) 527 (funcall pp (ewoc--node-data node))
533 (ewoc--node-data node))
534 (insert "\n") 528 (insert "\n")
535 (setq node (ewoc--node-next dll node))))) 529 (setq node (ewoc--node-next dll node)))))
536 (set-marker (ewoc--node-start-marker footer) (point)))) 530 (set-marker (ewoc--node-start-marker footer) (point))))
537 531
538 (defun ewoc-collect (ewoc predicate &rest args) 532 (defun ewoc-collect (ewoc predicate &rest args)
570 564
571 (defun ewoc-set-hf (ewoc header footer) 565 (defun ewoc-set-hf (ewoc header footer)
572 "Set the HEADER and FOOTER of EWOC." 566 "Set the HEADER and FOOTER of EWOC."
573 (setf (ewoc--node-data (ewoc--header ewoc)) header) 567 (setf (ewoc--node-data (ewoc--header ewoc)) header)
574 (setf (ewoc--node-data (ewoc--footer ewoc)) footer) 568 (setf (ewoc--node-data (ewoc--footer ewoc)) footer)
575 (ewoc--refresh-node 'insert (ewoc--header ewoc)) 569 (save-excursion
576 (ewoc--refresh-node 'insert (ewoc--footer ewoc))) 570 (ewoc--refresh-node 'insert (ewoc--header ewoc))
571 (ewoc--refresh-node 'insert (ewoc--footer ewoc))))
577 572
578 573
579 (provide 'ewoc) 574 (provide 'ewoc)
580 575
581 ;;; Local Variables: 576 ;;; Local Variables: