mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
(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'.
This commit is contained in:
parent
7ece7aba2b
commit
bb7a346faa
2 changed files with 66 additions and 64 deletions
|
|
@ -101,44 +101,40 @@
|
|||
|
||||
(eval-when-compile (require 'cl))
|
||||
|
||||
;; The doubly linked list is implemented as a circular list
|
||||
;; with a dummy node first and last. The dummy node is used as
|
||||
;; "the dll" (or rather the dynamically bound `ewoc--current-dll').
|
||||
|
||||
(defvar ewoc--current-dll)
|
||||
|
||||
;; The doubly linked list is implemented as a circular list with a dummy
|
||||
;; node first and last. The dummy node is used as "the dll".
|
||||
(defstruct (ewoc--node
|
||||
(:type vector) ;ewoc--node-nth needs this
|
||||
(:constructor nil)
|
||||
(:constructor ewoc--node-create (start-marker data)))
|
||||
left right data start-marker)
|
||||
|
||||
(defun ewoc--node-next (node)
|
||||
(defun ewoc--node-next (dll node)
|
||||
"Return the node after NODE, or nil if NODE is the last node."
|
||||
(let ((R (ewoc--node-right node)))
|
||||
(unless (eq ewoc--current-dll R) R)))
|
||||
(unless (eq dll R) R)))
|
||||
|
||||
(defun ewoc--node-prev (node)
|
||||
(defun ewoc--node-prev (dll node)
|
||||
"Return the node before NODE, or nil if NODE is the first node."
|
||||
(let ((L (ewoc--node-left node)))
|
||||
(unless (eq ewoc--current-dll L) L)))
|
||||
(unless (eq dll L) L)))
|
||||
|
||||
(defun ewoc--node-nth (n)
|
||||
"Return the Nth node from the doubly linked list `ewoc--current-dll'.
|
||||
(defun ewoc--node-nth (dll n)
|
||||
"Return the Nth node from the doubly linked list `dll'.
|
||||
N counts from zero. If N is negative, return the -(N+1)th last element.
|
||||
If N is out of range, return nil.
|
||||
Thus, (ewoc--node-nth 0) returns the first node,
|
||||
and (ewoc--node-nth -1) returns the last node."
|
||||
Thus, (ewoc--node-nth dll 0) returns the first node,
|
||||
and (ewoc--node-nth dll -1) returns the last node."
|
||||
;; Presuming a node is ":type vector", starting with `left' and `right':
|
||||
;; Branch 0 ("follow left pointer") is used when n is negative.
|
||||
;; Branch 1 ("follow right pointer") is used otherwise.
|
||||
(let* ((branch (if (< n 0) 0 1))
|
||||
(node (aref ewoc--current-dll branch)))
|
||||
(node (aref dll branch)))
|
||||
(if (< n 0) (setq n (- -1 n)))
|
||||
(while (and (not (eq ewoc--current-dll node)) (> n 0))
|
||||
(while (and (not (eq dll node)) (> n 0))
|
||||
(setq node (aref node branch))
|
||||
(setq n (1- n)))
|
||||
(unless (eq ewoc--current-dll node) node)))
|
||||
(unless (eq dll node) node)))
|
||||
|
||||
(defun ewoc-location (node)
|
||||
"Return the start location of NODE."
|
||||
|
|
@ -155,13 +151,13 @@ and (ewoc--node-nth -1) returns the last node."
|
|||
|
||||
(defmacro ewoc--set-buffer-bind-dll-let* (ewoc varlist &rest forms)
|
||||
"Execute FORMS with ewoc--buffer selected as current buffer,
|
||||
`ewoc--current-dll' bound to the dll, and VARLIST bound as in a let*.
|
||||
`ewoc--current-dll' will be bound when VARLIST is initialized, but
|
||||
`dll' bound to the dll, and VARLIST bound as in a let*.
|
||||
`dll' will be bound when VARLIST is initialized, but
|
||||
the current buffer will *not* have been changed.
|
||||
Return value of last form in FORMS."
|
||||
(let ((hnd (make-symbol "ewoc")))
|
||||
`(let* ((,hnd ,ewoc)
|
||||
(ewoc--current-dll (ewoc--dll ,hnd))
|
||||
(dll (ewoc--dll ,hnd))
|
||||
,@varlist)
|
||||
(with-current-buffer (ewoc--buffer ,hnd)
|
||||
,@forms))))
|
||||
|
|
@ -176,7 +172,7 @@ BUT if it is the header or the footer in EWOC return nil instead."
|
|||
(eq node (ewoc--footer ewoc)))
|
||||
node))
|
||||
|
||||
(defun ewoc--adjust (beg end node)
|
||||
(defun ewoc--adjust (beg end node dll)
|
||||
;; "Manually reseat" markers for NODE and its successors (including footer
|
||||
;; and dll), in the case where they originally shared start position with
|
||||
;; BEG, to END. BEG and END are buffer positions describing NODE's left
|
||||
|
|
@ -187,9 +183,12 @@ BUT if it is the header or the footer in EWOC return nil instead."
|
|||
(when (< beg end)
|
||||
(let (m)
|
||||
(while (and (= beg (setq m (ewoc--node-start-marker node)))
|
||||
;; The "dummy" node `dll' actually holds the marker that
|
||||
;; points to the end of the footer, so we check `dll'
|
||||
;; *after* reseating the marker.
|
||||
(progn
|
||||
(set-marker m end)
|
||||
(not (eq ewoc--current-dll node))))
|
||||
(not (eq dll node))))
|
||||
(setq node (ewoc--node-right node))))))
|
||||
|
||||
(defun ewoc--insert-new-node (node data pretty-printer)
|
||||
|
|
@ -203,10 +202,10 @@ NODE and leaving the new node's start there. Return the new node."
|
|||
(ewoc--node-right elemnode) node
|
||||
(ewoc--node-right (ewoc--node-left node)) elemnode
|
||||
(ewoc--node-left node) elemnode)
|
||||
(ewoc--refresh-node pretty-printer elemnode)
|
||||
(ewoc--refresh-node pretty-printer elemnode dll)
|
||||
elemnode)))
|
||||
|
||||
(defun ewoc--refresh-node (pp node)
|
||||
(defun ewoc--refresh-node (pp node dll)
|
||||
"Redisplay the element represented by NODE using the pretty-printer PP."
|
||||
(let ((inhibit-read-only t)
|
||||
(m (ewoc--node-start-marker node))
|
||||
|
|
@ -216,7 +215,7 @@ NODE and leaving the new node's start there. Return the new node."
|
|||
;; Calculate and insert the string.
|
||||
(goto-char m)
|
||||
(funcall pp (ewoc--node-data node))
|
||||
(ewoc--adjust m (point) R)))
|
||||
(ewoc--adjust m (point) R dll)))
|
||||
|
||||
(defun ewoc--wrap (func)
|
||||
(lexical-let ((ewoc--user-pp func))
|
||||
|
|
@ -284,19 +283,19 @@ fourth arg NOSEP non-nil inhibits this."
|
|||
"Enter DATA first in EWOC.
|
||||
Return the new node."
|
||||
(ewoc--set-buffer-bind-dll ewoc
|
||||
(ewoc-enter-after ewoc (ewoc--node-nth 0) data)))
|
||||
(ewoc-enter-after ewoc (ewoc--node-nth dll 0) data)))
|
||||
|
||||
(defun ewoc-enter-last (ewoc data)
|
||||
"Enter DATA last in EWOC.
|
||||
Return the new node."
|
||||
(ewoc--set-buffer-bind-dll ewoc
|
||||
(ewoc-enter-before ewoc (ewoc--node-nth -1) data)))
|
||||
(ewoc-enter-before ewoc (ewoc--node-nth dll -1) data)))
|
||||
|
||||
(defun ewoc-enter-after (ewoc node data)
|
||||
"Enter a new element DATA after NODE in EWOC.
|
||||
Return the new node."
|
||||
(ewoc--set-buffer-bind-dll ewoc
|
||||
(ewoc-enter-before ewoc (ewoc--node-next node) data)))
|
||||
(ewoc-enter-before ewoc (ewoc--node-next dll node) data)))
|
||||
|
||||
(defun ewoc-enter-before (ewoc node data)
|
||||
"Enter a new element DATA before NODE in EWOC.
|
||||
|
|
@ -309,16 +308,14 @@ Return the new node."
|
|||
Return nil if NODE is nil or the last element."
|
||||
(when node
|
||||
(ewoc--filter-hf-nodes
|
||||
ewoc (let ((ewoc--current-dll (ewoc--dll ewoc)))
|
||||
(ewoc--node-next node)))))
|
||||
ewoc (ewoc--node-next (ewoc--dll ewoc) node))))
|
||||
|
||||
(defun ewoc-prev (ewoc node)
|
||||
"Return the node in EWOC that precedes NODE.
|
||||
Return nil if NODE is nil or the first element."
|
||||
(when node
|
||||
(ewoc--filter-hf-nodes
|
||||
ewoc (let ((ewoc--current-dll (ewoc--dll ewoc)))
|
||||
(ewoc--node-prev node)))))
|
||||
ewoc (ewoc--node-prev (ewoc--dll ewoc) node))))
|
||||
|
||||
(defun ewoc-nth (ewoc n)
|
||||
"Return the Nth node.
|
||||
|
|
@ -330,8 +327,7 @@ Use `ewoc-data' to extract the data from the node."
|
|||
;; Skip the header (or footer, if n is negative).
|
||||
(setq n (if (< n 0) (1- n) (1+ n)))
|
||||
(ewoc--filter-hf-nodes ewoc
|
||||
(let ((ewoc--current-dll (ewoc--dll ewoc)))
|
||||
(ewoc--node-nth n))))
|
||||
(ewoc--node-nth (ewoc--dll ewoc) n)))
|
||||
|
||||
(defun ewoc-map (map-function ewoc &rest args)
|
||||
"Apply MAP-FUNCTION to all elements in EWOC.
|
||||
|
|
@ -348,12 +344,12 @@ arguments will be passed to MAP-FUNCTION."
|
|||
(ewoc--set-buffer-bind-dll-let* ewoc
|
||||
((footer (ewoc--footer ewoc))
|
||||
(pp (ewoc--pretty-printer ewoc))
|
||||
(node (ewoc--node-nth 1)))
|
||||
(node (ewoc--node-nth dll 1)))
|
||||
(save-excursion
|
||||
(while (not (eq node footer))
|
||||
(if (apply map-function (ewoc--node-data node) args)
|
||||
(ewoc--refresh-node pp node))
|
||||
(setq node (ewoc--node-next node))))))
|
||||
(ewoc--refresh-node pp node dll))
|
||||
(setq node (ewoc--node-next dll node))))))
|
||||
|
||||
(defun ewoc-delete (ewoc &rest nodes)
|
||||
"Delete NODES from EWOC."
|
||||
|
|
@ -365,7 +361,7 @@ arguments will be passed to MAP-FUNCTION."
|
|||
(when (eq last node)
|
||||
(setf last nil (ewoc--last-node ewoc) nil))
|
||||
(delete-region (ewoc--node-start-marker node)
|
||||
(ewoc--node-start-marker (ewoc--node-next node)))
|
||||
(ewoc--node-start-marker (ewoc--node-next dll node)))
|
||||
(set-marker (ewoc--node-start-marker node) nil)
|
||||
(setf L (ewoc--node-left node)
|
||||
R (ewoc--node-right node)
|
||||
|
|
@ -384,14 +380,14 @@ if it changes it.
|
|||
The PREDICATE is called with the element as its first argument. If any
|
||||
ARGS are given they will be passed to the PREDICATE."
|
||||
(ewoc--set-buffer-bind-dll-let* ewoc
|
||||
((node (ewoc--node-nth 1))
|
||||
((node (ewoc--node-nth dll 1))
|
||||
(footer (ewoc--footer ewoc))
|
||||
(goodbye nil)
|
||||
(inhibit-read-only t))
|
||||
(while (not (eq node footer))
|
||||
(unless (apply predicate (ewoc--node-data node) args)
|
||||
(push node goodbye))
|
||||
(setq node (ewoc--node-next node)))
|
||||
(setq node (ewoc--node-next dll node)))
|
||||
(apply 'ewoc-delete ewoc goodbye)))
|
||||
|
||||
(defun ewoc-locate (ewoc &optional pos guess)
|
||||
|
|
@ -403,27 +399,26 @@ If POS points before the first element, the first node is returned.
|
|||
If POS points after the last element, the last node is returned.
|
||||
If the EWOC is empty, nil is returned."
|
||||
(unless pos (setq pos (point)))
|
||||
(ewoc--set-buffer-bind-dll-let* ewoc
|
||||
((footer (ewoc--footer ewoc)))
|
||||
(ewoc--set-buffer-bind-dll ewoc
|
||||
|
||||
(cond
|
||||
;; Nothing present?
|
||||
((eq (ewoc--node-nth 1) (ewoc--node-nth -1))
|
||||
((eq (ewoc--node-nth dll 1) (ewoc--node-nth dll -1))
|
||||
nil)
|
||||
|
||||
;; Before second elem?
|
||||
((< pos (ewoc--node-start-marker (ewoc--node-nth 2)))
|
||||
(ewoc--node-nth 1))
|
||||
((< pos (ewoc--node-start-marker (ewoc--node-nth dll 2)))
|
||||
(ewoc--node-nth dll 1))
|
||||
|
||||
;; After one-before-last elem?
|
||||
((>= pos (ewoc--node-start-marker (ewoc--node-nth -2)))
|
||||
(ewoc--node-nth -2))
|
||||
((>= pos (ewoc--node-start-marker (ewoc--node-nth dll -2)))
|
||||
(ewoc--node-nth dll -2))
|
||||
|
||||
;; We now know that pos is within a elem.
|
||||
(t
|
||||
;; Make an educated guess about which of the three known
|
||||
;; node'es (the first, the last, or GUESS) is nearest.
|
||||
(let* ((best-guess (ewoc--node-nth 1))
|
||||
(let* ((best-guess (ewoc--node-nth dll 1))
|
||||
(distance (abs (- pos (ewoc--node-start-marker best-guess)))))
|
||||
(when guess
|
||||
(let ((d (abs (- pos (ewoc--node-start-marker guess)))))
|
||||
|
|
@ -431,7 +426,7 @@ If the EWOC is empty, nil is returned."
|
|||
(setq distance d)
|
||||
(setq best-guess guess))))
|
||||
|
||||
(let* ((g (ewoc--node-nth -1)) ;Check the last elem
|
||||
(let* ((g (ewoc--node-nth dll -1)) ;Check the last elem
|
||||
(d (abs (- pos (ewoc--node-start-marker g)))))
|
||||
(when (< d distance)
|
||||
(setq distance d)
|
||||
|
|
@ -454,14 +449,14 @@ If the EWOC is empty, nil is returned."
|
|||
(ewoc--node-start-marker best-guess))
|
||||
;; Loop until we are exactly one node too far down...
|
||||
(while (>= pos (ewoc--node-start-marker best-guess))
|
||||
(setq best-guess (ewoc--node-next best-guess)))
|
||||
(setq best-guess (ewoc--node-next dll best-guess)))
|
||||
;; ...and return the previous node.
|
||||
(ewoc--node-prev best-guess))
|
||||
(ewoc--node-prev dll best-guess))
|
||||
|
||||
;; Pos is before best-guess
|
||||
(t
|
||||
(while (< pos (ewoc--node-start-marker best-guess))
|
||||
(setq best-guess (ewoc--node-prev best-guess)))
|
||||
(setq best-guess (ewoc--node-prev dll best-guess)))
|
||||
best-guess)))))))
|
||||
|
||||
(defun ewoc-invalidate (ewoc &rest nodes)
|
||||
|
|
@ -471,7 +466,7 @@ Delete current text first, thus effecting a \"refresh\"."
|
|||
((pp (ewoc--pretty-printer ewoc)))
|
||||
(save-excursion
|
||||
(dolist (node nodes)
|
||||
(ewoc--refresh-node pp node)))))
|
||||
(ewoc--refresh-node pp node dll)))))
|
||||
|
||||
(defun ewoc-goto-prev (ewoc arg)
|
||||
"Move point to the ARGth previous element in EWOC.
|
||||
|
|
@ -485,10 +480,10 @@ Return the node we moved to."
|
|||
(setq arg (1- arg)))
|
||||
(while (and node (> arg 0))
|
||||
(setq arg (1- arg))
|
||||
(setq node (ewoc--node-prev node)))
|
||||
(setq node (ewoc--node-prev dll node)))
|
||||
;; Never step above the first element.
|
||||
(unless (ewoc--filter-hf-nodes ewoc node)
|
||||
(setq node (ewoc--node-nth 1)))
|
||||
(setq node (ewoc--node-nth dll 1)))
|
||||
(ewoc-goto-node ewoc node))))
|
||||
|
||||
(defun ewoc-goto-next (ewoc arg)
|
||||
|
|
@ -498,10 +493,10 @@ Return the node (or nil if we just passed the last node)."
|
|||
((node (ewoc-locate ewoc (point))))
|
||||
(while (and node (> arg 0))
|
||||
(setq arg (1- arg))
|
||||
(setq node (ewoc--node-next node)))
|
||||
(setq node (ewoc--node-next dll node)))
|
||||
;; Never step below the first element.
|
||||
;; (unless (ewoc--filter-hf-nodes ewoc node)
|
||||
;; (setq node (ewoc--node-nth -2)))
|
||||
;; (setq node (ewoc--node-nth dll -2)))
|
||||
(ewoc-goto-node ewoc node)))
|
||||
|
||||
(defun ewoc-goto-node (ewoc node)
|
||||
|
|
@ -520,15 +515,15 @@ number of elements needs to be refreshed."
|
|||
(ewoc--set-buffer-bind-dll-let* ewoc
|
||||
((footer (ewoc--footer ewoc)))
|
||||
(let ((inhibit-read-only t))
|
||||
(delete-region (ewoc--node-start-marker (ewoc--node-nth 1))
|
||||
(delete-region (ewoc--node-start-marker (ewoc--node-nth dll 1))
|
||||
(ewoc--node-start-marker footer))
|
||||
(goto-char (ewoc--node-start-marker footer))
|
||||
(let ((pp (ewoc--pretty-printer ewoc))
|
||||
(node (ewoc--node-nth 1)))
|
||||
(node (ewoc--node-nth dll 1)))
|
||||
(while (not (eq node footer))
|
||||
(set-marker (ewoc--node-start-marker node) (point))
|
||||
(funcall pp (ewoc--node-data node))
|
||||
(setq node (ewoc--node-next node)))))
|
||||
(setq node (ewoc--node-next dll node)))))
|
||||
(set-marker (ewoc--node-start-marker footer) (point))))
|
||||
|
||||
(defun ewoc-collect (ewoc predicate &rest args)
|
||||
|
|
@ -545,12 +540,12 @@ If more than two arguments are given the
|
|||
remaining arguments will be passed to PREDICATE."
|
||||
(ewoc--set-buffer-bind-dll-let* ewoc
|
||||
((header (ewoc--header ewoc))
|
||||
(node (ewoc--node-nth -2))
|
||||
(node (ewoc--node-nth dll -2))
|
||||
result)
|
||||
(while (not (eq node header))
|
||||
(if (apply predicate (ewoc--node-data node) args)
|
||||
(push (ewoc--node-data node) result))
|
||||
(setq node (ewoc--node-prev node)))
|
||||
(setq node (ewoc--node-prev dll node)))
|
||||
(nreverse result)))
|
||||
|
||||
(defun ewoc-buffer (ewoc)
|
||||
|
|
@ -573,8 +568,8 @@ Return nil if the buffer has been deleted."
|
|||
(setf (ewoc--node-data head) header
|
||||
(ewoc--node-data foot) footer)
|
||||
(save-excursion
|
||||
(ewoc--refresh-node hf-pp head)
|
||||
(ewoc--refresh-node hf-pp foot))))
|
||||
(ewoc--refresh-node hf-pp head dll)
|
||||
(ewoc--refresh-node hf-pp foot dll))))
|
||||
|
||||
|
||||
(provide 'ewoc)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue