32db9c7a3965289ed2c715d0539df423a32fa1d9
[gnus] / lisp / custom.el
1 ;;; custom.el --- User friendly customization support.
2
3 ;; Copyright (C) 1995, 1996 Free Software Foundation, Inc.
4
5 ;; Author: Per Abrahamsen <abraham@iesd.auc.dk>
6 ;; Keywords: help
7 ;; Version: 0.5
8
9 ;; This file is part of GNU Emacs.
10
11 ;; GNU Emacs is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; any later version.
15
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
25
26 ;;; Commentary:
27
28 ;; WARNING: This package is still under construction and not all of
29 ;; the features below are implemented.
30 ;;
31 ;; This package provides a framework for adding user friendly
32 ;; customization support to Emacs.  Having to do customization by
33 ;; editing a text file in some arcane syntax is user hostile in the
34 ;; extreme, and to most users emacs lisp definitely count as arcane.
35 ;;
36 ;; The intent is that authors of emacs lisp packages declare the
37 ;; variables intended for user customization with `custom-declare'.
38 ;; Custom can then automatically generate a customization buffer with
39 ;; `custom-buffer-create' where the user can edit the package
40 ;; variables in a simple and intuitive way, as well as a menu with
41 ;; `custom-menu-create' where he can set the more commonly used
42 ;; variables interactively.
43 ;;
44 ;; It is also possible to use custom for modifying the properties of
45 ;; other objects than the package itself, by specifying extra optional
46 ;; arguments to `custom-buffer-create'.
47 ;;
48 ;; Custom is inspired by OPEN LOOK property windows.
49
50 ;;; Todo:  
51 ;;
52 ;; - Toggle documentation in three states `none', `one-line', `full'.
53 ;; - Function to generate an XEmacs menu from a CUSTOM.
54 ;; - Write TeXinfo documentation.
55 ;; - Make it possible to hide sections by clicking at the level.
56 ;; - Declare AUC TeX variables.
57 ;; - Declare (ding) Gnus variables.
58 ;; - Declare Emacs variables.
59 ;; - Implement remaining types.
60 ;; - XEmacs port.
61 ;; - Allow `URL', `info', and internal hypertext buttons.
62 ;; - Support meta-variables and goal directed customization.
63 ;; - Make it easy to declare custom types independently.
64 ;; - Make it possible to declare default value and type for a single
65 ;;   variable, storing the data in a symbol property.
66 ;; - Syntactic sugar for CUSTOM declarations.
67 ;; - Use W3 for variable documentation.
68
69 ;;; Code:
70
71 (eval-when-compile
72   (require 'cl))
73
74 ;;; Compatibility:
75
76 (defun custom-xmas-add-text-properties (start end props &optional object)
77   (add-text-properties start end props object)
78   (put-text-property start end 'start-open t object)
79   (put-text-property start end 'end-open t object))
80
81 (defun custom-xmas-put-text-property (start end prop value &optional object)
82   (put-text-property start end prop value object)
83   (put-text-property start end 'start-open t object)
84   (put-text-property start end 'end-open t object))
85
86 (defun custom-xmas-extent-start-open ()
87   (map-extents (lambda (extent arg)
88                  (set-extent-property extent 'start-open t))
89                nil (point) (min (1+ (point)) (point-max))))
90                   
91 (if (string-match "XEmacs\\|Lucid" emacs-version)
92     (progn
93       (fset 'custom-add-text-properties 'custom-xmas-add-text-properties)
94       (fset 'custom-put-text-property 'custom-xmas-put-text-property)
95       (fset 'custom-extent-start-open 'custom-xmas-extent-start-open)
96       (fset 'custom-set-text-properties
97             (if (fboundp 'set-text-properties)
98                 'set-text-properties))
99       (fset 'custom-buffer-substring-no-properties
100             (if (fboundp 'buffer-substring-no-properties)
101                 'buffer-substring-no-properties
102               'custom-xmas-buffer-substring-no-properties)))
103   (fset 'custom-add-text-properties 'add-text-properties)
104   (fset 'custom-put-text-property 'put-text-property)
105   (fset 'custom-extent-start-open 'ignore)
106   (fset 'custom-set-text-properties 'set-text-properties)
107   (fset 'custom-buffer-substring-no-properties 
108         'buffer-substring-no-properties))
109
110 (defun custom-xmas-buffer-substring-no-properties (beg end)
111   "Return the text from BEG to END, without text properties, as a string."
112   (let ((string (buffer-substring beg end)))
113     (custom-set-text-properties 0 (length string) nil string)
114     string))
115
116 ;; XEmacs and Emacs 19.29 facep does different things.
117 (if (fboundp 'find-face)
118     (fset 'custom-facep 'find-face)
119   (fset 'custom-facep 'facep))
120
121 (if (custom-facep 'underline)
122     ()
123   ;; No underline face in XEmacs 19.12.
124   (and (fboundp 'make-face)
125        (funcall (intern "make-face") 'underline))
126   ;; Must avoid calling set-face-underline-p directly, because it
127   ;; is a defsubst in emacs19, and will make the .elc files non
128   ;; portable!
129   (or (and (fboundp 'face-differs-from-default-p)
130            (face-differs-from-default-p 'underline))
131       (and (fboundp 'set-face-underline-p)
132            (funcall 'set-face-underline-p 'underline t))))
133
134 (defun custom-xmas-set-text-properties (start end props &optional buffer)
135   (if (null buffer)
136       (if props
137           (while props
138             (custom-put-text-property 
139              start end (car props) (nth 1 props) buffer)
140             (setq props (nthcdr 2 props)))
141         (remove-text-properties start end ()))))
142
143 (or (fboundp 'event-point)
144     ;; Missing in Emacs 19.29.
145     (defun event-point (event)
146       "Return the character position of the given mouse-motion, button-press,
147 or button-release event.  If the event did not occur over a window, or did
148 not occur over text, then this returns nil.  Otherwise, it returns an index
149 into the buffer visible in the event's window."
150       (posn-point (event-start event))))
151
152 (eval-when-compile
153   (defvar x-colors nil)
154   (defvar custom-button-face nil)
155   (defvar custom-field-uninitialized-face nil)
156   (defvar custom-field-invalid-face nil)
157   (defvar custom-field-modified-face nil)
158   (defvar custom-field-face nil)
159   (defvar custom-mouse-face nil)
160   (defvar custom-field-active-face nil))
161
162 ;; We can't easily check for a working intangible.
163 (defconst intangible (if (and (boundp 'emacs-minor-version)
164                               (or (> emacs-major-version 19)
165                                   (and (> emacs-major-version 18)
166                                        (> emacs-minor-version 28))))
167                          (setq intangible 'intangible)
168                        (setq intangible 'intangible-if-it-had-been-working))
169   "The symbol making text intangible.")