2012-04-26 08:43:28 -04:00
|
|
|
|
;;; ewoc.el --- utility to maintain a view of a list of objects in a buffer -*- lexical-binding: t -*-
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
2022-01-01 02:45:51 -05:00
|
|
|
|
;; Copyright (C) 1991-2022 Free Software Foundation, Inc.
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
;; Author: Per Cederqvist <ceder@lysator.liu.se>
|
|
|
|
|
;; Inge Wallin <inge@lysator.liu.se>
|
2019-05-19 21:29:13 -07:00
|
|
|
|
;; Maintainer: Stefan Monnier <monnier@gnu.org>
|
2000-03-11 03:51:31 +00:00
|
|
|
|
;; Created: 3 Aug 1992
|
|
|
|
|
;; Keywords: extensions, lisp
|
|
|
|
|
|
|
|
|
|
;; This file is part of GNU Emacs.
|
|
|
|
|
|
2008-05-06 03:21:21 +00:00
|
|
|
|
;; GNU Emacs is free software: you can redistribute it and/or modify
|
2000-03-11 03:51:31 +00:00
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
2008-05-06 03:21:21 +00:00
|
|
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
;; (at your option) any later version.
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
2017-09-13 15:52:52 -07:00
|
|
|
|
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
|
|
|
|
;; Ewoc Was Once Cookie
|
2012-02-28 00:17:21 -08:00
|
|
|
|
;; But now it's Emacs's Widget for Object Collections
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
;; As the name implies this derives from the `cookie' package (part
|
2000-10-15 05:16:36 +00:00
|
|
|
|
;; of Elib). The changes are pervasive though mostly superficial:
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
2000-10-15 05:16:36 +00:00
|
|
|
|
;; - uses CL (and its `defstruct')
|
2000-03-11 03:51:31 +00:00
|
|
|
|
;; - separate from Elib.
|
|
|
|
|
;; - uses its own version of a doubly-linked list which allows us
|
|
|
|
|
;; to merge the elib-wrapper and the elib-node structures into ewoc-node
|
|
|
|
|
;; - dropping functions not used by PCL-CVS (the only client of ewoc at the
|
|
|
|
|
;; time of writing)
|
|
|
|
|
;; - removing unused arguments
|
|
|
|
|
;; - renaming:
|
|
|
|
|
;; elib-node ==> ewoc--node
|
|
|
|
|
;; collection ==> ewoc
|
|
|
|
|
;; tin ==> ewoc--node
|
|
|
|
|
;; cookie ==> data or element or elem
|
|
|
|
|
|
|
|
|
|
;; Introduction
|
|
|
|
|
;; ============
|
|
|
|
|
;;
|
|
|
|
|
;; Ewoc is a package that implements a connection between an
|
|
|
|
|
;; dll (a doubly linked list) and the contents of a buffer.
|
2021-09-27 23:56:55 +02:00
|
|
|
|
;; Possible uses are Dired (have all files in a list, and show them),
|
2000-03-11 03:51:31 +00:00
|
|
|
|
;; buffer-list, kom-prioritize (in the LysKOM elisp client) and
|
2008-05-09 22:31:03 +00:00
|
|
|
|
;; others. pcl-cvs.el and vc.el use ewoc.el.
|
2000-03-11 03:51:31 +00:00
|
|
|
|
;;
|
|
|
|
|
;; Ewoc can be considered as the `view' part of a model-view-controller.
|
|
|
|
|
;;
|
2021-09-14 07:55:56 +02:00
|
|
|
|
;; An `element' can be any Lisp object. When you use the ewoc
|
2000-03-11 03:51:31 +00:00
|
|
|
|
;; package you specify a pretty-printer, a function that inserts
|
|
|
|
|
;; a printable representation of the element in the buffer. (The
|
|
|
|
|
;; pretty-printer should use "insert" and not
|
|
|
|
|
;; "insert-before-markers").
|
|
|
|
|
;;
|
|
|
|
|
;; A `ewoc' consists of a doubly linked list of elements, a
|
|
|
|
|
;; header, a footer and a pretty-printer. It is displayed at a
|
|
|
|
|
;; certain point in a certain buffer. (The buffer and point are
|
|
|
|
|
;; fixed when the ewoc is created). The header and the footer
|
|
|
|
|
;; are constant strings. They appear before and after the elements.
|
|
|
|
|
;;
|
2021-09-14 07:55:56 +02:00
|
|
|
|
;; Ewoc does not affect the mode of the buffer in any way. It
|
2000-03-11 03:51:31 +00:00
|
|
|
|
;; merely makes it easy to connect an underlying data representation
|
|
|
|
|
;; to the buffer contents.
|
|
|
|
|
;;
|
|
|
|
|
;; A `ewoc--node' is an object that contains one element. There are
|
2000-10-15 05:16:36 +00:00
|
|
|
|
;; functions in this package that given an ewoc--node extract the data, or
|
|
|
|
|
;; give the next or previous ewoc--node. (All ewoc--nodes are linked together
|
|
|
|
|
;; in a doubly linked list. The `previous' ewoc--node is the one that appears
|
2000-03-11 03:51:31 +00:00
|
|
|
|
;; before the other in the buffer.) You should not do anything with
|
|
|
|
|
;; an ewoc--node except pass it to the functions in this package.
|
|
|
|
|
;;
|
|
|
|
|
;; An ewoc is a very dynamic thing. You can easily add or delete elements.
|
|
|
|
|
;; You can apply a function to all elements in an ewoc, etc, etc.
|
|
|
|
|
;;
|
|
|
|
|
;; Remember that an element can be anything. Your imagination is the
|
|
|
|
|
;; limit! It is even possible to have another ewoc as an
|
|
|
|
|
;; element. In that way some kind of tree hierarchy can be created.
|
|
|
|
|
;;
|
2006-05-27 18:13:15 +00:00
|
|
|
|
;; The Emacs Lisp Reference Manual documents ewoc.el's "public interface".
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
;; Coding conventions
|
|
|
|
|
;; ==================
|
|
|
|
|
;;
|
|
|
|
|
;; All functions of course start with `ewoc'. Functions and macros
|
|
|
|
|
;; starting with the prefix `ewoc--' are meant for internal use,
|
|
|
|
|
;; while those starting with `ewoc-' are exported for public use.
|
|
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
2012-06-10 09:28:26 -04:00
|
|
|
|
(eval-when-compile (require 'cl-lib))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
2006-05-29 04:39:46 +00:00
|
|
|
|
;; 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".
|
2012-06-10 09:28:26 -04:00
|
|
|
|
(cl-defstruct (ewoc--node
|
2006-05-27 10:10:35 +00:00
|
|
|
|
(:type vector) ;ewoc--node-nth needs this
|
2006-05-27 11:16:18 +00:00
|
|
|
|
(:constructor nil)
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(:constructor ewoc--node-create (start-marker data)))
|
|
|
|
|
left right data start-marker)
|
|
|
|
|
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(defun ewoc--node-next (dll node)
|
2000-03-11 03:51:31 +00:00
|
|
|
|
"Return the node after NODE, or nil if NODE is the last node."
|
2006-05-26 08:31:36 +00:00
|
|
|
|
(let ((R (ewoc--node-right node)))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(unless (eq dll R) R)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(defun ewoc--node-prev (dll node)
|
2000-03-11 03:51:31 +00:00
|
|
|
|
"Return the node before NODE, or nil if NODE is the first node."
|
2006-05-26 08:31:36 +00:00
|
|
|
|
(let ((L (ewoc--node-left node)))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(unless (eq dll L) L)))
|
2006-05-26 08:31:36 +00:00
|
|
|
|
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(defun ewoc--node-nth (dll n)
|
2021-09-14 07:55:56 +02:00
|
|
|
|
"Return the Nth node from the doubly linked list DLL.
|
2006-05-26 08:31:36 +00:00
|
|
|
|
N counts from zero. If N is negative, return the -(N+1)th last element.
|
|
|
|
|
If N is out of range, return nil.
|
2006-05-29 04:39:46 +00:00
|
|
|
|
Thus, (ewoc--node-nth dll 0) returns the first node,
|
|
|
|
|
and (ewoc--node-nth dll -1) returns the last node."
|
2006-05-27 10:10:35 +00:00
|
|
|
|
;; Presuming a node is ":type vector", starting with `left' and `right':
|
2000-03-11 03:51:31 +00:00
|
|
|
|
;; 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))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(node (aref dll branch)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(if (< n 0) (setq n (- -1 n)))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(while (and (not (eq dll node)) (> n 0))
|
2006-05-27 10:10:35 +00:00
|
|
|
|
(setq node (aref node branch))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(setq n (1- n)))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(unless (eq dll node) node)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
2000-10-15 05:16:36 +00:00
|
|
|
|
(defun ewoc-location (node)
|
|
|
|
|
"Return the start location of NODE."
|
|
|
|
|
(ewoc--node-start-marker node))
|
|
|
|
|
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
;;; The ewoc data type
|
|
|
|
|
|
2012-06-10 09:28:26 -04:00
|
|
|
|
(cl-defstruct (ewoc
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(:constructor nil)
|
2006-05-27 08:56:11 +00:00
|
|
|
|
(:constructor ewoc--create (buffer pretty-printer dll))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(:conc-name ewoc--))
|
2006-05-27 17:39:38 +00:00
|
|
|
|
buffer pretty-printer header footer dll last-node hf-pp)
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
(defmacro ewoc--set-buffer-bind-dll-let* (ewoc varlist &rest forms)
|
2021-09-18 13:12:41 +02:00
|
|
|
|
"Execute FORMS with `ewoc--buffer' selected as current buffer,
|
2006-05-29 04:39:46 +00:00
|
|
|
|
`dll' bound to the dll, and VARLIST bound as in a let*.
|
|
|
|
|
`dll' will be bound when VARLIST is initialized, but
|
2006-05-26 08:31:36 +00:00
|
|
|
|
the current buffer will *not* have been changed.
|
2000-03-11 03:51:31 +00:00
|
|
|
|
Return value of last form in FORMS."
|
2006-05-08 08:02:25 +00:00
|
|
|
|
(let ((hnd (make-symbol "ewoc")))
|
|
|
|
|
`(let* ((,hnd ,ewoc)
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(dll (ewoc--dll ,hnd))
|
2001-11-27 15:52:52 +00:00
|
|
|
|
,@varlist)
|
2006-05-08 08:02:25 +00:00
|
|
|
|
(with-current-buffer (ewoc--buffer ,hnd)
|
|
|
|
|
,@forms))))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
(defmacro ewoc--set-buffer-bind-dll (ewoc &rest forms)
|
|
|
|
|
`(ewoc--set-buffer-bind-dll-let* ,ewoc nil ,@forms))
|
|
|
|
|
|
|
|
|
|
(defsubst ewoc--filter-hf-nodes (ewoc node)
|
|
|
|
|
"Evaluate NODE once and return it.
|
|
|
|
|
BUT if it is the header or the footer in EWOC return nil instead."
|
|
|
|
|
(unless (or (eq node (ewoc--header ewoc))
|
|
|
|
|
(eq node (ewoc--footer ewoc)))
|
|
|
|
|
node))
|
|
|
|
|
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(defun ewoc--adjust (beg end node dll)
|
2006-05-18 12:04:40 +00:00
|
|
|
|
;; "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
|
|
|
|
|
;; neighbor. This operation is functionally equivalent to temporarily
|
|
|
|
|
;; setting these nodes' markers' insertion type to t around the pretty-print
|
2006-05-26 08:31:36 +00:00
|
|
|
|
;; call that precedes the call to `ewoc--adjust', and then changing them back
|
2006-05-18 12:04:40 +00:00
|
|
|
|
;; to nil.
|
|
|
|
|
(when (< beg end)
|
|
|
|
|
(let (m)
|
|
|
|
|
(while (and (= beg (setq m (ewoc--node-start-marker node)))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
;; The "dummy" node `dll' actually holds the marker that
|
|
|
|
|
;; points to the end of the footer, so we check `dll'
|
|
|
|
|
;; *after* reseating the marker.
|
2006-05-18 12:04:40 +00:00
|
|
|
|
(progn
|
|
|
|
|
(set-marker m end)
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(not (eq dll node))))
|
2006-05-18 12:04:40 +00:00
|
|
|
|
(setq node (ewoc--node-right node))))))
|
|
|
|
|
|
2007-03-30 16:12:19 +00:00
|
|
|
|
(defun ewoc--insert-new-node (node data pretty-printer dll)
|
2006-05-12 15:14:45 +00:00
|
|
|
|
"Insert before NODE a new node for DATA, displayed by PRETTY-PRINTER.
|
2007-03-30 16:12:19 +00:00
|
|
|
|
Fourth arg DLL -- from `(ewoc--dll EWOC)' -- is for internal purposes.
|
2006-05-12 15:14:45 +00:00
|
|
|
|
Call PRETTY-PRINTER with point at NODE's start, thus pushing back
|
|
|
|
|
NODE and leaving the new node's start there. Return the new node."
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(save-excursion
|
2006-05-29 03:47:56 +00:00
|
|
|
|
(let ((elemnode (ewoc--node-create
|
|
|
|
|
(copy-marker (ewoc--node-start-marker node)) data)))
|
Provide generalized variables in core Elisp.
* lisp/emacs-lisp/gv.el: New file.
* lisp/subr.el (push, pop): Extend to generalized variables.
* lisp/loadup.el (macroexp): Unload if preloaded and uncompiled.
* lisp/emacs-lisp/cl-lib.el (cl-pop, cl-push, cl--set-nthcdr): Remove.
* lisp/emacs-lisp/cl-macs.el: Require gv. Use gv-define-setter,
gv-define-simple-setter, and gv-define-expander.
Remove setf-methods defined in gv. Rename cl-setf -> setf.
(cl-setf, cl-do-pop, cl-get-setf-method): Remove.
(cl-letf, cl-letf*, cl-define-modify-macro, cl-defsetf)
(cl-define-setf-expander, cl-struct-setf-expander): Move to cl.el.
(cl-remf, cl-shiftf, cl-rotatef, cl-callf, cl-callf2): Rewrite with
gv-letplace.
(cl-defstruct): Don't define setf-method any more.
* lisp/emacs-lisp/cl.el (flet): Don't autoload.
(cl--letf, letf, cl--letf*, letf*, cl--gv-adapt)
(define-setf-expander, defsetf, define-modify-macro)
(cl-struct-setf-expander): Move from cl-lib.el.
* lisp/emacs-lisp/syntax.el:
* lisp/emacs-lisp/ewoc.el:
* lisp/emacs-lisp/smie.el:
* lisp/emacs-lisp/cconv.el:
* lisp/emacs-lisp/timer.el: Rename cl-setf -> setf, cl-push -> push.
(timer--time): Use gv-define-simple-setter.
* lisp/emacs-lisp/macroexp.el (macroexp-let2): Rename from macroexp-let²
to avoid coding-system problems in subr.el. Adjust all users.
(macroexp--maxsize, macroexp-small-p): New functions.
* lisp/emacs-lisp/bytecomp.el (byte-compile-file): Don't use cl-letf.
* lisp/scroll-bar.el (scroll-bar-mode):
* lisp/simple.el (auto-fill-mode, overwrite-mode, binary-overwrite-mode)
(normal-erase-is-backspace-mode): Don't use the `eq' place.
* lisp/winner.el (winner-configuration, winner-make-point-alist)
(winner-set-conf, winner-get-point, winner-set): Don't abuse letf.
* lisp/files.el (locate-file-completion-table): Avoid list*.
Fixes: debbugs:11657
2012-06-22 09:42:38 -04:00
|
|
|
|
(setf (ewoc--node-left elemnode) (ewoc--node-left node)
|
|
|
|
|
(ewoc--node-right elemnode) node
|
|
|
|
|
(ewoc--node-right (ewoc--node-left node)) elemnode
|
|
|
|
|
(ewoc--node-left node) elemnode)
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(ewoc--refresh-node pretty-printer elemnode dll)
|
2006-05-12 15:14:45 +00:00
|
|
|
|
elemnode)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(defun ewoc--refresh-node (pp node dll)
|
2000-03-22 02:57:23 +00:00
|
|
|
|
"Redisplay the element represented by NODE using the pretty-printer PP."
|
2020-09-05 22:18:59 +03:00
|
|
|
|
(let* ((m (ewoc--node-start-marker node))
|
|
|
|
|
(R (ewoc--node-right node))
|
|
|
|
|
(end (ewoc--node-start-marker R))
|
|
|
|
|
(inhibit-read-only t)
|
|
|
|
|
(offset (if (= (point) end)
|
|
|
|
|
'end
|
|
|
|
|
(when (< m (point) end)
|
|
|
|
|
(- (point) m)))))
|
|
|
|
|
(save-excursion
|
|
|
|
|
;; First, remove the string from the buffer:
|
|
|
|
|
(delete-region m end)
|
|
|
|
|
;; Calculate and insert the string.
|
|
|
|
|
(goto-char m)
|
|
|
|
|
(funcall pp (ewoc--node-data node))
|
|
|
|
|
(setq end (point))
|
|
|
|
|
(ewoc--adjust m (point) R dll))
|
|
|
|
|
(when offset
|
|
|
|
|
(goto-char (if (eq offset 'end)
|
|
|
|
|
end
|
|
|
|
|
(min (+ m offset) (1- end)))))))
|
2006-05-27 17:39:38 +00:00
|
|
|
|
|
|
|
|
|
(defun ewoc--wrap (func)
|
2012-04-26 08:43:28 -04:00
|
|
|
|
(lambda (data)
|
|
|
|
|
(funcall func data)
|
|
|
|
|
(insert "\n")))
|
2006-05-27 17:39:38 +00:00
|
|
|
|
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
;;; ===========================================================================
|
|
|
|
|
;;; Public members of the Ewoc package
|
|
|
|
|
|
2006-05-21 22:25:22 +00:00
|
|
|
|
;;;###autoload
|
2006-05-27 17:39:38 +00:00
|
|
|
|
(defun ewoc-create (pretty-printer &optional header footer nosep)
|
2000-03-11 03:51:31 +00:00
|
|
|
|
"Create an empty ewoc.
|
|
|
|
|
|
2000-03-22 02:57:23 +00:00
|
|
|
|
The ewoc will be inserted in the current buffer at the current position.
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
PRETTY-PRINTER should be a function that takes one argument, an
|
|
|
|
|
element, and inserts a string representing it in the buffer (at
|
2004-06-16 23:50:03 +00:00
|
|
|
|
point). The string PRETTY-PRINTER inserts may be empty or span
|
2006-05-18 12:04:40 +00:00
|
|
|
|
several lines. The PRETTY-PRINTER should use `insert', and not
|
2004-06-16 23:50:03 +00:00
|
|
|
|
`insert-before-markers'.
|
|
|
|
|
|
2006-05-18 12:04:40 +00:00
|
|
|
|
Optional second and third arguments HEADER and FOOTER are strings,
|
|
|
|
|
possibly empty, that will always be present at the top and bottom,
|
2006-05-27 17:39:38 +00:00
|
|
|
|
respectively, of the ewoc.
|
|
|
|
|
|
|
|
|
|
Normally, a newline is automatically inserted after the header,
|
|
|
|
|
the footer and every node's printed representation. Optional
|
|
|
|
|
fourth arg NOSEP non-nil inhibits this."
|
2006-05-10 08:02:21 +00:00
|
|
|
|
(let* ((dummy-node (ewoc--node-create 'DL-LIST 'DL-LIST))
|
Provide generalized variables in core Elisp.
* lisp/emacs-lisp/gv.el: New file.
* lisp/subr.el (push, pop): Extend to generalized variables.
* lisp/loadup.el (macroexp): Unload if preloaded and uncompiled.
* lisp/emacs-lisp/cl-lib.el (cl-pop, cl-push, cl--set-nthcdr): Remove.
* lisp/emacs-lisp/cl-macs.el: Require gv. Use gv-define-setter,
gv-define-simple-setter, and gv-define-expander.
Remove setf-methods defined in gv. Rename cl-setf -> setf.
(cl-setf, cl-do-pop, cl-get-setf-method): Remove.
(cl-letf, cl-letf*, cl-define-modify-macro, cl-defsetf)
(cl-define-setf-expander, cl-struct-setf-expander): Move to cl.el.
(cl-remf, cl-shiftf, cl-rotatef, cl-callf, cl-callf2): Rewrite with
gv-letplace.
(cl-defstruct): Don't define setf-method any more.
* lisp/emacs-lisp/cl.el (flet): Don't autoload.
(cl--letf, letf, cl--letf*, letf*, cl--gv-adapt)
(define-setf-expander, defsetf, define-modify-macro)
(cl-struct-setf-expander): Move from cl-lib.el.
* lisp/emacs-lisp/syntax.el:
* lisp/emacs-lisp/ewoc.el:
* lisp/emacs-lisp/smie.el:
* lisp/emacs-lisp/cconv.el:
* lisp/emacs-lisp/timer.el: Rename cl-setf -> setf, cl-push -> push.
(timer--time): Use gv-define-simple-setter.
* lisp/emacs-lisp/macroexp.el (macroexp-let2): Rename from macroexp-let²
to avoid coding-system problems in subr.el. Adjust all users.
(macroexp--maxsize, macroexp-small-p): New functions.
* lisp/emacs-lisp/bytecomp.el (byte-compile-file): Don't use cl-letf.
* lisp/scroll-bar.el (scroll-bar-mode):
* lisp/simple.el (auto-fill-mode, overwrite-mode, binary-overwrite-mode)
(normal-erase-is-backspace-mode): Don't use the `eq' place.
* lisp/winner.el (winner-configuration, winner-make-point-alist)
(winner-set-conf, winner-get-point, winner-set): Don't abuse letf.
* lisp/files.el (locate-file-completion-table): Avoid list*.
Fixes: debbugs:11657
2012-06-22 09:42:38 -04:00
|
|
|
|
(dll (progn (setf (ewoc--node-right dummy-node) dummy-node)
|
|
|
|
|
(setf (ewoc--node-left dummy-node) dummy-node)
|
2006-05-10 08:02:21 +00:00
|
|
|
|
dummy-node))
|
2006-05-27 17:39:38 +00:00
|
|
|
|
(wrap (if nosep 'identity 'ewoc--wrap))
|
2006-05-27 08:56:11 +00:00
|
|
|
|
(new-ewoc (ewoc--create (current-buffer)
|
2006-05-27 17:39:38 +00:00
|
|
|
|
(funcall wrap pretty-printer)
|
2006-05-27 08:56:11 +00:00
|
|
|
|
dll))
|
2006-05-27 17:39:38 +00:00
|
|
|
|
(hf-pp (funcall wrap 'insert))
|
2006-05-12 15:14:45 +00:00
|
|
|
|
(pos (point))
|
|
|
|
|
head foot)
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(ewoc--set-buffer-bind-dll new-ewoc
|
|
|
|
|
;; Set default values
|
|
|
|
|
(unless header (setq header ""))
|
|
|
|
|
(unless footer (setq footer ""))
|
Provide generalized variables in core Elisp.
* lisp/emacs-lisp/gv.el: New file.
* lisp/subr.el (push, pop): Extend to generalized variables.
* lisp/loadup.el (macroexp): Unload if preloaded and uncompiled.
* lisp/emacs-lisp/cl-lib.el (cl-pop, cl-push, cl--set-nthcdr): Remove.
* lisp/emacs-lisp/cl-macs.el: Require gv. Use gv-define-setter,
gv-define-simple-setter, and gv-define-expander.
Remove setf-methods defined in gv. Rename cl-setf -> setf.
(cl-setf, cl-do-pop, cl-get-setf-method): Remove.
(cl-letf, cl-letf*, cl-define-modify-macro, cl-defsetf)
(cl-define-setf-expander, cl-struct-setf-expander): Move to cl.el.
(cl-remf, cl-shiftf, cl-rotatef, cl-callf, cl-callf2): Rewrite with
gv-letplace.
(cl-defstruct): Don't define setf-method any more.
* lisp/emacs-lisp/cl.el (flet): Don't autoload.
(cl--letf, letf, cl--letf*, letf*, cl--gv-adapt)
(define-setf-expander, defsetf, define-modify-macro)
(cl-struct-setf-expander): Move from cl-lib.el.
* lisp/emacs-lisp/syntax.el:
* lisp/emacs-lisp/ewoc.el:
* lisp/emacs-lisp/smie.el:
* lisp/emacs-lisp/cconv.el:
* lisp/emacs-lisp/timer.el: Rename cl-setf -> setf, cl-push -> push.
(timer--time): Use gv-define-simple-setter.
* lisp/emacs-lisp/macroexp.el (macroexp-let2): Rename from macroexp-let²
to avoid coding-system problems in subr.el. Adjust all users.
(macroexp--maxsize, macroexp-small-p): New functions.
* lisp/emacs-lisp/bytecomp.el (byte-compile-file): Don't use cl-letf.
* lisp/scroll-bar.el (scroll-bar-mode):
* lisp/simple.el (auto-fill-mode, overwrite-mode, binary-overwrite-mode)
(normal-erase-is-backspace-mode): Don't use the `eq' place.
* lisp/winner.el (winner-configuration, winner-make-point-alist)
(winner-set-conf, winner-get-point, winner-set): Don't abuse letf.
* lisp/files.el (locate-file-completion-table): Avoid list*.
Fixes: debbugs:11657
2012-06-22 09:42:38 -04:00
|
|
|
|
(setf (ewoc--node-start-marker dll) (copy-marker pos)
|
|
|
|
|
foot (ewoc--insert-new-node dll footer hf-pp dll)
|
|
|
|
|
head (ewoc--insert-new-node foot header hf-pp dll)
|
|
|
|
|
(ewoc--hf-pp new-ewoc) hf-pp
|
|
|
|
|
(ewoc--footer new-ewoc) foot
|
|
|
|
|
(ewoc--header new-ewoc) head))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
;; Return the ewoc
|
|
|
|
|
new-ewoc))
|
|
|
|
|
|
2006-05-17 06:12:44 +00:00
|
|
|
|
(defalias 'ewoc-data 'ewoc--node-data
|
|
|
|
|
"Extract the data encapsulated by NODE and return it.
|
|
|
|
|
|
|
|
|
|
\(fn NODE)")
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
2006-05-22 05:41:48 +00:00
|
|
|
|
(defun ewoc-set-data (node data)
|
|
|
|
|
"Set NODE to encapsulate DATA."
|
Provide generalized variables in core Elisp.
* lisp/emacs-lisp/gv.el: New file.
* lisp/subr.el (push, pop): Extend to generalized variables.
* lisp/loadup.el (macroexp): Unload if preloaded and uncompiled.
* lisp/emacs-lisp/cl-lib.el (cl-pop, cl-push, cl--set-nthcdr): Remove.
* lisp/emacs-lisp/cl-macs.el: Require gv. Use gv-define-setter,
gv-define-simple-setter, and gv-define-expander.
Remove setf-methods defined in gv. Rename cl-setf -> setf.
(cl-setf, cl-do-pop, cl-get-setf-method): Remove.
(cl-letf, cl-letf*, cl-define-modify-macro, cl-defsetf)
(cl-define-setf-expander, cl-struct-setf-expander): Move to cl.el.
(cl-remf, cl-shiftf, cl-rotatef, cl-callf, cl-callf2): Rewrite with
gv-letplace.
(cl-defstruct): Don't define setf-method any more.
* lisp/emacs-lisp/cl.el (flet): Don't autoload.
(cl--letf, letf, cl--letf*, letf*, cl--gv-adapt)
(define-setf-expander, defsetf, define-modify-macro)
(cl-struct-setf-expander): Move from cl-lib.el.
* lisp/emacs-lisp/syntax.el:
* lisp/emacs-lisp/ewoc.el:
* lisp/emacs-lisp/smie.el:
* lisp/emacs-lisp/cconv.el:
* lisp/emacs-lisp/timer.el: Rename cl-setf -> setf, cl-push -> push.
(timer--time): Use gv-define-simple-setter.
* lisp/emacs-lisp/macroexp.el (macroexp-let2): Rename from macroexp-let²
to avoid coding-system problems in subr.el. Adjust all users.
(macroexp--maxsize, macroexp-small-p): New functions.
* lisp/emacs-lisp/bytecomp.el (byte-compile-file): Don't use cl-letf.
* lisp/scroll-bar.el (scroll-bar-mode):
* lisp/simple.el (auto-fill-mode, overwrite-mode, binary-overwrite-mode)
(normal-erase-is-backspace-mode): Don't use the `eq' place.
* lisp/winner.el (winner-configuration, winner-make-point-alist)
(winner-set-conf, winner-get-point, winner-set): Don't abuse letf.
* lisp/files.el (locate-file-completion-table): Avoid list*.
Fixes: debbugs:11657
2012-06-22 09:42:38 -04:00
|
|
|
|
(setf (ewoc--node-data node) data))
|
2006-05-22 05:41:48 +00:00
|
|
|
|
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(defun ewoc-enter-first (ewoc data)
|
2005-06-11 20:33:28 +00:00
|
|
|
|
"Enter DATA first in EWOC.
|
|
|
|
|
Return the new node."
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(ewoc--set-buffer-bind-dll ewoc
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(ewoc-enter-after ewoc (ewoc--node-nth dll 0) data)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
(defun ewoc-enter-last (ewoc data)
|
2005-06-11 20:33:28 +00:00
|
|
|
|
"Enter DATA last in EWOC.
|
|
|
|
|
Return the new node."
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(ewoc--set-buffer-bind-dll ewoc
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(ewoc-enter-before ewoc (ewoc--node-nth dll -1) data)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
(defun ewoc-enter-after (ewoc node data)
|
2000-10-15 05:16:36 +00:00
|
|
|
|
"Enter a new element DATA after NODE in EWOC.
|
2005-06-11 20:33:28 +00:00
|
|
|
|
Return the new node."
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(ewoc--set-buffer-bind-dll ewoc
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(ewoc-enter-before ewoc (ewoc--node-next dll node) data)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
(defun ewoc-enter-before (ewoc node data)
|
2000-10-15 05:16:36 +00:00
|
|
|
|
"Enter a new element DATA before NODE in EWOC.
|
2005-06-11 20:33:28 +00:00
|
|
|
|
Return the new node."
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(ewoc--set-buffer-bind-dll ewoc
|
2007-03-30 16:12:19 +00:00
|
|
|
|
(ewoc--insert-new-node node data (ewoc--pretty-printer ewoc) dll)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
(defun ewoc-next (ewoc node)
|
2005-06-11 20:33:28 +00:00
|
|
|
|
"Return the node in EWOC that follows NODE.
|
|
|
|
|
Return nil if NODE is nil or the last element."
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(when node
|
|
|
|
|
(ewoc--filter-hf-nodes
|
2006-05-29 04:39:46 +00:00
|
|
|
|
ewoc (ewoc--node-next (ewoc--dll ewoc) node))))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
(defun ewoc-prev (ewoc node)
|
2005-06-11 20:33:28 +00:00
|
|
|
|
"Return the node in EWOC that precedes NODE.
|
|
|
|
|
Return nil if NODE is nil or the first element."
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(when node
|
|
|
|
|
(ewoc--filter-hf-nodes
|
2006-05-29 04:39:46 +00:00
|
|
|
|
ewoc (ewoc--node-prev (ewoc--dll ewoc) node))))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
(defun ewoc-nth (ewoc n)
|
|
|
|
|
"Return the Nth node.
|
2001-12-20 19:01:00 +00:00
|
|
|
|
N counts from zero. Return nil if there is less than N elements.
|
2000-03-11 03:51:31 +00:00
|
|
|
|
If N is negative, return the -(N+1)th last element.
|
2006-05-26 08:31:36 +00:00
|
|
|
|
Thus, (ewoc-nth ewoc 0) returns the first node,
|
|
|
|
|
and (ewoc-nth ewoc -1) returns the last node.
|
2006-05-17 06:12:44 +00:00
|
|
|
|
Use `ewoc-data' to extract the data from the node."
|
2000-03-11 03:51:31 +00:00
|
|
|
|
;; Skip the header (or footer, if n is negative).
|
|
|
|
|
(setq n (if (< n 0) (1- n) (1+ n)))
|
|
|
|
|
(ewoc--filter-hf-nodes ewoc
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(ewoc--node-nth (ewoc--dll ewoc) n)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
(defun ewoc-map (map-function ewoc &rest args)
|
|
|
|
|
"Apply MAP-FUNCTION to all elements in EWOC.
|
|
|
|
|
MAP-FUNCTION is applied to the first element first.
|
|
|
|
|
If MAP-FUNCTION returns non-nil the element will be refreshed (its
|
|
|
|
|
pretty-printer will be called once again).
|
|
|
|
|
|
2004-06-16 23:50:03 +00:00
|
|
|
|
Note that the buffer for EWOC will be the current buffer when
|
|
|
|
|
MAP-FUNCTION is called. MAP-FUNCTION must restore the current
|
|
|
|
|
buffer before it returns, if it changes it.
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
If more than two arguments are given, the remaining
|
|
|
|
|
arguments will be passed to MAP-FUNCTION."
|
|
|
|
|
(ewoc--set-buffer-bind-dll-let* ewoc
|
|
|
|
|
((footer (ewoc--footer ewoc))
|
2006-05-17 10:38:15 +00:00
|
|
|
|
(pp (ewoc--pretty-printer ewoc))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(node (ewoc--node-nth dll 1)))
|
2020-09-05 22:18:59 +03:00
|
|
|
|
(while (not (eq node footer))
|
|
|
|
|
(if (apply map-function (ewoc--node-data node) args)
|
|
|
|
|
(ewoc--refresh-node pp node dll))
|
|
|
|
|
(setq node (ewoc--node-next dll node)))))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
2006-05-23 07:31:45 +00:00
|
|
|
|
(defun ewoc-delete (ewoc &rest nodes)
|
|
|
|
|
"Delete NODES from EWOC."
|
|
|
|
|
(ewoc--set-buffer-bind-dll-let* ewoc
|
2006-05-27 09:37:13 +00:00
|
|
|
|
((L nil) (R nil) (last (ewoc--last-node ewoc)))
|
2006-05-23 07:31:45 +00:00
|
|
|
|
(dolist (node nodes)
|
|
|
|
|
;; If we are about to delete the node pointed at by last-node,
|
|
|
|
|
;; set last-node to nil.
|
2006-05-27 09:37:13 +00:00
|
|
|
|
(when (eq last node)
|
Provide generalized variables in core Elisp.
* lisp/emacs-lisp/gv.el: New file.
* lisp/subr.el (push, pop): Extend to generalized variables.
* lisp/loadup.el (macroexp): Unload if preloaded and uncompiled.
* lisp/emacs-lisp/cl-lib.el (cl-pop, cl-push, cl--set-nthcdr): Remove.
* lisp/emacs-lisp/cl-macs.el: Require gv. Use gv-define-setter,
gv-define-simple-setter, and gv-define-expander.
Remove setf-methods defined in gv. Rename cl-setf -> setf.
(cl-setf, cl-do-pop, cl-get-setf-method): Remove.
(cl-letf, cl-letf*, cl-define-modify-macro, cl-defsetf)
(cl-define-setf-expander, cl-struct-setf-expander): Move to cl.el.
(cl-remf, cl-shiftf, cl-rotatef, cl-callf, cl-callf2): Rewrite with
gv-letplace.
(cl-defstruct): Don't define setf-method any more.
* lisp/emacs-lisp/cl.el (flet): Don't autoload.
(cl--letf, letf, cl--letf*, letf*, cl--gv-adapt)
(define-setf-expander, defsetf, define-modify-macro)
(cl-struct-setf-expander): Move from cl-lib.el.
* lisp/emacs-lisp/syntax.el:
* lisp/emacs-lisp/ewoc.el:
* lisp/emacs-lisp/smie.el:
* lisp/emacs-lisp/cconv.el:
* lisp/emacs-lisp/timer.el: Rename cl-setf -> setf, cl-push -> push.
(timer--time): Use gv-define-simple-setter.
* lisp/emacs-lisp/macroexp.el (macroexp-let2): Rename from macroexp-let²
to avoid coding-system problems in subr.el. Adjust all users.
(macroexp--maxsize, macroexp-small-p): New functions.
* lisp/emacs-lisp/bytecomp.el (byte-compile-file): Don't use cl-letf.
* lisp/scroll-bar.el (scroll-bar-mode):
* lisp/simple.el (auto-fill-mode, overwrite-mode, binary-overwrite-mode)
(normal-erase-is-backspace-mode): Don't use the `eq' place.
* lisp/winner.el (winner-configuration, winner-make-point-alist)
(winner-set-conf, winner-get-point, winner-set): Don't abuse letf.
* lisp/files.el (locate-file-completion-table): Avoid list*.
Fixes: debbugs:11657
2012-06-22 09:42:38 -04:00
|
|
|
|
(setf last nil (ewoc--last-node ewoc) nil))
|
2006-05-23 07:31:45 +00:00
|
|
|
|
(delete-region (ewoc--node-start-marker node)
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(ewoc--node-start-marker (ewoc--node-next dll node)))
|
2006-05-23 07:31:45 +00:00
|
|
|
|
(set-marker (ewoc--node-start-marker node) nil)
|
Provide generalized variables in core Elisp.
* lisp/emacs-lisp/gv.el: New file.
* lisp/subr.el (push, pop): Extend to generalized variables.
* lisp/loadup.el (macroexp): Unload if preloaded and uncompiled.
* lisp/emacs-lisp/cl-lib.el (cl-pop, cl-push, cl--set-nthcdr): Remove.
* lisp/emacs-lisp/cl-macs.el: Require gv. Use gv-define-setter,
gv-define-simple-setter, and gv-define-expander.
Remove setf-methods defined in gv. Rename cl-setf -> setf.
(cl-setf, cl-do-pop, cl-get-setf-method): Remove.
(cl-letf, cl-letf*, cl-define-modify-macro, cl-defsetf)
(cl-define-setf-expander, cl-struct-setf-expander): Move to cl.el.
(cl-remf, cl-shiftf, cl-rotatef, cl-callf, cl-callf2): Rewrite with
gv-letplace.
(cl-defstruct): Don't define setf-method any more.
* lisp/emacs-lisp/cl.el (flet): Don't autoload.
(cl--letf, letf, cl--letf*, letf*, cl--gv-adapt)
(define-setf-expander, defsetf, define-modify-macro)
(cl-struct-setf-expander): Move from cl-lib.el.
* lisp/emacs-lisp/syntax.el:
* lisp/emacs-lisp/ewoc.el:
* lisp/emacs-lisp/smie.el:
* lisp/emacs-lisp/cconv.el:
* lisp/emacs-lisp/timer.el: Rename cl-setf -> setf, cl-push -> push.
(timer--time): Use gv-define-simple-setter.
* lisp/emacs-lisp/macroexp.el (macroexp-let2): Rename from macroexp-let²
to avoid coding-system problems in subr.el. Adjust all users.
(macroexp--maxsize, macroexp-small-p): New functions.
* lisp/emacs-lisp/bytecomp.el (byte-compile-file): Don't use cl-letf.
* lisp/scroll-bar.el (scroll-bar-mode):
* lisp/simple.el (auto-fill-mode, overwrite-mode, binary-overwrite-mode)
(normal-erase-is-backspace-mode): Don't use the `eq' place.
* lisp/winner.el (winner-configuration, winner-make-point-alist)
(winner-set-conf, winner-get-point, winner-set): Don't abuse letf.
* lisp/files.el (locate-file-completion-table): Avoid list*.
Fixes: debbugs:11657
2012-06-22 09:42:38 -04:00
|
|
|
|
(setf L (ewoc--node-left node)
|
|
|
|
|
R (ewoc--node-right node)
|
|
|
|
|
;; Link neighbors to each other.
|
|
|
|
|
(ewoc--node-right L) R
|
|
|
|
|
(ewoc--node-left R) L
|
|
|
|
|
;; Forget neighbors.
|
|
|
|
|
(ewoc--node-left node) nil
|
|
|
|
|
(ewoc--node-right node) nil))))
|
2006-05-23 07:31:45 +00:00
|
|
|
|
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(defun ewoc-filter (ewoc predicate &rest args)
|
|
|
|
|
"Remove all elements in EWOC for which PREDICATE returns nil.
|
2021-09-27 23:56:55 +02:00
|
|
|
|
Note that the buffer for EWOC will be the current buffer when PREDICATE
|
2004-06-16 23:50:03 +00:00
|
|
|
|
is called. PREDICATE must restore the current buffer before it returns
|
2000-03-11 03:51:31 +00:00
|
|
|
|
if it changes it.
|
2004-06-16 23:50:03 +00:00
|
|
|
|
The PREDICATE is called with the element as its first argument. If any
|
2000-03-11 03:51:31 +00:00
|
|
|
|
ARGS are given they will be passed to the PREDICATE."
|
|
|
|
|
(ewoc--set-buffer-bind-dll-let* ewoc
|
2006-05-29 04:39:46 +00:00
|
|
|
|
((node (ewoc--node-nth dll 1))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(footer (ewoc--footer ewoc))
|
2006-05-23 07:31:45 +00:00
|
|
|
|
(goodbye nil)
|
2006-05-10 08:02:21 +00:00
|
|
|
|
(inhibit-read-only t))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(while (not (eq node footer))
|
|
|
|
|
(unless (apply predicate (ewoc--node-data node) args)
|
2006-05-23 07:31:45 +00:00
|
|
|
|
(push node goodbye))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(setq node (ewoc--node-next dll node)))
|
2006-05-23 07:31:45 +00:00
|
|
|
|
(apply 'ewoc-delete ewoc goodbye)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
2000-08-16 20:27:39 +00:00
|
|
|
|
(defun ewoc-locate (ewoc &optional pos guess)
|
2000-03-11 03:51:31 +00:00
|
|
|
|
"Return the node that POS (a buffer position) is within.
|
2000-08-16 20:27:39 +00:00
|
|
|
|
POS may be a marker or an integer. It defaults to point.
|
2004-06-16 23:50:03 +00:00
|
|
|
|
GUESS should be a node that it is likely to be near POS.
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
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."
|
2000-08-16 20:27:39 +00:00
|
|
|
|
(unless pos (setq pos (point)))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(ewoc--set-buffer-bind-dll ewoc
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
(cond
|
|
|
|
|
;; Nothing present?
|
2006-05-29 04:39:46 +00:00
|
|
|
|
((eq (ewoc--node-nth dll 1) (ewoc--node-nth dll -1))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
nil)
|
|
|
|
|
|
|
|
|
|
;; Before second elem?
|
2006-05-29 04:39:46 +00:00
|
|
|
|
((< pos (ewoc--node-start-marker (ewoc--node-nth dll 2)))
|
|
|
|
|
(ewoc--node-nth dll 1))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
;; After one-before-last elem?
|
2006-05-29 04:39:46 +00:00
|
|
|
|
((>= pos (ewoc--node-start-marker (ewoc--node-nth dll -2)))
|
|
|
|
|
(ewoc--node-nth dll -2))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
2018-02-16 15:16:15 -05:00
|
|
|
|
;; We now know that pos is within an elem.
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(t
|
|
|
|
|
;; Make an educated guess about which of the three known
|
|
|
|
|
;; node'es (the first, the last, or GUESS) is nearest.
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(let* ((best-guess (ewoc--node-nth dll 1))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(distance (abs (- pos (ewoc--node-start-marker best-guess)))))
|
|
|
|
|
(when guess
|
|
|
|
|
(let ((d (abs (- pos (ewoc--node-start-marker guess)))))
|
|
|
|
|
(when (< d distance)
|
|
|
|
|
(setq distance d)
|
|
|
|
|
(setq best-guess guess))))
|
|
|
|
|
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(let* ((g (ewoc--node-nth dll -1)) ;Check the last elem
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(d (abs (- pos (ewoc--node-start-marker g)))))
|
|
|
|
|
(when (< d distance)
|
|
|
|
|
(setq distance d)
|
|
|
|
|
(setq best-guess g)))
|
|
|
|
|
|
2006-05-26 08:31:36 +00:00
|
|
|
|
(when (ewoc--last-node ewoc) ;Check "previous".
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(let* ((g (ewoc--last-node ewoc))
|
|
|
|
|
(d (abs (- pos (ewoc--node-start-marker g)))))
|
|
|
|
|
(when (< d distance)
|
|
|
|
|
(setq distance d)
|
|
|
|
|
(setq best-guess g))))
|
|
|
|
|
|
|
|
|
|
;; best-guess is now a "best guess".
|
|
|
|
|
;; Find the correct node. First determine in which direction
|
|
|
|
|
;; it lies, and then move in that direction until it is found.
|
2003-02-04 13:24:35 +00:00
|
|
|
|
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(cond
|
|
|
|
|
;; Is pos after the guess?
|
|
|
|
|
((>= pos
|
|
|
|
|
(ewoc--node-start-marker best-guess))
|
|
|
|
|
;; Loop until we are exactly one node too far down...
|
|
|
|
|
(while (>= pos (ewoc--node-start-marker best-guess))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(setq best-guess (ewoc--node-next dll best-guess)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
;; ...and return the previous node.
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(ewoc--node-prev dll best-guess))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
;; Pos is before best-guess
|
|
|
|
|
(t
|
|
|
|
|
(while (< pos (ewoc--node-start-marker best-guess))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(setq best-guess (ewoc--node-prev dll best-guess)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
best-guess)))))))
|
|
|
|
|
|
|
|
|
|
(defun ewoc-invalidate (ewoc &rest nodes)
|
2005-06-11 20:33:28 +00:00
|
|
|
|
"Call EWOC's pretty-printer for each element in NODES.
|
|
|
|
|
Delete current text first, thus effecting a \"refresh\"."
|
2006-05-17 10:38:15 +00:00
|
|
|
|
(ewoc--set-buffer-bind-dll-let* ewoc
|
|
|
|
|
((pp (ewoc--pretty-printer ewoc)))
|
2020-09-05 22:18:59 +03:00
|
|
|
|
(dolist (node nodes)
|
|
|
|
|
(ewoc--refresh-node pp node dll))))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
2000-08-16 20:27:39 +00:00
|
|
|
|
(defun ewoc-goto-prev (ewoc arg)
|
2005-06-11 20:33:28 +00:00
|
|
|
|
"Move point to the ARGth previous element in EWOC.
|
2000-03-11 03:51:31 +00:00
|
|
|
|
Don't move if we are at the first element, or if EWOC is empty.
|
2005-06-11 20:33:28 +00:00
|
|
|
|
Return the node we moved to."
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(ewoc--set-buffer-bind-dll-let* ewoc
|
2000-11-06 07:13:07 +00:00
|
|
|
|
((node (ewoc-locate ewoc (point))))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(when node
|
2000-08-16 20:27:39 +00:00
|
|
|
|
;; If we were past the last element, first jump to it.
|
|
|
|
|
(when (>= (point) (ewoc--node-start-marker (ewoc--node-right node)))
|
|
|
|
|
(setq arg (1- arg)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(while (and node (> arg 0))
|
|
|
|
|
(setq arg (1- arg))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(setq node (ewoc--node-prev dll node)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
;; Never step above the first element.
|
|
|
|
|
(unless (ewoc--filter-hf-nodes ewoc node)
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(setq node (ewoc--node-nth dll 1)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(ewoc-goto-node ewoc node))))
|
|
|
|
|
|
2000-08-16 20:27:39 +00:00
|
|
|
|
(defun ewoc-goto-next (ewoc arg)
|
2005-06-11 20:33:28 +00:00
|
|
|
|
"Move point to the ARGth next element in EWOC.
|
|
|
|
|
Return the node (or nil if we just passed the last node)."
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(ewoc--set-buffer-bind-dll-let* ewoc
|
2000-11-06 07:13:07 +00:00
|
|
|
|
((node (ewoc-locate ewoc (point))))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(while (and node (> arg 0))
|
|
|
|
|
(setq arg (1- arg))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(setq node (ewoc--node-next dll node)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
;; Never step below the first element.
|
2000-08-16 20:27:39 +00:00
|
|
|
|
;; (unless (ewoc--filter-hf-nodes ewoc node)
|
2006-05-29 04:39:46 +00:00
|
|
|
|
;; (setq node (ewoc--node-nth dll -2)))
|
2011-03-03 21:16:56 -08:00
|
|
|
|
(unless node
|
|
|
|
|
(error "No next"))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(ewoc-goto-node ewoc node)))
|
|
|
|
|
|
|
|
|
|
(defun ewoc-goto-node (ewoc node)
|
2005-06-11 20:33:28 +00:00
|
|
|
|
"Move point to NODE in EWOC."
|
2018-03-05 14:32:20 -05:00
|
|
|
|
(with-current-buffer (ewoc--buffer ewoc)
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(goto-char (ewoc--node-start-marker node))
|
|
|
|
|
(if goal-column (move-to-column goal-column))
|
Provide generalized variables in core Elisp.
* lisp/emacs-lisp/gv.el: New file.
* lisp/subr.el (push, pop): Extend to generalized variables.
* lisp/loadup.el (macroexp): Unload if preloaded and uncompiled.
* lisp/emacs-lisp/cl-lib.el (cl-pop, cl-push, cl--set-nthcdr): Remove.
* lisp/emacs-lisp/cl-macs.el: Require gv. Use gv-define-setter,
gv-define-simple-setter, and gv-define-expander.
Remove setf-methods defined in gv. Rename cl-setf -> setf.
(cl-setf, cl-do-pop, cl-get-setf-method): Remove.
(cl-letf, cl-letf*, cl-define-modify-macro, cl-defsetf)
(cl-define-setf-expander, cl-struct-setf-expander): Move to cl.el.
(cl-remf, cl-shiftf, cl-rotatef, cl-callf, cl-callf2): Rewrite with
gv-letplace.
(cl-defstruct): Don't define setf-method any more.
* lisp/emacs-lisp/cl.el (flet): Don't autoload.
(cl--letf, letf, cl--letf*, letf*, cl--gv-adapt)
(define-setf-expander, defsetf, define-modify-macro)
(cl-struct-setf-expander): Move from cl-lib.el.
* lisp/emacs-lisp/syntax.el:
* lisp/emacs-lisp/ewoc.el:
* lisp/emacs-lisp/smie.el:
* lisp/emacs-lisp/cconv.el:
* lisp/emacs-lisp/timer.el: Rename cl-setf -> setf, cl-push -> push.
(timer--time): Use gv-define-simple-setter.
* lisp/emacs-lisp/macroexp.el (macroexp-let2): Rename from macroexp-let²
to avoid coding-system problems in subr.el. Adjust all users.
(macroexp--maxsize, macroexp-small-p): New functions.
* lisp/emacs-lisp/bytecomp.el (byte-compile-file): Don't use cl-letf.
* lisp/scroll-bar.el (scroll-bar-mode):
* lisp/simple.el (auto-fill-mode, overwrite-mode, binary-overwrite-mode)
(normal-erase-is-backspace-mode): Don't use the `eq' place.
* lisp/winner.el (winner-configuration, winner-make-point-alist)
(winner-set-conf, winner-get-point, winner-set): Don't abuse letf.
* lisp/files.el (locate-file-completion-table): Avoid list*.
Fixes: debbugs:11657
2012-06-22 09:42:38 -04:00
|
|
|
|
(setf (ewoc--last-node ewoc) node)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
(defun ewoc-refresh (ewoc)
|
|
|
|
|
"Refresh all data in EWOC.
|
|
|
|
|
The pretty-printer that was specified when the EWOC was created
|
|
|
|
|
will be called for all elements in EWOC.
|
|
|
|
|
Note that `ewoc-invalidate' is more efficient if only a small
|
|
|
|
|
number of elements needs to be refreshed."
|
|
|
|
|
(ewoc--set-buffer-bind-dll-let* ewoc
|
2000-03-22 02:57:23 +00:00
|
|
|
|
((footer (ewoc--footer ewoc)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(let ((inhibit-read-only t))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(delete-region (ewoc--node-start-marker (ewoc--node-nth dll 1))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(ewoc--node-start-marker footer))
|
|
|
|
|
(goto-char (ewoc--node-start-marker footer))
|
2006-05-12 07:29:42 +00:00
|
|
|
|
(let ((pp (ewoc--pretty-printer ewoc))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(node (ewoc--node-nth dll 1)))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(while (not (eq node footer))
|
|
|
|
|
(set-marker (ewoc--node-start-marker node) (point))
|
2006-05-12 07:29:42 +00:00
|
|
|
|
(funcall pp (ewoc--node-data node))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(setq node (ewoc--node-next dll node)))))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(set-marker (ewoc--node-start-marker footer) (point))))
|
|
|
|
|
|
|
|
|
|
(defun ewoc-collect (ewoc predicate &rest args)
|
|
|
|
|
"Select elements from EWOC using PREDICATE.
|
|
|
|
|
Return a list of all selected data elements.
|
2004-06-16 23:50:03 +00:00
|
|
|
|
PREDICATE is a function that takes a data element as its first
|
|
|
|
|
argument. The elements on the returned list will appear in the
|
|
|
|
|
same order as in the buffer. You should not rely on the order of
|
|
|
|
|
calls to PREDICATE.
|
|
|
|
|
Note that the buffer the EWOC is displayed in is the current
|
|
|
|
|
buffer when PREDICATE is called. PREDICATE must restore it if it
|
|
|
|
|
changes it.
|
2000-03-11 03:51:31 +00:00
|
|
|
|
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))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(node (ewoc--node-nth dll -2))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
result)
|
|
|
|
|
(while (not (eq node header))
|
|
|
|
|
(if (apply predicate (ewoc--node-data node) args)
|
|
|
|
|
(push (ewoc--node-data node) result))
|
2006-05-29 04:39:46 +00:00
|
|
|
|
(setq node (ewoc--node-prev dll node)))
|
2008-04-09 18:50:34 +00:00
|
|
|
|
result))
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
(defun ewoc-buffer (ewoc)
|
|
|
|
|
"Return the buffer that is associated with EWOC.
|
2005-06-11 20:33:28 +00:00
|
|
|
|
Return nil if the buffer has been deleted."
|
2000-03-11 03:51:31 +00:00
|
|
|
|
(let ((buf (ewoc--buffer ewoc)))
|
|
|
|
|
(when (buffer-name buf) buf)))
|
|
|
|
|
|
2000-03-22 02:57:23 +00:00
|
|
|
|
(defun ewoc-get-hf (ewoc)
|
|
|
|
|
"Return a cons cell containing the (HEADER . FOOTER) of EWOC."
|
|
|
|
|
(cons (ewoc--node-data (ewoc--header ewoc))
|
|
|
|
|
(ewoc--node-data (ewoc--footer ewoc))))
|
|
|
|
|
|
|
|
|
|
(defun ewoc-set-hf (ewoc header footer)
|
|
|
|
|
"Set the HEADER and FOOTER of EWOC."
|
2006-05-18 12:04:40 +00:00
|
|
|
|
(ewoc--set-buffer-bind-dll-let* ewoc
|
|
|
|
|
((head (ewoc--header ewoc))
|
2006-05-27 17:39:38 +00:00
|
|
|
|
(foot (ewoc--footer ewoc))
|
|
|
|
|
(hf-pp (ewoc--hf-pp ewoc)))
|
Provide generalized variables in core Elisp.
* lisp/emacs-lisp/gv.el: New file.
* lisp/subr.el (push, pop): Extend to generalized variables.
* lisp/loadup.el (macroexp): Unload if preloaded and uncompiled.
* lisp/emacs-lisp/cl-lib.el (cl-pop, cl-push, cl--set-nthcdr): Remove.
* lisp/emacs-lisp/cl-macs.el: Require gv. Use gv-define-setter,
gv-define-simple-setter, and gv-define-expander.
Remove setf-methods defined in gv. Rename cl-setf -> setf.
(cl-setf, cl-do-pop, cl-get-setf-method): Remove.
(cl-letf, cl-letf*, cl-define-modify-macro, cl-defsetf)
(cl-define-setf-expander, cl-struct-setf-expander): Move to cl.el.
(cl-remf, cl-shiftf, cl-rotatef, cl-callf, cl-callf2): Rewrite with
gv-letplace.
(cl-defstruct): Don't define setf-method any more.
* lisp/emacs-lisp/cl.el (flet): Don't autoload.
(cl--letf, letf, cl--letf*, letf*, cl--gv-adapt)
(define-setf-expander, defsetf, define-modify-macro)
(cl-struct-setf-expander): Move from cl-lib.el.
* lisp/emacs-lisp/syntax.el:
* lisp/emacs-lisp/ewoc.el:
* lisp/emacs-lisp/smie.el:
* lisp/emacs-lisp/cconv.el:
* lisp/emacs-lisp/timer.el: Rename cl-setf -> setf, cl-push -> push.
(timer--time): Use gv-define-simple-setter.
* lisp/emacs-lisp/macroexp.el (macroexp-let2): Rename from macroexp-let²
to avoid coding-system problems in subr.el. Adjust all users.
(macroexp--maxsize, macroexp-small-p): New functions.
* lisp/emacs-lisp/bytecomp.el (byte-compile-file): Don't use cl-letf.
* lisp/scroll-bar.el (scroll-bar-mode):
* lisp/simple.el (auto-fill-mode, overwrite-mode, binary-overwrite-mode)
(normal-erase-is-backspace-mode): Don't use the `eq' place.
* lisp/winner.el (winner-configuration, winner-make-point-alist)
(winner-set-conf, winner-get-point, winner-set): Don't abuse letf.
* lisp/files.el (locate-file-completion-table): Avoid list*.
Fixes: debbugs:11657
2012-06-22 09:42:38 -04:00
|
|
|
|
(setf (ewoc--node-data head) header
|
|
|
|
|
(ewoc--node-data foot) footer)
|
2020-09-05 22:18:59 +03:00
|
|
|
|
(ewoc--refresh-node hf-pp head dll)
|
|
|
|
|
(ewoc--refresh-node hf-pp foot dll)))
|
2000-03-22 02:57:23 +00:00
|
|
|
|
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
(provide 'ewoc)
|
|
|
|
|
|
2006-05-29 03:47:56 +00:00
|
|
|
|
;; Local Variables:
|
|
|
|
|
;; eval: (put 'ewoc--set-buffer-bind-dll 'lisp-indent-hook 1)
|
|
|
|
|
;; eval: (put 'ewoc--set-buffer-bind-dll-let* 'lisp-indent-hook 2)
|
|
|
|
|
;; End:
|
2000-03-11 03:51:31 +00:00
|
|
|
|
|
|
|
|
|
;;; ewoc.el ends here
|