aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLute Kamstra2005-03-21 17:10:06 +0000
committerLute Kamstra2005-03-21 17:10:06 +0000
commitea67f0cee4c6513c5366fb395efa6bd381a62a4a (patch)
tree4254dca7edeee7c225fdca9883cb6526384620a3
parentaf5a6df7b15cf2cf4da8a6aa38081725f9082479 (diff)
downloademacs-ea67f0cee4c6513c5366fb395efa6bd381a62a4a.tar.gz
emacs-ea67f0cee4c6513c5366fb395efa6bd381a62a4a.zip
Fix commentary section. Don't require cl for compilation.
(generic-mode-list): Add autoload cookie. (generic-use-find-file-hook, generic-lines-to-scan) (generic-find-file-regexp, generic-ignore-files-regexp) (generic-mode, generic-mode-find-file-hook) (generic-mode-ini-file-find-file-hook): Fix docstrings. (define-generic-mode): Make it a defmacro. Fix docstring. (generic-mode-internal): Code cleanup. Add autoload cookie. (generic-mode-set-comments): Code cleanup.
-rw-r--r--lisp/generic.el273
1 files changed, 139 insertions, 134 deletions
diff --git a/lisp/generic.el b/lisp/generic.el
index 9545b0970ac..e257f7bac59 100644
--- a/lisp/generic.el
+++ b/lisp/generic.el
@@ -34,27 +34,31 @@
34 34
35;; Generic-mode is a meta-mode which can be used to define small modes 35;; Generic-mode is a meta-mode which can be used to define small modes
36;; which provide basic comment and font-lock support. These modes are 36;; which provide basic comment and font-lock support. These modes are
37;; intended for the many configuration files and such which are too small 37;; intended for the many configuration files and such which are too
38;; for a "real" mode, but still have a regular syntax, comment characters 38;; small for a "real" mode, but still have a regular syntax, comment
39;; and the like. 39;; characters and the like.
40;; 40;;
41;; Each generic mode can define the following: 41;; Each generic mode can define the following:
42;; 42;;
43;; * List of comment-characters. The entries in this list should be 43;; * List of comment-characters. The entries in this list should be
44;; either a character, a one or two character string or a cons pair. 44;; either a character, a one or two character string or a cons pair.
45;; If the entry is a character or a one-character string 45;; If the entry is a character or a string, it is added to the
46;; LIMITATIONS: Emacs does not support comment strings of more than 46;; mode's syntax table with `comment-start' syntax. If the entry is
47;; a cons pair, the elements of the pair are considered to be
48;; `comment-start' and `comment-end' respectively. (The latter
49;; should be nil if you want comments to end at end of line.)
50;; LIMITATIONS: Emacs does not support comment strings of more than
47;; two characters in length. 51;; two characters in length.
48;; 52;;
49;; * List of keywords to font-lock. Each keyword should be a string. 53;; * List of keywords to font-lock. Each keyword should be a string.
50;; If you have additional keywords which should be highlighted in a face 54;; If you have additional keywords which should be highlighted in a
51;; different from `font-lock-keyword-face', you can use the convenience 55;; face different from `font-lock-keyword-face', you can use the
52;; function `generic-make-keywords-list' (which see), and add the 56;; convenience function `generic-make-keywords-list' (which see),
53;; result to the following list: 57;; and add the result to the following list:
54;; 58;;
55;; * Additional expressions to font-lock. This should be a list of 59;; * Additional expressions to font-lock. This should be a list of
56;; expressions, each of which should be of the same form 60;; expressions, each of which should be of the same form as those in
57;; as those in `font-lock-keywords'. 61;; `font-lock-keywords'.
58;; 62;;
59;; * List of regular expressions to be placed in auto-mode-alist. 63;; * List of regular expressions to be placed in auto-mode-alist.
60;; 64;;
@@ -79,35 +83,35 @@
79;; Use the `define-generic-mode' function to define new modes. 83;; Use the `define-generic-mode' function to define new modes.
80;; For example: 84;; For example:
81;; 85;;
82;; (require 'generic)
83;; (define-generic-mode 'foo-generic-mode 86;; (define-generic-mode 'foo-generic-mode
84;; (list ?% ) 87;; (list ?%)
85;; (list "keyword") 88;; (list "keyword")
86;; nil 89;; nil
87;; (list "\\.FOO\\'") 90;; (list "\\.FOO\\'")
88;; (list 'foo-setup-function)) 91;; (list 'foo-setup-function))
89;; 92;;
90;; defines a new generic-mode `foo-generic-mode', which has '%' as a 93;; defines a new generic-mode `foo-generic-mode', which has '%' as a
91;; comment character, and "keyword" as a keyword. When files which end in 94;; comment character, and "keyword" as a keyword. When files which
92;; '.FOO' are loaded, Emacs will go into foo-generic-mode and call 95;; end in '.FOO' are loaded, Emacs will go into foo-generic-mode and
93;; foo-setup-function. You can also use the function `foo-generic-mode' 96;; call foo-setup-function. You can also use the function
94;; (which is interactive) to put a buffer into foo-generic-mode. 97;; `foo-generic-mode' (which is interactive) to put a buffer into
98;; foo-generic-mode.
95;; 99;;
96;; AUTOMATICALLY ENTERING GENERIC MODE: 100;; AUTOMATICALLY ENTERING GENERIC MODE:
97;; 101;;
98;; Generic-mode provides a hook which automatically puts a 102;; Generic-mode provides a hook which automatically puts a file into
99;; file into default-generic-mode if the first few lines of a file in 103;; default-generic-mode if the first few lines of a file in
100;; fundamental mode start with a hash comment character. To disable 104;; fundamental mode start with a hash comment character. To disable
101;; this functionality, set the variable `generic-use-find-file-hook' 105;; this functionality, set the variable `generic-use-find-file-hook'
102;; to nil BEFORE loading generic-mode. See the variables 106;; to nil BEFORE loading generic-mode. See the variables
103;; `generic-lines-to-scan' and `generic-find-file-regexp' for customization 107;; `generic-lines-to-scan' and `generic-find-file-regexp' for
104;; options. 108;; customization options.
105;; 109;;
106;; GOTCHAS: 110;; GOTCHAS:
107;; 111;;
108;; Be careful that your font-lock definitions are correct. Getting them 112;; Be careful that your font-lock definitions are correct. Getting
109;; wrong can cause emacs to continually attempt to fontify! This problem 113;; them wrong can cause Emacs to continually attempt to fontify! This
110;; is not specific to generic-mode. 114;; problem is not specific to generic-mode.
111;; 115;;
112 116
113;; Credit for suggestions, brainstorming, help with debugging: 117;; Credit for suggestions, brainstorming, help with debugging:
@@ -117,9 +121,6 @@
117;; 121;;
118;;; Code: 122;;; Code:
119 123
120(eval-when-compile
121 (require 'cl))
122
123;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 124;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
124;; Internal Variables 125;; Internal Variables
125;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 126;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -128,6 +129,7 @@
128 "Global defaults for font-lock in a generic mode.") 129 "Global defaults for font-lock in a generic mode.")
129(make-variable-buffer-local 'generic-font-lock-defaults) 130(make-variable-buffer-local 'generic-font-lock-defaults)
130 131
132;;;###autoload
131(defvar generic-mode-list nil 133(defvar generic-mode-list nil
132 "A list of mode names for `generic-mode'. 134 "A list of mode names for `generic-mode'.
133Do not add entries to this list directly; use `define-generic-mode' 135Do not add entries to this list directly; use `define-generic-mode'
@@ -143,139 +145,140 @@ instead (which see).")
143 :group 'extensions) 145 :group 'extensions)
144 146
145(defcustom generic-use-find-file-hook t 147(defcustom generic-use-find-file-hook t
146 "*If non-nil, add a hook to enter default-generic-mode automatically. 148 "*If non-nil, add a hook to enter `default-generic-mode' automatically.
147This is done if the first few lines of a file in fundamental mode start 149This is done if the first few lines of a file in fundamental mode
148with a hash comment character." 150start with a hash comment character."
149 :group 'generic 151 :group 'generic
150 :type 'boolean 152 :type 'boolean)
151 )
152 153
153(defcustom generic-lines-to-scan 3 154(defcustom generic-lines-to-scan 3
154 "*Number of lines that `generic-mode-find-file-hook' looks at. 155 "*Number of lines that `generic-mode-find-file-hook' looks at.
155Relevant when deciding whether to enter `generic-mode' automatically. 156Relevant when deciding whether to enter Default-Generic mode automatically.
156This variable should be set to a small positive number." 157This variable should be set to a small positive number."
157 :group 'generic 158 :group 'generic
158 :type 'integer 159 :type 'integer)
159 )
160 160
161(defcustom generic-find-file-regexp "^#" 161(defcustom generic-find-file-regexp "^#"
162 "*Regular expression used by `generic-mode-find-file-hook'. 162 "*Regular expression used by `generic-mode-find-file-hook'.
163Files in fundamental mode whose first few lines contain a match for 163Files in fundamental mode whose first few lines contain a match
164this regexp, should be put into `default-generic-mode' instead. 164for this regexp, should be put into Default-Generic mode instead.
165The number of lines tested for the matches is specified by the value 165The number of lines tested for the matches is specified by the
166of the variable `generic-lines-to-scan', which see." 166value of the variable `generic-lines-to-scan', which see."
167 :group 'generic 167 :group 'generic
168 :type 'regexp 168 :type 'regexp)
169 )
170 169
171(defcustom generic-ignore-files-regexp "[Tt][Aa][Gg][Ss]\\'" 170(defcustom generic-ignore-files-regexp "[Tt][Aa][Gg][Ss]\\'"
172 "*Regular expression used by `generic-mode-find-file-hook'. 171 "*Regular expression used by `generic-mode-find-file-hook'.
173Files whose names match this regular expression should not be put 172Files whose names match this regular expression should not be put
174into `default-generic-mode', even if they have lines which match the 173into Default-Generic mode, even if they have lines which match
175regexp in `generic-find-file-regexp'. If the value is nil, 174the regexp in `generic-find-file-regexp'. If the value is nil,
176`generic-mode-find-file-hook' does not check the file names." 175`generic-mode-find-file-hook' does not check the file names."
177 :group 'generic 176 :group 'generic
178 :type '(choice (const :tag "Don't check file names" nil) regexp) 177 :type '(choice (const :tag "Don't check file names" nil) regexp))
179 )
180 178
181;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 179;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
182;; Functions 180;; Functions
183;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 181;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
184 182
185;;;###autoload 183;;;###autoload
186(defun define-generic-mode (name comment-list keyword-list font-lock-list 184(defmacro define-generic-mode (mode comment-list keyword-list
187 auto-mode-list function-list 185 font-lock-list auto-mode-list
188 &optional description) 186 function-list &optional docstring)
189 "Create a new generic mode with NAME. 187 "Create a new generic mode MODE.
190 188
191NAME should be a symbol; its string representation is used as the function 189MODE is the name of the command for the generic mode; it need not
192name. If DESCRIPTION is provided, it is used as the docstring for the new 190be quoted. The optional DOCSTRING is the documentation for the
193function. 191mode command. If you do not supply it, a default documentation
194 192string will be used instead.
195COMMENT-LIST is a list, whose entries are either a single character, 193
196a one or two character string or a cons pair. If the entry is a character 194COMMENT-LIST is a list, whose entries are either a single
197or a one-character string, it is added to the mode's syntax table with 195character, a one or two character string or a cons pair. If the
198`comment-start' syntax. If the entry is a cons pair, the elements of the 196entry is a character or a string, it is added to the mode's
199pair are considered to be `comment-start' and `comment-end' respectively. 197syntax table with `comment-start' syntax. If the entry is a cons
200\(The latter should be nil if you want comments to end at end of line.) 198pair, the elements of the pair are considered to be
201Note that Emacs has limitations regarding comment characters. 199`comment-start' and `comment-end' respectively. (The latter
202 200should be nil if you want comments to end at end of line.) Note
203KEYWORD-LIST is a list of keywords to highlight with `font-lock-keyword-face'. 201that Emacs has limitations regarding comment characters.
204Each keyword should be a string. 202
205 203KEYWORD-LIST is a list of keywords to highlight with
206FONT-LOCK-LIST is a list of additional expressions to highlight. Each entry 204`font-lock-keyword-face'. Each keyword should be a string.
207in the list should have the same form as an entry in `font-lock-keywords'. 205
208 206FONT-LOCK-LIST is a list of additional expressions to highlight.
209AUTO-MODE-LIST is a list of regular expressions to add to `auto-mode-alist'. 207Each entry in the list should have the same form as an entry in
210These regexps are added to `auto-mode-alist' as soon as `define-generic-mode' 208`font-lock-keywords'.
211is called; any old regexps with the same name are removed. 209
212 210AUTO-MODE-LIST is a list of regular expressions to add to
213FUNCTION-LIST is a list of functions to call to do some additional setup. 211`auto-mode-alist'. These regexps are added to `auto-mode-alist'
212as soon as `define-generic-mode' is called.
213
214FUNCTION-LIST is a list of functions to call to do some
215additional setup.
214 216
215See the file generic-x.el for some examples of `define-generic-mode'." 217See the file generic-x.el for some examples of `define-generic-mode'."
218 (let* ((name-unquoted (if (eq (car-safe mode) 'quote) ; Backward compatibility.
219 (eval mode)
220 mode))
221 (name-string (symbol-name name-unquoted))
222 (pretty-name (capitalize (replace-regexp-in-string
223 "-mode\\'" "" name-string))))
224
225 `(progn
226 ;; Add a new entry.
227 (add-to-list 'generic-mode-list ,name-string)
228
229 ;; Add it to auto-mode-alist
230 (dolist (re ,auto-mode-list)
231 (add-to-list 'auto-mode-alist (cons re ',name-unquoted)))
232
233 (defun ,name-unquoted ()
234 ,(or docstring
235 (concat pretty-name " mode.\n"
236 "This a generic mode defined with `define-generic-mode'."))
237 (interactive)
238 (generic-mode-internal ',name-unquoted ,comment-list ,keyword-list
239 ,font-lock-list ,function-list)))))
216 240
217 ;; Add a new entry 241;;;###autoload
218 (add-to-list 'generic-mode-list (symbol-name name))
219
220 ;; Add it to auto-mode-alist
221 (dolist (re auto-mode-list)
222 (add-to-list 'auto-mode-alist (cons re name)))
223
224 ;; Define a function for it using `defalias' (not `fset') to make
225 ;; the mode appear on load-history.
226 (defalias name
227 `(lambda nil
228 ,(or description (concat "Generic mode for type " (symbol-name name)))
229 (interactive)
230 (generic-mode-internal ',name ',comment-list ',keyword-list
231 ',font-lock-list ',function-list)))
232 )
233
234(defun generic-mode-internal (mode comments keywords font-lock-list funs) 242(defun generic-mode-internal (mode comments keywords font-lock-list funs)
235 "Go into the generic-mode MODE." 243 "Go into the generic mode MODE."
236 (let* ((generic-mode-hooks (intern (concat (symbol-name mode) "-hook"))) 244 (let* ((modename (symbol-name mode))
237 (modename (symbol-name mode)) 245 (generic-mode-hooks (intern (concat modename "-hook")))
238 (name (if (string-match "-mode\\'" modename) 246 (pretty-name (capitalize (replace-regexp-in-string
239 (substring modename 0 (match-beginning 0)) 247 "-mode\\'" "" modename))))
240 modename)) 248
241 )
242
243 ;; Put this after the point where we read generic-mode-name!
244 (kill-all-local-variables) 249 (kill-all-local-variables)
245 250
246 (setq 251 (setq major-mode mode
247 major-mode mode 252 mode-name pretty-name)
248 mode-name (capitalize name)
249 )
250 253
251 (generic-mode-set-comments comments) 254 (generic-mode-set-comments comments)
252 255
253 ;; Font-lock functionality 256 ;; Font-lock functionality
254 ;; Font-lock-defaults are always set even if there are no keywords 257 ;; Font-lock-defaults are always set even if there are no keywords
255 ;; or font-lock expressions, so comments can be highlighted. 258 ;; or font-lock expressions, so comments can be highlighted.
256 (setq generic-font-lock-defaults nil) 259 (setq generic-font-lock-defaults nil)
257 (generic-mode-set-font-lock keywords font-lock-list) 260 (generic-mode-set-font-lock keywords font-lock-list)
258 (make-local-variable 'font-lock-defaults) 261 (make-local-variable 'font-lock-defaults)
259 (setq font-lock-defaults (list 'generic-font-lock-defaults nil)) 262 (setq font-lock-defaults (list 'generic-font-lock-defaults nil))
260 263
261 ;; Call a list of functions 264 ;; Call a list of functions
262 (mapcar 'funcall funs) 265 (mapcar 'funcall funs)
263 266
264 (run-hooks generic-mode-hooks) 267 (run-hooks generic-mode-hooks)))
265 )
266 )
267 268
268;;;###autoload 269;;;###autoload
269(defun generic-mode (type) 270(defun generic-mode (mode)
270 "Basic comment and font-lock functionality for `generic' files. 271 "Enter generic mode MODE.
271\(Files which are too small to warrant their own mode, but have 272
272comment characters, keywords, and the like.) 273Generic modes provide basic comment and font-lock functionality
274for \"generic\" files. (Files which are too small to warrant their
275own mode, but have comment characters, keywords, and the like.)
273 276
274To define a generic-mode, use the function `define-generic-mode'. 277To define a generic-mode, use the function `define-generic-mode'.
275Some generic modes are defined in `generic-x.el'." 278Some generic modes are defined in `generic-x.el'."
276 (interactive 279 (interactive
277 (list (completing-read "Generic Type: " generic-mode-list nil t))) 280 (list (completing-read "Generic mode: " generic-mode-list nil t)))
278 (funcall (intern type))) 281 (funcall (intern mode)))
279 282
280;;; Comment Functionality 283;;; Comment Functionality
281(defun generic-mode-set-comments (comment-list) 284(defun generic-mode-set-comments (comment-list)
@@ -283,16 +286,16 @@ Some generic modes are defined in `generic-x.el'."
283 (let ((st (make-syntax-table)) 286 (let ((st (make-syntax-table))
284 (chars nil) 287 (chars nil)
285 (comstyles)) 288 (comstyles))
286 (make-local-variable 'comment-start) 289 (make-local-variable 'comment-start)
287 (make-local-variable 'comment-start-skip) 290 (make-local-variable 'comment-start-skip)
288 (make-local-variable 'comment-end) 291 (make-local-variable 'comment-end)
289 292
290 ;; Go through all the comments 293 ;; Go through all the comments
291 (dolist (start comment-list) 294 (dolist (start comment-list)
292 (let ((end nil) (comstyle "")) 295 (let (end (comstyle ""))
293 ;; Normalize 296 ;; Normalize
294 (when (consp start) 297 (when (consp start)
295 (setq end (or (cdr start) end)) 298 (setq end (cdr start))
296 (setq start (car start))) 299 (setq start (car start)))
297 (when (char-valid-p start) (setq start (char-to-string start))) 300 (when (char-valid-p start) (setq start (char-to-string start)))
298 (cond 301 (cond
@@ -360,18 +363,20 @@ Some generic modes are defined in `generic-x.el'."
360 imenu-case-fold-search t)) 363 imenu-case-fold-search t))
361 364
362;; This generic mode is always defined 365;; This generic mode is always defined
363(define-generic-mode 'default-generic-mode (list ?#) nil nil nil nil) 366(define-generic-mode default-generic-mode (list ?#) nil nil nil nil)
364 367
365;; A more general solution would allow us to enter generic-mode for 368;; A more general solution would allow us to enter generic-mode for
366;; *any* comment character, but would require us to synthesize a new 369;; *any* comment character, but would require us to synthesize a new
367;; generic-mode on the fly. I think this gives us most of what we 370;; generic-mode on the fly. I think this gives us most of what we
368;; want. 371;; want.
369(defun generic-mode-find-file-hook () 372(defun generic-mode-find-file-hook ()
370 "Hook function to enter `default-generic-mode' automatically. 373 "Hook function to enter Default-Generic mode automatically.
371Done if the first few lines of a file in `fundamental-mode' start with 374
372a match for the regexp in `generic-find-file-regexp', unless the 375Done if the first few lines of a file in Fundamental mode start
373file's name matches the regexp which is the value of the variable 376with a match for the regexp in `generic-find-file-regexp', unless
374`generic-ignore-files-regexp'. 377the file's name matches the regexp which is the value of the
378variable `generic-ignore-files-regexp'.
379
375This hook will be installed if the variable 380This hook will be installed if the variable
376`generic-use-find-file-hook' is non-nil. The variable 381`generic-use-find-file-hook' is non-nil. The variable
377`generic-lines-to-scan' determines the number of lines to look at." 382`generic-lines-to-scan' determines the number of lines to look at."
@@ -390,8 +395,8 @@ This hook will be installed if the variable
390 (default-generic-mode))))) 395 (default-generic-mode)))))
391 396
392(defun generic-mode-ini-file-find-file-hook () 397(defun generic-mode-ini-file-find-file-hook ()
393 "Hook function to enter default-generic-mode automatically for INI files. 398 "Hook function to enter Default-Generic mode automatically for INI files.
394Done if the first few lines of a file in `fundamental-mode' look like an 399Done if the first few lines of a file in Fundamental mode look like an
395INI file. This hook is NOT installed by default." 400INI file. This hook is NOT installed by default."
396 (and (eq major-mode 'fundamental-mode) 401 (and (eq major-mode 'fundamental-mode)
397 (save-excursion 402 (save-excursion