diff options
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | after/jsx-config.vim | 99 | ||||
| -rwxr-xr-x | build | 7 | ||||
| -rw-r--r-- | ftdetect/polyglot.vim | 1 | ||||
| -rw-r--r-- | indent/solidity.vim | 439 | ||||
| -rw-r--r-- | syntax/solidity.vim | 77 | 
6 files changed, 522 insertions, 102 deletions
| @@ -75,6 +75,7 @@ Optionally download one of the [releases](https://github.com/sheerun/vim-polyglo  - [sbt](https://github.com/derekwyatt/vim-sbt) (syntax, ftdetect)  - [scala](https://github.com/derekwyatt/vim-scala) (syntax, indent, compiler, ftplugin, ftdetect)  - [slim](https://github.com/slim-template/vim-slim) (syntax, indent, ftdetect) +- [solidity](https://github.com/ethereum/vim-solidity) (syntax, indent, ftdetect)  - [stylus](https://github.com/wavded/vim-stylus) (syntax, indent, ftplugin, ftdetect)  - [systemd](https://github.com/kurayama/systemd-vim-syntax) (syntax, ftdetect)  - [swift](https://github.com/toyamarinyon/vim-swift) (syntax, indent, ftdetect) diff --git a/after/jsx-config.vim b/after/jsx-config.vim index d617bb40..a1d4cbe0 100644 --- a/after/jsx-config.vim +++ b/after/jsx-config.vim @@ -31,102 +31,3 @@ if !g:jsx_pragma_required | finish | endif  " anything else in the file (except whitespace).  let s:jsx_pragma_pattern = '\%^\_s*\/\*\*\%(\_.\%(\*\/\)\@!\)*@jsx\_.\{-}\*\/'  let b:jsx_pragma_found = search(s:jsx_pragma_pattern, 'npw') -""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -" Vimscript file -" -" Set up a bunch of configuration variables. -" -" Also check (if desired) whether or not the @jsx pragma is correctly included -" in '%'.  Set the result in b:jsx_pragma_found. -" -" Language: JSX (JavaScript) -" Maintainer: Max Wang <mxawng@gmail.com> -" -""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" - -" Only check once. -if exists('b:jsx_pragma_found') -  finish -endif - -" Whether the .jsx extension is required to enable JSX syntax/indent. -if !exists('g:jsx_ext_required') -  let g:jsx_ext_required = 1 -endif - -" Whether the @jsx pragma is required to enable JSX syntax/indent. -if !exists('g:jsx_pragma_required') -  let g:jsx_pragma_required = 0 -endif -if !g:jsx_pragma_required | finish | endif - -" Look for the @jsx pragma.  It must be included in a docblock comment before -" anything else in the file (except whitespace). -let s:jsx_pragma_pattern = '\%^\_s*\/\*\*\%(\_.\%(\*\/\)\@!\)*@jsx\_.\{-}\*\/' -let b:jsx_pragma_found = search(s:jsx_pragma_pattern, 'npw') -""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -" Vimscript file -" -" Set up a bunch of configuration variables. -" -" Also check (if desired) whether or not the @jsx pragma is correctly included -" in '%'.  Set the result in b:jsx_pragma_found. -" -" Language: JSX (JavaScript) -" Maintainer: Max Wang <mxawng@gmail.com> -" -""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" - -" Only check once. -if exists('b:jsx_pragma_found') -  finish -endif - -" Whether the .jsx extension is required to enable JSX syntax/indent. -if !exists('g:jsx_ext_required') -  let g:jsx_ext_required = 1 -endif - -" Whether the @jsx pragma is required to enable JSX syntax/indent. -if !exists('g:jsx_pragma_required') -  let g:jsx_pragma_required = 0 -endif -if !g:jsx_pragma_required | finish | endif - -" Look for the @jsx pragma.  It must be included in a docblock comment before -" anything else in the file (except whitespace). -let s:jsx_pragma_pattern = '\%^\_s*\/\*\*\%(\_.\%(\*\/\)\@!\)*@jsx\_.\{-}\*\/' -let b:jsx_pragma_found = search(s:jsx_pragma_pattern, 'npw') -""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -" Vimscript file -" -" Set up a bunch of configuration variables. -" -" Also check (if desired) whether or not the @jsx pragma is correctly included -" in '%'.  Set the result in b:jsx_pragma_found. -" -" Language: JSX (JavaScript) -" Maintainer: Max Wang <mxawng@gmail.com> -" -""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" - -" Only check once. -if exists('b:jsx_pragma_found') -  finish -endif - -" Whether the .jsx extension is required to enable JSX syntax/indent. -if !exists('g:jsx_ext_required') -  let g:jsx_ext_required = 1 -endif - -" Whether the @jsx pragma is required to enable JSX syntax/indent. -if !exists('g:jsx_pragma_required') -  let g:jsx_pragma_required = 0 -endif -if !g:jsx_pragma_required | finish | endif - -" Look for the @jsx pragma.  It must be included in a docblock comment before -" anything else in the file (except whitespace). -let s:jsx_pragma_pattern = '\%^\_s*\/\*\*\%(\_.\%(\*\/\)\@!\)*@jsx\_.\{-}\*\/' -let b:jsx_pragma_found = search(s:jsx_pragma_pattern, 'npw') @@ -4,7 +4,7 @@ set -E  DIRS="syntax indent compiler autoload ftplugin ftdetect after/syntax after/indent after/ftplugin after/ftdetect"  DIRS_BASIC="syntax indent ftdetect after/syntax after/indent after/ftdetect" -DIRS_JSX="after" +DIRS_ALL="syntax indent compiler autoload ftplugin ftdetect after"  OUTPUT="" @@ -121,7 +121,7 @@ PACKS="    julia:dcjones/julia-minimalist-vim    json:sheerun/vim-json    jst:briancollins/vim-jst -  jsx:mxw/vim-jsx:_JSX +  jsx:mxw/vim-jsx:_ALL    latex:LaTeX-Box-Team/LaTeX-Box    less:groenewege/vim-less    liquid:tpope/vim-liquid @@ -144,6 +144,7 @@ PACKS="    sbt:derekwyatt/vim-sbt    scala:derekwyatt/vim-scala    slim:slim-template/vim-slim +  solidity:ethereum/vim-solidity    stylus:wavded/vim-stylus    systemd:kurayama/systemd-vim-syntax    swift:toyamarinyon/vim-swift @@ -163,7 +164,7 @@ PACKS="  "  rm -rf tmp -rm -rf $DIRS +rm -rf $DIRS_ALL  mkdir tmp  printf "Downloading packs..." diff --git a/ftdetect/polyglot.vim b/ftdetect/polyglot.vim index 5ecde6fc..0cabe1f8 100644 --- a/ftdetect/polyglot.vim +++ b/ftdetect/polyglot.vim @@ -191,6 +191,7 @@ au BufRead,BufNewFile *.scala set filetype=scala  au BufRead,BufNewFile * call s:DetectScala()  au BufRead,BufNewFile *.sbt setfiletype sbt.scala  autocmd BufNewFile,BufRead *.slim set filetype=slim +au BufNewFile,BufRead *.sol setf solidity  autocmd BufNewFile,BufReadPost *.styl set filetype=stylus  autocmd BufNewFile,BufReadPost *.stylus set filetype=stylus  autocmd BufNewFile,BufRead *.swift set filetype=swift diff --git a/indent/solidity.vim b/indent/solidity.vim new file mode 100644 index 00000000..29b60b5a --- /dev/null +++ b/indent/solidity.vim @@ -0,0 +1,439 @@ +" Vim indent file +" Language: Solidity +" Acknowledgement: Based off of vim-javascript + +" 0. Initialization {{{1 +" ================= + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") +  finish +endif +let b:did_indent = 1 + +setlocal nosmartindent + +" Now, set up our indentation expression and keys that trigger it. +setlocal indentexpr=GetSolidityIndent() +setlocal indentkeys=0{,0},0),0],0\,,!^F,o,O,e + +" Only define the function once. +if exists("*GetSolidityIndent") +  finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +" 1. Variables {{{1 +" ============ + +let s:js_keywords = '^\s*\(break\|case\|catch\|continue\|debugger\|default\|delete\|do\|else\|finally\|for\|function\|if\|in\|instanceof\|new\|return\|switch\|this\|throw\|try\|typeof\|var\|void\|while\|with\)' + +" Regex of syntax group names that are or delimit string or are comments. +let s:syng_strcom = 'string\|regex\|comment\c' + +" Regex of syntax group names that are strings. +let s:syng_string = 'regex\c' + +" Regex of syntax group names that are strings or documentation. +let s:syng_multiline = 'comment\c' + +" Regex of syntax group names that are line comment. +let s:syng_linecom = 'linecomment\c' + +" Expression used to check whether we should skip a match with searchpair(). +let s:skip_expr = "synIDattr(synID(line('.'),col('.'),1),'name') =~ '".s:syng_strcom."'" + +let s:line_term = '\s*\%(\%(\/\/\).*\)\=$' + +" Regex that defines continuation lines, not including (, {, or [. +let s:continuation_regex = '\%([\\*+/.:]\|\%(<%\)\@<![=-]\|\W[|&?]\|||\|&&\)' . s:line_term + +" Regex that defines continuation lines. +" TODO: this needs to deal with if ...: and so on +let s:msl_regex = '\%([\\*+/.:([]\|\%(<%\)\@<![=-]\|\W[|&?]\|||\|&&\)' . s:line_term + +let s:one_line_scope_regex = '\<\%(if\|else\|for\|while\)\>[^{;]*' . s:line_term + +" Regex that defines blocks. +let s:block_regex = '\%([{[]\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s:line_term + +let s:var_stmt = '^\s*var' + +let s:comma_first = '^\s*,' +let s:comma_last = ',\s*$' + +let s:ternary = '^\s\+[?|:]' +let s:ternary_q = '^\s\+?' + +" 2. Auxiliary Functions {{{1 +" ====================== + +" Check if the character at lnum:col is inside a string, comment, or is ascii. +function s:IsInStringOrComment(lnum, col) +  return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_strcom +endfunction + +" Check if the character at lnum:col is inside a string. +function s:IsInString(lnum, col) +  return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_string +endfunction + +" Check if the character at lnum:col is inside a multi-line comment. +function s:IsInMultilineComment(lnum, col) +  return !s:IsLineComment(a:lnum, a:col) && synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_multiline +endfunction + +" Check if the character at lnum:col is a line comment. +function s:IsLineComment(lnum, col) +  return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_linecom +endfunction + +" Find line above 'lnum' that isn't empty, in a comment, or in a string. +function s:PrevNonBlankNonString(lnum) +  let in_block = 0 +  let lnum = prevnonblank(a:lnum) +  while lnum > 0 +    " Go in and out of blocks comments as necessary. +    " If the line isn't empty (with opt. comment) or in a string, end search. +    let line = getline(lnum) +    if line =~ '/\*' +      if in_block +        let in_block = 0 +      else +        break +      endif +    elseif !in_block && line =~ '\*/' +      let in_block = 1 +    elseif !in_block && line !~ '^\s*\%(//\).*$' && !(s:IsInStringOrComment(lnum, 1) && s:IsInStringOrComment(lnum, strlen(line))) +      break +    endif +    let lnum = prevnonblank(lnum - 1) +  endwhile +  return lnum +endfunction + +" Find line above 'lnum' that started the continuation 'lnum' may be part of. +function s:GetMSL(lnum, in_one_line_scope) +  " Start on the line we're at and use its indent. +  let msl = a:lnum +  let lnum = s:PrevNonBlankNonString(a:lnum - 1) +  while lnum > 0 +    " If we have a continuation line, or we're in a string, use line as MSL. +    " Otherwise, terminate search as we have found our MSL already. +    let line = getline(lnum) +    let col = match(line, s:msl_regex) + 1 +    if (col > 0 && !s:IsInStringOrComment(lnum, col)) || s:IsInString(lnum, strlen(line)) +      let msl = lnum +    else +      " Don't use lines that are part of a one line scope as msl unless the +      " flag in_one_line_scope is set to 1 +      " +      if a:in_one_line_scope +        break +      end +      let msl_one_line = s:Match(lnum, s:one_line_scope_regex) +      if msl_one_line == 0 +        break +      endif +    endif +    let lnum = s:PrevNonBlankNonString(lnum - 1) +  endwhile +  return msl +endfunction + +function s:RemoveTrailingComments(content) +  let single = '\/\/\(.*\)\s*$' +  let multi = '\/\*\(.*\)\*\/\s*$' +  return substitute(substitute(a:content, single, '', ''), multi, '', '') +endfunction + +" Find if the string is inside var statement (but not the first string) +function s:InMultiVarStatement(lnum) +  let lnum = s:PrevNonBlankNonString(a:lnum - 1) + +"  let type = synIDattr(synID(lnum, indent(lnum) + 1, 0), 'name') + +  " loop through previous expressions to find a var statement +  while lnum > 0 +    let line = getline(lnum) + +    " if the line is a js keyword +    if (line =~ s:js_keywords) +      " check if the line is a var stmt +      " if the line has a comma first or comma last then we can assume that we +      " are in a multiple var statement +      if (line =~ s:var_stmt) +        return lnum +      endif + +      " other js keywords, not a var +      return 0 +    endif + +    let lnum = s:PrevNonBlankNonString(lnum - 1) +  endwhile + +  " beginning of program, not a var +  return 0 +endfunction + +" Find line above with beginning of the var statement or returns 0 if it's not +" this statement +function s:GetVarIndent(lnum) +  let lvar = s:InMultiVarStatement(a:lnum) +  let prev_lnum = s:PrevNonBlankNonString(a:lnum - 1) + +  if lvar +    let line = s:RemoveTrailingComments(getline(prev_lnum)) + +    " if the previous line doesn't end in a comma, return to regular indent +    if (line !~ s:comma_last) +      return indent(prev_lnum) - &sw +    else +      return indent(lvar) + &sw +    endif +  endif + +  return -1 +endfunction + + +" Check if line 'lnum' has more opening brackets than closing ones. +function s:LineHasOpeningBrackets(lnum) +  let open_0 = 0 +  let open_2 = 0 +  let open_4 = 0 +  let line = getline(a:lnum) +  let pos = match(line, '[][(){}]', 0) +  while pos != -1 +    if !s:IsInStringOrComment(a:lnum, pos + 1) +      let idx = stridx('(){}[]', line[pos]) +      if idx % 2 == 0 +        let open_{idx} = open_{idx} + 1 +      else +        let open_{idx - 1} = open_{idx - 1} - 1 +      endif +    endif +    let pos = match(line, '[][(){}]', pos + 1) +  endwhile +  return (open_0 > 0) . (open_2 > 0) . (open_4 > 0) +endfunction + +function s:Match(lnum, regex) +  let col = match(getline(a:lnum), a:regex) + 1 +  return col > 0 && !s:IsInStringOrComment(a:lnum, col) ? col : 0 +endfunction + +function s:IndentWithContinuation(lnum, ind, width) +  " Set up variables to use and search for MSL to the previous line. +  let p_lnum = a:lnum +  let lnum = s:GetMSL(a:lnum, 1) +  let line = getline(lnum) + +  " If the previous line wasn't a MSL and is continuation return its indent. +  " TODO: the || s:IsInString() thing worries me a bit. +  if p_lnum != lnum +    if s:Match(p_lnum,s:continuation_regex)||s:IsInString(p_lnum,strlen(line)) +      return a:ind +    endif +  endif + +  " Set up more variables now that we know we aren't continuation bound. +  let msl_ind = indent(lnum) + +  " If the previous line ended with [*+/.-=], start a continuation that +  " indents an extra level. +  if s:Match(lnum, s:continuation_regex) +    if lnum == p_lnum +      return msl_ind + a:width +    else +      return msl_ind +    endif +  endif + +  return a:ind +endfunction + +function s:InOneLineScope(lnum) +  let msl = s:GetMSL(a:lnum, 1) +  if msl > 0 && s:Match(msl, s:one_line_scope_regex) +    return msl +  endif +  return 0 +endfunction + +function s:ExitingOneLineScope(lnum) +  let msl = s:GetMSL(a:lnum, 1) +  if msl > 0 +    " if the current line is in a one line scope .. +    if s:Match(msl, s:one_line_scope_regex) +      return 0 +    else +      let prev_msl = s:GetMSL(msl - 1, 1) +      if s:Match(prev_msl, s:one_line_scope_regex) +        return prev_msl +      endif +    endif +  endif +  return 0 +endfunction + +" 3. GetSolidityIndent Function {{{1 +" ========================= + +function GetSolidityIndent() +  " 3.1. Setup {{{2 +  " ---------- + +  " Set up variables for restoring position in file.  Could use v:lnum here. +  let vcol = col('.') + +  " 3.2. Work on the current line {{{2 +  " ----------------------------- + +  let ind = -1 +  " Get the current line. +  let line = getline(v:lnum) +  " previous nonblank line number +  let prevline = prevnonblank(v:lnum - 1) + +  " If we got a closing bracket on an empty line, find its match and indent +  " according to it.  For parentheses we indent to its column - 1, for the +  " others we indent to the containing line's MSL's level.  Return -1 if fail. +  let col = matchend(line, '^\s*[],})]') +  if col > 0 && !s:IsInStringOrComment(v:lnum, col) +    call cursor(v:lnum, col) + +    let lvar = s:InMultiVarStatement(v:lnum) +    if lvar +      let prevline_contents = s:RemoveTrailingComments(getline(prevline)) + +      " check for comma first +      if (line[col - 1] =~ ',') +        " if the previous line ends in comma or semicolon don't indent +        if (prevline_contents =~ '[;,]\s*$') +          return indent(s:GetMSL(line('.'), 0)) +        " get previous line indent, if it's comma first return prevline indent +        elseif (prevline_contents =~ s:comma_first) +          return indent(prevline) +        " otherwise we indent 1 level +        else +          return indent(lvar) + &sw +        endif +      endif +    endif + + +    let bs = strpart('(){}[]', stridx(')}]', line[col - 1]) * 2, 2) +    if searchpair(escape(bs[0], '\['), '', bs[1], 'bW', s:skip_expr) > 0 +      if line[col-1]==')' && col('.') != col('$') - 1 +        let ind = virtcol('.')-1 +      else +        let ind = indent(s:GetMSL(line('.'), 0)) +      endif +    endif +    return ind +  endif + +  " If the line is comma first, dedent 1 level +  if (getline(prevline) =~ s:comma_first) +    return indent(prevline) - &sw +  endif + +  if (line =~ s:ternary) +    if (getline(prevline) =~ s:ternary_q) +      return indent(prevline) +    else +      return indent(prevline) + &sw +    endif +  endif + +  " If we are in a multi-line comment, cindent does the right thing. +  if s:IsInMultilineComment(v:lnum, 1) && !s:IsLineComment(v:lnum, 1) +    return cindent(v:lnum) +  endif + +  " Check for multiple var assignments +"  let var_indent = s:GetVarIndent(v:lnum) +"  if var_indent >= 0 +"    return var_indent +"  endif + +  " 3.3. Work on the previous line. {{{2 +  " ------------------------------- + +  " If the line is empty and the previous nonblank line was a multi-line +  " comment, use that comment's indent. Deduct one char to account for the +  " space in ' */'. +  if line =~ '^\s*$' && s:IsInMultilineComment(prevline, 1) +    return indent(prevline) - 1 +  endif + +  " Find a non-blank, non-multi-line string line above the current line. +  let lnum = s:PrevNonBlankNonString(v:lnum - 1) + +  " If the line is empty and inside a string, use the previous line. +  if line =~ '^\s*$' && lnum != prevline +    return indent(prevnonblank(v:lnum)) +  endif + +  " At the start of the file use zero indent. +  if lnum == 0 +    return 0 +  endif + +  " Set up variables for current line. +  let line = getline(lnum) +  let ind = indent(lnum) + +  " If the previous line ended with a block opening, add a level of indent. +  if s:Match(lnum, s:block_regex) +    return indent(s:GetMSL(lnum, 0)) + &sw +  endif + +  " If the previous line contained an opening bracket, and we are still in it, +  " add indent depending on the bracket type. +  if line =~ '[[({]' +    let counts = s:LineHasOpeningBrackets(lnum) +    if counts[0] == '1' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0 +      if col('.') + 1 == col('$') +        return ind + &sw +      else +        return virtcol('.') +      endif +    elseif counts[1] == '1' || counts[2] == '1' +      return ind + &sw +    else +      call cursor(v:lnum, vcol) +    end +  endif + +  " 3.4. Work on the MSL line. {{{2 +  " -------------------------- + +  let ind_con = ind +  let ind = s:IndentWithContinuation(lnum, ind_con, &sw) + +  " }}}2 +  " +  " +  let ols = s:InOneLineScope(lnum) +  if ols > 0 +    let ind = ind + &sw +  else +    let ols = s:ExitingOneLineScope(lnum) +    while ols > 0 && ind > 0 +      let ind = ind - &sw +      let ols = s:InOneLineScope(ols - 1) +    endwhile +  endif + +  return ind +endfunction + +" }}}1 + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/syntax/solidity.vim b/syntax/solidity.vim new file mode 100644 index 00000000..91a57e26 --- /dev/null +++ b/syntax/solidity.vim @@ -0,0 +1,77 @@ +" Vim syntax file +" Language:     Solidity +" Maintainer:   Tomlion (qycpublic@gmail.com) +" URL:          https://github.com/tomlion/vim-solidity + +if exists("b:current_syntax") +  finish +endif + +" basic +syn keyword solKeyword           break case const continue default delete do else for if in mapping +syn keyword solKeyword           new private public return returns struct switch this var while constant +syn keyword solKeyword           modifier suicide +syn keyword solConstant          true false wei szabo finny ether +syn keyword solBuiltinType       mapping real string text msg block tx ureal address bool bytes +syn keyword solBuiltinType       int int8 int16 int24 int32 int40 int48 int56 int64 int72 int80 int88 int96 int104 int112 int120 int128 int136 int144 int152 int160 int168 int178 int184 int192 int200 int208 int216 int224 int232 int240 int248 int256 +syn keyword solBuiltinType       uint uint8 uint16 uint24 uint32 uint40 uint48 uint56 uint64 uint72 uint80 uint88 uint96 uint104 uint112 uint120 uint128 uint136 uint144 uint152 uint160 uint168 uint178 uint184 uint192 uint200 uint208 uint216 uint224 uint232 uint240 uint248 uint256 +syn keyword solBuiltinType       hash hash8 hash16 hash24 hash32 hash40 hash48 hash56 hash64 hash72 hash80 hash88 hash96 hash104 hash112 hash120 hash128 hash136 hash144 hash152 hash160 hash168 hash178 hash184 hash192 hash200 hash208 hash216 hash224 hash232 hash240 hash248 hash256 +syn keyword solBuiltinType       string1 string2 string3 string4 string5 string6 string7 string8 string9 string10 string11 string12 string13 string14 string15 string16 string17 string18 string19 string20 string21 string22 string23 string24 string25 string26 string27 string28 string29 string30 string31 string32 +syn keyword solBuiltinType       bytes1 bytes2 bytes3 bytes4 bytes5 bytes6 bytes7 bytes8 bytes9 bytes10 bytes11 bytes12 bytes13 bytes14 bytes15 bytes16 bytes17 bytes18 bytes19 bytes20 bytes21 bytes22 bytes23 bytes24 bytes25 bytes26 bytes27 bytes28 bytes29 bytes30 bytes31 bytes32 + +hi def link solKeyword           Keyword +hi def link solConstant          Constant +hi def link solBuiltinType       Type + +syn match   solOperator          /\(!\||\|&\|+\|-\|<\|>\|=\|%\|\/\|*\|\~\|\^\)/ +syn match   solNumber            /\<-\=\d\+L\=\>\|\<0[xX]\x\+\>/ +syn match   solFloat             /\<-\=\%(\d\+\.\d\+\|\d\+\.\|\.\d\+\)\%([eE][+-]\=\d\+\)\=\>/ +syn region  solString            start=+"+  skip=+\\\\\|\\$"+  end=+"+ +syn region  solString            start=+'+  skip=+\\\\\|\\$'+  end=+'+ + +hi def link solOperator          Operator +hi def link solNumber            Number +hi def link solFloat             Float +hi def link solString            String + +" Function +syn match   solFunction          /\<function\>/ nextgroup=solFuncName,solFuncArgs skipwhite +syn match   solFuncName          contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*/ nextgroup=solFuncArgs skipwhite +syn region  solFuncArgs          contained matchgroup=solFuncParens start='(' end=')' contains=solFuncArgCommas,solBuiltinType nextgroup=solFuncBlock,solFuncModifier keepend skipwhite skipempty +syn match   solFuncModifier      contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*/ skipwhite +syn match   solFuncArgCommas     contained ',' + +hi def link solFunction          Type +hi def link solFuncName          Function +hi def link solFuncModifier      Function + +" Contract +syn match   solContract          /\<contract\>/ nextgroup=solContractName skipwhite +syn match   solContractName      contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*/ nextgroup=solContractParent skipwhite +syn region  solContractParent    contained start='is' end='{' contains=solContractName,solContractNoise,solContractCommas skipwhite skipempty +syn match   solContractNoise     contained 'is' containedin=solContractParent +syn match   solContractCommas    contained ',' + +hi def link solContract          Type +hi def link solContractName      Function + +" Event +syn match   solEvent             /\<event\>/ nextgroup=solEventName,solEventArgs skipwhite +syn match   solEventName         contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*/ nextgroup=solEventArgs skipwhite +syn region  solEventArgs         contained matchgroup=solFuncParens start='(' end=')' contains=solEventArgCommas,solBuiltinType,solEventArgSpecial skipwhite skipempty +syn match   solEventArgCommas    contained ',' +syn match   solEventArgSpecial   contained 'indexed' + +hi def link solEvent             Type +hi def link solEventName         Function +hi def link solEventArgSpecial   Label + +" Comment +syn keyword solCommentTodo       TODO FIXME XXX TBD contained +syn region  solLineComment       start=+\/\/+ end=+$+ contains=solCommentTodo,@Spell +syn region  solLineComment       start=+^\s*\/\/+ skip=+\n\s*\/\/+ end=+$+ contains=solCommentTodo,@Spell fold +syn region  solComment           start="/\*"  end="\*/" contains=solCommentTodo,@Spell fold + +hi def link solCommentTodo       Comment +hi def link solLineComment       Comment +hi def link solComment           Comment | 
