From 44b3d860cb85ccb4edd52fb0dcf6a4102d12e82a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 31 May 2016 01:53:12 +0200 Subject: [PATCH] Update --- README.md | 2 +- after/ftplugin/haskell.vim | 2 +- compiler/nim.vim | 2 +- ftdetect/polyglot.vim | 66 ++++--- ftplugin/crystal.vim | 24 +++ ftplugin/javascript.vim | 3 + ftplugin/slim.vim | 12 ++ indent/ansible.vim | 2 +- indent/haskell.vim | 22 +-- indent/javascript.vim | 331 +++++++++++++++----------------- indent/nim.vim | 2 +- indent/ruby.vim | 31 ++- indent/typescript.vim | 2 +- syntax/javascript.vim | 19 +- syntax/nim.vim | 25 ++- syntax/ruby.vim | 375 ++++++++++++++++++++++++++----------- syntax/scala.vim | 6 +- syntax/slim.vim | 7 + 18 files changed, 571 insertions(+), 362 deletions(-) create mode 100644 ftplugin/slim.vim diff --git a/README.md b/README.md index 9a1b624..c7d7cf9 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ Optionally download one of the [releases](https://github.com/sheerun/vim-polyglo - [rust](https://github.com/rust-lang/rust.vim) (syntax, indent, compiler, autoload, ftplugin, ftdetect) - [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) +- [slim](https://github.com/slim-template/vim-slim) (syntax, indent, ftplugin, ftdetect) - [solidity](https://github.com/ethereum/vim-solidity) (syntax, indent, ftdetect) - [stylus](https://github.com/wavded/vim-stylus) (syntax, indent, ftplugin, ftdetect) - [swift](https://github.com/keith/swift.vim) (syntax, indent, ftplugin, ftdetect) diff --git a/after/ftplugin/haskell.vim b/after/ftplugin/haskell.vim index 766d4f8..9fa505f 100644 --- a/after/ftplugin/haskell.vim +++ b/after/ftplugin/haskell.vim @@ -1,6 +1,6 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'haskell') == -1 -setlocal comments=s1fl:{-,mb:-,ex:-},:-- +setlocal comments=s1fl:{-,mb:\ \ ,ex:-},:-- setlocal iskeyword+=' endif diff --git a/compiler/nim.vim b/compiler/nim.vim index 47886ed..c47dad0 100644 --- a/compiler/nim.vim +++ b/compiler/nim.vim @@ -13,7 +13,7 @@ endif let s:cpo_save = &cpo set cpo-=C -CompilerSet makeprg=nim\ c\ $* +CompilerSet makeprg=nim\ c\ --verbosity:0\ $*\ %:p CompilerSet errorformat= \%-GHint:\ %m, diff --git a/ftdetect/polyglot.vim b/ftdetect/polyglot.vim index 160c164..abadf07 100644 --- a/ftdetect/polyglot.vim +++ b/ftdetect/polyglot.vim @@ -198,7 +198,7 @@ au BufNewFile,BufRead *.js setf javascript au BufNewFile,BufRead *.jsm setf javascript au BufNewFile,BufRead Jakefile setf javascript fun! s:SelectJavascript() - if getline(1) =~# '^#!.*/bin/env\s\+node\>' + if getline(1) =~# '^#!.*/bin/\%(env\s\+\)\?node\>' set ft=javascript endif endfun @@ -306,7 +306,7 @@ au BufRead,BufNewFile nginx.conf set ft=nginx endif if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'nim') == -1 -au BufNewFile,BufRead *.nim set filetype=nim +au BufNewFile,BufRead *.nim,*.nims set filetype=nim endif if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'nix') == -1 @@ -356,8 +356,8 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'plantuml') == - if did_filetype() finish endif -autocmd BufRead,BufNewFile * :if getline(1) =~ '^.*startuml.*$'| setfiletype plantuml | endif -autocmd BufRead,BufNewFile *.pu,*.uml,*.plantuml set filetype=plantuml +autocmd BufRead,BufNewFile * :if getline(1) =~ '^.*startuml.*$'| setfiletype plantuml | set filetype=plantuml | endif +autocmd BufRead,BufNewFile *.pu,*.uml,*.plantuml setfiletype plantuml | set filetype=plantuml endif if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'protobuf') == -1 @@ -399,30 +399,46 @@ function! s:setf(filetype) abort let &filetype = a:filetype endif endfunction -au BufNewFile,BufRead *.rb,*.rbw,*.gemspec call s:setf('ruby') -au BufNewFile,BufRead *.builder,*.rxml,*.rjs,*.ruby call s:setf('ruby') -au BufNewFile,BufRead [rR]akefile,*.rake call s:setf('ruby') -au BufNewFile,BufRead [rR]antfile,*.rant call s:setf('ruby') -au BufNewFile,BufRead .irbrc,irbrc call s:setf('ruby') -au BufNewFile,BufRead .pryrc call s:setf('ruby') -au BufNewFile,BufRead *.ru call s:setf('ruby') -au BufNewFile,BufRead Capfile,*.cap call s:setf('ruby') -au BufNewFile,BufRead Gemfile call s:setf('ruby') -au BufNewFile,BufRead Guardfile,.Guardfile call s:setf('ruby') +func! s:StarSetf(ft) + if expand("") !~ g:ft_ignore_pat + exe 'setf ' . a:ft + endif +endfunc +au BufNewFile,BufRead *.erb,*.rhtml call s:setf('eruby') +au BufNewFile,BufRead .irbrc,irbrc call s:setf('ruby') +au BufNewFile,BufRead *.rb,*.rbw,*.gemspec call s:setf('ruby') +au BufNewFile,BufRead *.ru call s:setf('ruby') +au BufNewFile,BufRead Gemfile call s:setf('ruby') +au BufNewFile,BufRead *.builder,*.rxml,*.rjs,*.ruby call s:setf('ruby') +au BufNewFile,BufRead [rR]akefile,*.rake call s:setf('ruby') +au BufNewFile,BufRead [rR]akefile* call s:StarSetf('ruby') +au BufNewFile,BufRead [rR]antfile,*.rant call s:setf('ruby') +endif +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ruby') == -1 + +function! s:setf(filetype) abort + if &filetype !=# a:filetype + let &filetype = a:filetype + endif +endfunction +au BufNewFile,BufRead Appraisals call s:setf('ruby') +au BufNewFile,BufRead .autotest call s:setf('ruby') +au BufNewFile,BufRead [Bb]uildfile call s:setf('ruby') +au BufNewFile,BufRead Capfile,*.cap call s:setf('ruby') au BufNewFile,BufRead Cheffile call s:setf('ruby') au BufNewFile,BufRead Berksfile call s:setf('ruby') -au BufNewFile,BufRead [vV]agrantfile call s:setf('ruby') -au BufNewFile,BufRead .autotest call s:setf('ruby') -au BufNewFile,BufRead *.erb,*.rhtml call s:setf('eruby') -au BufNewFile,BufRead [tT]horfile,*.thor call s:setf('ruby') -au BufNewFile,BufRead *.rabl call s:setf('ruby') -au BufNewFile,BufRead *.jbuilder call s:setf('ruby') -au BufNewFile,BufRead Puppetfile call s:setf('ruby') -au BufNewFile,BufRead [Bb]uildfile call s:setf('ruby') -au BufNewFile,BufRead Appraisals call s:setf('ruby') au BufNewFile,BufRead Podfile,*.podspec call s:setf('ruby') +au BufNewFile,BufRead Guardfile,.Guardfile call s:setf('ruby') +au BufNewFile,BufRead *.jbuilder call s:setf('ruby') +au BufNewFile,BufRead KitchenSink call s:setf('ruby') +au BufNewFile,BufRead *.opal call s:setf('ruby') +au BufNewFile,BufRead .pryrc call s:setf('ruby') +au BufNewFile,BufRead Puppetfile call s:setf('ruby') +au BufNewFile,BufRead *.rabl call s:setf('ruby') au BufNewFile,BufRead [rR]outefile call s:setf('ruby') -au BufNewFile,BufRead .simplecov set filetype=ruby +au BufNewFile,BufRead .simplecov call s:setf('ruby) +au BufNewFile,BufRead [tT]horfile,*.thor call s:setf('ruby') +au BufNewFile,BufRead [vV]agrantfile call s:setf('ruby') endif if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'rust') == -1 @@ -445,7 +461,7 @@ au BufRead,BufNewFile *.sbt setfiletype sbt.scala endif if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'slim') == -1 -autocmd BufNewFile,BufRead *.slim set filetype=slim +autocmd BufNewFile,BufRead *.slim setf slim endif if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'solidity') == -1 diff --git a/ftplugin/crystal.vim b/ftplugin/crystal.vim index f990a8d..29aac72 100644 --- a/ftplugin/crystal.vim +++ b/ftplugin/crystal.vim @@ -40,6 +40,30 @@ setlocal errorformat= \%C%p^, \%-C%.%# +let g:crystal_compiler_command = get(g:, 'crystal_compiler_command', 'crystal') +let g:crystal_auto_format = get(g:, 'crystal_auto_format', 0) + +command! -buffer -nargs=* CrystalImpl echo crystal_lang#impl(expand('%'), getpos('.'), ).output +command! -buffer -nargs=0 CrystalDef call crystal_lang#jump_to_definition(expand('%'), getpos('.')) +command! -buffer -nargs=* CrystalContext echo crystal_lang#context(expand('%'), getpos('.'), ).output +command! -buffer -nargs=* CrystalHierarchy echo crystal_lang#type_hierarchy(expand('%'), ) +command! -buffer -nargs=? CrystalSpecSwitch call crystal_lang#switch_spec_file() +command! -buffer -nargs=? CrystalSpecRunAll call crystal_lang#run_all_spec() +command! -buffer -nargs=? CrystalSpecRunCurrent call crystal_lang#run_current_spec() +command! -buffer -nargs=* -bar CrystalFormat call crystal_lang#format() + +nnoremap (crystal-jump-to-definition) :CrystalDef +nnoremap (crystal-show-context) :CrystalContext +nnoremap (crystal-spec-switch) :CrystalSpecSwitch +nnoremap (crystal-spec-run-all) :CrystalSpecRunAll +nnoremap (crystal-spec-run-current) :CrystalSpecRunCurrent +nnoremap (crystal-format) :CrystalFormat + +augroup plugin-ft-crystal + autocmd! + autocmd BufWritePre if g:crystal_auto_format | CrystalFormat | endif +augroup END + if get(g:, 'crystal_define_mappings', 1) nmap gd (crystal-jump-to-definition) nmap gc (crystal-show-context) diff --git a/ftplugin/javascript.vim b/ftplugin/javascript.vim index f89932f..2b085bc 100644 --- a/ftplugin/javascript.vim +++ b/ftplugin/javascript.vim @@ -1,5 +1,8 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'javascript') == -1 setlocal suffixesadd+=.js +if (v:version < 704 || (v:version == 704 && !has('patch002'))) && exists('®expengine') + set re=1 +end endif diff --git a/ftplugin/slim.vim b/ftplugin/slim.vim new file mode 100644 index 0000000..b3c7118 --- /dev/null +++ b/ftplugin/slim.vim @@ -0,0 +1,12 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'slim') == -1 + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +let b:undo_ftplugin = "setl isk<" + +setlocal iskeyword+=- + +endif diff --git a/indent/ansible.vim b/indent/ansible.vim index c802186..b3a9642 100644 --- a/indent/ansible.vim +++ b/indent/ansible.vim @@ -16,7 +16,7 @@ setlocal formatoptions=cl let s:comment = '\v^\s*#' " # comment let s:array_entry = '\v^\s*-\s' " - foo -let s:named_module_entry = '\v^\s*-\s*(name|hosts):\s*\S' " - name: 'do stuff' +let s:named_module_entry = '\v^\s*-\s*(name|hosts|role):\s*\S' " - name: 'do stuff' let s:dictionary_entry = '\v^\s*[^:-]+:\s*$' " with_items: let s:key_value = '\v^\s*[^:-]+:\s*\S' " apt: name=package let s:scalar_value = '\v:\s*[>|\|]\s*$' " shell: > diff --git a/indent/haskell.vim b/indent/haskell.vim index 891e659..b2767e1 100644 --- a/indent/haskell.vim +++ b/indent/haskell.vim @@ -113,24 +113,22 @@ function! GetHaskellIndent() let l:hlstack = s:getHLStack() " do not indent in strings and quasiquotes - if index(l:hlstack, 'haskellString') > -1 || index(l:hlstack, 'haskellQuasiQuote') > -1 + if index(l:hlstack, 'haskellQuasiQuote') > -1 || index(l:hlstack, 'haskellBlockComment') > -1 return -1 endif - " blockcomment handling - if index(l:hlstack, 'haskellBlockComment') > -1 - for l:c in range(v:lnum - 1, 0, -1) - let l:line = getline(l:c) - if l:line =~ '{-' - return 1 + match(l:line, '{-') - endif - endfor - return 1 - endif - let l:prevline = getline(v:lnum - 1) let l:line = getline(v:lnum) + " indent multiline strings + if index(l:hlstack, 'haskellString') > -1 + if l:line =~ '^\s*\\' + return match(l:prevline, '["\\]') + else + return - 1 + endif + endif + " reset if l:prevline =~ '^\s*$' && l:line !~ '^\s*\S' return 0 diff --git a/indent/javascript.vim b/indent/javascript.vim index 90e84cb..68e21ed 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -19,6 +19,7 @@ setlocal nosmartindent setlocal indentexpr=GetJavascriptIndent() setlocal formatexpr=Fixedgq(v:lnum,v:count) setlocal indentkeys=0{,0},0),0],0\,:,!^F,o,O,e +setlocal cinoptions+=j1,J1 " Only define the function once. if exists("*GetJavascriptIndent") @@ -42,19 +43,17 @@ endif " 1. Variables {{{1 " ============ -let s:js_keywords = '^\s*\(break\|catch\|const\|continue\|debugger\|delete\|do\|else\|finally\|for\|function\|if\|in\|instanceof\|let\|new\|return\|switch\|this\|throw\|try\|typeof\|var\|void\|while\|with\)' -let s:expr_case = '^\s*\(case\s\+[^\:]*\|default\)\s*:\s*' +let s:line_pre = '^\s*\%(\/\*.*\*\/\s*\)*' +let s:js_keywords = s:line_pre . '\%(break\|catch\|const\|continue\|debugger\|delete\|do\|else\|finally\|for\|function\|if\|in\|instanceof\|let\|new\|return\|switch\|this\|throw\|try\|typeof\|var\|void\|while\|with\)\>\C' +let s:expr_case = s:line_pre . '\%(case\s\+[^\:]*\|default\)\s*:\s*\C' " Regex of syntax group names that are or delimit string or are comments. -let s:syng_strcom = '\%(\%(template\)\@].*,\)' . s:line_term +let s:continuation_regex = '\%([*.?:]\|+\@\|=>\)\C' . s:line_term -let s:one_line_scope_regex = '\%(\%(\\|\<\%(if\|for\|while\)\>\s*(\%([^()]*\|[^()]*(\%([^()]*\|[^()]*(\%([^()]*\|[^()]*([^()]*)[^()]*\))[^()]*\))[^()]*\))\)\|=>\)' . s:line_term +function s:Onescope(lnum) + if getline(a:lnum) =~ s:one_line_scope_regex + return 1 + end + let mypos = col('.') + call cursor(a:lnum, 1) + if search('\<\%(while\|for\|if\)\>\s*(\C', 'ce', a:lnum) > 0 && + \ searchpair('(', '', ')', 'W', s:skip_expr, a:lnum) > 0 && + \ col('.') == strlen(s:RemoveTrailingComments(getline(a:lnum))) + call cursor(a:lnum, mypos) + return 1 + else + call cursor(a:lnum, mypos) + return 0 + end +endfunction " Regex that defines blocks. -let s:block_regex = '\%([{([]\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s:line_term +let s:block_regex = '[{([]' . s:line_term -let s:operator_first = '^\s*\%([*/.:?]\|\([-+]\)\1\@!\|||\|&&\)' +let s:operator_first = s:line_pre . '\%([.,:?]\|\([-/+*]\)\%(\1\|\*\|\/\)\@!\|||\|&&\)' -let s:var_stmt = '^\s*\%(const\|let\|var\)' +let s:var_stmt = s:line_pre . '\%(const\|let\|var\)\s\+\C' -let s:comma_first = '^\s*,' -let s:comma_last = ',\s*$' +let s:comma_last = ',' . s:line_term -let s:case_indent = s:sw() -let s:case_indent_after = s:sw() -let s:m = matchlist(&cinoptions, ':\(.\)') -if (len(s:m) > 2) - let s:case_indent = s:m[1] -endif -let s:m = matchlist(&cinoptions, '=\(.\)') -if (len(s:m) > 2) - let s:case_indent_after = s:m[1] -endif " 2. Auxiliary Functions {{{1 " ====================== @@ -106,11 +107,6 @@ 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 template string. -function s:IsInTempl(lnum, col) - return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_template -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 @@ -129,15 +125,15 @@ function s:PrevNonBlankNonString(lnum) " 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 s:IsInMultilineComment(lnum, matchend(line, '/\*') - 1) + if s:IsInMultilineComment(lnum, matchend(line, '^\s*/\*') - 1) && line !~ s:line_pre . '$' if in_block let in_block = 0 else break endif - elseif !in_block && s:IsInMultilineComment(lnum, matchend(line, '\*/') - 1) + elseif !in_block && s:IsInMultilineComment(lnum, match(line, '\*/\s*$') + 1) && line !~ s:line_pre . '$' let in_block = 1 - elseif !in_block && line !~ '^\s*\%(//\).*$' && !(s:IsInStringOrComment(lnum, 1) && s:IsInStringOrComment(lnum, strlen(line))) + elseif !in_block && line !~ s:line_pre . '\%(//\).*$' && !(s:IsInStringOrComment(lnum, 1) && s:IsInStringOrComment(lnum, strlen(line))) break endif let lnum = prevnonblank(lnum - 1) @@ -154,10 +150,12 @@ function s:GetMSL(lnum, in_one_line_scope) " 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 + let col = match(line, s:continuation_regex) + 1 + let coal = match(line, s:comma_last) + 1 let line2 = getline(msl) let col2 = matchend(line2, ')') - if (col > 0 && !s:IsInStringOrComment(lnum, col)) || s:IsInString(lnum, strlen(line)) + if ((col > 0 && !s:IsInStringOrComment(lnum, col) || coal > 0 && !s:IsInStringOrComment(lnum,coal)) && + \ !s:Match(lnum, s:expr_case)) || s:IsInString(lnum, strlen(line)) let msl = lnum " if there are more closing brackets, continue from the line which has the matching opening bracket @@ -176,7 +174,7 @@ function s:GetMSL(lnum, in_one_line_scope) if a:in_one_line_scope break end - let msl_one_line = s:Match(lnum, s:one_line_scope_regex) + let msl_one_line = s:Onescope(lnum) if msl_one_line == 0 break endif @@ -187,34 +185,41 @@ function s:GetMSL(lnum, in_one_line_scope) endfunction function s:RemoveTrailingComments(content) - let single = '\/\/\(.*\)\s*$' - let multi = '\/\*\(.*\)\*\/\s*$' - return substitute(substitute(a:content, single, '', ''), multi, '', '') + let single = '\/\/\%(.*\)\s*$' + let multi = '\/\*\%(.*\)\*\/\s*$' + return substitute(substitute(substitute(a:content, single, '', ''), multi, '', ''), '\s\+$', '', '') endfunction " Find if the string is inside var statement (but not the first string) -function s:InMultiVarStatement(lnum) +function s:InMultiVarStatement(lnum, cont, prev) let lnum = s:PrevNonBlankNonString(a:lnum - 1) -" let type = synIDattr(synID(lnum, indent(lnum) + 1, 0), 'name') + " 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) - + while lnum > 0 && (s:Match(lnum, s:comma_last) ||(a:cont && getline(lnum) =~ s:line_pre . '}') || + \ s:Match(lnum,s:continuation_regex)) || (a:prev && (s:Match(a:prev, s:comma_last) || + \ s:Match(a:prev,s:continuation_regex))) " if the line is a js keyword - if (line =~ s:js_keywords) + if a:cont + call cursor(lnum,1) + if searchpair('{', '', '}', 'bW', s:skip_expr) > 0 + let lnum = line('.') + end + end + if s:Match(lnum, 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) + if s:Match(lnum, s:var_stmt) && (s:Match(lnum, s:comma_last)||s:Match(lnum,s:continuation_regex)) return lnum endif " other js keywords, not a var - return 0 + if !s:Match(lnum, s:comma_last)||!s:Match(lnum,s:continuation_regex) + return 0 + end endif - let lnum = s:PrevNonBlankNonString(lnum - 1) endwhile @@ -222,25 +227,25 @@ function s:InMultiVarStatement(lnum) return 0 endfunction -" Find line above with beginning of the var statement or returns 0 if it's not +" Find line above with beginning of the var statement or returns 0 if it's not"{{{2 " this statement -function s:GetVarIndent(lnum) - let lvar = s:InMultiVarStatement(a:lnum) - let prev_lnum = s:PrevNonBlankNonString(a:lnum - 1) +" function s:GetVarIndent(lnum) +" let lvar = s:InMultiVarStatement(a:lnum, 0,0) +" let prev_lnum = s:PrevNonBlankNonString(a:lnum - 1) - if lvar - let line = s:RemoveTrailingComments(getline(prev_lnum)) +" 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) - s:sw() - else - return indent(lvar) + s:sw() - endif - endif +" " if the previous line doesn't end in a comma, return to regular indent +" if (line !~ s:comma_last) +" return indent(prev_lnum) - s:sw() +" else +" return indent(lvar) + s:sw() +" endif +" endif - return -1 -endfunction +" return -1 +" endfunction"}}} " Check if line 'lnum' has more opening brackets than closing ones. @@ -261,7 +266,7 @@ function s:LineHasOpeningBrackets(lnum) endif let pos = match(line, '[][(){}]', pos + 1) endwhile - return (open_0 > 0 ? 1 : (open_0 == 0 ? 0 : 2)) . (open_2 > 0) . (open_4 > 0) + return (open_0 > 0 ? 1 : (open_0 == 0 ? 0 : 2)) . (open_2 > 0 ? 1 : (open_2 == 0 ? 0 : 2)) . (open_4 > 0 ? 1 : (open_4 == 0 ? 0 : 2)) endfunction function s:Match(lnum, regex) @@ -293,7 +298,9 @@ function s:IndentWithContinuation(lnum, ind, width) return msl_ind + a:width else return msl_ind - endif + end + elseif s:InMultiVarStatement(p_lnum, 0, s:PrevNonBlankNonString(p_lnum - 1)) + return indent(p_lnum) - s:sw() endif return a:ind @@ -301,7 +308,7 @@ endfunction function s:InOneLineScope(lnum) let msl = s:GetMSL(a:lnum, 1) - if msl > 0 && s:Match(msl, s:one_line_scope_regex) + if msl > 0 && s:Onescope(msl) return msl endif return 0 @@ -311,11 +318,11 @@ 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) + if s:Onescope(msl) return 0 else let prev_msl = s:GetMSL(msl - 1, 1) - if s:Match(prev_msl, s:one_line_scope_regex) + if s:Onescope(prev_msl) return prev_msl endif endif @@ -327,13 +334,12 @@ endfunction " ========================= function GetJavascriptIndent() - " 3.1. Setup {{{2 + " 3.1. Setup {{{1 " ---------- - " Set up variables for restoring position in file. Could use v:lnum here. let vcol = col('.') - " 3.2. Work on the current line {{{2 + " 3.2. Work on the current line {{{1 " ----------------------------- let ind = -1 @@ -341,117 +347,80 @@ function GetJavascriptIndent() let line = getline(v:lnum) " previous nonblank line number let prevline = prevnonblank(v:lnum - 1) - - if (line =~ s:expr_case) - if (getline(prevline) =~ s:expr_case) - return indent(prevline) - else - if (getline(prevline) =~ s:block_regex) - return indent(prevline) + s:case_indent - else - return indent(prevline) - s:case_indent_after - endif - endif + + " to not change multiline string values + if synIDattr(synID(v:lnum, 1, 1), 'name') =~? 'string\|template' && line !~ s:line_pre . '[''"`]' + return indent(v:lnum) 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) && + \ s:IsInMultilineComment(v:lnum, match(line, '\s*$')) && line !~ '^\/\*' + return cindent(v:lnum) + endif + + " single opening bracket will assume you want a c style of indenting + if s:Match(v:lnum, s:line_pre . '{' . s:line_term) + return cindent(v:lnum) + endif + + " cindent each line which has a switch label + if (line =~ s:expr_case) + return cindent(v:lnum) + endif + " 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*[],})]') + let col = matchend(line, s:line_pre . '[]})]') 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) + s: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 + let ind = s:InMultiVarStatement(line('.'), 0, 0) ? indent(line('.')) : indent(s:GetMSL(line('.'), 0)) endif return ind endif - " If the line is comma first, dedent 1 level - if (getline(prevline) =~ s:comma_first) - return indent(prevline) - s:sw() - endif - if (getline(prevline) =~ s:expr_case) - return indent(prevline) + s:case_indent_after - endif - " If line starts with an operator... - if (s:Match(v:lnum, s:operator_first)) + if (line =~ s:operator_first) if (s:Match(prevline, s:operator_first)) " and so does previous line, don't indent return indent(prevline) end let counts = s:LineHasOpeningBrackets(prevline) - if counts[0] == '2' + if counts[0] == '2' || counts[1] == '2' || counts[2] == '2' call cursor(prevline, 1) " Search for the opening tag - let mnum = searchpair('(', '', ')', 'bW', s:skip_expr) - if mnum > 0 && s:Match(mnum, s:operator_first) - return indent(mnum) + let bs = strpart('(){}[]', stridx(')}]', line[col - 1]) * 2, 2) + if searchpair(escape(bs[0], '\['), '', bs[1], 'bW', s:skip_expr) > 0 && s:Match(line('.'), s:operator_first) + return indent(line('.')) end elseif counts[0] != '1' && counts[1] != '1' && counts[2] != '1' " otherwise, indent 1 level return indent(prevline) + s:sw() end + " If previous line starts with an operator... - elseif s:Match(prevline, s:operator_first) && !s:Match(prevline, s:comma_last) && !s:Match(prevline, '};\=' . s:line_term) + elseif (s:Match(prevline, s:operator_first) && !s:Match(prevline,s:continuation_regex))||getline(prevline) =~ ');\=' . s:line_term let counts = s:LineHasOpeningBrackets(prevline) - if counts[0] == '2' && counts[1] == '1' + if counts[0] == '2' && !s:Match(prevline, s:operator_first) call cursor(prevline, 1) " Search for the opening tag let mnum = searchpair('(', '', ')', 'bW', s:skip_expr) - if mnum > 0 && !s:Match(mnum, s:operator_first) - return indent(mnum) + s:sw() + if mnum > 0 && s:Match(mnum, s:operator_first) + return indent(mnum) - s:sw() + end + elseif s:Match(prevline, s:operator_first) + if counts[0] != '1' && counts[1] != '1' && counts[2] != '1' + return indent(prevline) - s:sw() end - elseif counts[0] != '1' && counts[1] != '1' && counts[2] != '1' - return indent(prevline) - s:sw() end end - if getline(prevline) =~ '^\s*`$' && s:IsInTempl(v:lnum, 1) - if line !~ '^\s*`$' - return indent(prevline) + s:sw() - endif - elseif line =~ '^\s*`$' && s:IsInTempl(prevline, 1) - return indent(prevline) - s:sw() - 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 + " 3.3. Work on the previous line. {{{1 " ------------------------------- " If the line is empty and the previous nonblank line was a multi-line @@ -477,11 +446,7 @@ function GetJavascriptIndent() " If the previous line ended with a block opening, add a level of indent. if s:Match(lnum, s:block_regex) - if (line =~ s:expr_case) - return indent(s:GetMSL(lnum, 0)) + s:sw()/2 - else - return indent(s:GetMSL(lnum, 0)) + s:sw() - endif + return s:InMultiVarStatement(lnum, 0, 0) ? indent(lnum) + s:sw() : indent(s:GetMSL(lnum, 0)) + s:sw() endif " Set up variables for current line. @@ -489,43 +454,43 @@ function GetJavascriptIndent() let ind = indent(lnum) " 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('$') || line =~ s:one_line_scope_regex - return ind + s:sw() - else - return virtcol('.') - endif - elseif counts[1] == '1' || counts[2] == '1' && counts[0] != '2' - return ind + s:sw() - else - call cursor(v:lnum, vcol) - end - elseif line =~ '.\+};\=' . s:line_term - call cursor(lnum, 1) - " Search for the opening tag - let mnum = searchpair('{', '', '}', 'bW', s:skip_expr) - if mnum > 0 - return indent(s:GetMSL(mnum, 0)) - end - elseif line =~ '.\+);\=' || line =~ s:comma_last + if s:Match(lnum, '[[({})\]]') let counts = s:LineHasOpeningBrackets(lnum) if counts[0] == '2' call cursor(lnum, 1) " Search for the opening tag - let mnum = searchpair('(', '', ')', 'bW', s:skip_expr) - if mnum > 0 - return indent(s:GetMSL(mnum, 0)) + if searchpair('(', '', ')', 'bW', s:skip_expr) > 0 + return indent(s:GetMSL(line('.'), 0)) end - elseif line !~ s:var_stmt - return indent(prevline) + elseif counts[1] == '2' && !s:Match(lnum, s:line_pre . '}') + call cursor(lnum, 1) + " Search for the opening tag + if searchpair('{', '', '}', 'bW', s:skip_expr) > 0 + return indent(s:GetMSL(line('.'), 0)) + end + elseif counts[2] == '2' && !s:Match(lnum, s:line_pre . ']') + call cursor(lnum, 1) + " Search for the opening tag + if searchpair('\[', '', '\]', 'bW', s:skip_expr) > 0 + return indent(s:GetMSL(line('.'), 0)) + end + elseif counts[1] == '1' || counts[2] == '1' || counts[0] == '1' || s:Onescope(lnum) + return ind + s:sw() + else + call cursor(v:lnum, vcol) end end - " 3.4. Work on the MSL line. {{{2 + " 3.4. Work on the MSL line. {{{1 " -------------------------- + if s:Match(lnum, s:comma_last) && !s:Match(lnum, s:continuation_regex) + return s:Match(lnum, s:var_stmt) ? indent(lnum) + s:sw() : indent(lnum) + elseif s:Match(s:PrevNonBlankNonString(lnum - 1), s:comma_last) + if !s:Match(lnum, s:comma_last) && s:InMultiVarStatement(lnum,1,0) + return indent(lnum) - s:sw() + end + end let ind_con = ind let ind = s:IndentWithContinuation(lnum, ind_con, s:sw()) @@ -550,7 +515,7 @@ endfunction let &cpo = s:cpo_save unlet s:cpo_save - +" gq{{{2 function! Fixedgq(lnum, count) let l:tw = &tw ? &tw : 80; @@ -611,5 +576,7 @@ function! Fixedgq(lnum, count) return 0 endfunction +"}}} +" vim: foldmethod=marker:foldlevel=1 endif diff --git a/indent/nim.vim b/indent/nim.vim index a0eae56..6b4ead6 100644 --- a/indent/nim.vim +++ b/indent/nim.vim @@ -121,7 +121,7 @@ function! GetNimIndent(lnum) endif if pline =~ '\(type\|import\|const\|var\)\s*$' - \ || pline =~ '=\s*\(object\|enum\|tuple\|generic\)' + \ || pline =~ '=\s*\(object\|enum\|tuple\|concept\)' return plindent + &sw endif diff --git a/indent/ruby.vim b/indent/ruby.vim index 3feb824..da622c1 100644 --- a/indent/ruby.vim +++ b/indent/ruby.vim @@ -20,6 +20,11 @@ if !exists('g:ruby_indent_access_modifier_style') let g:ruby_indent_access_modifier_style = 'normal' endif +if !exists('g:ruby_indent_block_style') + " Possible values: "expression", "do" + let g:ruby_indent_block_style = 'expression' +endif + setlocal nosmartindent " Now, set up our indentation expression and keys that trigger it. @@ -219,15 +224,15 @@ function s:GetMSL(lnum) elseif s:Match(lnum, s:non_bracket_continuation_regex) && \ (s:Match(msl, s:bracket_continuation_regex) || s:Match(msl, s:block_continuation_regex)) " If the current line is a bracket continuation or a block-starter, but - " the previous is a non-bracket one, respect the previous' indentation, - " and stop here. + " the previous is a non-bracket one, keep going to see if the previous + " line is a part of another continuation. " " Example: " method_call one, " two { " three " - return lnum + let msl = lnum elseif s:Match(lnum, s:bracket_continuation_regex) && \ (s:Match(msl, s:bracket_continuation_regex) || s:Match(msl, s:block_continuation_regex)) " If both lines are bracket continuations (the current may also be a @@ -419,7 +424,9 @@ function GetRubyIndent(...) if searchpair(escape(bs[0], '\['), '', bs[1], 'bW', s:skip_expr) > 0 if line[col-1]==')' && col('.') != col('$') - 1 let ind = virtcol('.') - 1 - else + elseif g:ruby_indent_block_style == 'do' + let ind = indent(line('.')) + else " g:ruby_indent_block_style == 'expression' let ind = indent(s:GetMSL(line('.'))) endif endif @@ -444,12 +451,15 @@ function GetRubyIndent(...) \ strpart(line, col('.') - 1, 2) !~ 'do' " assignment to case/begin/etc, on the same line, hanging indent let ind = virtcol('.') - 1 + elseif g:ruby_indent_block_style == 'do' + " align to line of the "do", not to the MSL + let ind = indent(line('.')) elseif getline(msl) =~ '=\s*\(#.*\)\=$' - " in the case of assignment to the msl, align to the starting line, - " not to the msl + " in the case of assignment to the MSL, align to the starting line, + " not to the MSL let ind = indent(line('.')) else - " align to the msl + " align to the MSL let ind = indent(msl) endif endif @@ -516,7 +526,10 @@ function GetRubyIndent(...) if s:Match(lnum, s:block_regex) let msl = s:GetMSL(lnum) - if getline(msl) =~ '=\s*\(#.*\)\=$' + if g:ruby_indent_block_style == 'do' + " don't align to the msl, align to the "do" + let ind = indent(lnum) + sw + elseif getline(msl) =~ '=\s*\(#.*\)\=$' " in the case of assignment to the msl, align to the starting line, " not to the msl let ind = indent(lnum) + sw @@ -564,7 +577,7 @@ function GetRubyIndent(...) if s:Match(line('.'), s:ruby_indent_keywords) return indent('.') + sw else - return indent('.') + return indent(s:GetMSL(line('.'))) endif else call cursor(clnum, vcol) diff --git a/indent/typescript.vim b/indent/typescript.vim index ec4781a..ed2e6c0 100644 --- a/indent/typescript.vim +++ b/indent/typescript.vim @@ -442,7 +442,7 @@ let &cpo = s:cpo_save unlet s:cpo_save function! Fixedgq(lnum, count) - let l:tw = &tw ? &tw : 80; + let l:tw = &tw ? &tw : 80 let l:count = a:count let l:first_char = indent(a:lnum) + 1 diff --git a/syntax/javascript.vim b/syntax/javascript.vim index 274eebf..d677d01 100644 --- a/syntax/javascript.vim +++ b/syntax/javascript.vim @@ -99,7 +99,11 @@ syntax match jsRegexpOr "\v\<@!\|" contained syntax match jsRegexpMod "\v\(@<=\?[:=!>]" contained syntax cluster jsRegexpSpecial contains=jsSpecial,jsRegexpBoundary,jsRegexpBackRef,jsRegexpQuantifier,jsRegexpOr,jsRegexpMod syntax region jsRegexpGroup start="\\\@ 703 || v:version == 603 && has("patch1088") + syntax region jsRegexpString start=+\%(\%(\%(return\|case\)\s\+\)\@50<=\|\%(\%([)\]"']\|\d\|\w\)\s*\)\@50\|\<0[xX]\x\+\>/ syntax keyword jsNumber Infinity syntax match jsFloat /\<-\=\%(\d\+\.\d\+\|\d\+\.\|\.\d\+\)\%([eE][+-]\=\d\+\)\=\>/ @@ -187,9 +191,9 @@ syntax cluster jsExpression contains=jsComment,jsLineComment,jsBlockComment,jsTa syntax cluster jsAll contains=@jsExpression,jsLabel,jsConditional,jsRepeat,jsReturn,jsStatement,jsTernaryIf,jsException syntax region jsBracket matchgroup=jsBrackets start="\[" end="\]" contains=@jsAll,jsParensErrB,jsParensErrC,jsBracket,jsParen,jsBlock,@htmlPreproc fold syntax region jsParen matchgroup=jsParens start="(" end=")" contains=@jsAll,jsOf,jsParensErrA,jsParensErrC,jsParen,jsBracket,jsBlock,@htmlPreproc fold extend -syntax region jsClassBlock matchgroup=jsClassBraces start="{" end="}" contains=jsFuncName,jsClassMethodDefinitions,jsOperator,jsArrowFunction,jsArrowFuncArgs,jsComment,jsBlockComment,jsLineComment contained fold +syntax region jsClassBlock matchgroup=jsClassBraces start="{" end="}" contains=jsFuncName,jsClassMethodDefinitions,jsOperator,jsArrowFunction,jsArrowFuncArgs,jsComment,jsBlockComment,jsLineComment,jsGenerator contained fold syntax region jsFuncBlock matchgroup=jsFuncBraces start="{" end="}" contains=@jsAll,jsParensErrA,jsParensErrB,jsParen,jsBracket,jsBlock,@htmlPreproc,jsClassDefinition fold extend -syntax region jsBlock matchgroup=jsBraces start="{" end="}" contains=@jsAll,jsParensErrA,jsParensErrB,jsParen,jsBracket,jsBlock,jsObjectKey,@htmlPreproc,jsClassDefinition fold extend +syntax region jsBlock matchgroup=jsBraces start="{" end="}" contains=@jsAll,jsParensErrA,jsParensErrB,jsParen,jsBracket,jsBlock,jsObjectKey,@htmlPreproc,jsClassDefinition extend syntax region jsTernaryIf matchgroup=jsTernaryIfOperator start=+?+ end=+:+ contains=@jsExpression,jsTernaryIf "" catch errors caused by wrong parenthesis @@ -202,8 +206,11 @@ syntax match jsFuncArgDestructuring contained /\({\|}\|=\|:\|\[\|\]\)/ extend exe 'syntax match jsFunction /\/ nextgroup=jsGenerator,jsFuncName,jsFuncArgs skipwhite '.(exists('g:javascript_conceal_function') ? 'conceal cchar='.g:javascript_conceal_function : '') exe 'syntax match jsArrowFunction /=>/ skipwhite nextgroup=jsFuncBlock contains=jsFuncBraces '.(exists('g:javascript_conceal_arrow_function') ? 'conceal cchar='.g:javascript_conceal_arrow_function : '') -syntax match jsGenerator contained '\*' nextgroup=jsFuncName,jsFuncArgs skipwhite -syntax match jsFuncName contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*/ nextgroup=jsFuncArgs skipwhite +syntax match jsGenerator contained /\*/ nextgroup=jsFuncName,jsFuncArgs skipwhite skipempty +syntax match jsFuncName contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*/ nextgroup=jsFuncArgs skipwhite skipempty +" These versions of jsFuncName is for use in object declarations with no key +" syntax match jsFuncName contained /\%(^[\r\n\t ]*\)\@<=[*\r\n\t ]*[a-zA-Z_$][0-9a-zA-Z_$]*[\r\n\t ]*(\@=/ nextgroup=jsFuncArgs skipwhite skipempty containedin=jsBlock contains=jsGenerator +" syntax match jsFuncName contained /\%(,[\r\n\t ]*\)\@<=[*\r\n\t ]*[a-zA-Z_$][0-9a-zA-Z_$]*[\r\n\t ]*(\@=/ nextgroup=jsFuncArgs skipwhite skipempty containedin=jsBlock contains=jsGenerator syntax region jsFuncArgs contained matchgroup=jsFuncParens start='(' end=')' contains=jsFuncArgCommas,jsFuncArgRest,jsComment,jsLineComment,jsStringS,jsStringD,jsNumber,jsFuncArgDestructuring,jsArrowFunction,jsParen,jsArrowFuncArgs nextgroup=jsFuncBlock keepend skipwhite skipempty syntax match jsFuncArgCommas contained ',' syntax match jsFuncArgRest contained /\%(\.\.\.[a-zA-Z_$][0-9a-zA-Z_$]*\))/ contains=jsFuncArgRestDots @@ -217,7 +224,7 @@ syntax match jsArrowFuncArgs /([^()]*)\s*\(=>\)\@=/ skipempty skipwhite conta syntax keyword jsClassKeywords extends class contained syntax match jsClassNoise /\./ contained syntax keyword jsClassMethodDefinitions get set static contained nextgroup=jsFuncName skipwhite skipempty -syntax match jsClassDefinition /class [a-zA-Z_$][0-9a-zA-Z_$ \n.]*/ contains=jsClassKeywords,jsClassNoise nextgroup=jsClassBlock skipwhite skipempty +syntax match jsClassDefinition /\\%( [a-zA-Z_$][0-9a-zA-Z_$ \n.]*\)*/ contains=jsClassKeywords,jsClassNoise nextgroup=jsClassBlock skipwhite skipempty " Define the default highlighting. " For version 5.7 and earlier: only when not done already diff --git a/syntax/nim.vim b/syntax/nim.vim index 868da69..fcf0627 100644 --- a/syntax/nim.vim +++ b/syntax/nim.vim @@ -21,25 +21,29 @@ endif if !exists("nim_highlight_space_errors") let nim_highlight_space_errors = 1 endif +if !exists("nim_highlight_special_vars") + let nim_highlight_special_vars = 1 +endif if exists("nim_highlight_all") let nim_highlight_numbers = 1 let nim_highlight_builtins = 1 let nim_highlight_exceptions = 1 let nim_highlight_space_errors = 1 + let nim_highlight_special_vars = 1 endif syn region nimBrackets contained extend keepend matchgroup=Bold start=+\(\\\)\@= 508 || !exists("did_nim_syn_inits") HiLink nimComment Comment HiLink nimTodo Todo HiLink nimDecorator Define + HiLink nimSpecialVar Identifier if nim_highlight_numbers == 1 HiLink nimNumber Number diff --git a/syntax/ruby.vim b/syntax/ruby.vim index 3a6ef48..0f23fc1 100644 --- a/syntax/ruby.vim +++ b/syntax/ruby.vim @@ -11,16 +11,41 @@ if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ruby') == -1 " Thanks to perl.vim authors, and to Reimer Behrends. :-) (MN) " ---------------------------------------------------------------------------- +" Prelude {{{1 if exists("b:current_syntax") finish endif +" Folding Config {{{1 if has("folding") && exists("ruby_fold") setlocal foldmethod=syntax endif +let s:foldable_groups = split( + \ get( + \ b:, + \ 'ruby_foldable_groups', + \ get(g:, 'ruby_foldable_groups', 'ALL') + \ ) + \ ) + +function! s:foldable(...) abort + if index(s:foldable_groups, 'ALL') > -1 + return 1 + endif + + for l:i in a:000 + if index(s:foldable_groups, l:i) > -1 + return 1 + endif + endfor + + return 0 +endfunction " }}} + syn cluster rubyNotTop contains=@rubyExtendedStringSpecial,@rubyRegexpSpecial,@rubyDeclaration,rubyConditional,rubyExceptional,rubyMethodExceptional,rubyTodo +" Whitespace Errors {{{1 if exists("ruby_space_errors") if !exists("ruby_no_trail_space_error") syn match rubySpaceError display excludenl "\s\+$" @@ -30,14 +55,14 @@ if exists("ruby_space_errors") endif endif -" Operators +" Operators {{{1 if exists("ruby_operators") - syn match rubyOperator "[~!^|*/%+-]\|&\.\@!\|\%(class\s*\)\@\|<=\|\%(<\|\>\|>=\|=\@\|\*\*\|\.\.\.\|\.\.\|::" + syn match rubyOperator "[~!^|*/%+-]\|&\.\@!\|\%(class\s*\)\@\|<=\|\%(<\|\>\|>=\|=\@1\|\*\*\|\.\.\.\|\.\.\|::" syn match rubyOperator "->\|-=\|/=\|\*\*=\|\*=\|&&=\|&=\|&&\|||=\||=\|||\|%=\|+=\|!\~\|!=" - syn region rubyBracketOperator matchgroup=rubyOperator start="\%(\w[?!]\=\|[]})]\)\@<=\[\s*" end="\s*]" contains=ALLBUT,@rubyNotTop + syn region rubyBracketOperator matchgroup=rubyOperator start="\%(\w[?!]\=\|[]})]\)\@2<=\[\s*" end="\s*]" contains=ALLBUT,@rubyNotTop endif -" Expression Substitution and Backslash Notation +" Expression Substitution and Backslash Notation {{{1 syn match rubyStringEscape "\\\\\|\\[abefnrstv]\|\\\o\{1,3}\|\\x\x\{1,2}" contained display syn match rubyStringEscape "\%(\\M-\\C-\|\\C-\\M-\|\\M-\\c\|\\c\\M-\|\\c\|\\C-\|\\M-\)\%(\\\o\{1,3}\|\\x\x\{1,2}\|\\\=\S\)" contained display syn match rubyQuoteEscape "\\[\\']" contained display @@ -47,18 +72,19 @@ syn match rubyInterpolation "#\%(\$\|@@\=\)\w\+" display contained con syn match rubyInterpolationDelimiter "#\ze\%(\$\|@@\=\)\w\+" display contained syn match rubyInterpolation "#\$\%(-\w\|\W\)" display contained contains=rubyInterpolationDelimiter,rubyPredefinedVariable,rubyInvalidVariable syn match rubyInterpolationDelimiter "#\ze\$\%(-\w\|\W\)" display contained -syn region rubyNoInterpolation start="\\#{" end="}" contained +syn region rubyNoInterpolation start="\\#{" end="}" contained syn match rubyNoInterpolation "\\#{" display contained syn match rubyNoInterpolation "\\#\%(\$\|@@\=\)\w\+" display contained syn match rubyNoInterpolation "\\#\$\W" display contained -syn match rubyDelimEscape "\\[(<{\[)>}\]]" transparent display contained contains=NONE +syn match rubyDelimiterEscape "\\[(<{\[)>}\]]" transparent display contained contains=NONE syn region rubyNestedParentheses start="(" skip="\\\\\|\\)" matchgroup=rubyString end=")" transparent contained syn region rubyNestedCurlyBraces start="{" skip="\\\\\|\\}" matchgroup=rubyString end="}" transparent contained syn region rubyNestedAngleBrackets start="<" skip="\\\\\|\\>" matchgroup=rubyString end=">" transparent contained syn region rubyNestedSquareBrackets start="\[" skip="\\\\\|\\\]" matchgroup=rubyString end="\]" transparent contained +" Regular Expression Metacharacters {{{1 " These are mostly Oniguruma ready syn region rubyRegexpComment matchgroup=rubyRegexpSpecial start="(?#" skip="\\)" end=")" contained syn region rubyRegexpParens matchgroup=rubyRegexpSpecial start="(\(?:\|?<\=[=!]\|?>\|?<[a-z_]\w*>\|?[imx]*-[imx]*:\=\|\%(?#\)\@!\)" skip="\\)" end=")" contained transparent contains=@rubyRegexpSpecial @@ -81,8 +107,8 @@ syn cluster rubyStringSpecial contains=rubyInterpolation,rubyNoInterpolati syn cluster rubyExtendedStringSpecial contains=@rubyStringSpecial,rubyNestedParentheses,rubyNestedCurlyBraces,rubyNestedAngleBrackets,rubyNestedSquareBrackets syn cluster rubyRegexpSpecial contains=rubyInterpolation,rubyNoInterpolation,rubyStringEscape,rubyRegexpSpecial,rubyRegexpEscape,rubyRegexpBrackets,rubyRegexpCharClass,rubyRegexpDot,rubyRegexpQuantifier,rubyRegexpAnchor,rubyRegexpParens,rubyRegexpComment -" Numbers and ASCII Codes -syn match rubyASCIICode "\%(\w\|[]})\"'/]\)\@" display syn match rubyInteger "\%(\%(\w\|[]})\"']\s*\)\@" display syn match rubyInteger "\%(\%(\w\|[]})\"']\s*\)\@" display @@ -90,20 +116,26 @@ syn match rubyInteger "\%(\%(\w\|[]})\"']\s*\)\@" display syn match rubyFloat "\%(\%(\w\|[]})\"']\s*\)\@" display -" Identifiers +" Identifiers {{{1 syn match rubyLocalVariableOrMethod "\<[_[:lower:]][_[:alnum:]]*[?!=]\=" contains=NONE display transparent syn match rubyBlockArgument "&[_[:lower:]][_[:alnum:]]" contains=NONE display transparent syn match rubyConstant "\%(\%(^\|[^.]\)\.\s*\)\@\%(\s*(\)\@!" syn match rubyClassVariable "@@\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*" display -syn match rubyInstanceVariable "@\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*" display +syn match rubyInstanceVariable "@\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*" display syn match rubyGlobalVariable "$\%(\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\|-.\)" -syn match rubySymbol "[]})\"':]\@\|<=\|<\|===\|[=!]=\|[=!]\~\|!@\|!\|>>\|>=\|>\||\|-@\|-\|/\|\[]=\|\[]\|\*\*\|\*\|&\|%\|+@\|+\|`\)" -syn match rubySymbol "[]})\"':]\@_,;:!?/.'"@$*\&+0]\)" -syn match rubySymbol "[]})\"':]\@\@!\)\=" -syn region rubySymbol start="[]})\"':]\@\|<=\|<\|===\|[=!]=\|[=!]\~\|!@\|!\|>>\|>=\|>\||\|-@\|-\|/\|\[]=\|\[]\|\*\*\|\*\|&\|%\|+@\|+\|`\)" +syn match rubySymbol "[]})\"':]\@1_,;:!?/.'"@$*\&+0]\)" +syn match rubySymbol "[]})\"':]\@1\@!\)\=" + +if s:foldable(':') + syn region rubySymbol start="[]})\"':]\@1\%(\s*(\)*\s*(\@=" @@ -120,96 +152,172 @@ syn match rubyPredefinedVariable "$\%(DEBUG\|FILENAME\|KCODE\|LOADED_FEATURES\|L syn match rubyPredefinedConstant "\%(\%(^\|[^.]\)\.\s*\)\@\%(\s*(\)\@!" syn match rubyPredefinedConstant "\%(\%(^\|[^.]\)\.\s*\)\@\%(\s*(\)\@!" -" Normal Regular Expression -syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="\%(\%(^\|\<\%(and\|or\|while\|until\|unless\|if\|elsif\|when\|not\|then\|else\)\|[;\~=!|&(,{[<>?:*+-]\)\s*\)\@<=/" end="/[iomxneus]*" skip="\\\\\|\\/" contains=@rubyRegexpSpecial fold -syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="\%(\h\k*\s\+\)\@<=/[ \t=]\@!" end="/[iomxneus]*" skip="\\\\\|\\/" contains=@rubyRegexpSpecial fold +" Normal Regular Expression {{{1 +if s:foldable('/') + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="\%(\%(^\|\<\%(and\|or\|while\|until\|unless\|if\|elsif\|when\|not\|then\|else\)\|[;\~=!|&(,{[<>?:*+-]\)\s*\)\@<=/" end="/[iomxneus]*" skip="\\\\\|\\/" contains=@rubyRegexpSpecial fold + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="\%(\h\k*\s\+\)\@<=/[ \t=]\@!" end="/[iomxneus]*" skip="\\\\\|\\/" contains=@rubyRegexpSpecial fold +else + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="\%(\%(^\|\<\%(and\|or\|while\|until\|unless\|if\|elsif\|when\|not\|then\|else\)\|[;\~=!|&(,{[<>?:*+-]\)\s*\)\@<=/" end="/[iomxneus]*" skip="\\\\\|\\/" contains=@rubyRegexpSpecial + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="\%(\h\k*\s\+\)\@<=/[ \t=]\@!" end="/[iomxneus]*" skip="\\\\\|\\/" contains=@rubyRegexpSpecial +endif -" Generalized Regular Expression -syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1[iomxneus]*" skip="\\\\\|\\\z1" contains=@rubyRegexpSpecial fold -syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r{" end="}[iomxneus]*" skip="\\\\\|\\}" contains=@rubyRegexpSpecial fold -syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r<" end=">[iomxneus]*" skip="\\\\\|\\>" contains=@rubyRegexpSpecial,rubyNestedAngleBrackets,rubyDelimEscape fold -syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r\[" end="\][iomxneus]*" skip="\\\\\|\\\]" contains=@rubyRegexpSpecial fold -syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r(" end=")[iomxneus]*" skip="\\\\\|\\)" contains=@rubyRegexpSpecial fold -syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r\z(\s\)" end="\z1[iomxneus]*" skip="\\\\\|\\\z1" contains=@rubyRegexpSpecial fold +" Generalized Regular Expression {{{1 +if s:foldable('%') + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1[iomxneus]*" skip="\\\\\|\\\z1" contains=@rubyRegexpSpecial fold + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r{" end="}[iomxneus]*" skip="\\\\\|\\}" contains=@rubyRegexpSpecial fold + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r<" end=">[iomxneus]*" skip="\\\\\|\\>" contains=@rubyRegexpSpecial,rubyNestedAngleBrackets,rubyDelimiterEscape fold + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r\[" end="\][iomxneus]*" skip="\\\\\|\\\]" contains=@rubyRegexpSpecial fold + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r(" end=")[iomxneus]*" skip="\\\\\|\\)" contains=@rubyRegexpSpecial fold + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r\z(\s\)" end="\z1[iomxneus]*" skip="\\\\\|\\\z1" contains=@rubyRegexpSpecial fold +else + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1[iomxneus]*" skip="\\\\\|\\\z1" contains=@rubyRegexpSpecial + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r{" end="}[iomxneus]*" skip="\\\\\|\\}" contains=@rubyRegexpSpecial + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r<" end=">[iomxneus]*" skip="\\\\\|\\>" contains=@rubyRegexpSpecial,rubyNestedAngleBrackets,rubyDelimiterEscape + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r\[" end="\][iomxneus]*" skip="\\\\\|\\\]" contains=@rubyRegexpSpecial + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r(" end=")[iomxneus]*" skip="\\\\\|\\)" contains=@rubyRegexpSpecial + syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="%r\z(\s\)" end="\z1[iomxneus]*" skip="\\\\\|\\\z1" contains=@rubyRegexpSpecial +endif -" Normal String +" Normal String {{{1 let s:spell_cluster = exists('ruby_spellcheck_strings') ? ',@Spell' : '' -exe 'syn region rubyString matchgroup=rubyStringDelimiter start="\"" end="\"" skip="\\\\\|\\\"" fold contains=@rubyStringSpecial' . s:spell_cluster -exe 'syn region rubyString matchgroup=rubyStringDelimiter start="''" end="''" skip="\\\\\|\\''" fold contains=rubyQuoteEscape' . s:spell_cluster +exe 'syn region rubyString matchgroup=rubyStringDelimiter start="\"" end="\"" skip="\\\\\|\\\"" ' . + \ (s:foldable('%') ? 'fold' : '') . ' contains=@rubyStringSpecial' . s:spell_cluster +exe 'syn region rubyString matchgroup=rubyStringDelimiter start="''" end="''" skip="\\\\\|\\''" ' . + \ (s:foldable('%') ? 'fold' : '') . ' contains=rubyQuoteEscape' . s:spell_cluster -" Shell Command Output -syn region rubyString matchgroup=rubyStringDelimiter start="`" end="`" skip="\\\\\|\\`" contains=@rubyStringSpecial fold +" Shell Command Output {{{1 +if s:foldable('%') + syn region rubyString matchgroup=rubyStringDelimiter start="`" end="`" skip="\\\\\|\\`" contains=@rubyStringSpecial fold +else + syn region rubyString matchgroup=rubyStringDelimiter start="`" end="`" skip="\\\\\|\\`" contains=@rubyStringSpecial +endif -" Generalized Single Quoted String, Symbol and Array of Strings -syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" fold -syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]{" end="}" skip="\\\\\|\\}" fold contains=rubyNestedCurlyBraces,rubyDelimEscape -syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]<" end=">" skip="\\\\\|\\>" fold contains=rubyNestedAngleBrackets,rubyDelimEscape -syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]\[" end="\]" skip="\\\\\|\\\]" fold contains=rubyNestedSquareBrackets,rubyDelimEscape -syn region rubyString matchgroup=rubyStringDelimiter start="%[qw](" end=")" skip="\\\\\|\\)" fold contains=rubyNestedParentheses,rubyDelimEscape -syn region rubyString matchgroup=rubyStringDelimiter start="%q\z(\s\)" end="\z1" skip="\\\\\|\\\z1" fold -syn region rubySymbol matchgroup=rubySymbolDelimiter start="%s\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" fold -syn region rubySymbol matchgroup=rubySymbolDelimiter start="%s{" end="}" skip="\\\\\|\\}" fold contains=rubyNestedCurlyBraces,rubyDelimEscape -syn region rubySymbol matchgroup=rubySymbolDelimiter start="%s<" end=">" skip="\\\\\|\\>" fold contains=rubyNestedAngleBrackets,rubyDelimEscape -syn region rubySymbol matchgroup=rubySymbolDelimiter start="%s\[" end="\]" skip="\\\\\|\\\]" fold contains=rubyNestedSquareBrackets,rubyDelimEscape -syn region rubySymbol matchgroup=rubySymbolDelimiter start="%s(" end=")" skip="\\\\\|\\)" fold contains=rubyNestedParentheses,rubyDelimEscape -syn region rubyString matchgroup=rubyStringDelimiter start="%s\z(\s\)" end="\z1" skip="\\\\\|\\\z1" fold +" Generalized Single Quoted String, Symbol and Array of Strings {{{1 +if s:foldable('%') + syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" fold + syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]{" end="}" skip="\\\\\|\\}" fold contains=rubyNestedCurlyBraces,rubyDelimiterEscape + syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]<" end=">" skip="\\\\\|\\>" fold contains=rubyNestedAngleBrackets,rubyDelimiterEscape + syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]\[" end="\]" skip="\\\\\|\\\]" fold contains=rubyNestedSquareBrackets,rubyDelimiterEscape + syn region rubyString matchgroup=rubyStringDelimiter start="%[qw](" end=")" skip="\\\\\|\\)" fold contains=rubyNestedParentheses,rubyDelimiterEscape + syn region rubyString matchgroup=rubyStringDelimiter start="%q\z(\s\)" end="\z1" skip="\\\\\|\\\z1" fold + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%s\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" fold + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%s{" end="}" skip="\\\\\|\\}" fold contains=rubyNestedCurlyBraces,rubyDelimiterEscape + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%s<" end=">" skip="\\\\\|\\>" fold contains=rubyNestedAngleBrackets,rubyDelimiterEscape + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%s\[" end="\]" skip="\\\\\|\\\]" fold contains=rubyNestedSquareBrackets,rubyDelimiterEscape + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%s(" end=")" skip="\\\\\|\\)" fold contains=rubyNestedParentheses,rubyDelimiterEscape + syn region rubyString matchgroup=rubyStringDelimiter start="%s\z(\s\)" end="\z1" skip="\\\\\|\\\z1" fold +else + syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" + syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]{" end="}" skip="\\\\\|\\}" contains=rubyNestedCurlyBraces,rubyDelimiterEscape + syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]<" end=">" skip="\\\\\|\\>" contains=rubyNestedAngleBrackets,rubyDelimiterEscape + syn region rubyString matchgroup=rubyStringDelimiter start="%[qw]\[" end="\]" skip="\\\\\|\\\]" contains=rubyNestedSquareBrackets,rubyDelimiterEscape + syn region rubyString matchgroup=rubyStringDelimiter start="%[qw](" end=")" skip="\\\\\|\\)" contains=rubyNestedParentheses,rubyDelimiterEscape + syn region rubyString matchgroup=rubyStringDelimiter start="%q\z(\s\)" end="\z1" skip="\\\\\|\\\z1" + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%s\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%s{" end="}" skip="\\\\\|\\}" contains=rubyNestedCurlyBraces,rubyDelimiterEscape + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%s<" end=">" skip="\\\\\|\\>" contains=rubyNestedAngleBrackets,rubyDelimiterEscape + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%s\[" end="\]" skip="\\\\\|\\\]" contains=rubyNestedSquareBrackets,rubyDelimiterEscape + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%s(" end=")" skip="\\\\\|\\)" contains=rubyNestedParentheses,rubyDelimiterEscape + syn region rubyString matchgroup=rubyStringDelimiter start="%s\z(\s\)" end="\z1" skip="\\\\\|\\\z1" +endif -" Generalized Double Quoted String and Array of Strings and Shell Command Output +" Generalized Double Quoted String and Array of Strings and Shell Command Output {{{1 " Note: %= is not matched here as the beginning of a double quoted string -syn region rubyString matchgroup=rubyStringDelimiter start="%\z([~`!@#$%^&*_\-+|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial fold -syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial fold -syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\={" end="}" skip="\\\\\|\\}" contains=@rubyStringSpecial,rubyNestedCurlyBraces,rubyDelimEscape fold -syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\=<" end=">" skip="\\\\\|\\>" contains=@rubyStringSpecial,rubyNestedAngleBrackets,rubyDelimEscape fold -syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\=\[" end="\]" skip="\\\\\|\\\]" contains=@rubyStringSpecial,rubyNestedSquareBrackets,rubyDelimEscape fold -syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\=(" end=")" skip="\\\\\|\\)" contains=@rubyStringSpecial,rubyNestedParentheses,rubyDelimEscape fold -syn region rubyString matchgroup=rubyStringDelimiter start="%[Qx]\z(\s\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial fold +if s:foldable('%') + syn region rubyString matchgroup=rubyStringDelimiter start="%\z([~`!@#$%^&*_\-+|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial fold + syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial fold + syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\={" end="}" skip="\\\\\|\\}" contains=@rubyStringSpecial,rubyNestedCurlyBraces,rubyDelimiterEscape fold + syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\=<" end=">" skip="\\\\\|\\>" contains=@rubyStringSpecial,rubyNestedAngleBrackets,rubyDelimiterEscape fold + syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\=\[" end="\]" skip="\\\\\|\\\]" contains=@rubyStringSpecial,rubyNestedSquareBrackets,rubyDelimiterEscape fold + syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\=(" end=")" skip="\\\\\|\\)" contains=@rubyStringSpecial,rubyNestedParentheses,rubyDelimiterEscape fold + syn region rubyString matchgroup=rubyStringDelimiter start="%[Qx]\z(\s\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial fold +else + syn region rubyString matchgroup=rubyStringDelimiter start="%\z([~`!@#$%^&*_\-+|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial + syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial + syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\={" end="}" skip="\\\\\|\\}" contains=@rubyStringSpecial,rubyNestedCurlyBraces,rubyDelimiterEscape + syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\=<" end=">" skip="\\\\\|\\>" contains=@rubyStringSpecial,rubyNestedAngleBrackets,rubyDelimiterEscape + syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\=\[" end="\]" skip="\\\\\|\\\]" contains=@rubyStringSpecial,rubyNestedSquareBrackets,rubyDelimiterEscape + syn region rubyString matchgroup=rubyStringDelimiter start="%[QWx]\=(" end=")" skip="\\\\\|\\)" contains=@rubyStringSpecial,rubyNestedParentheses,rubyDelimiterEscape + syn region rubyString matchgroup=rubyStringDelimiter start="%[Qx]\z(\s\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial +endif -" Array of Symbols -syn region rubySymbol matchgroup=rubySymbolDelimiter start="%i\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" fold -syn region rubySymbol matchgroup=rubySymbolDelimiter start="%i{" end="}" skip="\\\\\|\\}" fold contains=rubyNestedCurlyBraces,rubyDelimEscape -syn region rubySymbol matchgroup=rubySymbolDelimiter start="%i<" end=">" skip="\\\\\|\\>" fold contains=rubyNestedAngleBrackets,rubyDelimEscape -syn region rubySymbol matchgroup=rubySymbolDelimiter start="%i\[" end="\]" skip="\\\\\|\\\]" fold contains=rubyNestedSquareBrackets,rubyDelimEscape -syn region rubySymbol matchgroup=rubySymbolDelimiter start="%i(" end=")" skip="\\\\\|\\)" fold contains=rubyNestedParentheses,rubyDelimEscape +" Array of Symbols {{{1 +if s:foldable('%') + " Array of Symbols + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%i\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" fold + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%i{" end="}" skip="\\\\\|\\}" fold contains=rubyNestedCurlyBraces,rubyDelimiterEscape + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%i<" end=">" skip="\\\\\|\\>" fold contains=rubyNestedAngleBrackets,rubyDelimiterEscape + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%i\[" end="\]" skip="\\\\\|\\\]" fold contains=rubyNestedSquareBrackets,rubyDelimiterEscape + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%i(" end=")" skip="\\\\\|\\)" fold contains=rubyNestedParentheses,rubyDelimiterEscape -" Array of interpolated Symbols -syn region rubySymbol matchgroup=rubySymbolDelimiter start="%I\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial fold -syn region rubySymbol matchgroup=rubySymbolDelimiter start="%I{" end="}" skip="\\\\\|\\}" contains=@rubyStringSpecial,rubyNestedCurlyBraces,rubyDelimEscape fold -syn region rubySymbol matchgroup=rubySymbolDelimiter start="%I<" end=">" skip="\\\\\|\\>" contains=@rubyStringSpecial,rubyNestedAngleBrackets,rubyDelimEscape fold -syn region rubySymbol matchgroup=rubySymbolDelimiter start="%I\[" end="\]" skip="\\\\\|\\\]" contains=@rubyStringSpecial,rubyNestedSquareBrackets,rubyDelimEscape fold -syn region rubySymbol matchgroup=rubySymbolDelimiter start="%I(" end=")" skip="\\\\\|\\)" contains=@rubyStringSpecial,rubyNestedParentheses,rubyDelimEscape fold + " Array of interpolated Symbols + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%I\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial fold + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%I{" end="}" skip="\\\\\|\\}" contains=@rubyStringSpecial,rubyNestedCurlyBraces,rubyDelimiterEscape fold + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%I<" end=">" skip="\\\\\|\\>" contains=@rubyStringSpecial,rubyNestedAngleBrackets,rubyDelimiterEscape fold + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%I\[" end="\]" skip="\\\\\|\\\]" contains=@rubyStringSpecial,rubyNestedSquareBrackets,rubyDelimiterEscape fold + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%I(" end=")" skip="\\\\\|\\)" contains=@rubyStringSpecial,rubyNestedParentheses,rubyDelimiterEscape fold +else + " Array of Symbols + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%i\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%i{" end="}" skip="\\\\\|\\}" contains=rubyNestedCurlyBraces,rubyDelimiterEscape + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%i<" end=">" skip="\\\\\|\\>" contains=rubyNestedAngleBrackets,rubyDelimiterEscape + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%i\[" end="\]" skip="\\\\\|\\\]" contains=rubyNestedSquareBrackets,rubyDelimiterEscape + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%i(" end=")" skip="\\\\\|\\)" contains=rubyNestedParentheses,rubyDelimiterEscape -" Here Document + " Array of interpolated Symbols + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%I\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%I{" end="}" skip="\\\\\|\\}" contains=@rubyStringSpecial,rubyNestedCurlyBraces,rubyDelimiterEscape + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%I<" end=">" skip="\\\\\|\\>" contains=@rubyStringSpecial,rubyNestedAngleBrackets,rubyDelimiterEscape + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%I\[" end="\]" skip="\\\\\|\\\]" contains=@rubyStringSpecial,rubyNestedSquareBrackets,rubyDelimiterEscape + syn region rubySymbol matchgroup=rubySymbolDelimiter start="%I(" end=")" skip="\\\\\|\\)" contains=@rubyStringSpecial,rubyNestedParentheses,rubyDelimiterEscape +endif + +" Here Document {{{1 syn region rubyHeredocStart matchgroup=rubyStringDelimiter start=+\%(\%(class\s*\|\%([]})"'.]\|::\)\)\_s*\|\w\)\@>\|[<>]=\=\|<=>\|===\|[=!]=\|[=!]\~\|!\|`\)\%([[:space:];#(]\|$\)\@=" contained containedin=rubyAliasDeclaration,rubyAliasDeclaration2,rubyMethodDeclaration +syn match rubyFunction "\%(\s\|^\)\@1<=[_[:alpha:]][_[:alnum:]]*[?!=]\=\%(\s\|$\)\@=" contained containedin=rubyAliasDeclaration,rubyAliasDeclaration2 +syn match rubyFunction "\%([[:space:].]\|^\)\@2<=\%(\[\]=\=\|\*\*\|[-+!~]@\=\|[*/%|&^~]\|<<\|>>\|[<>]=\=\|<=>\|===\|[=!]=\|[=!]\~\|!\|`\)\%([[:space:];#(]\|$\)\@=" contained containedin=rubyAliasDeclaration,rubyAliasDeclaration2,rubyMethodDeclaration syn cluster rubyDeclaration contains=rubyAliasDeclaration,rubyAliasDeclaration2,rubyMethodDeclaration,rubyModuleDeclaration,rubyClassDeclaration,rubyFunction,rubyBlockParameter -" Keywords +" Keywords {{{1 " Note: the following keywords have already been defined: " begin case class def do end for if module unless until while syn match rubyControl "\<\%(and\|break\|in\|next\|not\|or\|redo\|rescue\|retry\|return\)\>[?!]\@!" @@ -219,8 +327,9 @@ syn match rubyBoolean "\<\%(true\|false\)\>[?!]\@!" syn match rubyPseudoVariable "\<\%(nil\|self\|__ENCODING__\|__dir__\|__FILE__\|__LINE__\|__callee__\|__method__\)\>[?!]\@!" " TODO: reorganise syn match rubyBeginEnd "\<\%(BEGIN\|END\)\>[?!]\@!" -" Expensive Mode - match 'end' with the appropriate opening keyword for syntax -" based folding and special highlighting of module/class/method definitions +" Expensive Mode {{{1 +" Match 'end' with the appropriate opening keyword for syntax based folding +" and special highlighting of module/class/method definitions if !exists("b:ruby_no_expensive") && !exists("ruby_no_expensive") syn match rubyDefine "\" nextgroup=rubyAliasDeclaration skipwhite skipnl syn match rubyDefine "\" nextgroup=rubyMethodDeclaration skipwhite skipnl @@ -228,23 +337,66 @@ if !exists("b:ruby_no_expensive") && !exists("ruby_no_expensive") syn match rubyClass "\" nextgroup=rubyClassDeclaration skipwhite skipnl syn match rubyModule "\" nextgroup=rubyModuleDeclaration skipwhite skipnl - syn region rubyMethodBlock start="\" matchgroup=rubyDefine end="\%(\" contains=ALLBUT,@rubyNotTop fold - syn region rubyBlock start="\" matchgroup=rubyClass end="\" contains=ALLBUT,@rubyNotTop fold - syn region rubyBlock start="\" matchgroup=rubyModule end="\" contains=ALLBUT,@rubyNotTop fold + if s:foldable('def') + syn region rubyMethodBlock start="\" matchgroup=rubyDefine end="\%(\" contains=ALLBUT,@rubyNotTop fold + else + syn region rubyMethodBlock start="\" matchgroup=rubyDefine end="\%(\" contains=ALLBUT,@rubyNotTop + endif + + if s:foldable('class') + syn region rubyBlock start="\" matchgroup=rubyClass end="\" contains=ALLBUT,@rubyNotTop fold + else + syn region rubyBlock start="\" matchgroup=rubyClass end="\" contains=ALLBUT,@rubyNotTop + endif + + if s:foldable('module') + syn region rubyBlock start="\" matchgroup=rubyModule end="\" contains=ALLBUT,@rubyNotTop fold + else + syn region rubyBlock start="\" matchgroup=rubyModule end="\" contains=ALLBUT,@rubyNotTop + endif " modifiers - syn match rubyConditionalModifier "\<\%(if\|unless\)\>" display - syn match rubyRepeatModifier "\<\%(while\|until\)\>" display + syn match rubyLineContinuation "\\$" nextgroup=rubyConditionalModifier,rubyRepeatModifier skipwhite skipnl + syn match rubyConditionalModifier "\<\%(if\|unless\)\>" + syn match rubyRepeatModifier "\<\%(while\|until\)\>" + + if s:foldable('do') + syn region rubyDoBlock matchgroup=rubyControl start="\" end="\" contains=ALLBUT,@rubyNotTop fold + else + syn region rubyDoBlock matchgroup=rubyControl start="\" end="\" contains=ALLBUT,@rubyNotTop + endif - syn region rubyDoBlock matchgroup=rubyControl start="\" end="\" contains=ALLBUT,@rubyNotTop fold " curly bracket block or hash literal - syn region rubyCurlyBlock matchgroup=rubyCurlyBlockDelimiter start="{" end="}" contains=ALLBUT,@rubyNotTop fold - syn region rubyArrayLiteral matchgroup=rubyArrayDelimiter start="\%(\w\|[\]})]\)\@" end="\" contains=ALLBUT,@rubyNotTop fold - syn region rubyCaseExpression matchgroup=rubyConditional start="\" end="\" contains=ALLBUT,@rubyNotTop fold - syn region rubyConditionalExpression matchgroup=rubyConditional start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*%&^|+=-]\|\%(\<[_[:lower:]][_[:alnum:]]*\)\@" end="\%(\%(\%(\.\@" contains=ALLBUT,@rubyNotTop fold + if s:foldable('begin') + syn region rubyBlockExpression matchgroup=rubyControl start="\" end="\" contains=ALLBUT,@rubyNotTop fold + else + syn region rubyBlockExpression matchgroup=rubyControl start="\" end="\" contains=ALLBUT,@rubyNotTop + endif + + if s:foldable('case') + syn region rubyCaseExpression matchgroup=rubyConditional start="\" end="\" contains=ALLBUT,@rubyNotTop fold + else + syn region rubyCaseExpression matchgroup=rubyConditional start="\" end="\" contains=ALLBUT,@rubyNotTop + endif + + if s:foldable('if') + syn region rubyConditionalExpression matchgroup=rubyConditional start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*%&^|+=-]\|\%(\<[_[:lower:]][_[:alnum:]]*\)\@" end="\%(\%(\%(\.\@1" contains=ALLBUT,@rubyNotTop fold + else + syn region rubyConditionalExpression matchgroup=rubyConditional start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*%&^|+=-]\|\%(\<[_[:lower:]][_[:alnum:]]*\)\@" end="\%(\%(\%(\.\@1" contains=ALLBUT,@rubyNotTop + endif syn match rubyConditional "\<\%(then\|else\|when\)\>[?!]\@!" contained containedin=rubyCaseExpression syn match rubyConditional "\<\%(then\|else\|elsif\)\>[?!]\@!" contained containedin=rubyConditionalExpression @@ -254,7 +406,12 @@ if !exists("b:ruby_no_expensive") && !exists("ruby_no_expensive") " statements with optional 'do' syn region rubyOptionalDoLine matchgroup=rubyRepeat start="\[?!]\@!" start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+-]\|\%(\<[_[:lower:]][_[:alnum:]]*\)\@" matchgroup=rubyOptionalDo end="\%(\\)" end="\ze\%(;\|$\)" oneline contains=ALLBUT,@rubyNotTop - syn region rubyRepeatExpression start="\[?!]\@!" start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+-]\|\%(\<[_[:lower:]][_[:alnum:]]*\)\@" matchgroup=rubyRepeat end="\" contains=ALLBUT,@rubyNotTop nextgroup=rubyOptionalDoLine fold + + if s:foldable('for') + syn region rubyRepeatExpression start="\[?!]\@!" start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+-]\|\%(\<[_[:lower:]][_[:alnum:]]*\)\@" matchgroup=rubyRepeat end="\" contains=ALLBUT,@rubyNotTop nextgroup=rubyOptionalDoLine fold + else + syn region rubyRepeatExpression start="\[?!]\@!" start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+-]\|\%(\<[_[:lower:]][_[:alnum:]]*\)\@" matchgroup=rubyRepeat end="\" contains=ALLBUT,@rubyNotTop nextgroup=rubyOptionalDoLine + endif if !exists("ruby_minlines") let ruby_minlines = 500 @@ -269,7 +426,7 @@ else syn match rubyKeyword "\<\%(alias\|undef\)\>[?!]\@!" endif -" Special Methods +" Special Methods {{{1 if !exists("ruby_no_special_methods") syn keyword rubyAccess public protected private public_class_method private_class_method public_constant private_constant module_function " attr is a common variable name @@ -284,41 +441,36 @@ if !exists("ruby_no_special_methods") syn keyword rubyKeyword callcc caller lambda proc endif -" Comments and Documentation +" Comments and Documentation {{{1 syn match rubySharpBang "\%^#!.*" display syn keyword rubyTodo FIXME NOTE TODO OPTIMIZE HACK REVIEW XXX todo contained syn match rubyComment "#.*" contains=rubySharpBang,rubySpaceError,rubyTodo,@Spell -if !exists("ruby_no_comment_fold") +if !exists("ruby_no_comment_fold") && s:foldable('#') syn region rubyMultilineComment start="^\s*#.*\n\%(^\s*#\)\@=" end="^\s*#.*\n\%(^\s*#\)\@!" contains=rubyComment transparent fold keepend syn region rubyDocumentation start="^=begin\ze\%(\s.*\)\=$" end="^=end\%(\s.*\)\=$" contains=rubySpaceError,rubyTodo,@Spell fold else syn region rubyDocumentation start="^=begin\s*$" end="^=end\s*$" contains=rubySpaceError,rubyTodo,@Spell endif +" Keyword Nobbling {{{1 " Note: this is a hack to prevent 'keywords' being highlighted as such when called as methods with an explicit receiver -syn match rubyKeywordAsMethod "\%(\%(\.\@" transparent contains=NONE -syn match rubyKeywordAsMethod "\%(\%(\.\@" transparent contains=NONE -syn match rubyKeywordAsMethod "\%(\%(\.\@" transparent contains=NONE -syn match rubyKeywordAsMethod "\%(\%(\.\@" transparent contains=NONE - -syn match rubyKeywordAsMethod "\<\%(alias\|begin\|case\|class\|def\|do\|end\)[?!]" transparent contains=NONE -syn match rubyKeywordAsMethod "\<\%(if\|module\|refine\|undef\|unless\|until\|while\)[?!]" transparent contains=NONE - -syn match rubyKeywordAsMethod "\%(\%(\.\@" transparent contains=NONE -syn match rubyKeywordAsMethod "\%(\%(\.\@" transparent contains=NONE -syn match rubyKeywordAsMethod "\%(\%(\.\@" transparent contains=NONE -syn match rubyKeywordAsMethod "\%(\%(\.\@" transparent contains=NONE -syn match rubyKeywordAsMethod "\%(\%(\.\@" transparent contains=NONE -syn match rubyKeywordAsMethod "\%(\%(\.\@" transparent contains=NONE +syn match rubyKeywordAsMethod "\%(\%(\.\@1\)" transparent contains=NONE +syn match rubyKeywordAsMethod "\(defined?\|exit!\)\@!\<[_[:lower:]][_[:alnum:]]*[?!]" transparent contains=NONE +" More Symbols {{{1 syn match rubySymbol "\%([{(,]\_s*\)\@<=\l\w*[!?]\=::\@!"he=e-1 -syn match rubySymbol "[]})\"':]\@\|⇒\|<-\|←\|->\|→\)" -syn match scalaSpecial /`[^`]*`/ " Backtick literals +syn match scalaSpecial /`[^`]\+`/ " Backtick literals hi link scalaSpecial PreProc syn keyword scalaExternal package import @@ -188,8 +188,8 @@ hi link scalaTypeAnnotationParameter Function syn match scalaShebang "\%^#!.*" display syn region scalaMultilineComment start="/\*" end="\*/" contains=scalaMultilineComment,scalaDocLinks,scalaParameterAnnotation,scalaCommentAnnotation,scalaTodo,scalaCommentCodeBlock,@Spell keepend fold syn match scalaCommentAnnotation "@[_A-Za-z0-9$]\+" contained -syn match scalaParameterAnnotation "@param" nextgroup=scalaParamAnnotationValue skipwhite contained -syn match scalaParamAnnotationValue /[`_A-Za-z0-9$]\+/ contained +syn match scalaParameterAnnotation "\%(@tparam\|@param\|@see\)" nextgroup=scalaParamAnnotationValue skipwhite contained +syn match scalaParamAnnotationValue /[.`_A-Za-z0-9$]\+/ contained syn region scalaDocLinks start="\[\[" end="\]\]" contained syn region scalaCommentCodeBlock matchgroup=Keyword start="{{{" end="}}}" contained syn match scalaTodo "\vTODO|FIXME|XXX" contained diff --git a/syntax/slim.vim b/syntax/slim.vim index 995186c..3f33e17 100644 --- a/syntax/slim.vim +++ b/syntax/slim.vim @@ -68,6 +68,12 @@ syn region slimInterpolation matchgroup=slimInterpolationDelimiter start="#{" en syn region slimInterpolation matchgroup=slimInterpolationDelimiter start="#{{" end="}}" contains=@hamlRubyTop containedin=javascriptStringS,javascriptStringD,slimWrappedAttrs syn match slimInterpolationEscape "\\\@