comparison lispref/display.texi @ 71009:a2f2de00b286

(Display): Add "Abstract Display" to menu. (Abstract Display, Abstract Display Functions) (Abstract Display Example): New nodes.
author Thien-Thi Nguyen <ttn@gnuvola.org>
date Sat, 27 May 2006 17:58:26 +0000
parents 4f398d726c7c
children 4241daad4b09
comparison
equal deleted inserted replaced
71008:ec0ff7478c19 71009:a2f2de00b286
27 * Fringes:: Controlling window fringes. 27 * Fringes:: Controlling window fringes.
28 * Scroll Bars:: Controlling vertical scroll bars. 28 * Scroll Bars:: Controlling vertical scroll bars.
29 * Display Property:: Enabling special display features. 29 * Display Property:: Enabling special display features.
30 * Images:: Displaying images in Emacs buffers. 30 * Images:: Displaying images in Emacs buffers.
31 * Buttons:: Adding clickable buttons to Emacs buffers. 31 * Buttons:: Adding clickable buttons to Emacs buffers.
32 * Abstract Display:: Emacs' Widget for Object Collections.
32 * Blinking:: How Emacs shows the matching open parenthesis. 33 * Blinking:: How Emacs shows the matching open parenthesis.
33 * Usual Display:: The usual conventions for displaying nonprinting chars. 34 * Usual Display:: The usual conventions for displaying nonprinting chars.
34 * Display Tables:: How to specify other conventions. 35 * Display Tables:: How to specify other conventions.
35 * Beeping:: Audible signal to the user. 36 * Beeping:: Audible signal to the user.
36 * Window Systems:: Which window system is being used. 37 * Window Systems:: Which window system is being used.
4619 Return the @var{n}th button before position @var{pos} in the current 4620 Return the @var{n}th button before position @var{pos} in the current
4620 buffer. If @var{count-current} is non-@code{nil}, count any button at 4621 buffer. If @var{count-current} is non-@code{nil}, count any button at
4621 @var{pos} in the search, instead of starting at the next button. 4622 @var{pos} in the search, instead of starting at the next button.
4622 @end defun 4623 @end defun
4623 4624
4625 @node Abstract Display
4626 @section Abstract Display
4627 @cindex ewoc
4628 @cindex display, abstract
4629 @cindex display, arbitrary objects
4630 @cindex model/view/controller
4631 @cindex view part, model/view/controller
4632
4633 The Ewoc package constructs buffer text that represents a structure
4634 of Lisp objects, and updates the text to follow changes in that
4635 structure. This is like the ``view'' component in the the
4636 ``model/view/controller'' design paradigm.
4637
4638 An @dfn{ewoc} is a structure that organizes information required to
4639 construct buffer text that represents certain Lisp data. The buffer
4640 text of the ewoc has three parts, in order: first, fixed @dfn{header}
4641 text; next, textual descriptions of a series of data elements (Lisp
4642 objects that you specify); and last, fixed @dfn{footer} text.
4643 Specifically, an ewoc contains information on:
4644
4645 @itemize @bullet
4646 @item
4647 The buffer which its text is generated in.
4648
4649 @item
4650 The text's start position in the buffer.
4651
4652 @item
4653 The header and footer strings.
4654
4655 @item
4656 A doubly-linked chain of @dfn{nodes}, each of which contains:
4657
4658 @itemize
4659 @item
4660 A @dfn{data element}, a single Lisp object.
4661
4662 @item
4663 Links to the preceding and following nodes in the chain.
4664 @end itemize
4665
4666 @item
4667 A @dfn{pretty-printer} function which is responsible for
4668 inserting the textual representation of a data
4669 element value into the current buffer.
4670 @end itemize
4671
4672 Typically, you define an ewoc with @code{ewoc-create}, and then pass
4673 the resulting ewoc structure to other functions in the Ewoc package to
4674 build nodes within it, and display it in the buffer. Once it is
4675 displayed in the buffer, other functions determine the correspondance
4676 between buffer positions and nodes, move point from one node's textual
4677 representation to another, and so forth. @xref{Abstract Display
4678 Functions}.
4679
4680 A node @dfn{encapsulates} a data element much the way a variable
4681 holds a value. Normally, encapsulation occurs as a part of adding a
4682 node to the ewoc. You can retrieve the data element value and place a
4683 new value in its place, like so:
4684
4685 @lisp
4686 (ewoc-data @var{node})
4687 @result{} value
4688
4689 (ewoc-set-data @var{node} @var{new-value})
4690 @result{} @var{new-value}
4691 @end lisp
4692
4693 @noindent
4694 You can also use, as the data element value, a Lisp object (list or
4695 vector) that is a container for the ``real'' value, or an index into
4696 some other structure. The example (@pxref{Abstract Display Example})
4697 uses the latter approach.
4698
4699 When the data changes, you will want to update the text in the
4700 buffer. You can update all nodes by calling @code{ewoc-refresh}, or
4701 just specific nodes using @code{ewoc-invalidate}, or all nodes
4702 satisfying a predicate using @code{ewoc-map}. Alternatively, you can
4703 delete invalid nodes using @code{ewoc-delete} or @code{ewoc-filter},
4704 and add new nodes in their place. Deleting a node from an ewoc deletes
4705 its associated textual description from buffer, as well.
4706
4707 @menu
4708 * Abstract Display Functions::
4709 * Abstract Display Example::
4710 @end menu
4711
4712 @node Abstract Display Functions
4713 @subsection Abstract Display Functions
4714
4715 In this subsection, @var{ewoc} and @var{node} stand for the
4716 structures described above (@pxref{Abstract Display}), while
4717 @var{data} stands for an arbitrary Lisp object used as a data element.
4718
4719 @defun ewoc-create pretty-printer &optional header footer nosep
4720 This constructs and returns a new ewoc, with no nodes (and thus no data
4721 elements). @var{pretty-printer} should be a function that takes one
4722 argument, a data element of the sort you plan to use in this ewoc, and
4723 inserts its textual description at point using @code{insert} (and never
4724 @code{insert-before-markers}, because that would interfere with the
4725 Ewoc package's internal mechanisms).
4726
4727 Normally, a newline is automatically inserted after the header,
4728 the footer and every node's textual description. If @var{nosep}
4729 is non-@code{nil}, no newline is inserted. This may be useful for
4730 displaying an entire ewoc on a single line, for example, or for
4731 making nodes ``invisible'' by arranging for @var{pretty-printer}
4732 to do nothing for those nodes.
4733
4734 An ewoc maintains its text in the buffer that is current when
4735 you create it, so switch to the intended buffer before calling
4736 @code{ewoc-create}.
4737 @end defun
4738
4739 @defun ewoc-buffer ewoc
4740 This returns the buffer where @var{ewoc} maintains its text.
4741 @end defun
4742
4743 @defun ewoc-get-hf ewoc
4744 This returns a cons cell @code{(@var{header} . @var{footer})}
4745 made from @var{ewoc}'s header and footer.
4746 @end defun
4747
4748 @defun ewoc-set-hf ewoc header footer
4749 This sets the header and footer of @var{ewoc} to the strings
4750 @var{header} and @var{footer}, respectively.
4751 @end defun
4752
4753 @defun ewoc-enter-first ewoc data
4754 @defunx ewoc-enter-last ewoc data
4755 These add a new node encapsulating @var{data}, putting it, respectively,
4756 at the beginning or end of @var{ewoc}'s chain of nodes.
4757 @end defun
4758
4759 @defun ewoc-enter-before ewoc node data
4760 @defunx ewoc-enter-after ewoc node data
4761 These add a new node encapsulating @var{data}, adding it to
4762 @var{ewoc} before or after @var{node}, respectively.
4763 @end defun
4764
4765 @defun ewoc-prev ewoc node
4766 @defunx ewoc-next ewoc node
4767 These return, respectively, the previous node and the next node of @var{node}
4768 in @var{ewoc}.
4769 @end defun
4770
4771 @defun ewoc-nth ewoc n
4772 This returns the node in @var{ewoc} found at zero-based index @var{n}.
4773 A negative @var{n} means count from the end. @code{ewoc-nth} returns
4774 @code{nil} if @var{n} is out of range.
4775 @end defun
4776
4777 @defun ewoc-data node
4778 This extracts the data encapsulated by @var{node} and returns it.
4779 @end defun
4780
4781 @defun ewoc-set-data node data
4782 This sets the data encapsulated by @var{node} to @var{data}.
4783 @end defun
4784
4785 @defun ewoc-locate ewoc &optional pos guess
4786 This determines the node in @var{ewoc} which contains point (or
4787 @var{pos} if specified), and returns that node. If @var{ewoc} has no
4788 nodes, it returns @code{nil}. If @var{pos} is before the first node,
4789 it returns the first node; if @var{pos} is after the last node, it returns
4790 the last node. The optional third arg @var{guess}
4791 should be a node that is likely to be near @var{pos}; this doesn't
4792 alter the result, but makes the function run faster.
4793 @end defun
4794
4795 @defun ewoc-location node
4796 This returns the start position of @var{node}.
4797 @end defun
4798
4799 @defun ewoc-goto-prev ewoc arg
4800 @defunx ewoc-goto-next ewoc arg
4801 These move point to the previous or next, respectively, @var{arg}th node
4802 in @var{ewoc}. @code{ewoc-goto-prev} does not move if it is already at
4803 the first node or if @var{ewoc} is empty, whereas @code{ewoc-goto-next}
4804 moves past the last node, returning @code{nil}. Excepting this special
4805 case, these functions return the node moved to.
4806 @end defun
4807
4808 @defun ewoc-goto-node ewoc node
4809 This moves point to the start of @var{node} in @var{ewoc}.
4810 @end defun
4811
4812 @defun ewoc-refresh ewoc
4813 This function regenerates the text of @var{ewoc}. It works by
4814 deleting the text between the header and the footer, i.e., all the
4815 data elements' representations, and then calling the pretty-printer
4816 function for each node, one by one, in order.
4817 @end defun
4818
4819 @defun ewoc-invalidate ewoc &rest nodes
4820 This is similar to @code{ewoc-refresh}, except that only @var{nodes} in
4821 @var{ewoc} are updated instead of the entire set.
4822 @end defun
4823
4824 @defun ewoc-delete ewoc &rest nodes
4825 This deletes each node in @var{nodes} from @var{ewoc}.
4826 @end defun
4827
4828 @defun ewoc-filter ewoc predicate &rest args
4829 This calls @var{predicate} for each data element in @var{ewoc} and
4830 deletes those nodes for which @var{predicate} returns @code{nil}.
4831 Any @var{args} are passed to @var{predicate}.
4832 @end defun
4833
4834 @defun ewoc-collect ewoc predicate &rest args
4835 This calls @var{predicate} for each data element in @var{ewoc}
4836 and returns a list of those elements for which @var{predicate}
4837 returns non-@code{nil}. The elements in the list are ordered
4838 as in the buffer. Any @var{args} are passed to @var{predicate}.
4839 @end defun
4840
4841 @defun ewoc-map map-function ewoc &rest args
4842 This calls @var{map-function} for each data element in @var{ewoc} and
4843 updates those nodes for which @var{map-function} returns non-@code{nil}.
4844 Any @var{args} are passed to @var{map-function}.
4845 @end defun
4846
4847 @node Abstract Display Example
4848 @subsection Abstract Display Example
4849
4850 Here is a simple example using functions of the ewoc package to
4851 implement a ``color components display'', an area in a buffer that
4852 represents a vector of three integers (itself representing a 24-bit RGB
4853 value) in various ways.
4854
4855 @example
4856 (setq colorcomp-ewoc nil
4857 colorcomp-data nil
4858 colorcomp-mode-map nil
4859 colorcomp-labels ["Red" "Green" "Blue"])
4860
4861 (defun colorcomp-pp (data)
4862 (if data
4863 (let ((comp (aref colorcomp-data data)))
4864 (insert (aref colorcomp-labels data) "\t: #x"
4865 (format "%02X" comp) " "
4866 (make-string (ash comp -2) ?#) "\n"))
4867 (let ((cstr (format "#%02X%02X%02X"
4868 (aref colorcomp-data 0)
4869 (aref colorcomp-data 1)
4870 (aref colorcomp-data 2)))
4871 (samp " (sample text) "))
4872 (insert "Color\t: "
4873 (propertize samp 'face `(foreground-color . ,cstr))
4874 (propertize samp 'face `(background-color . ,cstr))
4875 "\n"))))
4876
4877 (defun colorcomp (color)
4878 "Allow fiddling with COLOR in a new buffer.
4879 The buffer is in Color Components mode."
4880 (interactive "sColor (name or #RGB or #RRGGBB): ")
4881 (when (string= "" color)
4882 (setq color "green"))
4883 (unless (color-values color)
4884 (error "No such color: %S" color))
4885 (switch-to-buffer
4886 (generate-new-buffer (format "originally: %s" color)))
4887 (kill-all-local-variables)
4888 (setq major-mode 'colorcomp-mode
4889 mode-name "Color Components")
4890 (use-local-map colorcomp-mode-map)
4891 (erase-buffer)
4892 (buffer-disable-undo)
4893 (let ((data (apply 'vector (mapcar (lambda (n) (ash n -8))
4894 (color-values color))))
4895 (ewoc (ewoc-create 'colorcomp-pp
4896 "\nColor Components\n\n"
4897 (substitute-command-keys
4898 "\n\\@{colorcomp-mode-map@}"))))
4899 (set (make-local-variable 'colorcomp-data) data)
4900 (set (make-local-variable 'colorcomp-ewoc) ewoc)
4901 (ewoc-enter-last ewoc 0)
4902 (ewoc-enter-last ewoc 1)
4903 (ewoc-enter-last ewoc 2)
4904 (ewoc-enter-last ewoc nil)))
4905 @end example
4906
4907 @cindex controller part, model/view/controller
4908 This example can be extended to be a ``color selection widget'' (in
4909 other words, the controller part of the ``model/view/controller''
4910 design paradigm) by defining commands to modify @code{colorcomp-data}
4911 and to ``finish'' the selection process, and a keymap to tie it all
4912 together conveniently.
4913
4914 @example
4915 (defun colorcomp-mod (index limit delta)
4916 (let ((cur (aref colorcomp-data index)))
4917 (unless (= limit cur)
4918 (aset colorcomp-data index (+ cur delta)))
4919 (ewoc-invalidate
4920 colorcomp-ewoc
4921 (ewoc-nth colorcomp-ewoc index)
4922 (ewoc-nth colorcomp-ewoc -1))))
4923
4924 (defun colorcomp-R-more () (interactive) (colorcomp-mod 0 255 1))
4925 (defun colorcomp-G-more () (interactive) (colorcomp-mod 1 255 1))
4926 (defun colorcomp-B-more () (interactive) (colorcomp-mod 2 255 1))
4927 (defun colorcomp-R-less () (interactive) (colorcomp-mod 0 0 -1))
4928 (defun colorcomp-G-less () (interactive) (colorcomp-mod 1 0 -1))
4929 (defun colorcomp-B-less () (interactive) (colorcomp-mod 2 0 -1))
4930
4931 (defun colorcomp-copy-as-kill-and-exit ()
4932 "Copy the color components into the kill ring and kill the buffer.
4933 The string is formatted #RRGGBB (hash followed by six hex digits)."
4934 (interactive)
4935 (kill-new (format "#%02X%02X%02X"
4936 (aref colorcomp-data 0)
4937 (aref colorcomp-data 1)
4938 (aref colorcomp-data 2)))
4939 (kill-buffer nil))
4940
4941 (setq colorcomp-mode-map
4942 (let ((m (make-sparse-keymap)))
4943 (suppress-keymap m)
4944 (define-key m "i" 'colorcomp-R-less)
4945 (define-key m "o" 'colorcomp-R-more)
4946 (define-key m "k" 'colorcomp-G-less)
4947 (define-key m "l" 'colorcomp-G-more)
4948 (define-key m "," 'colorcomp-B-less)
4949 (define-key m "." 'colorcomp-B-more)
4950 (define-key m " " 'colorcomp-copy-as-kill-and-exit)
4951 m))
4952 @end example
4953
4954 Note that we never modify the data in each node, which is fixed when the
4955 ewoc is created to be either @code{nil} or an index into the vector
4956 @code{colorcomp-data}, the actual color components.
4957
4624 @node Blinking 4958 @node Blinking
4625 @section Blinking Parentheses 4959 @section Blinking Parentheses
4626 @cindex parenthesis matching 4960 @cindex parenthesis matching
4627 @cindex blinking 4961 @cindex blinking
4628 @cindex balancing parentheses 4962 @cindex balancing parentheses