; $Id: filters.rc,v 1.174 2003/07/27 15:35:18 tom Exp $
; majormodes in this file are ordered alphabetically for convenience - the
; precedence used by vile is strictly alphabetic, counting case.

define-mode ada
~with define-submode ada
	suf '\.\(\<ada\>\|\<ads\>\|\<adb\>\)$'
	comment-prefix	'^\s*--'
	comments	'^\s*--\s*$'
	fence-if   '^\s*\<if\>'
	fence-elif '^\s*\<elsif\>'
	fence-else '^\s*\<else\>'
	fence-fi   '^\s*\<end\>'
	ignorecase
~elsewith define-submode ada group 'begin'
	fence-if   '^\s*\<begin\>'
	fence-else '^\s*\<exception\>'
	fence-fi   '^\s*\<end\>'
~endwith

; GNU assembler (a Byzantine elaboration of AT&T)
define-mode as
~with define-submode as
	suf '\.[sS]$'
~endwith

; M$ assembler (a Byzantine elaboration of Intel)
define-mode asm
~with define-submode asm
	suf '\.asm$'
	fence-if   '^\s*\<\(if\|ifdef\|ifndef\)\>'
	fence-elif '^\s*\<elseif\>'
	fence-else '^\s*\<else\>'
	fence-fi   '^\s*\<endif\>'
~endwith

define-mode awk
~with define-submode awk
	suf '\.awk$'
	pre '^#!\s*\/.*awk\>\(\s*-[a-z]\+\)*\s*$'
	cindent
	cindent-chars $fences
	comment-prefix '^\s*#'
	comments   '^\s*#\s\+\s*$'
~endwith

define-mode basic
~with define-submode basic
	suf '\.bas$'
	comment-prefix '^\s*\''
	comments   '^\s*\'\s\+\s*$'
	ignorecase
	notabinsert
~endwith

define-mode bat
~with define-submode bat
	suf '\.\(bat\|cmd\)$'
	pre '\s*\(@\)\?echo\s*\(on\|off\)\?$'
	dos
	ignorecase
	comment-prefix '^\s*rem\>'
	comments   '^\s*rem\>\s\+\s*$'
~endwith

define-mode cfg
~with define-submode cfg
	suf '\.cfg$'
	comment-prefix	'^\s*#'
	comments	'^\s*#\s*$'
~endwith

define-mode cpp
~with define-submode cpp
	before "c"
	suf '\(\.\(C\|CC\|cc\|cpp\|cxx\|hxx\|hh\)$\)'
	cindent
	cindent-chars   &cat ':#' $fences
	filtername	'vile-c-filt -k cpp'
~endwith

define-mode csh
~with define-submode csh
	suf '\.\(csh[^/]*\|login\|logout\)$'
	pre '^#!\s*\/.*csh\>\(\s*-[a-z]\+\)*\s*$'
	filtername	'vile-sh-filt -k csh'
	comment-prefix	'^\s*#'
	comments	'^\s*#\s*$'
	fence-if	'^\s*\<if\>.*\<then\>'
	fence-elif	'^\s*\<else\s*if\>'
	fence-else	'^\s*\<else\>'
	fence-fi	'^\s*\<endif\>'
~elsewith define-submode csh group 'case'
	fence-if	'^\s*\<switch\>\s*(.*)'
	fence-elif	'^\s*\<case\>.*:'
	fence-else	'^\s*\<default\>\s*:'
	fence-fi	'^\s*\<endsw\>'
~elsewith define-submode csh group 'loop'
	fence-if	'^\s*\<foreach\s\+.*\|while\>\s*(.*)'
	fence-fi	'^\s*\<end\>'
~endwith

define-mode cweb
~with define-submode cweb
	suf '\(\.w\|\.web\)$'
~endwith

; Fences in DCL do not work well because we really want a fence-if which
; looks for an 'if' on a line where there is no 'then'.  But here is a set of
; expressions that work by relying on matching the if-once first, so it
; excludes the if-block.
define-mode dcl
~with define-submode dcl
	suf '\.\(com\|tpu\)$'
	comment-prefix	'^\s*\$!'
	comments	'^\s*\$!\s*$'
	ignorecase
~elsewith define-submode dcl group 'if-once'
	fence-if	'^\s*\(\$\s*\)\?\<if\>.*\<then\>'
~elsewith define-submode dcl group 'if-block'
	fence-if	'^\s*\(\$\s*\)\?\<if\>'
	fence-else	'^\s*\(\$\s*\)\?\<else\>'
	fence-fi	'^\s*\(\$\s*\)\?\<endif\>'
~endwith

define-mode def
~with define-submode def
	suf '\.\(def\)$'
	ignorecase
	dos
~endwith

define-mode diff
~with define-submode diff
	suf '\.\(patch\|dif\|diff\|diffs\|rej\)$'
	pre '^\<diff\>'
~endwith

; ECLiPSe (a dialect of Prolog)
define-mode ecl
~with define-submode ecl
	suf '\.\(ecl\|pro\)$'
~endwith

; Syntax descriptions for enscript
; NOTE: Smalltalk files also may have ".st" suffix.
define-mode est
~with define-submode est
	suf '\.st$'
	cindent
~endwith

; Embedded SQL in C/C++
define-mode esql
~with define-submode esql
	suf '\.\(ec\|pc\|ppc\)$'
	cindent
	cindent-chars &cat ':#' $fences
~endwith

; forms definition.
; FIXME: The groups should not nest (extend the syntax)
define-mode fdl
~with define-submode fdl
	suf '\.\<fdl\>$'
	comment-prefix '^\s*$rem\>'
	comments   '^\(\|$rem\)$'
	fence-if   '^\$\s*if\>'
	fence-elif '^\$\s*elseif\>'
	fence-else '^\$\s*else\>\s*$'
	fence-fi   '^\$\s*endif\s*$'
~elsewith define-submode fdl group 'form'
	fence-if   '^\$form\>'
	fence-fi   '^\$endform\s*$'
~elsewith define-submode fdl group 'field'
	fence-if   '^\$field\>$'
	fence-fi   '^\$endfield\s*$'
~elsewith define-submode fdl group 'group'
	fence-if   '^\$group\>'
	fence-fi   '^\$endgroup\s*$'
~elsewith define-submode fdl group 'array'
	fence-if   '^\$array\>'
	fence-fi   '^\$endarray\s*$'
~elsewith define-submode fdl group 'page'
	fence-if   '^\$page\>'
	fence-fi   '^\$endpage\s*$'
~elsewith define-submode fdl group 'scroll'
	fence-if   '^\$scroll\>'
	fence-fi   '^\$endscroll\s*$'
~elsewith define-submode fdl group 'state'
	fence-if   '^\$state\>'
	fence-fi   '^\$endstate\s*$'
~elsewith define-submode fdl group 'text'
	fence-if   '^\$text\>'
	fence-fi   '^\$endtext\s*$'
~endwith

; Inherit the C-style fences for JavaScript, but add new ones for HTML
define-mode html
~with define-submode html
	suf '\.\(html\|htm\)$'
	pre '\(<html>\|<script>\|<!doctype\|<!--\)'
	fence-pairs	'<>()[]{}'
	ignorecase
	comment-prefix	'^\s*--'
	comments	'^\s*$'
~elsewith define-submode html group 'script'
	fence-if	'^\s*<script>$'
	fence-fi	'^\s*</script>$'
~elsewith define-submode html group 'server'
	fence-if	'^\s*<server>$'
	fence-fi	'^\s*</server>$'
~elsewith define-submode html group 'html'
	fence-begin	'<--'
	fence-end	'-->'
~endwith

define-mode info
~with define-submode info
	after ti
	suf '\(\.\|\([a-z]*\)\)\(info\(-\d\+\)\?\)$'
~endwith

define-mode imake
~with define-submode imake
	before "def"
	suf 'I[Mm]akefile[^/]*$'
	pre '^\s*\(XCOMM\>\|\/\*\*\/#\)'
~endwith

define-mode java
~with define-submode java
	suf '\.java$'
	filtername 'vile-c-filt -j -p -k java'
	cindent
	cindent-chars &cat ':' $fences
~endwith

define-mode js
~with define-submode js
	suf '\.js$'
	filtername 'vile-c-filt -p -k js'
	cindent
	cindent-chars &cat ':' $fences
~endwith

define-mode key
~with define-submode key
	suf '\.\(key\|keywords\)$'
	comment-prefix	'^\s*:'
	comments	'^\s*:\s+*$'
~endwith

define-mode latex
~with define-submode latex
	filtername 'vile-latex-filt -a'
	suf '\.\(latex\|ltex\|ltx\|sty\|tex\)$'
	fence-pairs='<>{}()[]'
	comment-prefix	'^\s*%'
	comments	'^\s*%.*$'
~endwith

define-mode lex
~with define-submode lex
	suf '\.\(l\|lex\|flex\|flx\)$'
	cindent
	cindent-chars &cat ':#' $fences
~endwith

define-mode log
~with define-submode log
	suf '\(\(run\|make\)\.out\|\.log[^/]*\)$'
	before make
~endwith

; actually, m4 used for autoconf scripts, which is Bourne-shell
define-mode m4
~with define-submode m4
	pre '^\s*dnl\>'
	suf '\.\(ac\|m4\)$'
	comment-prefix '^\s*\(dnl\|#\)'
	comments   '^\s*\(dnl\>\|#\)\s*$'
	fence-if   '^\s*\<if\>'
	fence-elif '^\s*\<elif\>'
	fence-else '^\s*\<else\>'
	fence-fi   '^\s*\<fi\>'
~elsewith define-submode m4 group 'case'
	fence-if   '^\s*\<case\>.*\<in\>'
	fence-fi   '^\s*\<esac\>'
~elsewith define-submode m4 group 'do'
	fence-if   '\(^\s*\<do\>\|;\s*\<do\>\)\s*$'
	fence-fi   '^\s*\<done\>'
~endwith

define-mode mail
~with define-submode mail
	suf '\([Mm]ail\>[^/]*\|\<mbox\|mutt-[^/]*\)$'
	pre '^\(From \|To: \)'
~endwith

define-mode make
~with define-submode make
	suf '\([Mm]akefile[^/]*\|make\..*\|\.mak\|\.mk\)$'
	comment-prefix	'^\s*[!#]'
	comments	'^\s*[!#]\s*$'
~elsewith define-submode make group 'gnumake'
	fence-if   '^[ ]*if'
	fence-else '^[ ]*else\>'
	fence-fi   '^[ ]*endif\>'
~elsewith define-submode make group 'nmake'
	fence-if   '^\s*!if'
	fence-elif '^\s*!else\s*if'
	fence-else '^\s*!else\>'
	fence-fi   '^\s*!endif\>'
~if &sin $os 'win32'
	ignorecase
~endif
~endwith

define-mode mms
~with define-submode mms
	suf '\.mms$'
	comment-prefix	'^\s*[!#]'
	comments	'^\s*[!#]\s*$'
	ignorecase
	fence-if   '^\s*\.\<ifdef\>'
	fence-elif '^\s*\.\<elif\>'
	fence-else '^\s*\.\<else\>'
	fence-fi   '^\s*\.\<endif\>'
~endwith

; prevent .newsrc from being recognized as a mode that requires syntax
; highlighting, since it may contain very long lines.
define-mode newsrc
~with define-submode newsrc
	suf '\.\([^/]*newsrc[^/]*\)$'
	before "sh"
~endwith

define-mode nr
~with define-submode nr
	after "sh"
	suf '\.\(\([1-9ln][a-z]\?\)\|me\|ms\|man\)$'
	pre '^\.\\"'
	comment-prefix	'^\.\\"'
	comments	'^\.\\"\s*$'
~endwith

define-mode pas
~with define-submode pas
	suf '\.\(p\|pas\)$'
~endwith

define-mode pc
~with define-submode pc
	suf '\(\<printcap[^/]*\)$'
	filtername	'vile-tc-filt -k pc'
	comment-prefix	'^\s*[:#]'
	comments	'^\s*[:#]\s*$'
~endwith

; 'do' should really be a separate group, but since ambiguous fence-fi is
; very expensive to resolve, we combine it with the similar 'while' group.
define-mode perl
~with define-submode perl
	pre '^#\s*!\s*\.*\/.*perl[0-9]*\>'
	suf '\.\(pl\|pm\|PL\)$'
	before "mail"
	cindent
	cindent-chars  &cat ':' $fences
	comment-prefix '^\s*#'
	comments       '^\s*#\s*$'
	fence-pairs    '{}()[]<>'
	fence-if       '^\s*if\>.*{'
	fence-elif     '^\s*}\s*elsif\s*(.*{'
	fence-else     '^\s*}\s*else\s*{'
	fence-fi       '^\s*}\s*$'
;- The trailing "}" in the different perl groups makes it ambiguous and not
;- easy to use (so they're commented out).  Note that the default (if) group
;- still relies on having the "}" on the same lines as the elsif and else
;- keywords.
;~elsewith define-submode perl group 'while'
;	fence-if       '^\s*\(sub\|foreach\|while\|unless\|do\)\>.*{'
;	fence-fi       '^\s*}'
~endwith

; gettext message files
define-mode pot
~with define-submode pot
	suf '\.\(pot\|po\)$'
	comment-prefix '^#'
	comments       '^#\s*$'
~endwith

; PostScript
define-mode ps
~with define-submode ps
	suf '\.ps$'
~endwith

; Python
define-mode py
~with define-submode py
	pre '^#\s*!\s*\.*\/.*python\>'
	suf '\.py$'
	comment-prefix '^\s*#'
	comments   '^\s*#\s\+\s*$'
~endwith

; Ruby
define-mode rb
~with define-submode rb
	filtername 'vile-ruby-filt -k rb'
	pre '^#\s*!\s*\.*\/.*ruby*\>'
	suf '\.rb$'
~endwith

define-mode rc
~with define-submode rc
	after "vile"
	suf '\.rc\d*$'
	preamble '^\s*[^;"]'
	qualifiers=all
	comment-prefix	'^\s*//'
	comments	'^\s*//\s*$'
~endwith

define-mode rexx
~with define-submode rexx
	pre '^#\s*!\s*\.*\/.*\(rexx\|regina\|rxcurses\)\>'
	suf '\.\(cmd\|rexx\)$'
	~if &not &seq $os "win32"
		before "bat"
	~endif
	comment-prefix '^\s*#'
	comments   '^\s*#\s\+\s*$'
~endwith

; I capitalized the majormode RCS/SCCS names because matches are made in
; alphabetic order (usually not a problem, but conflicting with other modes,
; such as 'makemode').
define-mode RCS
~with define-submode RCS
	suf ',v$'
	filtername 'vile-rcs-filt'
~endwith

define-mode rpm
~with define-submode rpm
	suf '.spec$'
~endwith

; (see RCS)
define-mode SCCS
~with define-submode SCCS
	suf '\<s\.'
	pre '^\h'
	filtername 'vile-sccs-filt'
~elsewith define-submode SCCS group 'delete'
	fence-if       '^\D\s\+\(\d\+\)$'
	fence-fi       '^\E\s\+\(\d\+\)$'
~elsewith define-submode SCCS group 'insert'
	fence-if       '^\I\s\+\(\d\+\)$'
	fence-fi       '^\E\s\+\(\d\+\)$'
~endwith

define-mode sed
~with define-submode sed
	suf '\(sed\)$'
	pre '^#!\s*\/sed\>\(\s*-[a-z]*\s*\)\*\s*$'
	comment-prefix	'^\s*#'
	comments	'^\s*#\s*$'
~endwith

; This is matched after 'csh', and will pick up /bin/sh, /bin/bash, /bin/ksh
define-mode sh
~with define-submode sh
	suf '\(\.\(sh\|ksh\|[^/]*rc\)$\|profile$\|\.bash_[a-z]\+$\)'
	pre '^\(\(#!\s*\/.*sh\>\(\s*[-]\+[a-z]*\s*\)\?\)\|:\)\s*$'
	comment-prefix	'^\s*[:#]'
	comments	'^\s*[:#]\s*$'
	fence-if   '^\s*\<if\>'
	fence-elif '^\s*\<elif\>'
	fence-else '^\s*\<else\>'
	fence-fi   '^\s*\<fi\>'
~elsewith define-submode sh group 'case'
	fence-if   '^\s*\<case\>.*\<in\>'
	fence-elif '^\s*[^ 	)]\+)'
	fence-else '^\s*\*)'
	fence-fi   '^\s*\<esac\>'
~elsewith define-submode sh group 'do'
	fence-if   '\(^\s*\<do\>\|;\s*\<do\>\)\s*$'
	fence-fi   '^\s*\<done\>'
~endwith

define-mode sml
~with define-submode sml
	suf '\.sml$'
	comment-prefix	'^\s*[*]'
	fence-begin="(\\*"
	fence-end="\\*)"
~endwith

define-mode sql
~with define-submode sql
	before "bat"
	suf '\.sql$'
	pre '^\s*\(rem\>.*$\|remark\>.*$\|set\s\+echo\s\+\(on\|off\)\?$\)'
	comment-prefix	'^\s*rem\(ark\)\?'
	comments	'^\s*rem\(ark\)\?\s*$'
	ignorecase
	; PL/SQL
	fence-if   '^\s*if\>'
	fence-elif '^\s*elseif\>'
	fence-else '^\s*else\>\s*$'
	fence-fi   '^\s*end\s\+if\s*;'
~elsewith define-submode sql group 'loop'
	fence-if   '^\s*while\>.*\<loop\>'
	fence-fi   '^\s*end\s\+loop\s*;'
~elsewith define-submode sql group 'block'
	fence-if   '^\s*begin\>'
	fence-else '^\s*exception\>'
	fence-fi   '^\s*end\s*;'
~endwith

define-mode tags
~with define-submode tags
	suf '\<tags$'
	comment-prefix	'^!_'
	comments	'^!_$'
~endwith

; VILE's mktbls
define-mode tbl
~with define-submode tbl
	suf '\(modetbl\|cmdtbl\)$'
	comment-prefix	'^\s*#'
	comments	'^\s*#\s*$'
~endwith

define-mode tc
~with define-submode tc
	suf '\(\.tc\|\.tcap\|\<termcap[^/]*\)$'
	comment-prefix	'^\s*[:#]'
	comments	'^\s*[:#]\s*$'
~endwith

define-mode tcl
~with define-submode tcl
	before "sh"
	suf '\.\(tcl\|exp\)$'
	pre '^#!\s*\/.*\(wish\|wishx\|tclsh\|tcl\|expectk\)[0-9.]*\>\(\s*-[a-z]\+\)*\s*$'
	comment-prefix	'^\s*[:#]'
	comments	'^\s*[:#]\s*$'
~endwith

define-mode tex
~with define-submode tex
	suf '\.\(tex\)$'
	filtername 'vile-latex-filt -k tex'
	fence-pairs='<>{}()[]'
	comment-prefix	'^\s*%'
	comments	'^\s*%.*$'
~endwith

define-mode texi
~with define-submode texi
	suf '\.\(texi\|txi\|texinfo\)$'
~endwith

define-mode ti
~with define-submode ti
	before "sh"
	suf '\(\.ti\|\.tinfo\|\<terminfo\(\.src\)\?\)$'
	comment-prefix	'^\s*[:#]'
	comments	'^\s*[:#]\s*$'
~endwith

define-mode txt
~with define-submode txt
	suf '\(\(README\|CHANGES\|Change[Ll]og\|COPYING\)[^/]*\|\.\(txt\|doc\|hlp\)\)$'
	comment-prefix	'^\s*--'
	comments	'^\s*--\s*$'
~endwith

define-mode vb
~with define-submode vb
	before "basic"
	suf '\.\(bas\|frm\)$'
	pre '\(^VERSION\|VB_Name\)'
	qualifiers=all
	comment-prefix	'^\s*\''
	comments	'^\s*\'\s\+\s*$'
	dos
	ignorecase
	notabinsert
	filtername	'vile-basic-filt -k vb'
~endwith

define-mode vlog
~with define-submode vlog
	suf '\.v$'
	cindent
	cindent-chars $fences
~endwith

; "define-mode vile" is builtin
~with define-submode vile
	before "sh"
	suf '\(vile[^/]*rc\|vile.*/[^/]*rc\|\.exrc\|\.vile\)$'
	comment-prefix	'^\s*;'
	comments	'^\s*;\s*$'
	fence-if	'^\s*~if\>'
	fence-elif	'^\s*~elseif\>'
	fence-else	'^\s*~else\>'
	fence-fi	'^\s*~endif\>'
~elsewith define-submode vile group 'while'
	fence-if	'^\s*~while\>'
	fence-fi	'^\s*~endwhile\>'
~elsewith define-submode vile group 'with'
	fence-if	'^\s*~with\>'
	fence-elif	'^\s*~elsewith\>'
	fence-fi	'^\s*~endwith\>'
~elsewith define-submode vile group 'macro'
	fence-if	'^\s*\(\d\+\s*\)\?store-\(macro\|procedure\)'
	fence-fi	'^\s*~endm\>'
~endwith

define-mode vim
~with define-submode vim
	suf '\(\.vim\)$'
	comment-prefix	'^\s*"'
	before "make"
	filtername	'vile-vile-filt -k vim'
	comments	'^\s*"\s*$'
	fence-if	'^\s*if\>'
	fence-elif	'^\s*elseif\>'
	fence-else	'^\s*else\>'
	fence-fi	'^\s*endif\>'
~elsewith define-submode vim group 'while'
	fence-if	'^\s*while\>'
	fence-fi	'^\s*endwhile\>'
~endwith

define-mode xml
~with define-submode xml
	suf '\.xml$'
	pre '^\s*<?xml\s'
	fence-pairs	'<>()[]{}'
	comment-prefix	'^\s*--'
	comments	'^\s*$'
~endwith

define-mode xres
~with define-submode xres
	~if $filename-ic
		suf '\(\.Xdefaults\|\.ad\)$'
	~else
		suf '\(app-defaults/[A-Z]\?[A-Z][a-z0-9-]\+\|\.Xdefaults\(-[^/]\+$\)\|\.ad\)$'
	~endif
	comment-prefix	'^\s*!'
	comments	'^\s*!\s*$'
~endwith

define-mode xs
~with define-submode xs
	suf '\.xs$'
	cindent
	cindent-chars &cat ':' $fences
~endwith

define-mode yacc
~with define-submode yacc
	suf '\.\(y\|yacc\)$'
	cindent
	cindent-chars &cat ':#' $fences
~endwith

store-procedure HighlightFilter 'Invoke syntax-highlighting filter on the current buffer'
    ~if &not $highlight
	~return
    ~elseif &seq $majormode ''
	~return
    ~elseif &filter $majormode
	~local $curcol $curline
	~hidden goto-beginning-of-file
	~hidden attribute-directly end-of-file $majormode
	~return
    ~else
	~local $curcol $curline
	~local %filtername %filterpath %filteropts
	~hidden goto-beginning-of-file
	~if &seq $filtername ''
		set-variable %filtername &cat &cat 'vile-' $majormode '-filt'
	~else
		set-variable %filtername $filtername
	~endif
	set-variable %filterpath &word 0 %filtername
	set-variable %filteropts &right %filtername &add 1 &len %filterpath
	~if &seq '' &lookup e+p &cat %filterpath $exec-suffix
		set-variable %filterpath &lookup e+l &cat %filterpath $exec-suffix
	~endif
	~if &not &seq %filterpath ''
		~hidden attribute-from-filter end-of-file &cat &pquote %filterpath &cat %filteropts &cat ' -t' $tabstop
	~endif
    ~endif
~endm
store-procedure HighlightFilterMsg 'Attach highlighting to the current buffer'
	HighlightFilter
	write-message '[Attaching attributes...]'
~endm
bind-key HighlightFilterMsg ^X-q

store-procedure HighlightClear 'Clear all highlighting from the current buffer'
	~local $curcol $curline
	~hidden goto-beginning-of-file
	~hidden clear-attributes-til goto-char
~endm
bind-key HighlightClear ^X-Q

store-procedure set-highlighting ma 'Set a majormode and invoke highlighting'
	; show-variables
	write-message &cat $1 mode
	~force setl &cat $1 mode
	HighlightFilter
~endm
