Re: [xwt-users] vim syntax file

Rod Martin <[email protected]> Mon, 24 Nov 2003 16:55:21 -0500
Newsgroups gmane.comp.java.xwt.users
Organization Benshaw
Message-ID <[email protected]>
A syntax file with some small fixes.  Comments are getting highlighted better 
now.

Also, I got a request for an indenter file.  A little tweaking of the html 
indenter works pretty slick I think.  It will need to be renamed to xwt.vim 
once it's in the proper directory.

(Known) problems still standing:

- Large files sometimes not highlighted correctly
- I'm still not sure whether the 'constructor', 'prototype', 'toSource', 
'toString', 'valueOf' keywords or math constants (xwt.math.PI|E|etc) should 
be getting highlighted
- indenting acts weird on the second line here:
    if() {
    } else {
    }
    - when you type the second '{', the line gets indented, but it shouldn't

Have fun

Rod

_______________________________________________
users mailing list
[email protected]
http://lists.xwt.org/listinfo/users
xwt.vim (text/plain, 20.2 KB)
" Vim syntax file
" Language:	XWT
" Maintainer:	Rod Martin <[email protected]>
" Last Change:	Tue Nov 11 16:05:50 EST 2003
" Filenames:	*.xwt

" CREDITS:
"   Adapted from xml.vim by Paul Siegmann and javascript.vim by Claudio Fleiner
"
" REFERENCES:
"   [1] http://www.xwt.org/reference.html
"
" NOTE:
"   1) empty tag delimiters "/>" inside attribute values (strings)
"      confuse syntax highlighting.
"   2) for large files, folding can be pretty slow, especially when
"      loading a file the first time and viewoptions contains 'folds'
"      so that folds of previous sessions are applied.
"      Don't use 'foldmethod=syntax' in this case.
"   3) I left the CDATA and DTD stuff from xml.vim in but commented just in case...

if !exists("main_syntax")
    if version < 600
        syntax clear
    elseif exists("b:current_syntax")
        finish
    endif
    let main_syntax = 'xwt'
endif

let s:xwt_cpo_save = &cpo
set cpo&vim


syn case match

" mark illegal characters
syn match   xwtError "[{}<&]\|-->\|\*/"

syn keyword xwtTodo         contained TODO FIXME XXX


""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Highlight common structures in XWT and provide a cluster for these structures

syn cluster xwtPrimitive        contains=xwtStringD,xwtStringS,xwtSpecial,xwtSpecialCharacter,xwtNumber,xwtHexColor,xwtNull

syn region  xwtStringD          start=+"+  skip=+\\\\\|\\"+  end=+"+  contains=xwtSpecial,@htmlPreproc
syn region  xwtStringS          start=+'+  skip=+\\\\\|\\'+  end=+'+  contains=xwtSpecial,@htmlPreproc
syn match   xwtSpecial          "\\\d\d\d\|\\."
syn match   xwtSpecialCharacter "'\\.'"
syn match   xwtNumber           "-\=\<\d\+L\=\>\|0[xX][0-9a-fA-F]\+\>"
syn match   xwtHexColor         +"#[0-9A-Fa-f]\{3,8}"+ 
syn keyword xwtNull             null NULL Null


"""""""""""""""""""""""""
" Highlight XWT comments

syn cluster xwtComments contains=xwtLineComment,xwtComment,xwtComment2,xwtHeaderComments

" //
syn match   xwtLineComment      "\/\/.*$" contains=xwtTodo

" /* ... */
syn region  xwtComment          start="/\*"  end="\*/" contains=xwtCommentString,xwtCharacter,xwtNumber,xwtTodo extend

" <!-- ... -->
syn region  xwtComment2         start=+<!--+ end=+-->+ contains=xwtTodo extend

" The comments between the <xwt> tag and the next tag in an XWT document
" FIXME: The start= regex isn't very efficient, but I couldn't get anything else to work
syn region  xwtHeaderComments
    \ start=+\(<xwt>\_.\)\@<=\_.+     
    \ end=+\(<static\|<template\|<import\|<preapply\|<redirect\|<postapply\)\@=+
    \ contains=xwtTodo
    \ extend

syn match   xwtCommentSkip      "^[ \t]*\*\($\|[ \t]\+\)"
syn region  xwtCommentString    start=+"+  skip=+\\\\\|\\"+  end=+"+ end=+\*/+me=s-1,he=s-1 contains=xwtSpecial,xwtCommentSkip,@htmlPreproc
syn region  xwtComment2String   start=+"+  skip=+\\\\\|\\"+  end=+$\|"+  contains=xwtSpecial,@htmlPreproc





" =====  ECMAScript Stuff ===================================================================================


" group all javaScript highlighting features into a cluster
syn cluster javaScript contains=javaScriptConditional,javaScriptRepeat,javaScriptBranch,javaScriptOperator,javaScriptType,
    \ javaScriptStatement,javaScriptFunction,javaScriptBoolean,javaScriptBraces,
    \ javaScriptParen


""""""""""""""""""""""""""""""""
" Highlight javaScript keywords

syn keyword javaScriptConditional      if else
syn keyword javaScriptRepeat           while for
syn keyword javaScriptBranch           break continue switch case default
syn keyword javaScriptOperator         new in
syn keyword javaScriptType             this var
syn keyword javaScriptStatement        return with
syn keyword javaScriptFunction         function
syn keyword javaScriptBoolean          true false
syn match   javaScriptBraces           "[{}]"

" catch errors caused by wrong parenthesis
syn match   javaScriptInParen     contained "[{}]"
syn region  javaScriptParen       transparent start="(" end=")" contains=javaScriptParen,javaScript.*,
    \ xwtError,jSArrayFunction,jSArrayKeyword,@xwtPrimitive,@xwt
syn match   javaScriptParenError  ")"


""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Highlight functions/properties provided by the xwt object

" the math object
syn region  javaScriptMath   start=+math+ end=+\(\.\w\+\)\?+ contains=jSMathProperty,jSMathFunction,jSMathKeyword
syn keyword jSMathKeyword    contained math
syn keyword jSMathProperty   contained E LN10 LN2 LOG10E LOG2E PI SQRT1_2 SQRT2
syn keyword jSMathFunction   contained abs acos asin atan atan2 ceil cos exp floor log max min pow random round sin sqrt tan

" the date object
syn region  javaScriptDate   start=+date+ end=+\(\.\w\+\)\?+ contains=jSDateKeyword,jSDateFunction
syn keyword jSDateKeyword    contained date
syn keyword jSDateFunction   contained getDate getDay getFullYear getHours getMilliseconds getMinutes getMonth getSeconds getTime
syn keyword jSDateFunction   contained getTimezoneOffset getUTCDate getUTCDay getUTCFullYear getUTCHours getUTCMilliseconds
syn keyword jSDateFunction   contained getUTCMinutes getUTCMonth getUTCSeconds
syn keyword jSDateFunction   contained setDate setDay setFullYear setHours setMilliseconds setMinutes setMonth setSeconds setTime
syn keyword jSDateFunction   contained setTimezoneOffset setUTCDate setUTCDay setUTCFullYear setUTCHours setUTCMilliseconds
syn keyword jSDateFunction   contained setUTCMinutes setUTCMonth setUTCSeconds
syn keyword jSDateFunction   contained toGMTString toLocaleString toUTCString toString toSource valueOf

" the string object
syn region  javaScriptString start=+string+ end=+\(\.\w\+\)\?+ contains=jSStringKeyword,jSStringFunction
syn keyword jSStringKeyword  contained string 
syn keyword jSStringFunction contained charAt charCodeAt concat fromCharCode indexOf lastIndexOf replace search slice split substr
syn keyword jSStringFunction contained substring toLowerCase toSource toString toUpperCase valueOf

" array functions and properties
syn keyword jSArrayFunction  contained concat join pop push shift slice splice sort toSource toString unshift valueOf
syn keyword jSArrayKeyword   contained length



" =====  XML-ish Stuff ======================================================================================

syn cluster xwtXML contains=xwtTag,xwtEndTag,xwtEntity

" punctuation (within attributes) e.g. <tag xwt:foo.attribute ...>
syn match   xwtAttribPunct +[:.]+ contained display

" attribute, everything before the '='
" PROVIDES: @xwtAttribHook
" EXAMPLE: <tag foo.attribute = "value">
"               ^^^^^^^^^^^^^
syn match xwtAttrib +[-'"<]\@<!\<[a-zA-Z:_][-.0-9a-zA-Z0-9:_]*\>\(['">]\@!\|$\)+ 
    \ contained contains=xwtAttribPunct,@xwtAttribHook display

" namespace spec
" PROVIDES: @xwtNamespaceHook
" EXAMPLE: <xsl:for-each select = "lola">
"           ^^^
if exists("g:xwt_namespace_transparent")
    syn match   xwtNamespace +\(<\|</\)\@<=[^ /!?<>"':]\+[:]\@=+ contained contains=@xwtNamespaceHook transparent display
else
    syn match   xwtNamespace +\(<\|</\)\@<=[^ /!?<>"':]\+[:]\@=+ contained contains=@xwtNamespaceHook display
endif

" tag name
" PROVIDES: @xwtTagHook
" EXAMPLE: <tag foo.attribute = "value">
"           ^^^
syn match   xwtTagName +[<]\@<=[^ /!?<>"']\++ contained contains=xwtNamespace,xwtAttribPunct,@xwtTagHook display

" start tag
" use matchgroup=xwtTag to skip over the leading '<'
" PROVIDES: @xwtStartTagHook
" EXAMPLE: <tag id="whoops">
"          s^^^^^^^^^^^^^^^e
syn region   xwtTag matchgroup=xwtTag start=+<[^ /!?<>"']\@=+ matchgroup=xwtTag end=+>+ contained
    \ contains=xwtError,xwtTagName,xwtAttrib,xwtEqual,xwtStringD,xwtStringS,@xwtStartTagHook

" end tag name
" PROVIDES: @xwtTagHook
" EXAMPLE: </tag>
"            ^^^
syn match   xwtEndTagName +\(</\)\@<=[^ /!?<>"']\++ contained contains=xwtNamespace,xwtAttribPunct,@xwtTagHook display

" highlight the end tag
" PROVIDES: @xwtTagHook
" (should we provide a separate @xwtEndTagHook ?)
" EXAMPLE: </tag>
"          ^^^^^^
syn region   xwtEndTag matchgroup=xwtEndTag start=+</[^ /!?<>"']\@=+ matchgroup=xwtEndTag end=+>+ contained
    \ contains=xwtError,xwtEndTagName,@xwtTagHook

" &entities;
syn match   xwtEntity                 "&[^; \t]*;" contains=xwtEntityPunct
syn match   xwtEntityPunct  contained "[&.;]"

" tag elements with syntax-folding.
" NOTE: NO HIGHLIGHING -- highlighing is done by contained elements
" PROVIDES: @xwtRegionHook
" EXAMPLE:
" <tag id="whoops">
"   <!-- comment -->
"   <another.tag></another.tag>
"   <empty.tag/>
"   some data
" </tag>
syn region   xwtRegion start=+<\z([^ /!?<>"']\+\)+ skip=+<!--\_.\{-}-->+ end=+</\z1\_\s\{-}>+ matchgroup=xwtEndTag end=+/>+ fold
    \ contains=xwtError,xwtRegion,xwtReadTrap,xwtWriteTrap,xwtObject,jSArrayFunction,jSArrayKeyword,
    \ @xwtPrimitive,@xwtXML,@xwt,@javaScript,@xwtComments,@xwtRegionHook
    \ keepend
    \ extend



" =====  XWT-Specific Stuff  ======================================================================================

syn cluster xwt contains=xwtReadTrap,xwtWriteTrap,xwtEventProperty,xwtRootBoxProperty,xwtObject,xwtFunction,xwtArg,@xwtBox

" The '+=' of a read/write trap
syn match  xwtReadTrap             "\(+=\)\(\s*function\s*(\s*)\)\@="        contained
syn match  xwtWriteTrap            "\(+=\)\(\s*function\s*(\s*\w\+\s*)\)\@=" contained


""""""""""""""""""""""""""""""""""""""""""""""
" Highlight box references and box properties

syn cluster xwtBox             contains=xwtBoxRef,xwtBoxRefName,xwtBoxProperty

" In a box reference '$foo',  '$' is the xwtBoxRef and 'foo' is the xwtBoxRefName
syn match   xwtBoxRef          "\$\(\w\+\)\@=" contained
syn match   xwtBoxRefName      "\$\@<=\(\w\+\)" contained

syn keyword xwtBoxProperty     contained fill stroke image tile fixedaspect text path font
syn keyword xwtBoxProperty     contained shrink hshrink vshrink width height cols rows colspan rowspan align invisible
syn keyword xwtBoxProperty     contained absolute x y globalx globaly minwidth maxwidth minheight maxheight
syn keyword xwtBoxProperty     contained numchildren redirect childadded childremoved
syn keyword xwtBoxProperty     contained cursor mousex mousey static mouseinside root thisbox indexof


""""""""""""""""""""""""""""""""""""""""""""""
" Highlight xwt objects, events and functions
" (See http://www.xwt.org/reference.html

" XWT events
syn match   xwtEventProperty   +Press[123]\|Release[123]\|Click[123]\|DoubleClick[123]+ contained
syn keyword xwtEventProperty   contained Enter Leave Move KeyPressed KeyReleased SizeChange PosChange

" XWT root box properties
syn keyword xwtRootBoxProperty contained Focused Maximized Minimized Close icon titlebar toback tofront

" the arguments object
syn region  xwtArg             start=+arguments+ end=+\(\.\w\+\)\?+ contains=xwtArgKeyword,xwtBoxProperty
syn keyword xwtArgKeyword      contained arguments length trapee trapname cascade callee

" other XWT objects and functions
syn region  xwtObject          start=+xwt+ end=+\(\.\w\+\)\?+ contains=xwtObjectKeyword,xwtFunction
    \ ,xwtLog,xwtUI,xwtFS,xwtRPC,xwtThread,xwtStream,xwtCrypto,javaScriptMath,javaScriptDate,javaScriptString

" The obects and functions below are split up so that highlighting also checks for heirarchical errors
" ie, in 'xwt.log.print' the 'print' will be highlighted, but in 'xwt.print' it will not 
syn keyword xwtObjectKeyword   contained xwt box origin
syn keyword xwtFunction        contained apply clone graft regexp
syn region  xwtLog             start=+log+ end=+\(\.\w\+\)\?+ contains=xwtLogKeyword,xwtLogFunction
syn keyword xwtLogKeyword      contained log
syn keyword xwtLogFunction     contained print dump
syn region  xwtUI              start=+ui+ end=+\(\.\w\+\)\?+ contains=xwtUIKeyword,xwtUIFunction,xwtKey,xwtScreen,xwtMouse
syn keyword xwtUIKeyword       contained ui clipboard maxdim frame window
syn keyword xwtUIFunction      contained browser
syn region  xwtKey             start=+key+ end=+\(\.\w\+\)\?+ contains=xwtKeyKeyword,xwtAlt
syn keyword xwtKeyKeyword      contained key control shift 
syn region  xwtAlt             start=+alt+ end=+\(\.\w\+\)\?+ contains=xwtAltKeyword
syn keyword xwtAltKeyword      contained alt name
syn region  xwtScreen          start=+screen+ end=+\(\.\w\+\)\?+ contains=xwtScreenKeyword
syn keyword xwtScreenKeyword   contained screen width height
syn region  xwtMouse           start=+mouse+ end=+\(\.\w\+\)\?+ contains=xwtMouseKeyword
syn keyword xwtMouseKeyword    contained mouse button
syn region  xwtFS              start=+fs+ end=+\(\.\w\+\)\?+ contains=xwtFSKeyword
syn keyword xwtFSKeyword       contained fs home temp 
syn region  xwtRPC             start=+rpc+ end=+\(\.\w\+\)\?+ contains=xwtRPCKeyword,xwtRPCFunction
syn keyword xwtRPCKeyword      contained rpc
syn keyword xwtRPCFunction     contained xml soap
syn region  xwtThread          start=+thread+ end=+\(\.\w\+\)\?+ contains=xwtThreadKeyword,xwtThreadFunction
syn keyword xwtThreadKeyword   contained thread 
syn keyword xwtThreadFunction  contained yield sleep 
syn region  xwtStream          start=+stream+ end=+\(\.\w\+\)\?+ contains=xwtStreamKeyword,xwtStreamFunction,xwtParse
syn keyword xwtStreamKeyword   contained stream 
syn keyword xwtStreamFunction  contained unzip uncab cache watch fromURL 
syn region  xwtParse           start=+parse+ end=+\(\.\w\+\)\?+ contains=xwtParseKeyword,xwtParseFunction
syn keyword xwtParseKeyword    contained parse 
syn keyword xwtParseFunction   contained html xml utf8 
syn region  xwtCrypto          start=+crypto+ end=+\(\.\w\+\)\?+ contains=xwtCryptoKeyword,xwtCryptoFunction
syn keyword xwtCryptoKeyword   contained crypto 
syn keyword xwtCryptoFunction  contained rsa rc4 md5 sha1 


" ================================================================================================================


" synchronizing
" TODO !!! to be improved !!!

"syn sync match xwtSyncDT grouphere  xwtDocType +\_.\(<!DOCTYPE\)\@=+
" syn sync match xwtSyncDT groupthere  NONE       +]>+

" FIXME: This isn't working quite right.  If you jump around in a file with a lot of ECMAScript,
" not all XWT keywords get highlighted properly
syn sync match xwtSync grouphere   xwtRegion  +\_.\(<[^ /!?<>"']\+\)\@=+
" syn sync match xwtSync grouphere  xwtRegion "<[^ /!?<>"']*>"
syn sync match xwtSync groupthere  xwtRegion  +</[^ /!?<>"']\+>+

"syn sync minlines=100


" ====  Highlighting  ==============================================================================================

" Define the default highlighting.
" For version 5.7 and earlier: only when not done already
" For version 5.8 and later: only when an item doesn't have highlighting yet
if version >= 508 || !exists("did_javascript_syn_inits")
    if version < 508
        let did_javascript_syn_inits = 1
        command -nargs=+ HiLink hi link <args>
    else
        command -nargs=+ HiLink hi def link <args>
    endif

    HiLink xwtError		                Error
    HiLink xwtTodo                      Todo
                 
    HiLink xwtStringD		            String
    HiLink xwtStringS		            String
                 
    HiLink xwtSpecial                   Special
"    HiLink xwtSpecialCharacter          javaScriptSpecial
    HiLink xwtSpecialCharacter          Special
    HiLink xwtCharacter                 Character
"    HiLink xwtNumber                    javaScriptValue
    HiLink xwtNumber                    Number
    HiLink xwtHexColor                  Number
    HiLink xwtNull                      Special
                 
    HiLink xwtLineComment               Comment
    HiLink xwtComment                   Comment
    HiLink xwtComment2                  Comment
    HiLink xwtHeaderComments            Comment


    HiLink javaScriptConditional        Conditional
    HiLink javaScriptRepeat             Repeat
    HiLink javaScriptBranch             Conditional
    HiLink javaScriptOperator           Operator
    HiLink javaScriptType               Type
    HiLink javaScriptStatement          Statement
    HiLink javaScriptFunction           Function
    HiLink javaScriptBraces             Function
    HiLink javaScriptError              Error
"    HiLink javaScrParenError            javaScriptError
"    HiLink javaScriptInParen            javaScriptError
    HiLink javaScriptParenError         Error
    HiLink javaScriptInParen            Error
    HiLink javaScriptBoolean            Boolean

    HiLink jSMathKeyword                Keyword
    HiLink jSMathProperty               Keyword
    HiLink jSMathFunction               Function
    HiLink jSDateKeyword                Keyword
    HiLink jSDateFunction               Function
    HiLink jSStringKeyword              Keyword
    HiLink jSStringFunction             Function
    HiLink jSArrayKeyword               Keyword
    HiLink jSArrayFunction              Function

    HiLink xwtTag		                Function
    HiLink xwtTagName		            Statement
    HiLink xwtEndTag		            Function
    HiLink xwtEndTagName                Statement
    if !exists("g:xwt_namespace_transparent")
        HiLink xwtNamespace	            Tag
    endif
    HiLink xwtEntity		            Statement
    HiLink xwtEntityPunct	            Statement
    HiLink xwtAttribPunct	            Normal
    HiLink xwtAttrib		            Identifier


    HiLink xwtReadTrap                  Special
    HiLink xwtWriteTrap                 Underlined

    HiLink xwtBoxRef                    Special     
    HiLink xwtBoxRefName                Keyword     
    HiLink xwtBoxProperty               Keyword     
    HiLink xwtRootBoxProperty           Keyword     
    HiLink xwtEventProperty             Keyword     

    HiLink xwtObjectKeyword             Keyword
    HiLink xwtFunction                  Function
    HiLink xwtArgKeyword                Keyword
    HiLink xwtLogKeyword                Keyword 
    HiLink xwtLogFunction               Function
    HiLink xwtUIKeyword                 Keyword 
    HiLink xwtUIFunction                Function
    HiLink xwtKeyKeyword                Keyword 
    HiLink xwtAltKeyword                Keyword 
    HiLink xwtScreenKeyword             Keyword 
    HiLink xwtMouseKeyword              Keyword 
    HiLink xwtFSKeyword                 Keyword 
    HiLink xwtRPCKeyword                Keyword 
    HiLink xwtRPCFunction               Function
    HiLink xwtThreadKeyword             Keyword 
    HiLink xwtThreadFunction            Function
    HiLink xwtStreamKeyword             Keyword 
    HiLink xwtStreamFunction            Function
    HiLink xwtParseKeyword              Keyword 
    HiLink xwtParseFunction             Function
    HiLink xwtCryptoKeyword             Keyword 
    HiLink xwtCryptoFunction            Function


    " CData and DTD highlighting stuff

    "HiLink xwtProcessingDelim	        Comment
    "HiLink xwtProcessing	            Type

    "HiLink xwtCdata		            String
    "HiLink xwtCdataCdata	            Statement
    "HiLink xwtCdataStart	            Type
    "HiLink xwtCdataEnd	                Type

    "HiLink xwtDocTypeDecl	            Function
    "HiLink xwtDocTypeKeyword	        Statement
    "HiLink xwtInlineDTD	            Function

    delcommand HiLink
endif


let b:current_syntax = "xwt"
if main_syntax == 'xwt'
  unlet main_syntax
endif

let &cpo = s:xwt_cpo_save
unlet s:xwt_cpo_save

" vim: ts=8

"  ====  Extra CData and DTD stuff (might need later) ==============================================================

" CData sections
"
" PROVIDES: @xwtCdataHook
"
"syn region    xwtCdata
"    \ start=+<!\[CDATA\[+
"    \ end=+]]>+
"    \ contains=xwtCdataStart,xwtCdataEnd,@xwtCdataHook
"    \ keepend
"    \ extend

" using the following line instead leads to corrupt folding at CDATA regions
" syn match    xwtCdata      +<!\[CDATA\[\_.\{-}]]>+  contains=xwtCdataStart,xwtCdataEnd,@xwtCdataHook
"syn match    xwtCdataStart +<!\[CDATA\[+  contained contains=xwtCdataCdata
"syn keyword  xwtCdataCdata CDATA          contained
"syn match    xwtCdataEnd   +]]>+          contained


" Processing instructions
" This allows "?>" inside strings -- good idea?
"syn region  xwtProcessing matchgroup=xwtProcessingDelim start="<?" end="?>" contains=xwtAttrib,xwtEqual,xwtString


" DTD -- we use dtd.vim here
"syn region  xwtDocType matchgroup=xwtDocTypeDecl
"    \ start="<!DOCTYPE"he=s+2,rs=s+2 end=">"
"    \ fold
"    \ contains=xwtDocTypeKeyword,xwtInlineDTD,xwtString
"syn keyword xwtDocTypeKeyword contained DOCTYPE PUBLIC SYSTEM
"syn region  xwtInlineDTD contained matchgroup=xwtDocTypeDecl start="\[" end="]" contains=@xwtDTD
"syn include @xwtDTD <sfile>:p:h/dtd.vim
"unlet b:current_syntax
xwt_indent.vim (text/plain, 3.1 KB)
" Description:	xwt indenter
" Maintainer:   Rod Martin (adapted from html.vim by Johannes Zellner <[email protected]>)
" URL:	        www.xwt.org	
" Last Change:  Mon Nov 24 15:55:55 EST 2003 
" Globals:	g:xwt_indent_tags         -- indenting tags
"		g:xwt_indent_strict       -- inhibit 'O O' elements
"		g:xwt_indent_strict_table -- inhibit 'O -' elements

" Only load this indent file when no other was loaded.
if exists("b:did_indent")
    finish
endif
let b:did_indent = 1

filetype indent on

setlocal autoindent
setlocal smartindent
" XWT does not allow tabs
set expandtab

" [-- local settings (must come before aborting the script) --]
setlocal indentexpr=XwtIndentGet(v:lnum)
setlocal indentkeys=o,O,*<Return>,<>>,<bs>,{,}


if exists('g:xwt_indent_tags')
    unlet g:xwt_indent_tags
endif

" [-- helper function to assemble tag list --]
fun! <SID>XwtIndentPush(tag)
    if exists('g:xwt_indent_tags')
	let g:xwt_indent_tags = g:xwt_indent_tags.'\|'.a:tag
    else
	let g:xwt_indent_tags = a:tag
    endif
endfun


call <SID>XwtIndentPush('\w*')

delfun <SID>XwtIndentPush

set cpo-=C

" [-- count indent-increasing tags of line a:lnum --]
fun! <SID>XwtIndentOpen(lnum)
    let s = substitute('x'.getline(a:lnum),
    \ '.\{-}\(\(<\)\('.g:xwt_indent_tags.'\)[^/]*[^/]>\)', "\1", 'g')
    let s = substitute(s, "[^\1].*$", '', '')
    return strlen(s)
endfun

" [-- count indent-decreasing tags of line a:lnum --]
fun! <SID>XwtIndentClose(lnum)
    let s = substitute('x'.getline(a:lnum),
    \ '.\{-}\(\(<\)/\('.g:xwt_indent_tags.'\)\>>\)', "\1", 'g')
    let s = substitute(s, "[^\1].*$", '', '')
    return strlen(s)
endfun

" [-- count indent-increasing '{' --]
fun! <SID>XwtIndentOpenAlt(lnum)
    return strlen(substitute(getline(a:lnum), '[^{]\+', '', 'g'))
endfun

" [-- count indent-decreasing '}' --]
fun! <SID>XwtIndentCloseAlt(lnum)
    return strlen(substitute(getline(a:lnum), '[^}]\+', '', 'g'))
endfun

" [-- return the sum of indents respecting the syntax of a:lnum --]
fun! <SID>XwtIndentSum(lnum, style)
    if a:style == match(getline(a:lnum), '^\s*</')
	if a:style == match(getline(a:lnum), '^\s*</\<\('.g:xwt_indent_tags.'\)\>')
	    let open = <SID>XwtIndentOpen(a:lnum)
	    let close = <SID>XwtIndentClose(a:lnum)
	    if 0 != open || 0 != close
		return open - close
	    endif
	endif
    endif
    if '' != &syntax &&
	\ synIDattr(synID(a:lnum, 1, 1), 'name') =~ '\(xwt\).*' &&
	\ synIDattr(synID(a:lnum, strlen(getline(a:lnum)) - 1, 1), 'name')
	\ =~ '\(xwt\).*'
	if a:style == match(getline(a:lnum), '^\s*}')
	    return <SID>XwtIndentOpenAlt(a:lnum) - <SID>XwtIndentCloseAlt(a:lnum)
	endif
    endif
    return 0
endfun

fun! XwtIndentGet(lnum)
    " Find a non-empty line above the current line.
    let lnum = prevnonblank(a:lnum - 1)

    " Hit the start of the file, use zero indent.
    if lnum == 0
	return 0
    endif

    let restore_ic=&ic
    let &ic=1 " ignore case

    let ind = <SID>XwtIndentSum(lnum, -1)
    let ind = ind + <SID>XwtIndentSum(a:lnum, 0)

    let &ic=restore_ic

    return indent(lnum) + (&sw * ind)
endfun

" [-- EOF <runtime>/indent/xwt.vim --]