diff options
| -rw-r--r-- | lisp/ChangeLog | 19 | ||||
| -rw-r--r-- | lisp/generic.el | 442 |
2 files changed, 147 insertions, 314 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index bec5f449b6b..b259abd71e4 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,24 @@ | |||
| 1 | 2000-10-04 Peter Breton <pbreton@ne.mediaone.net> | 1 | 2000-10-04 Peter Breton <pbreton@ne.mediaone.net> |
| 2 | 2 | ||
| 3 | * generic.el: | ||
| 4 | Incorporates extensive cleanup and docfixes by | ||
| 5 | Stefan Monnier (monnier+gnu/emacs@flint.cs.yale.edu). | ||
| 6 | Uses cl compile-time macros. | ||
| 7 | (generic-mode-name, generic-comment-list, | ||
| 8 | generic-keywords-list, generic-font-lock-expressions, | ||
| 9 | generic-mode-function-list, generic-mode-syntax-table): | ||
| 10 | Removed variables. | ||
| 11 | (generic-mode-alist): Renamed to generic-mode-list. | ||
| 12 | (generic-find-file-regexp): Default changed to "^#". | ||
| 13 | (generic-read-type): Uses completing read on generic-mode-list. | ||
| 14 | (generic-mode-sanity-check): removed this function. | ||
| 15 | (generic-add-to-auto-mode): Removed this function | ||
| 16 | (generic-mode-internal): Binds mode-specific definitions | ||
| 17 | into function instead of putting them in alist. | ||
| 18 | (generic-mode-set-comments): Reworked extensively. | ||
| 19 | (generic-mode-find-file-hook): Simplified regexp searching | ||
| 20 | (generic-make-keywords-list): Omit extra pair of parens | ||
| 21 | |||
| 3 | * find-lisp.el (find-lisp-find-files-internal): | 22 | * find-lisp.el (find-lisp-find-files-internal): |
| 4 | Make sure directory name ends with "/". | 23 | Make sure directory name ends with "/". |
| 5 | 24 | ||
diff --git a/lisp/generic.el b/lisp/generic.el index 2d8cf4c937b..e08b4ad371c 100644 --- a/lisp/generic.el +++ b/lisp/generic.el | |||
| @@ -51,11 +51,11 @@ | |||
| 51 | ;; different from `font-lock-keyword-face', you can use the convenience | 51 | ;; different from `font-lock-keyword-face', you can use the convenience |
| 52 | ;; function `generic-make-keywords-list' (which see), and add the | 52 | ;; function `generic-make-keywords-list' (which see), and add the |
| 53 | ;; result to the following list: | 53 | ;; result to the following list: |
| 54 | ;; | 54 | ;; |
| 55 | ;; * Additional expressions to font-lock. This should be a list of | 55 | ;; * Additional expressions to font-lock. This should be a list of |
| 56 | ;; expressions, each of which should be of the same form | 56 | ;; expressions, each of which should be of the same form |
| 57 | ;; as those in `font-lock-defaults-alist'. | 57 | ;; as those in `font-lock-defaults-alist'. |
| 58 | ;; | 58 | ;; |
| 59 | ;; * List of regular expressions to be placed in auto-mode-alist. | 59 | ;; * List of regular expressions to be placed in auto-mode-alist. |
| 60 | ;; | 60 | ;; |
| 61 | ;; * List of functions to call to do some additional setup | 61 | ;; * List of functions to call to do some additional setup |
| @@ -73,7 +73,7 @@ | |||
| 73 | ;; | 73 | ;; |
| 74 | ;; Do NOT use "mode: generic"! | 74 | ;; Do NOT use "mode: generic"! |
| 75 | ;; See also "AUTOMATICALLY ENTERING GENERIC MODE" below. | 75 | ;; See also "AUTOMATICALLY ENTERING GENERIC MODE" below. |
| 76 | ;; | 76 | ;; |
| 77 | ;; DEFINING NEW GENERIC MODES: | 77 | ;; DEFINING NEW GENERIC MODES: |
| 78 | ;; | 78 | ;; |
| 79 | ;; Use the `define-generic-mode' function to define new modes. | 79 | ;; Use the `define-generic-mode' function to define new modes. |
| @@ -84,7 +84,7 @@ | |||
| 84 | ;; (list ?% ) | 84 | ;; (list ?% ) |
| 85 | ;; (list "keyword") | 85 | ;; (list "keyword") |
| 86 | ;; nil | 86 | ;; nil |
| 87 | ;; (list "\.FOO") | 87 | ;; (list "\\.FOO\\'") |
| 88 | ;; (list 'foo-setup-function)) | 88 | ;; (list 'foo-setup-function)) |
| 89 | ;; | 89 | ;; |
| 90 | ;; defines a new generic-mode `foo-generic-mode', which has '%' as a | 90 | ;; defines a new generic-mode `foo-generic-mode', which has '%' as a |
| @@ -102,19 +102,24 @@ | |||
| 102 | ;; to nil BEFORE loading generic-mode. See the variables | 102 | ;; to nil BEFORE loading generic-mode. See the variables |
| 103 | ;; `generic-lines-to-scan' and `generic-find-file-regexp' for customization | 103 | ;; `generic-lines-to-scan' and `generic-find-file-regexp' for customization |
| 104 | ;; options. | 104 | ;; options. |
| 105 | ;; | 105 | ;; |
| 106 | ;; GOTCHAS: | 106 | ;; GOTCHAS: |
| 107 | ;; | 107 | ;; |
| 108 | ;; Be careful that your font-lock definitions are correct. Getting them | 108 | ;; Be careful that your font-lock definitions are correct. Getting them |
| 109 | ;; wrong can cause emacs to continually attempt to fontify! This problem | 109 | ;; wrong can cause emacs to continually attempt to fontify! This problem |
| 110 | ;; is not specific to generic-mode. | 110 | ;; is not specific to generic-mode. |
| 111 | ;; | 111 | ;; |
| 112 | 112 | ||
| 113 | ;; Credit for suggestions, brainstorming, help with debugging: | 113 | ;; Credit for suggestions, brainstorming, help with debugging: |
| 114 | ;; ACorreir@pervasive-sw.com (Alfred Correira) | 114 | ;; ACorreir@pervasive-sw.com (Alfred Correira) |
| 115 | 115 | ;; Extensive cleanup by: | |
| 116 | ;; Stefan Monnier (monnier+gnu/emacs@flint.cs.yale.edu) | ||
| 117 | ;; | ||
| 116 | ;;; Code: | 118 | ;;; Code: |
| 117 | 119 | ||
| 120 | (eval-when-compile | ||
| 121 | (require 'cl)) | ||
| 122 | |||
| 118 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 123 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 119 | ;; Internal Variables | 124 | ;; Internal Variables |
| 120 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 125 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| @@ -123,38 +128,8 @@ | |||
| 123 | "Global defaults for font-lock in a generic mode.") | 128 | "Global defaults for font-lock in a generic mode.") |
| 124 | (make-variable-buffer-local 'generic-font-lock-defaults) | 129 | (make-variable-buffer-local 'generic-font-lock-defaults) |
| 125 | 130 | ||
| 126 | (defvar generic-mode-name 'default-generic-mode | 131 | (defvar generic-mode-list nil |
| 127 | "The name of the generic mode. | 132 | "A list of mode names for `generic-mode'. |
| 128 | This is the car of one of the items in `generic-mode-alist'. | ||
| 129 | This variable is buffer-local.") | ||
| 130 | (make-variable-buffer-local 'generic-mode-name) | ||
| 131 | |||
| 132 | (defvar generic-comment-list nil | ||
| 133 | "List of comment characters for a generic mode.") | ||
| 134 | (make-variable-buffer-local 'generic-comment-list) | ||
| 135 | |||
| 136 | (defvar generic-keywords-list nil | ||
| 137 | "List of keywords for a generic mode.") | ||
| 138 | (make-variable-buffer-local 'generic-keywords-list) | ||
| 139 | |||
| 140 | (defvar generic-font-lock-expressions nil | ||
| 141 | "List of font-lock expressions for a generic mode.") | ||
| 142 | (make-variable-buffer-local 'generic-font-lock-expressions) | ||
| 143 | |||
| 144 | (defvar generic-mode-function-list nil | ||
| 145 | "List of customization functions to call for a generic mode.") | ||
| 146 | (make-variable-buffer-local 'generic-mode-function-list) | ||
| 147 | |||
| 148 | (defvar generic-mode-syntax-table nil | ||
| 149 | "Syntax table for use in a generic mode.") | ||
| 150 | (make-variable-buffer-local 'generic-mode-syntax-table) | ||
| 151 | |||
| 152 | (defvar generic-mode-alist nil | ||
| 153 | "An association list for `generic-mode'. | ||
| 154 | Each entry in the list looks like this: | ||
| 155 | |||
| 156 | NAME COMMENT-LIST KEYWORD-LIST FONT-LOCK-LIST AUTO-MODE-LIST FUNCTION-LIST. | ||
| 157 | |||
| 158 | Do not add entries to this list directly; use `define-generic-mode' | 133 | Do not add entries to this list directly; use `define-generic-mode' |
| 159 | instead (which see).") | 134 | instead (which see).") |
| 160 | 135 | ||
| @@ -183,7 +158,7 @@ This variable should be set to a small positive number." | |||
| 183 | :type 'integer | 158 | :type 'integer |
| 184 | ) | 159 | ) |
| 185 | 160 | ||
| 186 | (defcustom generic-find-file-regexp "#.*\n\\(.*\n\\)?" | 161 | (defcustom generic-find-file-regexp "^#" |
| 187 | "*Regular expression used by `generic-mode-find-file-hook'. | 162 | "*Regular expression used by `generic-mode-find-file-hook'. |
| 188 | Used to determine if files in fundamental mode should be put into | 163 | Used to determine if files in fundamental mode should be put into |
| 189 | `default-generic-mode' instead." | 164 | `default-generic-mode' instead." |
| @@ -198,27 +173,8 @@ Used to determine if files in fundamental mode should be put into | |||
| 198 | (defsubst generic-read-type () | 173 | (defsubst generic-read-type () |
| 199 | (completing-read | 174 | (completing-read |
| 200 | "Generic Type: " | 175 | "Generic Type: " |
| 201 | (mapcar | 176 | generic-mode-list |
| 202 | '(lambda (elt) (list (symbol-name (car elt)))) | 177 | nil t)) |
| 203 | generic-mode-alist) nil t)) | ||
| 204 | |||
| 205 | ;; Basic sanity checks. It does *not* check whether the elements of the lists | ||
| 206 | ;; are of the correct type. | ||
| 207 | (defsubst generic-mode-sanity-check (name comment-list keyword-list | ||
| 208 | font-lock-list auto-mode-list | ||
| 209 | function-list &optional description) | ||
| 210 | (and (not (symbolp name)) | ||
| 211 | (error "%s is not a symbol" (princ name))) | ||
| 212 | |||
| 213 | (mapcar '(lambda (elt) | ||
| 214 | (if (not (listp elt)) | ||
| 215 | (error "%s is not a list" (princ elt)))) | ||
| 216 | (list comment-list keyword-list font-lock-list | ||
| 217 | auto-mode-list function-list)) | ||
| 218 | |||
| 219 | (and (not (or (null description) (stringp description))) | ||
| 220 | (error "Description must be a string or nil")) | ||
| 221 | ) | ||
| 222 | 178 | ||
| 223 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 179 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 224 | ;; Functions | 180 | ;; Functions |
| @@ -240,8 +196,8 @@ function. | |||
| 240 | COMMENT-LIST is a list, whose entries are either a single character, | 196 | COMMENT-LIST is a list, whose entries are either a single character, |
| 241 | a one or two character string or a cons pair. If the entry is a character | 197 | a one or two character string or a cons pair. If the entry is a character |
| 242 | or a one-character string, it is added to the mode's syntax table with | 198 | or a one-character string, it is added to the mode's syntax table with |
| 243 | comment-start syntax. If the entry is a cons pair, the elements of the | 199 | `comment-start' syntax. If the entry is a cons pair, the elements of the |
| 244 | pair are considered to be comment-start and comment-end respectively. | 200 | pair are considered to be `comment-start' and `comment-end' respectively. |
| 245 | Note that Emacs has limitations regarding comment characters. | 201 | Note that Emacs has limitations regarding comment characters. |
| 246 | 202 | ||
| 247 | KEYWORD-LIST is a list of keywords to highlight with `font-lock-keyword-face'. | 203 | KEYWORD-LIST is a list of keywords to highlight with `font-lock-keyword-face'. |
| @@ -250,122 +206,61 @@ Each keyword should be a string. | |||
| 250 | FONT-LOCK-LIST is a list of additional expressions to highlight. Each entry | 206 | FONT-LOCK-LIST is a list of additional expressions to highlight. Each entry |
| 251 | in the list should have the same form as an entry in `font-lock-defaults-alist' | 207 | in the list should have the same form as an entry in `font-lock-defaults-alist' |
| 252 | 208 | ||
| 253 | AUTO-MODE-LIST is a list of regular expressions to add to auto-mode-alist. | 209 | AUTO-MODE-LIST is a list of regular expressions to add to `auto-mode-alist'. |
| 254 | These regexps are added to auto-mode-alist as soon as `define-generic-mode' | 210 | These regexps are added to `auto-mode-alist' as soon as `define-generic-mode' |
| 255 | is called; any old regexps with the same name are removed. | 211 | is called; any old regexps with the same name are removed. |
| 256 | 212 | ||
| 257 | FUNCTION-LIST is a list of functions to call to do some additional setup. | 213 | FUNCTION-LIST is a list of functions to call to do some additional setup. |
| 258 | 214 | ||
| 259 | See the file generic-x.el for some examples of `define-generic-mode'." | 215 | See the file generic-x.el for some examples of `define-generic-mode'." |
| 260 | 216 | ||
| 261 | ;; Basic sanity check | ||
| 262 | (generic-mode-sanity-check name | ||
| 263 | comment-list keyword-list font-lock-list | ||
| 264 | auto-mode-list function-list description) | ||
| 265 | |||
| 266 | ;; Remove any old entry | ||
| 267 | (setq generic-mode-alist | ||
| 268 | (delq (assq name generic-mode-alist) | ||
| 269 | generic-mode-alist)) | ||
| 270 | |||
| 271 | ;; Add a new entry | 217 | ;; Add a new entry |
| 272 | (setq generic-mode-alist | 218 | (unless (assq name generic-mode-list) |
| 273 | (append | 219 | (push (list name) generic-mode-list)) |
| 274 | (list | ||
| 275 | (list | ||
| 276 | name comment-list keyword-list font-lock-list | ||
| 277 | auto-mode-list function-list | ||
| 278 | )) | ||
| 279 | generic-mode-alist)) | ||
| 280 | 220 | ||
| 281 | ;; Add it to auto-mode-alist | 221 | ;; Add it to auto-mode-alist |
| 282 | (generic-add-to-auto-mode name auto-mode-list t) | 222 | (dolist (re auto-mode-list) |
| 283 | 223 | (add-to-list 'auto-mode-alist (cons re name))) | |
| 284 | ;; Define a function for it | 224 | |
| 285 | (generic-create-generic-function name description) | 225 | ;; Define a function for it using `defalias' (not `fset') to make |
| 226 | ;; the mode appear on load-history. | ||
| 227 | (defalias name | ||
| 228 | `(lambda nil | ||
| 229 | ,(or description (concat "Generic mode for type " (symbol-name name))) | ||
| 230 | (interactive) | ||
| 231 | (generic-mode-internal ',name ',comment-list ',keyword-list | ||
| 232 | ',font-lock-list ',function-list))) | ||
| 286 | ) | 233 | ) |
| 287 | 234 | ||
| 288 | (defun generic-add-to-auto-mode (mode auto-mode-list | 235 | (defun generic-mode-internal (mode comments keywords font-lock-list funs) |
| 289 | &optional remove-old prepend) | ||
| 290 | "Add the entries for MODE to `auto-mode-alist', supplied as AUTO-MODE-ALIST. | ||
| 291 | If remove-old is non-nil, removes old entries first. If prepend is | ||
| 292 | non-nil, prepends entries to auto-mode-alist; otherwise, appends them." | ||
| 293 | |||
| 294 | (if (not (listp auto-mode-list)) | ||
| 295 | (error "%s is not a list" (princ auto-mode-list))) | ||
| 296 | |||
| 297 | (let ((new-mode (intern (symbol-name mode)))) | ||
| 298 | (and remove-old | ||
| 299 | (let ((auto-mode-entry)) | ||
| 300 | (while (setq auto-mode-entry (rassq new-mode auto-mode-alist)) | ||
| 301 | (setq auto-mode-alist | ||
| 302 | (delq auto-mode-entry | ||
| 303 | auto-mode-alist))))) | ||
| 304 | |||
| 305 | (mapcar '(lambda (entry) | ||
| 306 | (generic-add-auto-mode-entry new-mode entry prepend)) | ||
| 307 | auto-mode-list))) | ||
| 308 | |||
| 309 | (defun generic-add-auto-mode-entry (name entry &optional prepend) | ||
| 310 | "Add a new NAME regexp with ENTRY to the end of `auto-mode-alist'. | ||
| 311 | If prepend is non-nil, add the entry to the front of the list." | ||
| 312 | (let ((new-entry (list (cons entry name)))) | ||
| 313 | (setq auto-mode-alist | ||
| 314 | (if prepend | ||
| 315 | (append new-entry auto-mode-alist) | ||
| 316 | (append auto-mode-alist new-entry))))) | ||
| 317 | |||
| 318 | (defun generic-create-generic-function (name &optional description) | ||
| 319 | "Create a generic mode function with NAME. | ||
| 320 | If DESCRIPTION is provided, it is used as the docstring." | ||
| 321 | (let ((symname (symbol-name name))) | ||
| 322 | ;; Use `defalias', not `fset' to make the mode appear on | ||
| 323 | ;; load-history. | ||
| 324 | (defalias (intern symname) | ||
| 325 | (list 'lambda nil | ||
| 326 | (or description | ||
| 327 | (concat "Generic mode for type " symname)) | ||
| 328 | (list 'interactive) | ||
| 329 | (list 'generic-mode-with-type (list 'quote name)))))) | ||
| 330 | |||
| 331 | (defun generic-mode-with-type (&optional mode) | ||
| 332 | "Go into the generic-mode MODE." | 236 | "Go into the generic-mode MODE." |
| 333 | (let* ((type (or mode generic-mode-name)) | 237 | (let* ((generic-mode-hooks (intern (concat (symbol-name mode) "-hook"))) |
| 334 | (generic-mode-list (assoc type generic-mode-alist)) | 238 | (modename (symbol-name mode)) |
| 335 | (generic-mode-hooks (intern (concat (symbol-name type) "-hooks"))) | 239 | (name (if (string-match "-mode\\'" modename) |
| 240 | (substring modename 0 (match-beginning 0)) | ||
| 241 | modename)) | ||
| 336 | ) | 242 | ) |
| 337 | 243 | ||
| 338 | (and (not generic-mode-list) | ||
| 339 | (error "Can't find generic-mode information for type %s" | ||
| 340 | (princ generic-mode-name))) | ||
| 341 | |||
| 342 | ;; Put this after the point where we read generic-mode-name! | 244 | ;; Put this after the point where we read generic-mode-name! |
| 343 | (kill-all-local-variables) | 245 | (kill-all-local-variables) |
| 344 | 246 | ||
| 345 | (setq | 247 | (setq |
| 346 | generic-mode-name type | 248 | major-mode mode |
| 347 | generic-comment-list (nth 1 generic-mode-list) | 249 | mode-name (capitalize name) |
| 348 | generic-keywords-list (nth 2 generic-mode-list) | ||
| 349 | generic-font-lock-expressions (nth 3 generic-mode-list) | ||
| 350 | generic-mode-function-list (nth 5 generic-mode-list) | ||
| 351 | major-mode type | ||
| 352 | mode-name (symbol-name type) | ||
| 353 | ) | 250 | ) |
| 354 | 251 | ||
| 355 | (generic-mode-set-comments generic-comment-list) | 252 | (generic-mode-set-comments comments) |
| 356 | 253 | ||
| 357 | ;; Font-lock functionality | 254 | ;; Font-lock functionality |
| 358 | ;; Font-lock-defaults are always set even if there are no keywords | 255 | ;; Font-lock-defaults are always set even if there are no keywords |
| 359 | ;; or font-lock expressions, so comments can be highlighted. | 256 | ;; or font-lock expressions, so comments can be highlighted. |
| 360 | (setq generic-font-lock-defaults nil) | 257 | (setq generic-font-lock-defaults nil) |
| 361 | (generic-mode-set-font-lock generic-keywords-list | 258 | (generic-mode-set-font-lock keywords font-lock-list) |
| 362 | generic-font-lock-expressions) | ||
| 363 | (make-local-variable 'font-lock-defaults) | 259 | (make-local-variable 'font-lock-defaults) |
| 364 | (setq font-lock-defaults (list 'generic-font-lock-defaults nil)) | 260 | (setq font-lock-defaults (list 'generic-font-lock-defaults nil)) |
| 365 | 261 | ||
| 366 | ;; Call a list of functions | 262 | ;; Call a list of functions |
| 367 | (and generic-mode-function-list | 263 | (mapcar 'funcall funs) |
| 368 | (mapcar 'funcall generic-mode-function-list)) | ||
| 369 | 264 | ||
| 370 | (run-hooks generic-mode-hooks) | 265 | (run-hooks generic-mode-hooks) |
| 371 | ) | 266 | ) |
| @@ -374,159 +269,88 @@ If DESCRIPTION is provided, it is used as the docstring." | |||
| 374 | ;;;###autoload | 269 | ;;;###autoload |
| 375 | (defun generic-mode (type) | 270 | (defun generic-mode (type) |
| 376 | "Basic comment and font-lock functionality for `generic' files. | 271 | "Basic comment and font-lock functionality for `generic' files. |
| 377 | (Files which are too small to warrant their own mode, but have | 272 | \(Files which are too small to warrant their own mode, but have |
| 378 | comment characters, keywords, and the like.) | 273 | comment characters, keywords, and the like.) |
| 379 | 274 | ||
| 380 | To define a generic-mode, use the function `define-generic-mode'. | 275 | To define a generic-mode, use the function `define-generic-mode'. |
| 381 | Some generic modes are defined in `generic-x.el'." | 276 | Some generic modes are defined in `generic-x.el'." |
| 382 | (interactive | 277 | (interactive |
| 383 | (list (generic-read-type))) | 278 | (list (generic-read-type))) |
| 384 | (generic-mode-with-type (intern type))) | 279 | (funcall (intern type))) |
| 385 | 280 | ||
| 386 | ;;; Comment Functionality | 281 | ;;; Comment Functionality |
| 387 | (defun generic-mode-set-comments (comment-list) | 282 | (defun generic-mode-set-comments (comment-list) |
| 388 | "Set up comment functionality for generic mode." | 283 | "Set up comment functionality for generic mode." |
| 389 | (if (null comment-list) | 284 | (let ((st (make-syntax-table)) |
| 390 | nil | 285 | (chars nil) |
| 391 | (let ((generic-mode-syntax-table (make-syntax-table))) | 286 | (comstyles)) |
| 392 | (make-local-variable 'comment-start) | 287 | (make-local-variable 'comment-start) |
| 393 | (make-local-variable 'comment-start-skip) | 288 | (make-local-variable 'comment-start-skip) |
| 394 | (make-local-variable 'comment-end) | 289 | (make-local-variable 'comment-end) |
| 395 | (mapcar 'generic-mode-set-a-comment comment-list) | 290 | |
| 396 | (set-syntax-table generic-mode-syntax-table)))) | 291 | ;; Go through all the comments |
| 397 | 292 | (dolist (start comment-list) | |
| 398 | (defun generic-mode-set-a-comment (comment) | 293 | (let ((end ?\n) (comstyle "")) |
| 399 | (and (char-or-string-p comment) | 294 | ;; Normalize |
| 400 | (if (stringp comment) | 295 | (when (consp start) |
| 401 | (cond | 296 | (setq end (or (cdr start) end)) |
| 402 | ((eq (length comment) 1) | 297 | (setq start (car start))) |
| 403 | (generic-mode-set-comment-char | 298 | (when (char-valid-p start) (setq start (char-to-string start))) |
| 404 | (string-to-char comment))) | 299 | (when (char-valid-p end) (setq end (char-to-string end))) |
| 405 | ((eq (length comment) 2) | 300 | |
| 406 | (generic-mode-set-comment-string comment)) | 301 | ;; Setup the vars for `comment-region' |
| 407 | (t | 302 | (if comment-start |
| 408 | (error "Character string %s must be one or two characters long" | 303 | ;; We have already setup a comment-style, so use style b |
| 409 | comment)) | 304 | (progn |
| 410 | ) | 305 | (setq comstyle "b") |
| 411 | (generic-mode-set-comment-char comment))) | 306 | (setq comment-start-skip |
| 412 | (and (consp comment) | 307 | (concat comment-start-skip "\\|" (regexp-quote start) "+\\s-*"))) |
| 413 | (generic-mode-set-comment-pair comment))) | 308 | ;; First comment-style |
| 414 | 309 | (setq comment-start start) | |
| 415 | (defun generic-mode-set-comment-char (comment-char) | 310 | (setq comment-end (unless (string-equal end "\n") end)) |
| 416 | "Set COMMENT-CHAR as a comment character for generic mode." | 311 | (setq comment-start-skip (concat (regexp-quote start) "+\\s-*"))) |
| 417 | (if (not comment-char) | 312 | |
| 418 | nil | 313 | ;; Reuse comstyles if necessary |
| 419 | (setq | 314 | (setq comstyle |
| 420 | comment-end "" | 315 | (or (cdr (assoc start comstyles)) |
| 421 | comment-start (char-to-string comment-char) | 316 | (cdr (assoc end comstyles)) |
| 422 | comment-start-skip (concat comment-start "+ *") | 317 | comstyle)) |
| 423 | ) | 318 | (push (cons start comstyle) comstyles) |
| 424 | 319 | (push (cons end comstyle) comstyles) | |
| 425 | (modify-syntax-entry comment-char "<" | 320 | |
| 426 | generic-mode-syntax-table) | 321 | ;; Setup the syntax table |
| 427 | (modify-syntax-entry ?\n ">" | 322 | (if (= (length start) 1) |
| 428 | generic-mode-syntax-table))) | 323 | (modify-syntax-entry (string-to-char start) |
| 429 | 324 | (concat "< " comstyle) st) | |
| 430 | (defun generic-mode-set-comment-string (comment-string) | 325 | (let ((c0 (elt start 0)) (c1 (elt start 1))) |
| 431 | "Set COMMENT-STRING as a comment string for generic mode." | 326 | ;; Store the relevant info but don't update yet |
| 432 | (if (not comment-string) | 327 | (push (cons c0 (concat (cdr (assoc c0 chars)) "1")) chars) |
| 433 | nil | 328 | (push (cons c1 (concat (cdr (assoc c1 chars)) |
| 434 | (setq | 329 | (concat "2" comstyle))) chars))) |
| 435 | comment-end "" | 330 | (if (= (length end) 1) |
| 436 | comment-start comment-string | 331 | (modify-syntax-entry (string-to-char end) |
| 437 | comment-start-skip (concat comment-start " *") | 332 | (concat ">" comstyle) st) |
| 438 | ) | 333 | (let ((c0 (elt end 0)) (c1 (elt end 1))) |
| 439 | 334 | ;; Store the relevant info but don't update yet | |
| 440 | (let ((first (elt comment-string 0)) | 335 | (push (cons c0 (concat (cdr (assoc c0 chars)) |
| 441 | (second (elt comment-string 1))) | 336 | (concat "3" comstyle))) chars) |
| 442 | ;; C++ style comments | 337 | (push (cons c1 (concat (cdr (assoc c1 chars)) "4")) chars))))) |
| 443 | (if (char-equal first second) | 338 | |
| 444 | (progn | 339 | ;; Process the chars that were part of a 2-char comment marker |
| 445 | (modify-syntax-entry first "<12b" | 340 | (dolist (cs (nreverse chars)) |
| 446 | generic-mode-syntax-table) | 341 | (modify-syntax-entry (car cs) |
| 447 | (modify-syntax-entry ?\n ">b" | 342 | (concat (char-to-string (char-syntax (car cs))) |
| 448 | generic-mode-syntax-table))) | 343 | " " (cdr cs)) |
| 449 | ;; Some other two character string | 344 | st)) |
| 450 | (modify-syntax-entry first "<1" | 345 | (set-syntax-table st))) |
| 451 | generic-mode-syntax-table) | ||
| 452 | (modify-syntax-entry second "<2" | ||
| 453 | generic-mode-syntax-table) | ||
| 454 | (modify-syntax-entry ?\n ">" | ||
| 455 | generic-mode-syntax-table)))) | ||
| 456 | |||
| 457 | (defun generic-mode-set-comment-pair (comment-pair) | ||
| 458 | "Set COMMENT-PAIR as a comment start and end for generic mode." | ||
| 459 | (let ((generic-comment-start (car comment-pair)) | ||
| 460 | (generic-comment-end (cdr comment-pair)) | ||
| 461 | ) | ||
| 462 | (setq | ||
| 463 | comment-end generic-comment-end | ||
| 464 | comment-start generic-comment-start | ||
| 465 | comment-start-skip (concat generic-comment-start " *") | ||
| 466 | ) | ||
| 467 | |||
| 468 | ;; Sanity checks | ||
| 469 | (and (not (and (stringp generic-comment-start) | ||
| 470 | (stringp generic-comment-end))) | ||
| 471 | (error "Elements of cons pair must be strings")) | ||
| 472 | (and (not (and (equal (length generic-comment-start) 2) | ||
| 473 | (equal (length generic-comment-end) 2))) | ||
| 474 | (error "Start and end must be exactly two characters long")) | ||
| 475 | |||
| 476 | (let ((first (elt generic-comment-start 0)) | ||
| 477 | (second (elt generic-comment-start 1)) | ||
| 478 | (third (elt generic-comment-end 0)) | ||
| 479 | (fourth (elt generic-comment-end 1)) | ||
| 480 | ) | ||
| 481 | |||
| 482 | (modify-syntax-entry first ". 1" generic-mode-syntax-table) | ||
| 483 | (modify-syntax-entry second ". 2" generic-mode-syntax-table) | ||
| 484 | |||
| 485 | (modify-syntax-entry | ||
| 486 | third | ||
| 487 | (concat | ||
| 488 | "." | ||
| 489 | (cond | ||
| 490 | ((char-equal first third) " 13") | ||
| 491 | ((char-equal second third) " 23") | ||
| 492 | (t " 3")) | ||
| 493 | ) | ||
| 494 | generic-mode-syntax-table) | ||
| 495 | |||
| 496 | (modify-syntax-entry | ||
| 497 | fourth | ||
| 498 | (concat | ||
| 499 | "." | ||
| 500 | (cond | ||
| 501 | ((char-equal first fourth) " 14") | ||
| 502 | ((char-equal second fourth) " 24") | ||
| 503 | (t " 4")) | ||
| 504 | ) | ||
| 505 | generic-mode-syntax-table) | ||
| 506 | ))) | ||
| 507 | 346 | ||
| 508 | (defun generic-mode-set-font-lock (keywords font-lock-expressions) | 347 | (defun generic-mode-set-font-lock (keywords font-lock-expressions) |
| 509 | "Set up font-lock functionality for generic mode." | 348 | "Set up font-lock functionality for generic mode." |
| 510 | (let ((generic-font-lock-expressions)) | 349 | (setq generic-font-lock-defaults |
| 511 | ;; Keywords | 350 | (append |
| 512 | (and keywords | 351 | (when keywords |
| 513 | (setq | 352 | (list (generic-make-keywords-list keywords font-lock-keyword-face))) |
| 514 | generic-font-lock-expressions | 353 | font-lock-expressions))) |
| 515 | (append | ||
| 516 | (list (let ((regexp (regexp-opt keywords))) | ||
| 517 | (list (concat "\\<\\(" regexp "\\)\\>") | ||
| 518 | 1 | ||
| 519 | 'font-lock-keyword-face))) | ||
| 520 | generic-font-lock-expressions))) | ||
| 521 | ;; Other font-lock expressions | ||
| 522 | (and font-lock-expressions | ||
| 523 | (setq generic-font-lock-expressions | ||
| 524 | (append | ||
| 525 | font-lock-expressions | ||
| 526 | generic-font-lock-expressions))) | ||
| 527 | (and (or font-lock-expressions keywords) | ||
| 528 | (setq generic-font-lock-defaults generic-font-lock-expressions)) | ||
| 529 | )) | ||
| 530 | 354 | ||
| 531 | ;; Support for [KEYWORD] constructs found in INF, INI and Samba files | 355 | ;; Support for [KEYWORD] constructs found in INF, INI and Samba files |
| 532 | (defun generic-bracket-support () | 356 | (defun generic-bracket-support () |
| @@ -542,28 +366,20 @@ Some generic modes are defined in `generic-x.el'." | |||
| 542 | ;; generic-mode on the fly. I think this gives us most of what we | 366 | ;; generic-mode on the fly. I think this gives us most of what we |
| 543 | ;; want. | 367 | ;; want. |
| 544 | (defun generic-mode-find-file-hook () | 368 | (defun generic-mode-find-file-hook () |
| 545 | "Hook function to enter default-generic-mode automatically. | 369 | "Hook function to enter `default-generic-mode' automatically. |
| 546 | Done if the first few lines of a file in `fundamental-mode' start with | 370 | Done if the first few lines of a file in `fundamental-mode' start with |
| 547 | a hash comment character. This hook will be installed if the variable | 371 | a hash comment character. This hook will be installed if the variable |
| 548 | `generic-use-find-file-hook' is non-nil. The variable | 372 | `generic-use-find-file-hook' is non-nil. The variable |
| 549 | `generic-lines-to-scan' determines the number of lines to look at." | 373 | `generic-lines-to-scan' determines the number of lines to look at." |
| 550 | (if (not (eq major-mode 'fundamental-mode)) | 374 | (when (eq major-mode 'fundamental-mode) |
| 551 | nil | 375 | (save-excursion |
| 552 | (and (or (> 1 generic-lines-to-scan) | 376 | (goto-char (point-min)) |
| 553 | (< 50 generic-lines-to-scan)) | 377 | (when (re-search-forward generic-find-file-regexp |
| 554 | (error "Variable `generic-lines-to-scan' should be set to a small" | 378 | (save-excursion |
| 555 | " positive number")) | 379 | (forward-line generic-lines-to-scan) |
| 556 | (let ((comment-regexp "") | 380 | (point)) t) |
| 557 | (count 0) | ||
| 558 | ) | ||
| 559 | (while (< count generic-lines-to-scan) | ||
| 560 | (setq comment-regexp (concat comment-regexp | ||
| 561 | generic-find-file-regexp)) | ||
| 562 | (setq count (1+ count))) | ||
| 563 | (save-excursion | ||
| 564 | (goto-char (point-min)) | 381 | (goto-char (point-min)) |
| 565 | (and (looking-at comment-regexp) | 382 | (default-generic-mode))))) |
| 566 | (generic-mode-with-type 'default-generic-mode)))))) | ||
| 567 | 383 | ||
| 568 | (defun generic-mode-ini-file-find-file-hook () | 384 | (defun generic-mode-ini-file-find-file-hook () |
| 569 | "Hook function to enter default-generic-mode automatically for INI files. | 385 | "Hook function to enter default-generic-mode automatically for INI files. |
| @@ -573,7 +389,7 @@ INI file. This hook is NOT installed by default." | |||
| 573 | (save-excursion | 389 | (save-excursion |
| 574 | (goto-char (point-min)) | 390 | (goto-char (point-min)) |
| 575 | (and (looking-at "^\\s-*\\[.*\\]") | 391 | (and (looking-at "^\\s-*\\[.*\\]") |
| 576 | (generic-mode-with-type 'ini-generic-mode))))) | 392 | (ini-generic-mode))))) |
| 577 | 393 | ||
| 578 | (and generic-use-find-file-hook | 394 | (and generic-use-find-file-hook |
| 579 | (add-hook 'find-file-hooks 'generic-mode-find-file-hook)) | 395 | (add-hook 'find-file-hooks 'generic-mode-find-file-hook)) |
| @@ -581,14 +397,12 @@ INI file. This hook is NOT installed by default." | |||
| 581 | (defun generic-make-keywords-list (keywords-list face &optional prefix suffix) | 397 | (defun generic-make-keywords-list (keywords-list face &optional prefix suffix) |
| 582 | "Return a regular expression matching the specified KEYWORDS-LIST. | 398 | "Return a regular expression matching the specified KEYWORDS-LIST. |
| 583 | The regexp is highlighted with FACE." | 399 | The regexp is highlighted with FACE." |
| 584 | (and (not (listp keywords-list)) | 400 | (unless (listp keywords-list) |
| 585 | (error "Keywords argument must be a list of strings")) | 401 | (error "Keywords argument must be a list of strings")) |
| 586 | (list (concat (or prefix "") | 402 | (list (concat prefix "\\<" |
| 587 | "\\<\\(" | ||
| 588 | ;; Use an optimized regexp. | 403 | ;; Use an optimized regexp. |
| 589 | (regexp-opt keywords-list t) | 404 | (regexp-opt keywords-list t) |
| 590 | "\\)\\>" | 405 | "\\>" suffix) |
| 591 | (or suffix "")) | ||
| 592 | 1 | 406 | 1 |
| 593 | face)) | 407 | face)) |
| 594 | 408 | ||