Mercurial > emacs
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 |