emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: lisp/generic.el patch.


From: Lute Kamstra
Subject: Re: lisp/generic.el patch.
Date: Thu, 17 Mar 2005 17:34:04 +0100
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux)

Here is an updated patch that incorporates the feedback of Stefan and
Richard.

I also changed three other things:

  I removed the (eval-when-compile (require 'cl)) as that is not
  needed.

  I changed define-generic-mode so that the name of the mode command
  need not be quoted (while retaining backward compatibility).  This
  makes define-generic-mode more like other defining forms.  I updated
  the docstring of define-generic-mode to reflect this change.

  I changed the default docstring of a generic mode.

Ok to commit?

Lute.


2005-03-17  Lute Kamstra  <address@hidden>

        * generic.el: 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.

Index: lisp/generic.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/generic.el,v
retrieving revision 1.27
diff -c -r1.27 generic.el
*** lisp/generic.el     14 Mar 2005 11:06:20 -0000      1.27
--- lisp/generic.el     17 Mar 2005 16:29:31 -0000
***************
*** 34,60 ****
  
  ;; Generic-mode is a meta-mode which can be used to define small modes
  ;; which provide basic comment and font-lock support.  These modes are
! ;; intended for the many configuration files and such which are too small
! ;; for a "real" mode, but still have a regular syntax, comment characters
! ;; and the like.
  ;;
  ;; Each generic mode can define the following:
  ;;
  ;; * List of comment-characters.  The entries in this list should be
  ;;   either a character, a one or two character string or a cons pair.
! ;;   If the entry is a character or a one-character string
! ;;   LIMITATIONS:  Emacs does not support comment strings of more than
  ;;   two characters in length.
  ;;
  ;; * List of keywords to font-lock.  Each keyword should be a string.
! ;;   If you have additional keywords which should be highlighted in a face
! ;;   different from `font-lock-keyword-face', you can use the convenience
! ;;   function `generic-make-keywords-list' (which see), and add the
! ;;   result to the following list:
  ;;
  ;; * Additional expressions to font-lock.  This should be a list of
! ;;   expressions, each of which should be of the same form
! ;;   as those in `font-lock-keywords'.
  ;;
  ;; * List of regular expressions to be placed in auto-mode-alist.
  ;;
--- 34,64 ----
  
  ;; Generic-mode is a meta-mode which can be used to define small modes
  ;; which provide basic comment and font-lock support.  These modes are
! ;; intended for the many configuration files and such which are too
! ;; small for a "real" mode, but still have a regular syntax, comment
! ;; characters and the like.
  ;;
  ;; Each generic mode can define the following:
  ;;
  ;; * List of comment-characters.  The entries in this list should be
  ;;   either a character, a one or two character string or a cons pair.
! ;;   If the entry is a character or a string, it is added to the
! ;;   mode's syntax table with `comment-start' syntax.  If the entry is
! ;;   a cons pair, the elements of the pair are considered to be
! ;;   `comment-start' and `comment-end' respectively.  (The latter
! ;;   should be nil if you want comments to end at end of line.)
! ;;   LIMITATIONS: Emacs does not support comment strings of more than
  ;;   two characters in length.
  ;;
  ;; * List of keywords to font-lock.  Each keyword should be a string.
! ;;   If you have additional keywords which should be highlighted in a
! ;;   face different from `font-lock-keyword-face', you can use the
! ;;   convenience function `generic-make-keywords-list' (which see),
! ;;   and add the result to the following list:
  ;;
  ;; * Additional expressions to font-lock.  This should be a list of
! ;;   expressions, each of which should be of the same form as those in
! ;;   `font-lock-keywords'.
  ;;
  ;; * List of regular expressions to be placed in auto-mode-alist.
  ;;
***************
*** 79,113 ****
  ;; Use the `define-generic-mode' function to define new modes.
  ;; For example:
  ;;
- ;;   (require 'generic)
  ;;   (define-generic-mode 'foo-generic-mode
! ;;                        (list ?% )
! ;;                        (list "keyword")
! ;;                        nil
! ;;                      (list "\\.FOO\\'")
! ;;                      (list 'foo-setup-function))
  ;;
  ;; defines a new generic-mode `foo-generic-mode', which has '%' as a
! ;; comment character, and "keyword" as a keyword. When files which end in
! ;; '.FOO' are loaded, Emacs will go into foo-generic-mode and call
! ;; foo-setup-function.  You can also use the function `foo-generic-mode'
! ;; (which is interactive) to put a buffer into foo-generic-mode.
  ;;
  ;; AUTOMATICALLY ENTERING GENERIC MODE:
  ;;
! ;; Generic-mode provides a hook which automatically puts a
! ;; file into default-generic-mode if the first few lines of a file in
! ;; fundamental mode start with a hash comment character. To disable
  ;; this functionality, set the variable `generic-use-find-file-hook'
! ;; to nil BEFORE loading generic-mode. See the variables
! ;; `generic-lines-to-scan' and `generic-find-file-regexp' for customization
! ;; options.
  ;;
  ;; GOTCHAS:
  ;;
! ;; Be careful that your font-lock definitions are correct.  Getting them
! ;; wrong can cause emacs to continually attempt to fontify! This problem
! ;; is not specific to generic-mode.
  ;;
  
  ;; Credit for suggestions, brainstorming, help with debugging:
--- 83,117 ----
  ;; Use the `define-generic-mode' function to define new modes.
  ;; For example:
  ;;
  ;;   (define-generic-mode 'foo-generic-mode
! ;;     (list ?%)
! ;;     (list "keyword")
! ;;     nil
! ;;     (list "\\.FOO\\'")
! ;;     (list 'foo-setup-function))
  ;;
  ;; defines a new generic-mode `foo-generic-mode', which has '%' as a
! ;; comment character, and "keyword" as a keyword.  When files which
! ;; end in '.FOO' are loaded, Emacs will go into foo-generic-mode and
! ;; call foo-setup-function.  You can also use the function
! ;; `foo-generic-mode' (which is interactive) to put a buffer into
! ;; foo-generic-mode.
  ;;
  ;; AUTOMATICALLY ENTERING GENERIC MODE:
  ;;
! ;; Generic-mode provides a hook which automatically puts a file into
! ;; default-generic-mode if the first few lines of a file in
! ;; fundamental mode start with a hash comment character.  To disable
  ;; this functionality, set the variable `generic-use-find-file-hook'
! ;; to nil BEFORE loading generic-mode.  See the variables
! ;; `generic-lines-to-scan' and `generic-find-file-regexp' for
! ;; customization options.
  ;;
  ;; GOTCHAS:
  ;;
! ;; Be careful that your font-lock definitions are correct.  Getting
! ;; them wrong can cause Emacs to continually attempt to fontify! This
! ;; problem is not specific to generic-mode.
  ;;
  
  ;; Credit for suggestions, brainstorming, help with debugging:
***************
*** 117,125 ****
  ;;
  ;;; Code:
  
- (eval-when-compile
-   (require 'cl))
- 
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;; Internal Variables
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
--- 121,126 ----
***************
*** 128,133 ****
--- 129,135 ----
    "Global defaults for font-lock in a generic mode.")
  (make-variable-buffer-local 'generic-font-lock-defaults)
  
+ ;;;###autoload
  (defvar generic-mode-list nil
    "A list of mode names for `generic-mode'.
  Do not add entries to this list directly; use `define-generic-mode'
***************
*** 143,281 ****
    :group 'extensions)
  
  (defcustom generic-use-find-file-hook t
!   "*If non-nil, add a hook to enter default-generic-mode automatically.
! This is done if the first few lines of a file in fundamental mode start
! with a hash comment character."
    :group 'generic
!   :type  'boolean
!   )
  
  (defcustom generic-lines-to-scan 3
    "*Number of lines that `generic-mode-find-file-hook' looks at.
! Relevant when deciding whether to enter `generic-mode' automatically.
  This variable should be set to a small positive number."
    :group 'generic
!   :type  'integer
!   )
  
  (defcustom generic-find-file-regexp "^#"
    "*Regular expression used by `generic-mode-find-file-hook'.
! Files in fundamental mode whose first few lines contain a match for
! this regexp, should be put into `default-generic-mode' instead.
! The number of lines tested for the matches is specified by the value
! of the variable `generic-lines-to-scan', which see."
    :group 'generic
!   :type  'regexp
!   )
  
  (defcustom generic-ignore-files-regexp "[Tt][Aa][Gg][Ss]\\'"
    "*Regular expression used by `generic-mode-find-file-hook'.
  Files whose names match this regular expression should not be put
! into `default-generic-mode', even if they have lines which match the
! regexp in `generic-find-file-regexp'.  If the value is nil,
  `generic-mode-find-file-hook' does not check the file names."
    :group 'generic
!   :type  '(choice (const :tag "Don't check file names" nil) regexp)
!   )
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;; Functions
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
  ;;;###autoload
! (defun define-generic-mode (name comment-list    keyword-list   font-lock-list
!                                auto-mode-list  function-list
!                                &optional description)
!   "Create a new generic mode with NAME.
! 
! NAME should be a symbol; its string representation is used as the function
! name. If DESCRIPTION is provided, it is used as the docstring for the new
! function.
! 
! COMMENT-LIST is a list, whose entries are either a single character,
! a one or two character string or a cons pair. If the entry is a character
! or a one-character string, it is added to the mode's syntax table with
! `comment-start' syntax.  If the entry is a cons pair, the elements of the
! pair are considered to be `comment-start' and `comment-end' respectively.
! \(The latter should be nil if you want comments to end at end of line.)
! Note that Emacs has limitations regarding comment characters.
! 
! KEYWORD-LIST is a list of keywords to highlight with `font-lock-keyword-face'.
! Each keyword should be a string.
! 
! FONT-LOCK-LIST is a list of additional expressions to highlight. Each entry
! in the list should have the same form as an entry in `font-lock-keywords'.
! 
! AUTO-MODE-LIST is a list of regular expressions to add to `auto-mode-alist'.
! These regexps are added to `auto-mode-alist' as soon as `define-generic-mode'
! is called; any old regexps with the same name are removed.
  
! FUNCTION-LIST is a list of functions to call to do some additional setup.
  
  See the file generic-x.el for some examples of `define-generic-mode'."
  
!   ;; Add a new entry
!   (add-to-list 'generic-mode-list (symbol-name name))
! 
!   ;; Add it to auto-mode-alist
!   (dolist (re auto-mode-list)
!     (add-to-list 'auto-mode-alist (cons re name)))
! 
!   ;; Define a function for it using `defalias' (not `fset') to make
!   ;; the mode appear on load-history.
!   (defalias name
!     `(lambda nil
!        ,(or description (concat "Generic mode for type " (symbol-name name)))
!        (interactive)
!        (generic-mode-internal ',name ',comment-list ',keyword-list
!                             ',font-lock-list ',function-list)))
!   )
! 
  (defun generic-mode-internal (mode comments keywords font-lock-list funs)
!   "Go into the generic-mode MODE."
!   (let* ((generic-mode-hooks (intern (concat (symbol-name mode) "-hook")))
!        (modename (symbol-name mode))
!        (name (if (string-match "-mode\\'" modename)
!                  (substring modename 0 (match-beginning 0))
!                modename))
!        )
  
-     ;; Put this after the point where we read generic-mode-name!
      (kill-all-local-variables)
  
!     (setq
!      major-mode                          mode
!      mode-name                           (capitalize name)
!      )
  
!     (generic-mode-set-comments     comments)
  
      ;; Font-lock functionality
      ;; Font-lock-defaults are always set even if there are no keywords
      ;; or font-lock expressions, so comments can be highlighted.
      (setq generic-font-lock-defaults nil)
!     (generic-mode-set-font-lock      keywords font-lock-list)
!     (make-local-variable          'font-lock-defaults)
      (setq font-lock-defaults (list 'generic-font-lock-defaults nil))
  
      ;; Call a list of functions
      (mapcar 'funcall funs)
  
!     (run-hooks generic-mode-hooks)
!     )
!   )
  
  ;;;###autoload
! (defun generic-mode (type)
!   "Basic comment and font-lock functionality for `generic' files.
! \(Files which are too small to warrant their own mode, but have
! comment characters, keywords, and the like.)
  
  To define a generic-mode, use the function `define-generic-mode'.
  Some generic modes are defined in `generic-x.el'."
    (interactive
!    (list (completing-read "Generic Type: " generic-mode-list nil t)))
!   (funcall (intern type)))
  
  ;;; Comment Functionality
  (defun generic-mode-set-comments (comment-list)
--- 145,284 ----
    :group 'extensions)
  
  (defcustom generic-use-find-file-hook t
!   "*If non-nil, add a hook to enter Default-Generic mode automatically.
! This is done if the first few lines of a file in fundamental mode
! start with a hash comment character."
    :group 'generic
!   :type  'boolean)
  
  (defcustom generic-lines-to-scan 3
    "*Number of lines that `generic-mode-find-file-hook' looks at.
! Relevant when deciding whether to enter Default-Generic mode automatically.
  This variable should be set to a small positive number."
    :group 'generic
!   :type  'integer)
  
  (defcustom generic-find-file-regexp "^#"
    "*Regular expression used by `generic-mode-find-file-hook'.
! Files in fundamental mode whose first few lines contain a match
! for this regexp, should be put into Default-Generic mode instead.
! The number of lines tested for the matches is specified by the
! value of the variable `generic-lines-to-scan', which see."
    :group 'generic
!   :type  'regexp)
  
  (defcustom generic-ignore-files-regexp "[Tt][Aa][Gg][Ss]\\'"
    "*Regular expression used by `generic-mode-find-file-hook'.
  Files whose names match this regular expression should not be put
! into Default-Generic mode, even if they have lines which match
! the regexp in `generic-find-file-regexp'.  If the value is nil,
  `generic-mode-find-file-hook' does not check the file names."
    :group 'generic
!   :type  '(choice (const :tag "Don't check file names" nil) regexp))
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;; Functions
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  
  ;;;###autoload
! (defmacro define-generic-mode (mode comment-list keyword-list
!                                   font-lock-list auto-mode-list
!                                   function-list &optional docstring)
!   "Create a new generic mode MODE.
! 
! MODE is the name of the command for the generic mode; it need not
! be quoted.  The optional DOCSTRING is the documentation for the
! mode command.  If you do not supply it, a default documentation
! string will be used instead.
! 
! COMMENT-LIST is a list, whose entries are either a single
! character, a one or two character string or a cons pair.  If the
! entry is a character or a string, it is added to the mode's
! syntax table with `comment-start' syntax.  If the entry is a cons
! pair, the elements of the pair are considered to be
! `comment-start' and `comment-end' respectively.  (The latter
! should be nil if you want comments to end at end of line.)  Note
! that Emacs has limitations regarding comment characters.
! 
! KEYWORD-LIST is a list of keywords to highlight with
! `font-lock-keyword-face'.  Each keyword should be a string.
! 
! FONT-LOCK-LIST is a list of additional expressions to highlight.
! Each entry in the list should have the same form as an entry in
! `font-lock-keywords'.
! 
! AUTO-MODE-LIST is a list of regular expressions to add to
! `auto-mode-alist'.  These regexps are added to `auto-mode-alist'
! as soon as `define-generic-mode' is called.
  
! FUNCTION-LIST is a list of functions to call to do some
! additional setup.
  
  See the file generic-x.el for some examples of `define-generic-mode'."
+   (let* ((name-unquoted (if (eq (car-safe mode) 'quote) ; Backward 
compatibility.
+                           (eval mode)
+                         mode))
+        (name-string (symbol-name name-unquoted))
+        (pretty-name (capitalize (replace-regexp-in-string
+                                  "-mode\\'" "" name-string))))
+ 
+     `(progn
+        ;; Add a new entry.
+        (add-to-list 'generic-mode-list ,name-string)
+ 
+        ;; Add it to auto-mode-alist
+        (dolist (re ,auto-mode-list)
+        (add-to-list 'auto-mode-alist (cons re ',name-unquoted)))
+ 
+        (defun ,name-unquoted ()
+        ,(or docstring
+             (concat pretty-name " mode.\n"
+                     "This a generic mode defined with 
`define-generic-mode'."))
+        (interactive)
+        (generic-mode-internal ',name-unquoted ,comment-list ,keyword-list
+                               ,font-lock-list ,function-list)))))
  
! ;;;###autoload
  (defun generic-mode-internal (mode comments keywords font-lock-list funs)
!   "Go into the generic mode MODE."
!   (let* ((modename (symbol-name mode))
!        (generic-mode-hooks (intern (concat modename "-hook")))
!        (pretty-name (capitalize (replace-regexp-in-string
!                                  "-mode\\'" "" modename))))
  
      (kill-all-local-variables)
  
!     (setq major-mode mode
!         mode-name pretty-name)
  
!     (generic-mode-set-comments comments)
  
      ;; Font-lock functionality
      ;; Font-lock-defaults are always set even if there are no keywords
      ;; or font-lock expressions, so comments can be highlighted.
      (setq generic-font-lock-defaults nil)
!     (generic-mode-set-font-lock  keywords font-lock-list)
!     (make-local-variable 'font-lock-defaults)
      (setq font-lock-defaults (list 'generic-font-lock-defaults nil))
  
      ;; Call a list of functions
      (mapcar 'funcall funs)
  
!     (run-hooks generic-mode-hooks)))
  
  ;;;###autoload
! (defun generic-mode (mode)
!   "Enter generic mode MODE.
! 
! Generic modes provide basic comment and font-lock functionality
! for \"generic\" files.  (Files which are too small to warrant their
! own mode, but have comment characters, keywords, and the like.)
  
  To define a generic-mode, use the function `define-generic-mode'.
  Some generic modes are defined in `generic-x.el'."
    (interactive
!    (list (completing-read "Generic mode: " generic-mode-list nil t)))
!   (funcall (intern mode)))
  
  ;;; Comment Functionality
  (defun generic-mode-set-comments (comment-list)
***************
*** 283,298 ****
    (let ((st (make-syntax-table))
        (chars nil)
        (comstyles))
!     (make-local-variable           'comment-start)
!     (make-local-variable           'comment-start-skip)
!     (make-local-variable           'comment-end)
  
      ;; Go through all the comments
      (dolist (start comment-list)
!       (let ((end nil) (comstyle ""))
        ;; Normalize
        (when (consp start)
!         (setq end (or (cdr start) end))
          (setq start (car start)))
        (when (char-valid-p start) (setq start (char-to-string start)))
        (cond
--- 286,301 ----
    (let ((st (make-syntax-table))
        (chars nil)
        (comstyles))
!     (make-local-variable 'comment-start)
!     (make-local-variable 'comment-start-skip)
!     (make-local-variable 'comment-end)
  
      ;; Go through all the comments
      (dolist (start comment-list)
!       (let (end (comstyle ""))
        ;; Normalize
        (when (consp start)
!         (setq end (cdr start))
          (setq start (car start)))
        (when (char-valid-p start) (setq start (char-to-string start)))
        (cond
***************
*** 360,377 ****
          imenu-case-fold-search t))
  
  ;; This generic mode is always defined
! (define-generic-mode 'default-generic-mode (list ?#)  nil nil nil nil)
  
  ;; A more general solution would allow us to enter generic-mode for
  ;; *any* comment character, but would require us to synthesize a new
  ;; generic-mode on the fly. I think this gives us most of what we
  ;; want.
  (defun generic-mode-find-file-hook ()
!   "Hook function to enter `default-generic-mode' automatically.
! Done if the first few lines of a file in `fundamental-mode' start with
! a match for the regexp in `generic-find-file-regexp', unless the
! file's name matches the regexp which is the value of the variable
! `generic-ignore-files-regexp'.
  This hook will be installed if the variable
  `generic-use-find-file-hook' is non-nil.  The variable
  `generic-lines-to-scan' determines the number of lines to look at."
--- 363,382 ----
          imenu-case-fold-search t))
  
  ;; This generic mode is always defined
! (define-generic-mode default-generic-mode (list ?#) nil nil nil nil)
  
  ;; A more general solution would allow us to enter generic-mode for
  ;; *any* comment character, but would require us to synthesize a new
  ;; generic-mode on the fly. I think this gives us most of what we
  ;; want.
  (defun generic-mode-find-file-hook ()
!   "Hook function to enter Default-Generic mode automatically.
! 
! Done if the first few lines of a file in Fundamental mode start
! with a match for the regexp in `generic-find-file-regexp', unless
! the file's name matches the regexp which is the value of the
! variable `generic-ignore-files-regexp'.
! 
  This hook will be installed if the variable
  `generic-use-find-file-hook' is non-nil.  The variable
  `generic-lines-to-scan' determines the number of lines to look at."
***************
*** 390,397 ****
        (default-generic-mode)))))
  
  (defun generic-mode-ini-file-find-file-hook ()
!   "Hook function to enter default-generic-mode automatically for INI files.
! Done if the first few lines of a file in `fundamental-mode' look like an
  INI file.  This hook is NOT installed by default."
    (and (eq major-mode 'fundamental-mode)
         (save-excursion
--- 395,402 ----
        (default-generic-mode)))))
  
  (defun generic-mode-ini-file-find-file-hook ()
!   "Hook function to enter Default-Generic mode automatically for INI files.
! Done if the first few lines of a file in Fundamental mode look like an 
  INI file.  This hook is NOT installed by default."
    (and (eq major-mode 'fundamental-mode)
         (save-excursion




reply via email to

[Prev in Thread] Current Thread [Next in Thread]