There is a free, but not open source, 3d modelling package called Anim8or at http://www.anim8or.com/ which, in the new beta release has a scripting language. Anim8or also has modelling files, so there are really two different syntaxes associated with this. The modelling files are something I have not tried to make Vim support, so in the attached patch I have named the file a8s.vim rather than anim8or.vim.
The patch is a clumsy hack (with a blunt instrument, so to speak) at the C syntax file, to get it to support the a8s syntax. It is definitely buggy: #parameters("this", "that", "the other) fails with a syntax error on the last bracket and the colouring for it doesn't work as I'd expect from hacking the #define directive in C. That may not even be the right approach, given the semantics. I tried to provide support the highlighting $variables, but couldn't understand how this was done in perl.vim or sh.vim to get it right, so I've left that for now. Anyway, I'm putting this forward in the hope that someone more fluent in vim scripting, syntax, etc can [help me?] make something presentable out of it, and the hope that others find it of some use. I've created a small web page about this at http://www.eng.cse.dmu.ac.uk/~hgs/anim8or/ from which you can get the attached patch and the syntax file itself. Thank you, Hugh
--- vim70/filetype.vim.orig 2006-05-07 15:13:38.000000000 +0100 +++ vim70/filetype.vim 2006-09-12 10:38:16.345750000 +0100 @@ -95,6 +95,9 @@ " AMPL au BufNewFile,BufRead *.run setf ampl +" Anim8or Script +au BufNewFile,BufRead *.a8s setf a8s + " Ant au BufNewFile,BufRead build.xml setf ant --- vim70/syntax/a8s.vim.orig 1970-01-01 00:01:00.000000000 +0000 +++ vim70/syntax/a8s.vim 2006-09-12 11:33:58.627000000 +0100 @@ -0,0 +1,268 @@ +" Vim syntax file +" Language: Anim8or Script +" Maintainer: Hugh Sasse <[EMAIL PROTECTED]> +" Last Change: 2006 Sep 11 + +" Quit when a (custom) syntax file was already loaded +if exists("b:current_syntax") + finish +endif + +" A bunch of useful C keywords +syn keyword a8sStatement break return continue +syn keyword a8sLabel case default +syn keyword a8sConditional if else switch +syn keyword a8sRepeat while for to do + +syn keyword a8sTodo contained TODO FIXME XXX + +" a8sCommentGroup allows adding matches for special things in comments +syn cluster a8sCommentGroup contains=a8sTodo + +" String and Character constants +" Highlight special characters (those which have a backslash) differently +syn match a8sSpecial display contained "\\\(x\x\+\|\o\{1,3}\|.\|$\)" +if !exists("a8s_no_utf") + syn match a8sSpecial display contained "\\\(u\x\{4}\|U\x\{8}\)" +endif +if exists("a8s_no_cformat") + syn region a8sString start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=a8sSpecial,@Spell + " a8sCppString: same as a8sString, but ends at end of line + syn region a8sCppString start=+L\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=a8sSpecial,@Spell +else + if !exists("a8s_no_c99") " ISO C99 + syn match a8sFormat display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlLjzt]\|ll\|hh\)\=\([aAbdiuoxXDOUfFeEgGcCsSpn]\|\[\^\=.[^]]*\]\)" contained + else + syn match a8sFormat display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlL]\|ll\)\=\([bdiuoxXDOUfeEgGcCsSpn]\|\[\^\=.[^]]*\]\)" contained + endif + syn match a8sFormat display "%%" contained + syn region a8sString start=+L\="+ skip=+\\\\\|\\"+ end=+"+ contains=a8sSpecial,a8sFormat,@Spell + " a8sCppString: same as a8sString, but ends at end of line + syn region a8sCppString start=+L\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=a8sSpecial,a8sFormat,@Spell +endif + +syn match a8sCharacter "L\='[^\\]'" +syn match a8sCharacter "L'[^']*'" contains=a8sSpecial +if exists("a8s_gnu") + syn match a8sSpecialError "L\='\\[^'\"?\\abefnrtv]'" + syn match a8sSpecialCharacter "L\='\\['\"?\\abefnrtv]'" +else + syn match a8sSpecialError "L\='\\[^'\"?\\abfnrtv]'" + syn match a8sSpecialCharacter "L\='\\['\"?\\abfnrtv]'" +endif +syn match a8sSpecialCharacter display "L\='\\\o\{1,3}'" +syn match a8sSpecialCharacter display "'\\x\x\{1,2}'" +syn match a8sSpecialCharacter display "L'\\x\x\+'" + +"when wanted, highlight trailing white space +if exists("a8s_space_errors") + if !exists("a8s_no_trail_space_error") + syn match a8sSpaceError display excludenl "\s\+$" + endif + if !exists("a8s_no_tab_space_error") + syn match a8sSpaceError display " \+\t"me=e-1 + endif +endif + +"catch errors caused by wrong parenthesis and brackets +" also accept <% for {, %> for }, <: for [ and :> for ] (C99) +" But avoid matching <::. +syn cluster a8sParenGroup contains=a8sParenError,a8sIncluded,a8sSpecial,a8sCommentSkip,a8sCommentString,a8sComment2String,@a8sCommentGroup,a8sCommentStartError,a8sUserCont,a8sUserLabel,a8sBitField,a8sCommentSkip,a8sOctalZero,a8sCppOut,a8sCppOut2,a8sCppSkip,a8sFormat,a8sNumber,a8sFloat,a8sOctal,a8sOctalError,a8sNumbersCom +if exists("a8s_no_curly_error") + syn region a8sParen transparent start='(' end=')' contains=ALLBUT,@a8sParenGroup,a8sCppParen,a8sCppString,@Spell + " a8sCppParen: same as a8sParen but ends at end-of-line; used in a8sDefine + syn region a8sCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@a8sParenGroup,a8sParen,a8sString,@Spell + syn match a8sParenError display ")" + syn match a8sErrInParen display contained "^[{}]\|^<%\|^%>" +elseif exists("a8s_no_bracket_error") + syn region a8sParen transparent start='(' end=')' contains=ALLBUT,@a8sParenGroup,a8sCppParen,a8sCppString,@Spell + " a8sCppParen: same as a8sParen but ends at end-of-line; used in a8sDefine + syn region a8sCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@a8sParenGroup,a8sParen,a8sString,@Spell + syn match a8sParenError display ")" + syn match a8sErrInParen display contained "[{}]\|<%\|%>" +else + syn region a8sParen transparent start='(' end=')' contains=ALLBUT,@a8sParenGroup,a8sCppParen,a8sErrInBracket,a8sCppBracket,a8sCppString,@Spell + " a8sCppParen: same as a8sParen but ends at end-of-line; used in a8sDefine + syn region a8sCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@a8sParenGroup,a8sErrInBracket,a8sParen,a8sBracket,a8sString,@Spell + syn match a8sParenError display "[\])]" + syn match a8sErrInParen display contained "[\]{}]\|<%\|%>" + syn region a8sBracket transparent start='\[\|<::[EMAIL PROTECTED]' end=']\|:>' contains=ALLBUT,@a8sParenGroup,a8sErrInParen,a8sCppParen,a8sCppBracket,a8sCppString,@Spell + " a8sCppBracket: same as a8sParen but ends at end-of-line; used in a8sDefine + syn region a8sCppBracket transparent start='\[\|<::[EMAIL PROTECTED]' skip='\\$' excludenl end=']\|:>' end='$' contained contains=ALLBUT,@a8sParenGroup,a8sErrInParen,a8sParen,a8sBracket,a8sString,@Spell + syn match a8sErrInBracket display contained "[);{}]\|<%\|%>" +endif + +"integer number, or floating point number without a dot and with "f". +syn case ignore +syn match a8sNumbers display transparent "\<\d\|\.\d" contains=a8sNumber,a8sFloat,a8sOctalError,a8sOctal +" Same, but without octal error (for comments) +syn match a8sNumbersCom display contained transparent "\<\d\|\.\d" contains=a8sNumber,a8sFloat,a8sOctal +syn match a8sNumber display contained "\d\+\(u\=l\{0,2}\|ll\=u\)\>" +"hex number +syn match a8sNumber display contained "0x\x\+\(u\=l\{0,2}\|ll\=u\)\>" +" Flag the first zero of an octal number as something special +syn match a8sOctal display contained "0\o\+\(u\=l\{0,2}\|ll\=u\)\>" contains=a8sOctalZero +syn match a8sOctalZero display contained "\<0" +syn match a8sFloat display contained "\d\+f" +"floating point number, with dot, optional exponent +syn match a8sFloat display contained "\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\=" +"floating point number, starting with a dot, optional exponent +syn match a8sFloat display contained "\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>" +"floating point number, without dot, with exponent +syn match a8sFloat display contained "\d\+e[-+]\=\d\+[fl]\=\>" +if !exists("a8s_no_c99") + "hexadecimal floating point number, optional leading digits, with dot, with exponent + syn match a8sFloat display contained "0x\x*\.\x\+p[-+]\=\d\+[fl]\=\>" + "hexadecimal floating point number, with leading digits, optional dot, with exponent + syn match a8sFloat display contained "0x\x\+\.\=p[-+]\=\d\+[fl]\=\>" +endif + +" flag an octal number with wrong digits +syn match a8sOctalError display contained "0\o*[89]\d*" +syn case match + +if exists("a8s_comment_strings") + " A comment can contain a8sString, a8sCharacter and a8sNumber. + " But a "*/" inside a a8sString in a a8sComment DOES end the comment! So we + " need to use a special type of a8sString: a8sCommentString, which also ends on + " "*/", and sees a "*" at the start of the line as comment again. + " Unfortunately this doesn't very well work for // type of comments :-( + syntax match a8sCommentSkip contained "^\s*\*\($\|\s\+\)" + syntax region a8sCommentString contained start=+L\=\\\@<!"+ skip=+\\\\\|\\"+ end=+"+ end=+\*/+me=s-1 contains=a8sSpecial,a8sCommentSkip + syntax region a8sComment2String contained start=+L\=\\\@<!"+ skip=+\\\\\|\\"+ end=+"+ end="$" contains=a8sSpecial + syntax region a8sCommentL start="//" skip="\\$" end="$" keepend [EMAIL PROTECTED],a8sComment2String,a8sCharacter,a8sNumbersCom,a8sSpaceError,@Spell + if exists("a8s_no_comment_fold") + " ####### + syntax region a8sComment matchgroup=a8sCommentStart start="/\*" end="\*/" [EMAIL PROTECTED],a8sCommentStartError,a8sCommentString,a8sCharacter,a8sNumbersCom,a8sSpaceError,@Spell + else + syntax region a8sComment matchgroup=a8sCommentStart start="/\*" end="\*/" [EMAIL PROTECTED],a8sCommentStartError,a8sCommentString,a8sCharacter,a8sNumbersCom,a8sSpaceError,@Spell fold + endif +else + syn region a8sCommentL start="//" skip="\\$" end="$" keepend [EMAIL PROTECTED],a8sSpaceError,@Spell + if exists("a8s_no_comment_fold") + syn region a8sComment matchgroup=a8sCommentStart start="/\*" end="\*/" [EMAIL PROTECTED],a8sCommentStartError,a8sSpaceError,@Spell + else + syn region a8sComment matchgroup=a8sCommentStart start="/\*" end="\*/" [EMAIL PROTECTED],a8sCommentStartError,a8sSpaceError,@Spell fold + endif +endif +" keep a // comment separately, it terminates a preproc. conditional +syntax match a8sCommentError display "\*/" +syntax match a8sCommentStartError display "/\*"me=e-1 contained + +syntax region a8sBlock start="{" end="}" transparent fold + +syn keyword a8sOperator sizeof +if exists("a8s_gnu") + syn keyword a8sStatement __asm__ + syn keyword a8sOperator typeof __real__ __imag__ +endif +syn keyword a8sType int float double +syn keyword a8sType shape material point2 point3 +syn keyword a8sType float4x4 file string quaternion +syn keyword a8sType project object figure sequence +syn keyword a8sType scene meshdata tridata + +syn keyword a8sStructure struct union enum typedef +syn keyword a8sStorageClass static register auto volatile extern const + + +syn region a8sPreCondit start="^\s*\(#\)\s*\(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" end="//"me=s-1 contains=a8sComment,a8sCppString,a8sCharacter,a8sCppParen,a8sParenError,a8sNumbers,a8sCommentError,a8sSpaceError +syn match a8sPreCondit display "^\s*\(#\)\s*\(else\|endif\)\>" +if !exists("a8s_no_if0") + if !exists("a8s_no_if0_fold") + syn region a8sCppOut start="^\s*\(#\)\s*if\s\+0\+\>" end="[EMAIL PROTECTED]|$" contains=a8sCppOut2 fold + else + syn region a8sCppOut start="^\s*\(#\)\s*if\s\+0\+\>" end="[EMAIL PROTECTED]|$" contains=a8sCppOut2 + endif + syn region a8sCppOut2 contained start="0" end="^\s*\(#\)\s*\(endif\>\|else\>\|elif\>\)" contains=a8sSpaceError,a8sCppSkip + syn region a8sCppSkip contained start="^\s*\(#\)\s*\(if\>\|ifdef\>\|ifndef\>\)" skip="\\$" end="^\s*\(#\)\s*endif\>" contains=a8sSpaceError,a8sCppSkip +endif +syn region a8sIncluded display contained start=+"+ skip=+\\\\\|\\"+ end=+"+ +syn match a8sIncluded display contained "<[^>]*>" +syn match a8sInclude display "^\s*\(#\)\s*include\>\s*["<]" contains=a8sIncluded +"syn match a8sLineSkip "\\$" +syn cluster a8sPreProcGroup contains=a8sPreCondit,a8sIncluded,a8sInclude,a8sDefine,a8sErrInParen,a8sErrInBracket,a8sUserLabel,a8sSpecial,a8sOctalZero,a8sCppOut,a8sCppOut2,a8sCppSkip,a8sFormat,a8sNumber,a8sFloat,a8sOctal,a8sOctalError,a8sNumbersCom,a8sString,a8sCommentSkip,a8sCommentString,a8sComment2String,@a8sCommentGroup,a8sCommentStartError,a8sParen,a8sBracket,a8sMulti +syn region a8sDefine start="^\s*\(%:\|#\)\s*\(define\|undef\)\>" skip="\\$" end="$" end="//"me=s-1 contains=ALLBUT,@a8sPreProcGroup,@Spell +" for parameter directive +syn region a8sParameter start="^\s*\(%:\|#\)\s*\(parameter\)\>" skip="\\$" end="$" end="//"me=s-1 contains=ALLBUT,@a8sPreProcGroup,@Spell +" for button directive +syn region a8sButton start="^\s*\(%:\|#\)\s*\(button\)\>" skip="\\$" end="$" end="//"me=s-1 contains=ALLBUT,@a8sPreProcGroup,@Spell +syn region a8sPreProc start="^\s*\(%:\|#\)\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@a8sPreProcGroup,@Spell + +" Highlight User Labels +syn cluster a8sMultiGroup contains=a8sIncluded,a8sSpecial,a8sCommentSkip,a8sCommentString,a8sComment2String,@a8sCommentGroup,a8sCommentStartError,a8sUserCont,a8sUserLabel,a8sBitField,a8sOctalZero,a8sCppOut,a8sCppOut2,a8sCppSkip,a8sFormat,a8sNumber,a8sFloat,a8sOctal,a8sOctalError,a8sNumbersCom,a8sCppParen,a8sCppBracket,a8sCppString +syn region a8sMulti transparent start='?' skip='::' end=':' contains=ALLBUT,@a8sMultiGroup,@Spell +" Avoid matching foo::bar() in C++ by requiring that the next char is not ':' +syn cluster a8sLabelGroup contains=a8sUserLabel +syn match a8sUserCont display "^\s*\I\i*\s*:$" [EMAIL PROTECTED] +syn match a8sUserCont display ";\s*\I\i*\s*:$" [EMAIL PROTECTED] +syn match a8sUserCont display "^\s*\I\i*\s*:[^:]"me=e-1 [EMAIL PROTECTED] +syn match a8sUserCont display ";\s*\I\i*\s*:[^:]"me=e-1 [EMAIL PROTECTED] + +syn match a8sUserLabel display "\I\i*" contained + +" Avoid recognizing most bitfields as labels +syn match a8sBitField display "^\s*\I\i*\s*:\s*[1-9]"me=e-1 contains=a8sType +syn match a8sBitField display ";\s*\I\i*\s*:\s*[1-9]"me=e-1 contains=a8sType + +if exists("a8s_minlines") + let b:a8s_minlines = a8s_minlines +else + if !exists("a8s_no_if0") + let b:a8s_minlines = 50 " #if 0 constructs can be long + else + let b:a8s_minlines = 15 " mostly for () constructs + endif +endif +exec "syn sync ccomment a8sComment minlines=" . b:a8s_minlines + +" Define the default highlighting. +" Only used when an item doesn't have highlighting yet +hi def link a8sFormat a8sSpecial +hi def link a8sCppString a8sString +hi def link a8sCommentL a8sComment +hi def link a8sCommentStart a8sComment +hi def link a8sLabel Label +hi def link a8sUserLabel Label +hi def link a8sConditional Conditional +hi def link a8sRepeat Repeat +hi def link a8sCharacter Character +hi def link a8sSpecialCharacter a8sSpecial +hi def link a8sNumber Number +hi def link a8sOctal Number +hi def link a8sOctalZero PreProc " link this to Error if you want +hi def link a8sFloat Float +hi def link a8sOctalError a8sError +hi def link a8sParenError a8sError +hi def link a8sErrInParen a8sError +hi def link a8sErrInBracket a8sError +hi def link a8sCommentError a8sError +hi def link a8sCommentStartError a8sError +hi def link a8sSpaceError a8sError +hi def link a8sSpecialError a8sError +hi def link a8sOperator Operator +hi def link a8sStructure Structure +hi def link a8sStorageClass StorageClass +hi def link a8sInclude Include +hi def link a8sPreProc PreProc +hi def link a8sDefine Macro +hi def link a8sIncluded a8sString +hi def link a8sError Error +hi def link a8sStatement Statement +hi def link a8sPreCondit PreCondit +hi def link a8sType Type +hi def link a8sConstant Constant +hi def link a8sCommentString a8sString +hi def link a8sComment2String a8sString +hi def link a8sCommentSkip a8sComment +hi def link a8sString String +hi def link a8sComment Comment +hi def link a8sSpecial SpecialChar +hi def link a8sTodo Todo +hi def link a8sCppSkip a8sCppOut +hi def link a8sCppOut2 a8sCppOut +hi def link a8sCppOut Comment + +let b:current_syntax = "a8s" + +" vim: ts=8