" Vim syntax file
" Language:    MUSH/MUX (local additions for folding and support mushpp, see
"                        http://christianrobinson.name/programming/perl/mushpp)
" Maintainer:  Christian J. Robinson <heptite@gmail.com>
" Last Change: August 25, 2010

" ----------------------------------------------------------------------------
"
" Place this file in <runtime>/after/syntax/mush.vim -- it requires that the
" syntax/mush.vim distributed with Vim exist and sourced first.
"
" You can enable folding by putting the following variable(s) in your
" ~/.vimrc:
"
" To enable folding of formatted, multiline MUSH/MUX commands:
"   :let mush_fold = 1
"
" To enable folding of @@ ... \n ... \nEOL style multi-line comments:
"   :let mush_fold_comments = 1
"
" To enable folding of multi-line #define, #ascii, and
" #ifn?def...#endif (including #else!) directives:
"   :let mush_fold_defines = 1
"
" ----------------------------------------------------------------------------


" Unset mush_fold* if they're set but this version of Vim doesn't support it:
if version < 600
	if exists("mush_fold")
		unlet mush_fold
	endif
	if exists("mush_fold_comments")
		unlet mush_fold_comments
	endif
	if exists("mush_fold_defines")
		unlet mush_fold_defines
	endif
endif

" Make @@ style comments span a region, since unformat/mushpp sends them to
" the MUSH.  Also make /@@ @@/ style comments oneline for mushpp:
syntax clear mushComment
syntax match  mushComment +^".*$+  contains=mushTodo,@Spell
			\ containedin=ALLBUT,mushInclude,mushDefine,mushPreCondit,mushComment
syntax match  mushComment +^#.*$+  contains=mushTodo,@Spell
			\ containedin=ALLBUT,mushInclude,mushDefine,mushPreCondit,mushComment
if exists("mush_fold_comments")
	syntax region mushComment
			\ start=+^\s*@@\s\++ end=+^\(-\|EOL\)$\|[^\\];+ fold keepend
			\ contains=mushTodo,mushCommentString,MushSpecial,@Spell
			\ containedin=ALLBUT,mushInclude,mushDefine,mushPreCondit,mushComment
else
	syntax region mushComment
			\ start=+^\s*@@\s\++ end=+^\(-\|EOL\)$\|[^\\];+me=s-1
			\ contains=mushTodo,mushCommentString,MushSpecial,@Spell
			\ containedin=ALLBUT,mushInclude,mushDefine,mushPreCondit,mushComment
endif
syntax region mushComment matchgroup=mushCommentStart
			\ start=+/@@+ end=+@@/+
			\ contains=mushTodo,mushCommentStartError,mushCommentString,@Spell
			\ containedin=ALLBUT,mushInclude,mushDefine,mushPreCondit,mushComment,mushCommentStartError
			\ oneline

" Make defines/includes highlight differently than # comments:
if exists("mush_fold_defines")
	syntax region mushDefine
			\ start="^\s*#\s*\(eval_\)\=define\>\s"
			\ skip='\\$' end='$' fold
else
	syntax region mushDefine
			\ start="^\s*#\s*\(eval_\)\=define\>\s"
			\ skip='\\$' end='$'
end
syntax match mushIncluded +\s\S\++ms=s+1 contained
syntax match mushInclude  "^\s*#\s*include\>\s\+.*" contains=mushIncluded

syntax clear mushPreCondit
syntax match mushPreCondit "^\s*#\s*\(ifdef\|ifndef\)\>\s\+.*"
syntax match mushPreCondit "^\s*#\s*else\>\s*"
syntax match mushPreCondit "^\s*#\s*endif\>\(\s\+.*\)\?"

if exists("mush_fold_defines")
	syntax region mushAsciiBody matchgroup=mushAscii
			\ start="^\s*#\s*ascii\s\+\S\+"
			\ end="^\s*#\s*endascii\(\s\+.*\)\?"
			\ fold

	syntax region mushPreConditFold
			\ start="^\s*#\s*\(ifdef\|ifndef\)\>\s\+"
			\ end="^\s*#\s*endif\>\(\s\+.*\)\?"
			\ transparent fold extend keepend
			\ matchgroup=mushPreCondit contains=TOP

else
	syntax region mushAsciiBody matchgroup=mushAscii
			\ start="^\s*#\s*ascii\s\+\S\+"
			\ end="^\s*#\s*endascii\(\s\+.*\)\?"
endif

" TODO: Delete this stuff once the main syntax file gets fixed:

" The mushString highlighting is never right, clear it:
syntax clear mushString

" The match end offset for mushCommentStartError is off by one, fix it:
syntax clear mushCommentStartError
syntax match mushCommentStartError display +/@@+me=e-2 contained

" Unfortunately 'TRANSPARENT' is a MUSH flag, but also recognized as a syntax
" directive in Vim--this is the only way to highlight it:
syn clear mushFlag
syntax match   mushFlag +\<TRANSPARENT\>+
" ...and since the main syntax file tries to use TRANSPARENT in a syn keyword,
" we have to clear /all/ the mushFlag keywords and redefine them here (see
" above):
syntax keyword mushFlag PLAYER ABODE BUILDER CHOWN_OK DARK FLOATING
syntax keyword mushFlag GOING HAVEN INHERIT JUMP_OK KEY LINK_OK MONITOR
syntax keyword mushFlag NOSPOOF OPAQUE QUIET STICKY TRACE UNFINDABLE VISUAL
syntax keyword mushFlag WIZARD PARENT_OK ZONE AUDIBLE CONNECTED DESTROY_OK
syntax keyword mushFlag ENTER_OK HALTED IMMORTAL LIGHT MYOPIC PUPPET TERSE
syntax keyword mushFlag ROBOT SAFE VERBOSE CONTROL_OK COMMANDS IC OOC

" Fix a typo in the global syntax file (mushAttributes -> mushAttribute) and
" fix it so function keywords only highlight when followed by ()'s
" (mushFunction -> mushFunctionBrackets):
syntax clear mushFuncBoundaries
syntax region mushFuncBoundaries start="\[" end="\]"
			\ contains=mushFunctionBrackets,mushFlag,mushAttribute,mushNumber,mushCommand,mushVariable,mushSpecial2

" END TODO

syntax match MushSpecial "^EOL\s*$"

if exists("mush_fold")
	syn region mushFold start==^\w\+\s*(= end==^\(-\|EOL\)$= fold transparent keepend contains=TOP
	syn region mushFold start==^[&@]\w\+= end==^\(-\|EOL\)$= fold transparent keepend contains=TOP
	syn region mushFold start==^\(think\|say\s\|nsay\|say/noeval\s\|pose\s\|pose/default\s\|pose/nospace\s\|page\s\|page/noeval\\s|[:;]\S\)=
				\ end==^\(-\|EOL\)$= fold transparent keepend contains=TOP
	syn sync fromstart
	setlocal foldmethod=syntax foldminlines=2
endif

"if exists("mush_fold")
"	syn cluster mushFoldExclude contains=mushFold,mushIncluded,mushFunction,mushAtCommandList,mushSpecial2,mushTodo
"	syn region mushFold start==^[&@]\w\+= end==^-$= contains=ALLBUT,@mushFoldExclude
"		\ fold transparent keepend extend excludenl
"	syn sync fromstart
"	setlocal foldmethod=syntax foldminlines=2
"endif

if version >= 508 || !exists("did_mush_syn_inits")
	if version < 508
		let did_mush_syn_inits = 1
		command -nargs=+ HiLink hi link <args>
	else
		command -nargs=+ HiLink hi def link <args>
	endif

	HiLink mushAsciiBody         String
	HiLink mushAscii             Macro
	HiLink mushCommentStartError Error

	delcommand HiLink
endif