This doesn’t appear to work with XEmacs 21.1. Does anyone know how to do this with XEmacs?
The following in your ~/.emacs adds very basic syntax highlighting for all sorts of files:
(require 'generic-x)
It will add syntax highlighting for batch files, ini files, command files, registry files, apache files, samba files, resource files, fvwm files, etc. For a complete list, see below.
When editing the init files of obscure programs, I often add the following to the first line of the file:
# -*- mode: default-generic -*-
Suppose we have a little language called foo; a typical foo-file might look something like:
!! this is a comment
account=foo; !! another comment
user=jimmy;
password=$3cre7;Using define-generic-mode, we can easily define a mode for this:
(require 'generic-x) ;; we need this
(define-generic-mode
'foo-mode ;; name of the mode to create
'("!!") ;; comments start with '!!'
'("account" "user"
"password") ;; some keywords
'(("=" . 'font-lock-operator) ;; '=' is an operator
(";" . 'font-lock-builtin)) ;; ';' is a built-in
'("\\.foo$") ;; files for which to activate this mode
nil ;; other functions to call
"A mode for foo files" ;; doc string for this mode
)(example taken from http://emacs-fu.blogspot.com/2010/04/creating-custom-modes-easy-way-with.html)
For very simple languages, you can use generic mode to “generate” a new MajorMode for you. The following example is for keymap files as used by the loadkeys(1) program.
First, an example of the language:
# this only works for console!
# allow control tab
control keycode 15 = Macro
# shift capslock is compose key
shift keycode 58 = Compose
# cedilla on 4
altgr keycode 5 = ccedilla
shift altgr keycode 5 = Ccedilla
# control up down left right home end
control keycode 103 = Meta_p
control keycode 108 = Meta_n
control keycode 105 = Meta_Control_b
control keycode 106 = Meta_Control_f
control keycode 102 = Meta_less
control keycode 107 = Meta_greaterAnd now for the major mode.
Here’s our first try. It has the following features:
"#".".map" and ".keymap". (define-generic-mode 'keymap-mode
'("#")
'("control" "meta" "shift" "alt" "altgr" "compose" "keycode")
nil
'(".keymap\\'" ".map\\'")
nil)Here’s the second try. Additional features:
(define-generic-mode 'keymap-mode
'("#")
'("control" "meta" "shift" "alt" "altgr" "compose" "keycode")
'(("[0-9]+" . 'font-lock-variable-name-face))
'(".keymap\\'" ".map\\'")
nil
"Major mode for editing keymap files as used by loadkeys(1).")The use of the FONT-LOCK-LIST parameter is very powerful. It allows you to highlight any RegularExpression using any Face.
Here’s how to define a very simple PL/SQL mode. Naturally you’d be better off customizing SqlMode, but this example is just here to illustrate how to make "--" a comment starter. In order to highlight the stuff correctly, we use a font-lock expression. In order to set ‘comment-start’, we use an anonymous function (a lambda expression, which needs no quoting).
(define-generic-mode 'poor-man-plsql-mode
()
'("if" "end" "else" "begin" "declare" "function" "procedure")
'(("\\(--.*\\)" 1 'font-lock-comment-face))
'("\\.pls\\'")
(list (lambda () (setq comment-start "--")))
"Major mode for very simple PL/SQL highlighting.")For more info on the font locking, see FontLockKeywords.
Here’s an even longer example:
(define-generic-mode 'htaccess-mode
'(?#)
'(;; core
"AcceptPathInfo" "AccessFileName" "AddDefaultCharset" "AddOutputFilterByType"
"AllowEncodedSlashes" "AllowOverride" "AuthName" "AuthType"
"CGIMapExtension" "ContentDigest" "DefaultType" "DocumentRoot"
"EnableMMAP" "EnableSendfile" "ErrorDocument" "ErrorLog"
"FileETag" "ForceType" "HostnameLookups" "IdentityCheck"
"Include" "KeepAlive" "KeepAliveTimeout" "LimitInternalRecursion"
"LimitRequestBody" "LimitRequestFields" "LimitRequestFieldSize" "LimitRequestLine"
"LimitXMLRequestBody" "LogLevel" "MaxKeepAliveRequests" "NameVirtualHost"
"Options" "Require" "RLimitCPU" "RLimitMEM"
"RLimitNPROC" "Satisfy" "ScriptInterpreterSource" "ServerAdmin"
"ServerAlias" "ServerName" "ServerPath" "ServerRoot"
"ServerSignature" "ServerTokens" "SetHandler" "SetInputFilter"
"SetOutputFilter" "TimeOut" "UseCanonicalName"
;; .htaccess tutorial
"AddHandler" "AuthUserFile" "AuthGroupFile"
;; mod_rewrite
"RewriteBase" "RewriteCond" "RewriteEngine" "RewriteLock" "RewriteLog"
"RewriteLogLevel" "RewriteMap" "RewriteOptions" "RewriteRule"
;; mod_alias
"Alias" "AliasMatch" "Redirect" "RedirectMatch" "RedirectPermanent"
"RedirectTemp" "ScriptAlias" "ScriptAliasMatch")
'(("%{\\([A-Z_]+\\)}" 1 font-lock-variable-name-face)
("\\b[0-9][0-9][0-9]\\b" . font-lock-constant-face)
("\\[.*\\]" . font-lock-type-face))
'(".htaccess\\'")
nil
"Generic mode for Apache .htaccess files.")First, test whether it works by calling M-x foo-mode if you defined a new generic mode called foo-mode. If that works, you might want to enable foo-mode for all files whose names match a certain pattern (regexp).
Traditionally, you would add an entry to ‘auto-mode-alist’ to do that. Here is an example which enables a fictive scala-mode for all files whose names end in ".scala":
(add-to-list 'auto-mode-alist '(""\\.scala\\'" . scala-mode))Using ‘define-generic-mode’ takes care of that for you, however. Note how the fourth argument, AUTO-MODE-LIST, allows you to specify the patterns filenames should match. There is no need for adding patterns to ‘auto-mode-alist’ as shown above, if you define new modes using ‘define-generic-mode’.
Put this in your ~/.emacs file:
(require 'generic-x)
Now you should have a lot more modes to choose from.
Note that the list depends on the operating system used. You can set the variables ‘generic-define-mswindows-modes’ and ‘generic-define-unix-modes’ before loading generic-x. That will make sure you get the respective defaults. Here’s a list so that a search of the wiki will find this page:
== How does it work to use a face other than any of the font-lock-xxx faces? This does not work:
(define-generic-mode 'test-mode
(list "# ") ;; orange comment-list
(list "test1") ;; blue keyword-list
(list (list "\\(HIGHLIGHT-THIS\\)" '(1 'info-menu-star))) ;; font-lock-list
() ;; auto-mode-list
() ;; function-list
"test-mode")Yes it does. Generic mode is just like any other major mode. Simpler perhaps, but it certainly prevents any font-lock stuff by other (major) modes.
The next step of complexity is DerivedMode.