comparison lisp/emacs-lisp/ewoc.el @ 70707:346a9c09f370

(ewoc--adjust): New func. (ewoc--insert-new-node): Don't insert trailing newline. Instead, adjust succesor nodes' start markers. (ewoc--refresh-node): Delete all text from current node's start marker to the next one's; adjust successor nodes' start markers. (ewoc--create): Doc fixes. (ewoc--refresh): Don't insert newline. (ewoc--set-hf): Use `ewoc--set-buffer-bind-dll-let*'.
author Thien-Thi Nguyen <ttn@gnuvola.org>
date Thu, 18 May 2006 12:04:40 +0000
parents 9d6a9b899f95
children 9ce3cc1e5e89
comparison
equal deleted inserted replaced
70706:4bd88182f5ec 70707:346a9c09f370
203 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."
204 (unless (or (eq node (ewoc--header ewoc)) 204 (unless (or (eq node (ewoc--header ewoc))
205 (eq node (ewoc--footer ewoc))) 205 (eq node (ewoc--footer ewoc)))
206 node)) 206 node))
207 207
208 (defun ewoc--adjust (beg end node)
209 ;; "Manually reseat" markers for NODE and its successors (including footer
210 ;; and dll), in the case where they originally shared start position with
211 ;; BEG, to END. BEG and END are buffer positions describing NODE's left
212 ;; neighbor. This operation is functionally equivalent to temporarily
213 ;; setting these nodes' markers' insertion type to t around the pretty-print
214 ;; call that precedes the call to `ewoc-adjust', and then changing them back
215 ;; to nil.
216 (when (< beg end)
217 (let (m)
218 (while (and (= beg (setq m (ewoc--node-start-marker node)))
219 (progn
220 (set-marker m end)
221 (not (eq dll node))))
222 (setq node (ewoc--node-right node))))))
223
208 (defun ewoc--insert-new-node (node data pretty-printer) 224 (defun ewoc--insert-new-node (node data pretty-printer)
209 "Insert before NODE a new node for DATA, displayed by PRETTY-PRINTER. 225 "Insert before NODE a new node for DATA, displayed by PRETTY-PRINTER.
210 Call PRETTY-PRINTER with point at NODE's start, thus pushing back 226 Call PRETTY-PRINTER with point at NODE's start, thus pushing back
211 NODE and leaving the new node's start there. Return the new node." 227 NODE and leaving the new node's start there. Return the new node."
212 (save-excursion 228 (save-excursion
213 (let* ((inhibit-read-only t) 229 (let* ((inhibit-read-only t)
214 (m (copy-marker (ewoc--node-start-marker node))) 230 (m (copy-marker (ewoc--node-start-marker node)))
215 (pos (marker-position m)) 231 (pos (marker-position m))
216 (elemnode (ewoc--node-create m data))) 232 (elemnode (ewoc--node-create m data)))
217 (goto-char pos) 233 (goto-char pos)
218 ;; Insert the trailing newline using insert-before-markers
219 ;; so that the start position for the next element is updated.
220 (insert-before-markers ?\n)
221 ;; Move back, and call the pretty-printer.
222 (backward-char 1)
223 (funcall pretty-printer data) 234 (funcall pretty-printer data)
224 (setf (marker-position m) pos 235 (setf (marker-position m) pos
225 (ewoc--node-left elemnode) (ewoc--node-left node) 236 (ewoc--node-left elemnode) (ewoc--node-left node)
226 (ewoc--node-right elemnode) node 237 (ewoc--node-right elemnode) node
227 (ewoc--node-right (ewoc--node-left node)) elemnode 238 (ewoc--node-right (ewoc--node-left node)) elemnode
228 (ewoc--node-left node) elemnode) 239 (ewoc--node-left node) elemnode)
240 (ewoc--adjust pos (point) node)
229 elemnode))) 241 elemnode)))
230 242
231 (defun ewoc--refresh-node (pp node) 243 (defun ewoc--refresh-node (pp node)
232 "Redisplay the element represented by NODE using the pretty-printer PP." 244 "Redisplay the element represented by NODE using the pretty-printer PP."
233 (let ((inhibit-read-only t)) 245 (let ((inhibit-read-only t)
246 (m (ewoc--node-start-marker node))
247 (R (ewoc--node-right node)))
234 ;; First, remove the string from the buffer: 248 ;; First, remove the string from the buffer:
235 (delete-region (ewoc--node-start-marker node) 249 (delete-region m (ewoc--node-start-marker R))
236 (1- (marker-position
237 (ewoc--node-start-marker (ewoc--node-right node)))))
238 ;; Calculate and insert the string. 250 ;; Calculate and insert the string.
239 (goto-char (ewoc--node-start-marker node)) 251 (goto-char m)
240 (funcall pp (ewoc--node-data node)))) 252 (funcall pp (ewoc--node-data node))
253 (ewoc--adjust m (point) R)))
241 254
242 ;;; =========================================================================== 255 ;;; ===========================================================================
243 ;;; Public members of the Ewoc package 256 ;;; Public members of the Ewoc package
244 257
245 258
249 The ewoc will be inserted in the current buffer at the current position. 262 The ewoc will be inserted in the current buffer at the current position.
250 263
251 PRETTY-PRINTER should be a function that takes one argument, an 264 PRETTY-PRINTER should be a function that takes one argument, an
252 element, and inserts a string representing it in the buffer (at 265 element, and inserts a string representing it in the buffer (at
253 point). The string PRETTY-PRINTER inserts may be empty or span 266 point). The string PRETTY-PRINTER inserts may be empty or span
254 several lines. A trailing newline will always be inserted 267 several lines. The PRETTY-PRINTER should use `insert', and not
255 automatically. The PRETTY-PRINTER should use `insert', and not
256 `insert-before-markers'. 268 `insert-before-markers'.
257 269
258 Optional second argument HEADER is a string that will always be 270 Optional second and third arguments HEADER and FOOTER are strings,
259 present at the top of the ewoc. HEADER should end with a 271 possibly empty, that will always be present at the top and bottom,
260 newline. Optional third argument FOOTER is similar, and will 272 respectively, of the ewoc."
261 be inserted at the bottom of the ewoc."
262 (let* ((dummy-node (ewoc--node-create 'DL-LIST 'DL-LIST)) 273 (let* ((dummy-node (ewoc--node-create 'DL-LIST 'DL-LIST))
263 (dll (progn (setf (ewoc--node-right dummy-node) dummy-node) 274 (dll (progn (setf (ewoc--node-right dummy-node) dummy-node)
264 (setf (ewoc--node-left dummy-node) dummy-node) 275 (setf (ewoc--node-left dummy-node) dummy-node)
265 dummy-node)) 276 dummy-node))
266 (new-ewoc 277 (new-ewoc
525 (let ((pp (ewoc--pretty-printer ewoc)) 536 (let ((pp (ewoc--pretty-printer ewoc))
526 (node (ewoc--node-nth dll 1))) 537 (node (ewoc--node-nth dll 1)))
527 (while (not (eq node footer)) 538 (while (not (eq node footer))
528 (set-marker (ewoc--node-start-marker node) (point)) 539 (set-marker (ewoc--node-start-marker node) (point))
529 (funcall pp (ewoc--node-data node)) 540 (funcall pp (ewoc--node-data node))
530 (insert "\n")
531 (setq node (ewoc--node-next dll node))))) 541 (setq node (ewoc--node-next dll node)))))
532 (set-marker (ewoc--node-start-marker footer) (point)))) 542 (set-marker (ewoc--node-start-marker footer) (point))))
533 543
534 (defun ewoc-collect (ewoc predicate &rest args) 544 (defun ewoc-collect (ewoc predicate &rest args)
535 "Select elements from EWOC using PREDICATE. 545 "Select elements from EWOC using PREDICATE.
564 (cons (ewoc--node-data (ewoc--header ewoc)) 574 (cons (ewoc--node-data (ewoc--header ewoc))
565 (ewoc--node-data (ewoc--footer ewoc)))) 575 (ewoc--node-data (ewoc--footer ewoc))))
566 576
567 (defun ewoc-set-hf (ewoc header footer) 577 (defun ewoc-set-hf (ewoc header footer)
568 "Set the HEADER and FOOTER of EWOC." 578 "Set the HEADER and FOOTER of EWOC."
569 (setf (ewoc--node-data (ewoc--header ewoc)) header) 579 (ewoc--set-buffer-bind-dll-let* ewoc
570 (setf (ewoc--node-data (ewoc--footer ewoc)) footer) 580 ((head (ewoc--header ewoc))
571 (save-excursion 581 (foot (ewoc--footer ewoc)))
572 (ewoc--refresh-node 'insert (ewoc--header ewoc)) 582 (setf (ewoc--node-data head) header
573 (ewoc--refresh-node 'insert (ewoc--footer ewoc)))) 583 (ewoc--node-data foot) footer)
584 (save-excursion
585 (ewoc--refresh-node 'insert head)
586 (ewoc--refresh-node 'insert foot))))
574 587
575 588
576 (provide 'ewoc) 589 (provide 'ewoc)
577 590
578 ;;; Local Variables: 591 ;;; Local Variables: