]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
Update a few runtime files.
authorBram Moolenaar <Bram@vim.org>
Mon, 9 Dec 2019 22:11:18 +0000 (23:11 +0100)
committerBram Moolenaar <Bram@vim.org>
Mon, 9 Dec 2019 22:11:18 +0000 (23:11 +0100)
runtime/autoload/rubycomplete.vim
runtime/doc/pi_logipat.txt
runtime/doc/pi_netrw.txt
runtime/doc/todo.txt
runtime/doc/version8.txt
runtime/ftplugin/ruby.vim
runtime/indent/ruby.vim
runtime/syntax/ruby.vim

index ea184702326c6fac3cc1a85078e8cc6686aa9304..e8a1879668979818ae313b7d8ac6ac2e3b286b91 100644 (file)
@@ -3,7 +3,7 @@
 " Maintainer:          Mark Guzman <segfault@hasno.info>
 " URL:                 https://github.com/vim-ruby/vim-ruby
 " Release Coordinator: Doug Kearns <dougkearns@gmail.com>
-" Last Change:         2019 Jan 06
+" Last Change:         2019 Feb 25
 " ----------------------------------------------------------------------------
 "
 " Ruby IRB/Complete author: Keiju ISHITSUKA(keiju@ishitsuka.com)
@@ -53,6 +53,23 @@ if !exists("g:rubycomplete_include_objectspace")
 endif
 " }}} configuration failsafe initialization
 
+" {{{ regex patterns
+
+" Regex that defines the start-match for the 'end' keyword.
+let s:end_start_regex =
+      \ '\C\%(^\s*\|[=,*/%+\-|;{]\|<<\|>>\|:\s\)\s*\zs' .
+      \ '\<\%(module\|class\|if\|for\|while\|until\|case\|unless\|begin' .
+      \   '\|\%(\K\k*[!?]\?\s\+\)\=def\):\@!\>' .
+      \ '\|\%(^\|[^.:@$]\)\@<=\<do:\@!\>'
+
+" Regex that defines the middle-match for the 'end' keyword.
+let s:end_middle_regex = '\<\%(ensure\|else\|\%(\%(^\|;\)\s*\)\@<=\<rescue:\@!\>\|when\|elsif\):\@!\>'
+
+" Regex that defines the end-match for the 'end' keyword.
+let s:end_end_regex = '\%(^\|[^.:@$]\)\@<=\<end:\@!\>'
+
+" }}} regex patterns
+
 " {{{ vim-side support functions
 let s:rubycomplete_debug = 0
 
@@ -103,7 +120,7 @@ function! s:GetBufferRubyEntity( name, type, ... )
     endif
 
     let curpos = getpos(".")
-    let [enum,ecol] = searchpairpos( crex, '', '\(end\|}\)', 'W' )
+    let [enum,ecol] = searchpairpos( s:end_start_regex, s:end_middle_regex, s:end_end_regex, 'W' )
     call cursor(lastpos[1], lastpos[2])
 
     if lnum > enum
@@ -128,19 +145,28 @@ function! s:IsPosInClassDef(pos)
     return ret
 endfunction
 
+function! s:IsInComment(pos)
+    let stack = synstack(a:pos[0], a:pos[1])
+    if !empty(stack)
+        return synIDattr(stack[0], 'name') =~ 'ruby\%(.*Comment\|Documentation\)'
+    else
+        return 0
+    endif
+endfunction
+
 function! s:GetRubyVarType(v)
     let stopline = 1
     let vtp = ''
-    let pos = getpos('.')
+    let curpos = getpos('.')
     let sstr = '^\s*#\s*@var\s*'.escape(a:v, '*').'\>\s\+[^ \t]\+\s*$'
     let [lnum,lcol] = searchpos(sstr,'nb',stopline)
     if lnum != 0 && lcol != 0
-        call setpos('.',pos)
+        call setpos('.',curpos)
         let str = getline(lnum)
         let vtp = substitute(str,sstr,'\1','')
         return vtp
     endif
-    call setpos('.',pos)
+    call setpos('.',curpos)
     let ctors = '\(now\|new\|open\|get_instance'
     if exists('g:rubycomplete_rails') && g:rubycomplete_rails == 1 && s:rubycomplete_rails_loaded == 1
         let ctors = ctors.'\|find\|create'
@@ -150,9 +176,13 @@ function! s:GetRubyVarType(v)
 
     let fstr = '=\s*\([^ \t]\+.' . ctors .'\>\|[\[{"''/]\|%[xwQqr][(\[{@]\|[A-Za-z0-9@:\-()\.]\+...\?\|lambda\|&\)'
     let sstr = ''.escape(a:v, '*').'\>\s*[+\-*/]*'.fstr
-    let [lnum,lcol] = searchpos(sstr,'nb',stopline)
-    if lnum != 0 && lcol != 0
-        let str = matchstr(getline(lnum),fstr,lcol)
+    let pos = searchpos(sstr,'bW')
+    while pos != [0,0] && s:IsInComment(pos)
+        let pos = searchpos(sstr,'bW')
+    endwhile
+    if pos != [0,0]
+        let [lnum, col] = pos
+        let str = matchstr(getline(lnum),fstr,col)
         let str = substitute(str,'^=\s*','','')
 
         call setpos('.',pos)
@@ -174,7 +204,7 @@ function! s:GetRubyVarType(v)
         end
         return ''
     endif
-    call setpos('.',pos)
+    call setpos('.',curpos)
     return ''
 endfunction
 
@@ -671,11 +701,10 @@ class VimRubyCompletion
           methods.delete_if { |c| c.match( /'/ ) }
         end
 
-      when /^::([A-Z][^:\.\(]*)$/ # Absolute Constant or class methods
+      when /^::([A-Z][^:\.\(]*)?$/ # Absolute Constant or class methods
         dprint "const or cls"
         receiver = $1
-        methods = Object.constants
-        methods.grep(/^#{receiver}/).collect{|e| "::" + e}
+        methods = Object.constants.collect{ |c| c.to_s }.grep(/^#{receiver}/)
 
       when /^(((::)?[A-Z][^:.\(]*)+?)::?([^:.]*)$/ # Constant or class methods
         receiver = $1
@@ -684,13 +713,13 @@ class VimRubyCompletion
         load_buffer_class( receiver )
         load_buffer_module( receiver )
         begin
-          classes = eval("#{receiver}.constants")
-          #methods = eval("#{receiver}.methods")
+          constants = eval("#{receiver}.constants").collect{ |c| c.to_s }.grep(/^#{message}/)
+          methods = eval("#{receiver}.methods").collect{ |m| m.to_s }.grep(/^#{message}/)
         rescue Exception
           dprint "exception: %s" % $!
+          constants = []
           methods = []
         end
-        methods.grep(/^#{message}/).collect{|e| receiver + "::" + e}
 
       when /^(:[^:.]+)\.([^.]*)$/ # Symbol
         dprint "symbol"
index 8d33a565acb35f9cc66905636dadce24765514c0..23db48700eece025464792fd1beb4a755d86ab1f 100644 (file)
@@ -41,7 +41,6 @@ Copyright: (c) 2004-2015 by Charles E. Campbell       *logiPat-copyright*
                is performed and echoed onto the display.
 
        :LogiPatFlags {search flags}                    *LogiPat-flags*
-               :LogiPatFlags {search flags}
                LogiPat uses the |search()| command.  The flags
                passed to that call to search() may be specified
                by the :LogiPatFlags command.
@@ -105,7 +104,7 @@ Copyright: (c) 2004-2015 by Charles E. Campbell     *logiPat-copyright*
 
 
 ==============================================================================
-3. LogiPat History                                     *logiPat-history*
+5. LogiPat History                                     *logiPat-history*
 
        v4 Jun 22, 2015 * LogiPat has been picked up by Bram M for standard
                          plugin distribution; hence the name change
index 94dbfa550330d0c611bb20c04750f531f9ff7cc9..c271c5f0f67e0e1cf281db71241c540f15f37889 100644 (file)
@@ -1,4 +1,4 @@
-*pi_netrw.txt*  For Vim version 8.1.  Last change: 2019 Nov 30
+*pi_netrw.txt*  For Vim version 8.1.  Last change: 2019 Dec 09
 
            ------------------------------------------------
            NETRW REFERENCE MANUAL    by Charles E. Campbell
@@ -1184,7 +1184,7 @@ One may easily "bookmark" the currently browsed directory by using >
                                                                *.netrwbook*
 Bookmarks are retained in between sessions of vim in a file called .netrwbook
 as a |List|, which is typically stored in the first directory on the user's
-|'runtimepath'|; entries are kept in sorted order.
+runtimepath'; entries are kept in sorted order.
 
 If there are marked files and/or directories, mb will add them to the bookmark
 list.
index f709155ccd11f9e9260d3a663840f8fa5315707f..cf2cc80b083ec2ef4e73e8dc46bce4298023dadc 100644 (file)
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 8.1.  Last change: 2019 Dec 07
+*todo.txt*      For Vim version 8.1.  Last change: 2019 Dec 08
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -118,6 +118,8 @@ E290, E292, E362, E366, E450, E451, E452,
 E453, E454, E460, E489, E491, E565, E578, E610, E611, E653,
 E654, E856, E857, E860, E861, E863, E889, E900
 
+Patch to move duplicated code to a function. (Yegappan Lakshmanan, #5330)
+
 Running test_gui and test_gui_init with Motif sometimes kills the window
 manager.  Problem with Motif? Now test_gui crashes in submenu_change().
 Athena is OK.
index 7aeada537c7cc09543254a4043806b893cbd9d78..c13fa10d08f4e8d546d0343df6a97bad155d01cf 100644 (file)
@@ -1,4 +1,4 @@
-*version8.txt*  For Vim version 8.1.  Last change: 2019 Dec 08
+*version8.txt*  For Vim version 8.1.  Last change: 2019 Dec 09
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -25831,14 +25831,14 @@ window.  This also works for normal windows.
 Text properties                                        *new-text-properties*
 ---------------
 
-Text properties give a plugin author flexibility what to highlight.  This can
-be used with an external asynchronous parser to do syntax highlighting.  Or
-to highlight text in a popup window.  The text properties stick with the text
-when characters are deleted or inserted, which makes them also useful as text
-markers. See |text-properties|.
+Text properties give a plugin author flexibility about what to highlight.
+This can be used with an external asynchronous parser to do syntax
+highlighting.  Or to highlight text in a popup window.  The text properties
+stick with the text when characters are deleted or inserted, which makes them
+also useful as text markers. See |text-properties|.
 
 The listener functions have been added to report text changes to a server so
-that it can dynamically update highligting, mark syntax errors and the like.
+that it can dynamically update highlighting, mark syntax errors and the like.
 See |listener_add()|.
 
 
@@ -39746,7 +39746,7 @@ Files:      src/testdir/test_exit.vim, src/ex_docmd.c
 
 Patch 8.1.2198
 Problem:    Crash when using :center in autocommand.
-Solution:   Bail out early for an empty line. (Dominique pelle, closes #5095)
+Solution:   Bail out early for an empty line. (Dominique Pelle, closes #5095)
 Files:     src/ex_cmds.c, src/testdir/test_textformat.vim
 
 Patch 8.1.2199
@@ -40610,7 +40610,7 @@ Solution:   Make sure long line does not overflow IObuff. (Dominique Pelle,
 Files:     src/quickfix.c, src/testdir/test_quickfix.vim
 
 Patch 8.1.2341
-Problem:    Not so easy to interrupt a script programatically.
+Problem:    Not so easy to interrupt a script programmatically.
 Solution:   Add the interrupt() function. (Yasuhiro Matsumoto, closes #2834)
 Files:     runtime/doc/eval.txt, src/evalfunc.c, src/ex_eval.c,
             src/testdir/Make_all.mak, src/testdir/test_interrupt.vim
@@ -41039,7 +41039,7 @@ Solution:   Free the old title.  Don't copy expr_line.
 Files:     src/term.c, src/os_unix.c, src/register.c
 
 Patch 8.1.2407
-Problem:    proto file and dependenciess outdated.
+Problem:    proto file and dependencies outdated.
 Solution:   Update proto files and dependencies.
 Files:     src/Makefile, src/proto/bufwrite.pro, src/proto/cmdhist.pro,
             src/proto/optionstr.pro, src/proto/popupwin.pro,
index 054c35e5fa0fc3acebba246898c9c53e4b4161ee..b4a8eaa0d8067390848f029da7ee251be5caf595 100644 (file)
@@ -3,7 +3,7 @@
 " Maintainer:          Tim Pope <vimNOSPAM@tpope.org>
 " URL:                 https://github.com/vim-ruby/vim-ruby
 " Release Coordinator: Doug Kearns <dougkearns@gmail.com>
-" Last Change:         2019 Jan 06
+" Last Change:         2019 Nov 06
 
 if (exists("b:did_ftplugin"))
   finish
@@ -24,20 +24,20 @@ if exists("loaded_matchit") && !exists("b:match_words")
   let b:match_ignorecase = 0
 
   let b:match_words =
-       \ '\<\%(if\|unless\|case\|while\|until\|for\|do\|class\|module\|def\|begin\)\>=\@!' .
+       \ '{\|\<\%(if\|unless\|case\|while\|until\|for\|do\|class\|module\|def\|=\@<!begin\)\>=\@!' .
        \ ':' .
        \ '\<\%(else\|elsif\|ensure\|when\|rescue\|break\|redo\|next\|retry\)\>' .
        \ ':' .
-        \ '\%(^\|[^.\:@$]\)\@<=\<end\:\@!\>' .
-       \ ',{:},\[:\],(:)'
+        \ '}\|\%(^\|[^.\:@$=]\)\@<=\<end\:\@!\>' .
+        \ ',^=begin\>:^=end\>,' .
+       \ ',\[:\],(:)'
 
   let b:match_skip =
        \ "synIDattr(synID(line('.'),col('.'),0),'name') =~ '" .
-       \ "\\<ruby\\%(String\\|StringDelimiter\\|ASCIICode\\|Escape\\|" .
-        \ "Regexp\\|RegexpDelimiter\\|" .
-       \ "Interpolation\\|NoInterpolation\\|Comment\\|Documentation\\|" .
-       \ "ConditionalModifier\\|RepeatModifier\\|OptionalDo\\|" .
-       \ "Function\\|BlockArgument\\|KeywordAsMethod\\|ClassVariable\\|" .
+       \ "\\<ruby\\%(String\\|.\+Delimiter\\|Character\\|.\+Escape\\|" .
+        \ "Regexp\\|Interpolation\\|Comment\\|Documentation\\|" .
+       \ "ConditionalModifier\\|RepeatModifier\\|RescueModifier\\|OptionalDo\\|" .
+       \ "MethodName\\|BlockArgument\\|KeywordAsMethod\\|ClassVariable\\|" .
        \ "InstanceVariable\\|GlobalVariable\\|Symbol\\)\\>'"
 endif
 
@@ -87,7 +87,7 @@ endfunction
 
 function! s:build_path(path) abort
   let path = join(map(copy(a:path), 'v:val ==# "." ? "" : v:val'), ',')
-  if &g:path !~# '\v^\.%(,/%(usr|emx)/include)=,,$'
+  if &g:path !~# '\v^%(\.,)=%(/%(usr|emx)/include,)=,$'
     let path = substitute(&g:path,',,$',',','') . ',' . path
   endif
   return path
@@ -152,7 +152,7 @@ endif
 function! s:map(mode, flags, map) abort
   let from = matchstr(a:map, '\S\+')
   if empty(mapcheck(from, a:mode))
-    exe a:mode.'map' '<buffer>' a:map
+    exe a:mode.'map' '<buffer>' a:flags a:map
     let b:undo_ftplugin .= '|sil! '.a:mode.'unmap <buffer> '.from
   endif
 endfunction
@@ -311,13 +311,16 @@ function! s:synid() abort
 endfunction
 
 function! s:wrap_i(back,forward) abort
-  execute 'norm k'.a:forward
+  execute 'norm! k'
+  execute 'norm '.a:forward
   let line = line('.')
   execute 'norm '.a:back
   if line('.') == line - 1
     return s:wrap_a(a:back,a:forward)
   endif
-  execute 'norm jV'.a:forward.'k'
+  execute 'norm! jV'
+  execute 'norm '.a:forward
+  execute 'norm! k'
 endfunction
 
 function! s:wrap_a(back,forward) abort
@@ -330,11 +333,15 @@ function! s:wrap_a(back,forward) abort
     -
   endwhile
   if exists('after')
-    execute 'norm V'.a:forward.'j'
+    execute 'norm! V'
+    execute 'norm '.a:forward
+    execute 'norm! j'
   elseif line('.') > 1 && getline(line('.')-1) =~# '^\s*$'
-    execute 'norm kV'.a:forward
+    execute 'norm! kV'
+    execute 'norm '.a:forward
   else
-    execute 'norm V'.a:forward
+    execute 'norm! V'
+    execute 'norm '.a:forward
   endif
 endfunction
 
@@ -366,7 +373,6 @@ function! RubyCursorFile() abort
   endtry
   let pre = matchstr(strpart(getline('.'), 0, col('.')-1), '.*\f\@<!')
   let post = matchstr(strpart(getline('.'), col('.')), '\f\@!.*')
-  let ext = getline('.') =~# '^\s*\%(require\%(_relative\)\=\|autoload\)\>' && cfile !~# '\.rb$' ? '.rb' : ''
   if s:synid() ==# hlID('rubyConstant')
     let cfile = substitute(cfile,'\.\w\+[?!=]\=$','','')
     let cfile = substitute(cfile,'^::','','')
@@ -375,12 +381,15 @@ function! RubyCursorFile() abort
     let cfile = substitute(cfile,'\(\l\|\d\)\(\u\)','\1_\2', 'g')
     return tolower(cfile) . '.rb'
   elseif getline('.') =~# '^\s*require_relative\s*\(["'']\).*\1\s*$'
-    let cfile = expand('%:p:h') . '/' . matchstr(getline('.'),'\(["'']\)\zs.\{-\}\ze\1') . ext
+    let cfile = expand('%:p:h') . '/' . matchstr(getline('.'),'\(["'']\)\zs.\{-\}\ze\1')
+    let cfile .= cfile !~# '\.rb$' ? '.rb' : ''
   elseif getline('.') =~# '^\s*\%(require[( ]\|load[( ]\|autoload[( ]:\w\+,\)\s*\%(::\)\=File\.expand_path(\(["'']\)\.\./.*\1,\s*__FILE__)\s*$'
     let target = matchstr(getline('.'),'\(["'']\)\.\.\zs/.\{-\}\ze\1')
-    let cfile = expand('%:p:h') . target . ext
+    let cfile = expand('%:p:h') . target
+    let cfile .= cfile !~# '\.rb$' ? '.rb' : ''
   elseif getline('.') =~# '^\s*\%(require \|load \|autoload :\w\+,\)\s*\(["'']\).*\1\s*$'
-    let cfile = matchstr(getline('.'),'\(["'']\)\zs.\{-\}\ze\1') . ext
+    let cfile = matchstr(getline('.'),'\(["'']\)\zs.\{-\}\ze\1')
+    let cfile .= cfile !~# '\.rb$' ? '.rb' : ''
   elseif pre.post =~# '\<File.expand_path[( ].*[''"]\{2\}, *__FILE__\>' && cfile =~# '^\.\.'
     let cfile = expand('%:p:h') . strpart(cfile, 2)
   else
index 5c420d75438181e3f7fa6f48df3dc843aa57b269..23b61fdfe08f0eef90915d3a4d3ba611bc03fe7b 100644 (file)
@@ -4,7 +4,7 @@
 " Previous Maintainer: Nikolai Weibull <now at bitwi.se>
 " URL:                 https://github.com/vim-ruby/vim-ruby
 " Release Coordinator: Doug Kearns <dougkearns@gmail.com>
-" Last Change:         2019 Jan 06
+" Last Change:         2019 Dec 08
 
 " 0. Initialization {{{1
 " =================
@@ -51,15 +51,27 @@ set cpo&vim
 
 " Syntax group names that are strings.
 let s:syng_string =
-      \ ['String', 'Interpolation', 'InterpolationDelimiter', 'NoInterpolation', 'StringEscape']
+      \ ['String', 'Interpolation', 'InterpolationDelimiter', 'StringEscape']
 
 " Syntax group names that are strings or documentation.
 let s:syng_stringdoc = s:syng_string + ['Documentation']
 
 " Syntax group names that are or delimit strings/symbols/regexes or are comments.
-let s:syng_strcom = s:syng_stringdoc +
-      \ ['Regexp', 'RegexpDelimiter', 'RegexpEscape',
-      \ 'Symbol', 'StringDelimiter', 'ASCIICode', 'Comment']
+let s:syng_strcom = s:syng_stringdoc + [
+      \ 'Character',
+      \ 'Comment',
+      \ 'HeredocDelimiter',
+      \ 'PercentRegexpDelimiter',
+      \ 'PercentStringDelimiter',
+      \ 'PercentSymbolDelimiter',
+      \ 'Regexp',
+      \ 'RegexpCharClass',
+      \ 'RegexpDelimiter',
+      \ 'RegexpEscape',
+      \ 'StringDelimiter',
+      \ 'Symbol',
+      \ 'SymbolDelimiter',
+      \ ]
 
 " Expression used to check whether we should skip a match with searchpair().
 let s:skip_expr =
@@ -69,7 +81,7 @@ let s:skip_expr =
 let s:ruby_indent_keywords =
       \ '^\s*\zs\<\%(module\|class\|if\|for' .
       \   '\|while\|until\|else\|elsif\|case\|when\|unless\|begin\|ensure\|rescue' .
-      \   '\|\%(\K\k*[!?]\?\)\=\s*def\):\@!\>' .
+      \   '\|\%(\K\k*[!?]\?\s\+\)\=def\):\@!\>' .
       \ '\|\%([=,*/%+-]\|<<\|>>\|:\s\)\s*\zs' .
       \    '\<\%(if\|for\|while\|until\|case\|unless\|begin\):\@!\>'
 
@@ -83,7 +95,7 @@ let s:ruby_deindent_keywords =
 let s:end_start_regex =
       \ '\C\%(^\s*\|[=,*/%+\-|;{]\|<<\|>>\|:\s\)\s*\zs' .
       \ '\<\%(module\|class\|if\|for\|while\|until\|case\|unless\|begin' .
-      \   '\|\%(\K\k*[!?]\?\)\=\s*def\):\@!\>' .
+      \   '\|\%(\K\k*[!?]\?\s\+\)\=def\):\@!\>' .
       \ '\|\%(^\|[^.:@$]\)\@<=\<do:\@!\>'
 
 " Regex that defines the middle-match for the 'end' keyword.
@@ -146,7 +158,7 @@ let s:block_regex =
 let s:block_continuation_regex = '^\s*[^])}\t ].*'.s:block_regex
 
 " Regex that describes a leading operator (only a method call's dot for now)
-let s:leading_operator_regex = '^\s*[.]'
+let s:leading_operator_regex = '^\s*\%(&\=\.\)'
 
 " 2. GetRubyIndent Function {{{1
 " =========================
@@ -695,7 +707,10 @@ endfunction
 
 " Check if the character at lnum:col is inside a string delimiter
 function! s:IsInStringDelimiter(lnum, col) abort
-  return s:IsInRubyGroup(['StringDelimiter'], a:lnum, a:col)
+  return s:IsInRubyGroup(
+        \ ['HeredocDelimiter', 'PercentStringDelimiter', 'StringDelimiter'],
+        \ a:lnum, a:col
+        \ )
 endfunction
 
 function! s:IsAssignment(str, pos) abort
index 8b88378e6063831063af6c7ca45f1b7d4cd421c2..0de63d0ef3a7d875c5aa4283c8e046891e6466fd 100644 (file)
@@ -3,7 +3,7 @@
 " Maintainer:          Doug Kearns <dougkearns@gmail.com>
 " URL:                 https://github.com/vim-ruby/vim-ruby
 " Release Coordinator: Doug Kearns <dougkearns@gmail.com>
-" Last Change:         2018 Jul 09
+" Last Change:         2019 Jul 13
 " ----------------------------------------------------------------------------
 "
 " Previous Maintainer: Mirko Nasato
@@ -19,6 +19,11 @@ endif
 let s:cpo_sav = &cpo
 set cpo&vim
 
+" eRuby Config {{{1
+if exists('main_syntax') && main_syntax == 'eruby'
+  let b:ruby_no_expensive = 1
+endif
+
 " Folding Config {{{1
 if has("folding") && exists("ruby_fold")
   setlocal foldmethod=syntax
@@ -33,6 +38,10 @@ let s:foldable_groups = split(
       \        )
 
 function! s:foldable(...) abort
+  if index(s:foldable_groups, 'NONE') > -1
+    return 0
+  endif
+
   if index(s:foldable_groups, 'ALL') > -1
     return 1
   endif
@@ -44,9 +53,20 @@ function! s:foldable(...) abort
   endfor
 
   return 0
-endfunction " }}}
+endfunction
+
+function! s:run_syntax_fold(args) abort
+  let [_0, _1, groups, cmd; _] = matchlist(a:args, '\(["'']\)\(.\{-}\)\1\s\+\(.*\)')
+  if call('s:foldable', split(groups))
+    let cmd .= ' fold'
+  endif
+  exe cmd
+endfunction
+
+com! -nargs=* SynFold call s:run_syntax_fold(<q-args>)
 
-syn cluster rubyNotTop contains=@rubyExtendedStringSpecial,@rubyRegexpSpecial,@rubyDeclaration,rubyConditional,rubyExceptional,rubyMethodExceptional,rubyTodo,rubyModuleName,rubyClassName,rubySymbolDelimiter
+" Not-Top Cluster {{{1
+syn cluster rubyNotTop contains=@rubyCommentNotTop,@rubyStringNotTop,@rubyRegexpSpecial,@rubyDeclaration,@rubyExceptionHandler,@rubyClassOperator,rubyConditional,rubyModuleName,rubyClassName,rubySymbolDelimiter,rubyParentheses
 
 " Whitespace Errors {{{1
 if exists("ruby_space_errors")
@@ -59,427 +79,400 @@ if exists("ruby_space_errors")
 endif
 
 " Operators {{{1
-if exists("ruby_operators")
-  syn match  rubyOperator "[~!^|*/%+-]\|&\.\@!\|\%(class\s*\)\@<!<<\|<=>\|<=\|\%(<\|\<class\s\+\u\w*\s*\)\@<!<[^<]\@=\|===\|==\|=\~\|>>\|>=\|=\@1<!>\|\*\*\|\.\.\.\|\.\.\|::"
-  syn match  rubyOperator "->\|-=\|/=\|\*\*=\|\*=\|&&=\|&=\|&&\|||=\||=\|||\|%=\|+=\|!\~\|!="
-  syn region rubyBracketOperator matchgroup=rubyOperator start="\%(\w[?!]\=\|[]})]\)\@2<=\[\s*" end="\s*]" contains=ALLBUT,@rubyNotTop
-endif
 
-" 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
+syn match rubyEnglishBooleanOperator "\<\%(and\|or\|not\)\>"
+
+if exists("ruby_operators") || exists("ruby_pseudo_operators")
+  syn match rubyDotOperator       "\.\|&\."
+
+  syn match rubyTernaryOperator    "\%(\w\|[^\x00-\x7F]\)\@1<!?\|:"
+  syn match rubyArithmeticOperator "\*\*\|[*/%+]\|->\@!"
+  syn match rubyComparisonOperator "<=>\|<=\|<\|>=\|[-=]\@1<!>"
+  syn match rubyBitwiseOperator    "[~^|]\|&\.\@!\|<<\|>>"
+  syn match rubyBooleanOperator    "\%(\w\|[^\x00-\x7F]\)\@1<!!\|&&\|||"
+  syn match rubyRangeOperator     "\.\.\.\="
+  syn match rubyAssignmentOperator "=>\@!\|-=\|/=\|\*\*=\|\*=\|&&=\|&=\|||=\||=\|%=\|+=\|>>=\|<<=\|\^="
+  syn match rubyAssignmentOperator "=>\@!" containedin=rubyBlockParameterList " TODO: this is inelegant
+  syn match rubyEqualityOperator   "===\|==\|!=\|!\~\|=\~"
+
+  syn region rubyBracketOperator matchgroup=rubyOperator start="\%(\%(\w\|[^\x00-\x7F]\)[?!]\=\|[]})]\)\@2<=\[" end="]" contains=ALLBUT,@rubyNotTop
+
+  syn match rubyScopeOperator      "::"
+  syn match rubySuperClassOperator  "<"         contained
+  syn match rubyEigenClassOperator  "<<" contained
+  syn match rubyLambdaOperator     "->"
+  syn match rubySplatOperator      "\%([[{(|,=]\_s*\)\@<=\*"
+  syn match rubySplatOperator      "\%(^\|\s\)\@1<=\*\%(\h\|[^\x00-\x7F]\|[:$@[]\)\@="
+  syn match rubyDoubleSplatOperator "\%([{(|,]\_s*\)\@<=\*\*"
+  syn match rubyDoubleSplatOperator "\s\@1<=\*\*\%(\h\|[^\x00-\x7F]\|[:$@{]\)\@="
+  syn match rubyProcOperator       "\%([[(|,]\_s*\)\@<=&"
+  syn match rubyProcOperator       "\s\@1<=&\%(\h\|[^\x00-\x7F]\|[:$@]\|->\)\@="
+
+  syn cluster rubyProperOperator contains=rubyTernaryOperator,rubyArithmeticOperator,rubyComparisonOperator,rubyBitwiseOperator,rubyBooleanOperator,rubyRangeOperator,rubyAssignmentOperator,rubyEqualityOperator,rubyDefinedOperator,rubyEnglishBooleanOperator
+  syn cluster rubyClassOperator  contains=rubyEigenClassOperator,rubySuperClassOperator
+  syn cluster rubyPseudoOperator contains=rubyDotOperator,rubyScopeOperator,rubyEigenClassOperator,rubySuperClassOperator,rubyLambdaOperator,rubySplatOperator,rubyDoubleSplatOperator,rubyProcOperator
+  syn cluster rubyOperator      contains=ruby.*Operator
+endif
 
+" String Interpolation and Backslash Notation {{{1
 syn region rubyInterpolation         matchgroup=rubyInterpolationDelimiter start="#{" end="}" contained contains=ALLBUT,@rubyNotTop
-syn match  rubyInterpolation         "#\%(\$\|@@\=\)\w\+"    display contained contains=rubyInterpolationDelimiter,rubyInstanceVariable,rubyClassVariable,rubyGlobalVariable,rubyPredefinedVariable
-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 match  rubyNoInterpolation       "\\#{"                  display contained
-syn match  rubyNoInterpolation       "\\#\%(\$\|@@\=\)\w\+"  display contained
-syn match  rubyNoInterpolation       "\\#\$\W"               display contained
+syn match  rubyInterpolation         "#\$\%(-\w\|[!$&"'*+,./0:;<>?@\`~_]\|\w\+\)" display contained contains=rubyInterpolationDelimiter,@rubyGlobalVariable
+syn match  rubyInterpolation         "#@@\=\w\+"                                  display contained contains=rubyInterpolationDelimiter,rubyInstanceVariable,rubyClassVariable
+syn match  rubyInterpolationDelimiter "#\ze[$@]"                                  display contained
+
+syn match rubyStringEscape "\\\_."                                                                                        contained display
+syn match rubyStringEscape "\\\o\{1,3}\|\\x\x\{1,2}"                                                                      contained display
+syn match rubyStringEscape "\\u\%(\x\{4}\|{\x\{1,6}\%(\s\+\x\{1,6}\)*}\)"                                                 contained display
+syn match rubyStringEscape "\%(\\M-\\C-\|\\C-\\M-\|\\M-\\c\|\\c\\M-\|\\c\|\\C-\|\\M-\)\%(\\\o\{1,3}\|\\x\x\{1,2}\|\\\=.\)" contained display
+
+syn match rubyBackslashEscape "\\\\" contained display
+syn match rubyQuoteEscape     "\\'"  contained display
+syn match rubySpaceEscape     "\\ "  contained display
 
-syn match rubyDelimiterEscape  "\\[(<{\[)>}\]]" transparent display contained contains=NONE
+syn match rubyParenthesisEscape          "\\[()]"  contained display
+syn match rubyCurlyBraceEscape   "\\[{}]"  contained display
+syn match rubyAngleBracketEscape  "\\[<>]"  contained display
+syn match rubySquareBracketEscape "\\[[\]]" contained display
 
 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
 
+syn cluster rubySingleCharEscape contains=rubyBackslashEscape,rubyQuoteEscape,rubySpaceEscape,rubyParenthesisEscape,rubyCurlyBraceEscape,rubyAngleBracketEscape,rubySquareBracketEscape
+syn cluster rubyNestedBrackets  contains=rubyNested.\+
+syn cluster rubyStringSpecial   contains=rubyInterpolation,rubyStringEscape
+syn cluster rubyStringNotTop    contains=@rubyStringSpecial,@rubyNestedBrackets,@rubySingleCharEscape
+
 " 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
-syn region rubyRegexpBrackets  matchgroup=rubyRegexpCharClass start="\[\^\="                                                             skip="\\\]" end="\]" contained transparent contains=rubyStringEscape,rubyRegexpEscape,rubyRegexpCharClass oneline
-syn match  rubyRegexpCharClass "\\[DdHhSsWw]"         contained display
-syn match  rubyRegexpCharClass "\[:\^\=\%(alnum\|alpha\|ascii\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|xdigit\):\]" contained
-syn match  rubyRegexpEscape    "\\[].*?+^$|\\/(){}[]" contained
-syn match  rubyRegexpQuantifier        "[*?+][?+]\="          contained display
-syn match  rubyRegexpQuantifier        "{\d\+\%(,\d*\)\=}?\=" contained display
-syn match  rubyRegexpAnchor    "[$^]\|\\[ABbGZz]"     contained display
-syn match  rubyRegexpDot       "\."                   contained display
-syn match  rubyRegexpSpecial   "|"                    contained display
-syn match  rubyRegexpSpecial   "\\[1-9]\d\=\d\@!"     contained display
-syn match  rubyRegexpSpecial   "\\k<\%([a-z_]\w*\|-\=\d\+\)\%([+-]\d\+\)\=>" contained display
-syn match  rubyRegexpSpecial   "\\k'\%([a-z_]\w*\|-\=\d\+\)\%([+-]\d\+\)\='" contained display
-syn match  rubyRegexpSpecial   "\\g<\%([a-z_]\w*\|-\=\d\+\)>" contained display
-syn match  rubyRegexpSpecial   "\\g'\%([a-z_]\w*\|-\=\d\+\)'" contained display
-
-syn cluster rubyStringSpecial        contains=rubyInterpolation,rubyNoInterpolation,rubyStringEscape
-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 {{{1
-syn match rubyASCIICode "\%(\w\|[]})\"'/]\)\@1<!\%(?\%(\\M-\\C-\|\\C-\\M-\|\\M-\\c\|\\c\\M-\|\\c\|\\C-\|\\M-\)\=\%(\\\o\{1,3}\|\\x\x\{1,2}\|\\\=\S\)\)"
-syn match rubyInteger  "\%(\%(\w\|[]})\"']\s*\)\@<!-\)\=\<0[xX]\x\+\%(_\x\+\)*r\=i\=\>"                                                                display
-syn match rubyInteger  "\%(\%(\w\|[]})\"']\s*\)\@<!-\)\=\<\%(0[dD]\)\=\%(0\|[1-9]\d*\%(_\d\+\)*\)r\=i\=\>"                                             display
-syn match rubyInteger  "\%(\%(\w\|[]})\"']\s*\)\@<!-\)\=\<0[oO]\=\o\+\%(_\o\+\)*r\=i\=\>"                                                              display
-syn match rubyInteger  "\%(\%(\w\|[]})\"']\s*\)\@<!-\)\=\<0[bB][01]\+\%(_[01]\+\)*r\=i\=\>"                                                            display
-syn match rubyFloat    "\%(\%(\w\|[]})\"']\s*\)\@<!-\)\=\<\%(0\|[1-9]\d*\%(_\d\+\)*\)\.\d\+\%(_\d\+\)*r\=i\=\>"                                        display
-syn match rubyFloat    "\%(\%(\w\|[]})\"']\s*\)\@<!-\)\=\<\%(0\|[1-9]\d*\%(_\d\+\)*\)\%(\.\d\+\%(_\d\+\)*\)\=\%([eE][-+]\=\d\+\%(_\d\+\)*\)r\=i\=\>"   display
+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
+syn region rubyRegexpBrackets    matchgroup=rubyRegexpCharClass start="\[\^\="                                                             skip="\\\\\|\\\]" end="\]" contained transparent contains=rubyRegexpBrackets,rubyStringEscape,rubyRegexpEscape,rubyRegexpCharClass,rubyRegexpIntersection oneline
+syn match  rubyRegexpCharClass   "\\[DdHhRSsWw]"        contained display
+syn match  rubyRegexpCharClass   "\[:\^\=\%(alnum\|alpha\|ascii\|blank\|cntrl\|digit\|graph\|lower\|print\|punct\|space\|upper\|word\|xdigit\):\]" contained
+syn match  rubyRegexpCharClass   "\\[pP]{^\=.\{-}}"     contained display
+syn match  rubyRegexpEscape      "\\[].*?+^$|\\/(){}[]" contained " see commit e477f10
+syn match  rubyRegexpQuantifier          "[*?+][?+]\="          contained display
+syn match  rubyRegexpQuantifier          "{\d\+\%(,\d*\)\=}?\=" contained display
+syn match  rubyRegexpAnchor      "[$^]\|\\[ABbGZz]"     contained display
+syn match  rubyRegexpDot         "\.\|\\X"              contained display
+syn match  rubyRegexpIntersection "&&"                  contained display
+syn match  rubyRegexpSpecial     "\\K"                  contained display
+syn match  rubyRegexpSpecial     "|"                    contained display
+syn match  rubyRegexpSpecial     "\\[1-9]\d\=\d\@!"     contained display
+syn match  rubyRegexpSpecial     "\\k<\%([a-z_]\w*\|-\=\d\+\)\%([+-]\d\+\)\=>" contained display
+syn match  rubyRegexpSpecial     "\\k'\%([a-z_]\w*\|-\=\d\+\)\%([+-]\d\+\)\='" contained display
+syn match  rubyRegexpSpecial     "\\g<\%([a-z_]\w*\|-\=\d\+\)>"                contained display
+syn match  rubyRegexpSpecial     "\\g'\%([a-z_]\w*\|-\=\d\+\)'"                contained display
+
+syn cluster rubyRegexpSpecial contains=@rubyStringSpecial,rubyRegexpSpecial,rubyRegexpEscape,rubyRegexpBrackets,rubyRegexpCharClass,rubyRegexpDot,rubyRegexpQuantifier,rubyRegexpAnchor,rubyRegexpParens,rubyRegexpComment,rubyRegexpIntersection
+
+" Numbers {{{1
+syn match rubyInteger "\%(\%(\w\|[^\x00-\x7F]\|[]})\"']\s*\)\@<!-\)\=\<0[xX]\x\+\%(_\x\+\)*r\=i\=\>"                                                          display
+syn match rubyInteger "\%(\%(\w\|[^\x00-\x7F]\|[]})\"']\s*\)\@<!-\)\=\<\%(0[dD]\)\=\%(0\|[1-9]\d*\%(_\d\+\)*\)r\=i\=\>"                                               display
+syn match rubyInteger "\%(\%(\w\|[^\x00-\x7F]\|[]})\"']\s*\)\@<!-\)\=\<0[oO]\=\o\+\%(_\o\+\)*r\=i\=\>"                                                        display
+syn match rubyInteger "\%(\%(\w\|[^\x00-\x7F]\|[]})\"']\s*\)\@<!-\)\=\<0[bB][01]\+\%(_[01]\+\)*r\=i\=\>"                                                      display
+syn match rubyFloat   "\%(\%(\w\|[^\x00-\x7F]\|[]})\"']\s*\)\@<!-\)\=\<\%(0\|[1-9]\d*\%(_\d\+\)*\)\.\d\+\%(_\d\+\)*r\=i\=\>"                                  display
+syn match rubyFloat   "\%(\%(\w\|[^\x00-\x7F]\|[]})\"']\s*\)\@<!-\)\=\<\%(0\|[1-9]\d*\%(_\d\+\)*\)\%(\.\d\+\%(_\d\+\)*\)\=\%([eE][-+]\=\d\+\%(_\d\+\)*\)i\=\>" display
 
 " Identifiers {{{1
-syn match rubyLocalVariableOrMethod "\<[_[:lower:]][_[:alnum:]]*[?!=]\=" contains=NONE display transparent
-syn match rubyBlockArgument        "&[_[:lower:]][_[:alnum:]]"          contains=NONE display transparent
-
-syn match  rubyClassName       "\%(\%(^\|[^.]\)\.\s*\)\@<!\<\u\%(\w\|[^\x00-\x7F]\)*\>\%(\s*(\)\@!" contained
-syn match  rubyModuleName      "\%(\%(^\|[^.]\)\.\s*\)\@<!\<\u\%(\w\|[^\x00-\x7F]\)*\>\%(\s*(\)\@!" contained
-syn match  rubyConstant                "\%(\%(^\|[^.]\)\.\s*\)\@<!\<\u\%(\w\|[^\x00-\x7F]\)*\>\%(\s*(\)\@!"
-syn match  rubyClassVariable   "@@\%(\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  rubySymbolDelimiter ":" contained
-syn match  rubySymbol          "[]})\"':]\@1<!:\%(\^\|\~@\|\~\|<<\|<=>\|<=\|<\|===\|[=!]=\|[=!]\~\|!@\|!\|>>\|>=\|>\||\|-@\|-\|/\|\[]=\|\[]\|\*\*\|\*\|&\|%\|+@\|+\|`\)" contains=rubySymbolDelimiter
-syn match  rubySymbol          "[]})\"':]\@1<!:\$\%(-.\|[`~<=>_,;:!?/.'"@$*\&+0]\)" contains=rubySymbolDelimiter
-syn match  rubySymbol          "[]})\"':]\@1<!:\%(\$\|@@\=\)\=\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*" contains=rubySymbolDelimiter
-syn match  rubySymbol          "[]})\"':]\@1<!:\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\%([?!=]>\@!\)\=" contains=rubySymbolDelimiter
-
-if s:foldable(':')
-  syn region rubySymbol                matchgroup=rubySymbolDelimiter start="[]})\"':]\@1<!:'"  end="'"  skip="\\\\\|\\'"  contains=rubyQuoteEscape fold
-  syn region rubySymbol                matchgroup=rubySymbolDelimiter start="[]})\"':]\@1<!:\"" end="\"" skip="\\\\\|\\\"" contains=@rubyStringSpecial fold
-else
-  syn region rubySymbol                matchgroup=rubySymbolDelimiter start="[]})\"':]\@1<!:'"  end="'"  skip="\\\\\|\\'"  contains=rubyQuoteEscape
-  syn region rubySymbol                matchgroup=rubySymbolDelimiter start="[]})\"':]\@1<!:\"" end="\"" skip="\\\\\|\\\"" contains=@rubyStringSpecial
+syn match rubyClassName               "\%(\%(^\|[^.]\)\.\s*\)\@<!\<[[:upper:]]\%(\w\|[^\x00-\x7F]\)*\>\%(\s*(\)\@!" contained
+syn match rubyModuleName       "\%(\%(^\|[^.]\)\.\s*\)\@<!\<[[:upper:]]\%(\w\|[^\x00-\x7F]\)*\>\%(\s*(\)\@!" contained
+syn match rubyConstant        "\%(\%(^\|[^.]\)\.\s*\)\@<!\<[[:upper:]]\%(\w\|[^\x00-\x7F]\)*\>\%(\s*(\)\@!"
+syn match rubyClassVariable    "@@\%(\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 rubySymbolDelimiter  ":" contained
+syn match rubySymbol          "[]})\"':]\@1<!:\%(\^\|\~@\|\~\|<<\|<=>\|<=\|<\|===\|[=!]=\|[=!]\~\|!@\|!\|>>\|>=\|>\||\|-@\|-\|/\|\[]=\|\[]\|\*\*\|\*\|&\|%\|+@\|+\|`\)" contains=rubySymbolDelimiter
+syn match rubySymbol          "[]})\"':]\@1<!:\$\%(-.\|[`~<=>_,;:!?/.'"@$*\&+0]\)"                         contains=rubySymbolDelimiter
+syn match rubySymbol          "[]})\"':]\@1<!:\%(\$\|@@\=\)\=\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*"  contains=rubySymbolDelimiter
+syn match rubySymbol          "[]})\"':]\@1<!:\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\%([?!=]>\@!\)\=" contains=rubySymbolDelimiter
+
+SynFold ':' syn region rubySymbol matchgroup=rubySymbolDelimiter start="[]})\"':]\@1<!:'"  end="'"  skip="\\\\\|\\'"  contains=rubyQuoteEscape,rubyBackslashEscape
+SynFold ':' syn region rubySymbol matchgroup=rubySymbolDelimiter start="[]})\"':]\@1<!:\"" end="\"" skip="\\\\\|\\\"" contains=@rubyStringSpecial
+
+syn match rubyCapitalizedMethod "\%(\%(^\|[^.]\)\.\s*\)\@<!\<\u\%(\w\|[^\x00-\x7F]\)*\>\%(\s*(\)\@="
+
+syn region rubyParentheses       start="("                              end=")" contains=ALLBUT,@rubyNotTop containedin=rubyBlockParameterList
+syn region rubyBlockParameterList start="\%(\%(\<do\>\|{\)\_s*\)\@32<=|" end="|" contains=ALLBUT,@rubyNotTop,@rubyProperOperator
+
+if exists('ruby_global_variable_error')
+  syn match rubyGlobalVariableError "$[^A-Za-z_]"      display
+  syn match rubyGlobalVariableError "$-[^0FIKWadilpvw]" display
 endif
 
-syn match  rubyCapitalizedMethod       "\%(\%(^\|[^.]\)\.\s*\)\@<!\<\u\%(\w\|[^\x00-\x7F]\)*\>\%(\s*(\)*\s*(\@="
-
-syn match  rubyBlockParameter    "\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*" contained
-syn region rubyBlockParameterList start="\%(\%(\<do\>\|{\)\_s*\)\@32<=|" end="|" oneline display contains=rubyBlockParameter
-
-syn match rubyInvalidVariable   "$[^ A-Za-z_-]"
-syn match rubyPredefinedVariable #$[!$&"'*+,./0:;<=>?@\`~]#
-syn match rubyPredefinedVariable "$\d\+"                                                                                  display
-syn match rubyPredefinedVariable "$_\>"                                                                                           display
-syn match rubyPredefinedVariable "$-[0FIKadilpvw]\>"                                                                      display
-syn match rubyPredefinedVariable "$\%(deferr\|defout\|stderr\|stdin\|stdout\)\>"                                          display
-syn match rubyPredefinedVariable "$\%(DEBUG\|FILENAME\|KCODE\|LOADED_FEATURES\|LOAD_PATH\|PROGRAM_NAME\|SAFE\|VERBOSE\)\>" display
-syn match rubyPredefinedConstant "\%(\%(^\|[^.]\)\.\s*\)\@<!\<\%(ARGF\|ARGV\|ENV\|DATA\|FALSE\|NIL\|STDERR\|STDIN\|STDOUT\|TOPLEVEL_BINDING\|TRUE\)\>\%(\s*(\)\@!"
+syn match rubyPredefinedVariable #$[!$&"'*+,./0:;<>?@\`~]#
+syn match rubyPredefinedVariable "$\d\+"                                                                           display
+syn match rubyPredefinedVariable "$_\>"                                                                                    display
+syn match rubyPredefinedVariable "$-[0FIWadilpvw]\>"                                                               display
+syn match rubyPredefinedVariable "$\%(stderr\|stdin\|stdout\)\>"                                                   display
+syn match rubyPredefinedVariable "$\%(DEBUG\|FILENAME\|LOADED_FEATURES\|LOAD_PATH\|PROGRAM_NAME\|SAFE\|VERBOSE\)\>" display
+syn match rubyPredefinedConstant "\%(\%(^\|[^.]\)\.\s*\)\@<!\<\%(ARGF\|ARGV\|ENV\|DATA\|STDERR\|STDIN\|STDOUT\|TOPLEVEL_BINDING\)\>\%(\s*(\)\@!"
 syn match rubyPredefinedConstant "\%(\%(^\|[^.]\)\.\s*\)\@<!\<\%(RUBY_\%(VERSION\|RELEASE_DATE\|PLATFORM\|PATCHLEVEL\|REVISION\|DESCRIPTION\|COPYRIGHT\|ENGINE\)\)\>\%(\s*(\)\@!"
 
-" 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 {{{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 {{{1
+" Deprecated/removed in 1.9
+syn match rubyPredefinedVariable "$="
+syn match rubyPredefinedVariable "$-K\>"                 display
+syn match rubyPredefinedVariable "$\%(deferr\|defout\)\>" display
+syn match rubyPredefinedVariable "$KCODE\>"              display
+" Deprecated/removed in 2.4
+syn match rubyPredefinedConstant "\%(\%(^\|[^.]\)\.\s*\)\@<!\<\%(FALSE\|NIL\|TRUE\)\>\%(\s*(\)\@!"
+
+syn cluster rubyGlobalVariable contains=rubyGlobalVariable,rubyPredefinedVariable,rubyGlobalVariableError
+
+" Normal Regular Expressions {{{1
+SynFold '/' syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="\%(\%(^\|\<\%(and\|or\|while\|until\|unless\|if\|elsif\|when\|not\|then\|else\)\|[;\~=!|&(,{[<>?:*+-]\)\s*\)\@<=/" end="/[iomxneus]*" skip="\\\\\|\\/" contains=@rubyRegexpSpecial nextgroup=@rubyModifier skipwhite
+SynFold '/' syn region rubyRegexp matchgroup=rubyRegexpDelimiter start="\%(\%(\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\s\+\)\@<=/\%(=\|\_s\)\@!"                                     end="/[iomxneus]*" skip="\\\\\|\\/" contains=@rubyRegexpSpecial nextgroup=@rubyModifier skipwhite
+
+" Generalized Regular Expressions {{{1
+SynFold '%' syn region rubyRegexp matchgroup=rubyPercentRegexpDelimiter start="%r\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1[iomxneus]*" skip="\\\\\|\\\z1" contains=@rubyRegexpSpecial nextgroup=@rubyModifier skipwhite
+SynFold '%' syn region rubyRegexp matchgroup=rubyPercentRegexpDelimiter start="%r{"                               end="}[iomxneus]*"   skip="\\\\\|\\}"   contains=@rubyRegexpSpecial
+SynFold '%' syn region rubyRegexp matchgroup=rubyPercentRegexpDelimiter start="%r<"                               end=">[iomxneus]*"   skip="\\\\\|\\>"   contains=@rubyRegexpSpecial,rubyNestedAngleBrackets
+SynFold '%' syn region rubyRegexp matchgroup=rubyPercentRegexpDelimiter start="%r\["                              end="\][iomxneus]*"  skip="\\\\\|\\\]"  contains=@rubyRegexpSpecial
+SynFold '%' syn region rubyRegexp matchgroup=rubyPercentRegexpDelimiter start="%r("                               end=")[iomxneus]*"   skip="\\\\\|\\)"   contains=@rubyRegexpSpecial
+SynFold '%' syn region rubyRegexp matchgroup=rubyPercentRegexpDelimiter start="%r\z(\s\)"                         end="\z1[iomxneus]*" skip="\\\\\|\\\z1" contains=@rubyRegexpSpecial
+
+" Characters {{{1
+syn match rubyCharacter "\%(\w\|[^\x00-\x7F]\|[]})\"'/]\)\@1<!\%(?\%(\\M-\\C-\|\\C-\\M-\|\\M-\\c\|\\c\\M-\|\\c\|\\C-\|\\M-\)\=\%(\\\o\{1,3}\|\\x\x\{1,2}\|\\[[:space:]]\|\\\=[^[:space:]]\)\)"
+syn match rubyCharacter "\%(\w\|[^\x00-\x7F]\|[]})\"'/]\)\@1<!?\\u\%(\x\{4}\|{\x\{1,6}}\)"
+
+" Normal Strings {{{1
 let s:spell_cluster = exists('ruby_spellcheck_strings') ? ',@Spell' : ''
-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
+let s:fold_arg     = s:foldable('string')              ? ' fold'   : ''
+exe 'syn region rubyString matchgroup=rubyStringDelimiter start="\"" end="\"" skip="\\\\\|\\\""  contains=@rubyStringSpecial'                 . s:spell_cluster . s:fold_arg
+exe 'syn region rubyString matchgroup=rubyStringDelimiter start="''" end="''" skip="\\\\\|\\''"  contains=rubyQuoteEscape,rubyBackslashEscape' . s:spell_cluster . s:fold_arg
+unlet s:spell_cluster s:fold_arg
 
 " 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
+SynFold 'string' syn region rubyString matchgroup=rubyStringDelimiter start="`" end="`" skip="\\\\\|\\`" contains=@rubyStringSpecial
 
-" 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 Single Quoted Strings, Symbols, Array of Strings and Array of Symbols {{{1
 
-" 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
-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
+" Non-bracket punctuation delimiters {{{2
+let s:names = { '~': 'Tilde', '`': 'BackQuote', '!': 'Bang', '@': 'At', '#': 'Hash', '$': 'Dollar', '%': 'Percent', '^': 'Caret',
+      \                '&': 'Ampersand', '*': 'Asterix', '_': 'Underscore', '-': 'Dash', '+': 'Plus', '=': 'Equals', '|': 'Bar',
+      \                '\': 'Backslash', ':': 'Colon', ';': 'Semicolon', '"': 'DoubleQuote', "'": 'Quote', ',': 'Comma', '.': 'Period',
+      \                '?': 'QuestionMark', '/': 'ForwardSlash' }
 
-" 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,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
-
-  " 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
+for s:delimiter in keys(s:names)
+  let s:group = 'ruby' . s:names[s:delimiter] . 'Escape'
 
-" Here Document {{{1
-syn region rubyHeredocStart matchgroup=rubyStringDelimiter start=+\%(\%(class\|::\)\_s*\|\%([]})"'.]\)\s\|\w\)\@<!<<[-~]\=\zs\%(\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)+  end=+$+ oneline contains=ALLBUT,@rubyNotTop
-syn region rubyHeredocStart matchgroup=rubyStringDelimiter start=+\%(\%(class\|::\)\_s*\|\%([]})"'.]\)\s\|\w\)\@<!<<[-~]\=\zs"\%([^"]*\)"+ end=+$+ oneline contains=ALLBUT,@rubyNotTop
-syn region rubyHeredocStart matchgroup=rubyStringDelimiter start=+\%(\%(class\|::\)\_s*\|\%([]})"'.]\)\s\|\w\)\@<!<<[-~]\=\zs'\%([^']*\)'+ end=+$+ oneline contains=ALLBUT,@rubyNotTop
-syn region rubyHeredocStart matchgroup=rubyStringDelimiter start=+\%(\%(class\|::\)\_s*\|\%([]})"'.]\)\s\|\w\)\@<!<<[-~]\=\zs`\%([^`]*\)`+ end=+$+ oneline contains=ALLBUT,@rubyNotTop
-
-if s:foldable('<<')
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]})"'.]\)\s\|\w\)\@<!<<\z(\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2 matchgroup=rubyStringDelimiter end=+^\z1$+ contains=rubyHeredocStart,rubyHeredoc,@rubyStringSpecial fold keepend
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]})"'.]\)\s\|\w\)\@<!<<"\z([^"]*\)"\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2     matchgroup=rubyStringDelimiter end=+^\z1$+ contains=rubyHeredocStart,rubyHeredoc,@rubyStringSpecial fold keepend
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]})"'.]\)\s\|\w\)\@<!<<'\z([^']*\)'\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2     matchgroup=rubyStringDelimiter end=+^\z1$+ contains=rubyHeredocStart,rubyHeredoc                    fold keepend
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]})"'.]\)\s\|\w\)\@<!<<`\z([^`]*\)`\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2     matchgroup=rubyStringDelimiter end=+^\z1$+ contains=rubyHeredocStart,rubyHeredoc,@rubyStringSpecial fold keepend
-
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]}).]\)\s\|\w\)\@<!<<[-~]\z(\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3    matchgroup=rubyStringDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart,@rubyStringSpecial fold keepend
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]}).]\)\s\|\w\)\@<!<<[-~]"\z([^"]*\)"\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3  matchgroup=rubyStringDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart,@rubyStringSpecial fold keepend
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]}).]\)\s\|\w\)\@<!<<[-~]'\z([^']*\)'\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3  matchgroup=rubyStringDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart                   fold keepend
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]}).]\)\s\|\w\)\@<!<<[-~]`\z([^`]*\)`\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3  matchgroup=rubyStringDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart,@rubyStringSpecial fold keepend
-else
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]})"'.]\)\s\|\w\)\@<!<<\z(\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2 matchgroup=rubyStringDelimiter end=+^\z1$+ contains=rubyHeredocStart,rubyHeredoc,@rubyStringSpecial keepend
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]})"'.]\)\s\|\w\)\@<!<<"\z([^"]*\)"\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2     matchgroup=rubyStringDelimiter end=+^\z1$+ contains=rubyHeredocStart,rubyHeredoc,@rubyStringSpecial keepend
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]})"'.]\)\s\|\w\)\@<!<<'\z([^']*\)'\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2     matchgroup=rubyStringDelimiter end=+^\z1$+ contains=rubyHeredocStart,rubyHeredoc                    keepend
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]})"'.]\)\s\|\w\)\@<!<<`\z([^`]*\)`\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2     matchgroup=rubyStringDelimiter end=+^\z1$+ contains=rubyHeredocStart,rubyHeredoc,@rubyStringSpecial keepend
-
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]}).]\)\s\|\w\)\@<!<<[-~]\z(\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3    matchgroup=rubyStringDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart,@rubyStringSpecial keepend
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]}).]\)\s\|\w\)\@<!<<[-~]"\z([^"]*\)"\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3  matchgroup=rubyStringDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart,@rubyStringSpecial keepend
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]}).]\)\s\|\w\)\@<!<<[-~]'\z([^']*\)'\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3  matchgroup=rubyStringDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart                   keepend
-  syn region rubyString start=+\%(\%(class\|::\)\_s*\|\%([]}).]\)\s\|\w\)\@<!<<[-~]`\z([^`]*\)`\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3  matchgroup=rubyStringDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart,@rubyStringSpecial keepend
-endif
+  if s:delimiter =~ '[\"]'
+    let s:delimiter = '\' . s:delimiter
+  endif
 
-" eRuby Config {{{1
-if exists('main_syntax') && main_syntax == 'eruby'
-  let b:ruby_no_expensive = 1
-endif
+  exe 'syn match ' . s:group . ' "\V\\' . s:delimiter . '" contained display'
+  exe 'syn cluster rubySingleCharEscape add=' . s:group
+  exe 'SynFold ''%'' syn region rubyString matchgroup=rubyPercentStringDelimiter start="\V%q' . s:delimiter . '" end="\V' . s:delimiter . '" skip="\V\\\\\|\\' . s:delimiter . '" contains=rubyBackslashEscape,'                . s:group . ' nextgroup=@rubyModifier skipwhite'
+  exe 'SynFold ''%'' syn region rubyString matchgroup=rubyPercentStringDelimiter start="\V%w' . s:delimiter . '" end="\V' . s:delimiter . '" skip="\V\\\\\|\\' . s:delimiter . '" contains=rubyBackslashEscape,rubySpaceEscape,' . s:group . ' nextgroup=@rubyModifier skipwhite'
+  exe 'SynFold ''%'' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="\V%s' . s:delimiter . '" end="\V' . s:delimiter . '" skip="\V\\\\\|\\' . s:delimiter . '" contains=rubyBackslashEscape,'                . s:group . ' nextgroup=@rubyModifier skipwhite'
+  exe 'SynFold ''%'' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="\V%i' . s:delimiter . '" end="\V' . s:delimiter . '" skip="\V\\\\\|\\' . s:delimiter . '" contains=rubyBackslashEscape,rubySpaceEscape,' . s:group . ' nextgroup=@rubyModifier skipwhite'
+  exe 'hi def link ' . s:group . ' rubyStringEscape'
+endfor
+
+unlet s:delimiter s:group s:names
+" }}}2
+
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%q{"      end="}"   skip="\\\\\|\\}"   contains=rubyBackslashEscape,rubyCurlyBraceEscape,rubyNestedCurlyBraces
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%q<"      end=">"   skip="\\\\\|\\>"   contains=rubyBackslashEscape,rubyAngleBracketEscape,rubyNestedAngleBrackets
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%q\["     end="\]"  skip="\\\\\|\\\]"  contains=rubyBackslashEscape,rubySquareBracketEscape,rubyNestedSquareBrackets
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%q("      end=")"   skip="\\\\\|\\)"   contains=rubyBackslashEscape,rubyParenthesisEscape,rubyNestedParentheses
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%q\z(\s\)" end="\z1" skip="\\\\\|\\\z1" contains=rubyBackslashEscape,rubySpaceEscape
+
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%w{"      end="}"   skip="\\\\\|\\}"   contains=rubyBackslashEscape,rubySpaceEscape,rubyCurlyBraceEscape,rubyNestedCurlyBraces
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%w<"      end=">"   skip="\\\\\|\\>"   contains=rubyBackslashEscape,rubySpaceEscape,rubyAngleBracketEscape,rubyNestedAngleBrackets
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%w\["     end="\]"  skip="\\\\\|\\\]"  contains=rubyBackslashEscape,rubySpaceEscape,rubySquareBracketEscape,rubyNestedSquareBrackets
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%w("      end=")"   skip="\\\\\|\\)"   contains=rubyBackslashEscape,rubySpaceEscape,rubyParenthesisEscape,rubyNestedParentheses
+
+SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%s{"      end="}"   skip="\\\\\|\\}"   contains=rubyBackslashEscape,rubyCurlyBraceEscape,rubyNestedCurlyBraces
+SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%s<"      end=">"   skip="\\\\\|\\>"   contains=rubyBackslashEscape,rubyAngleBracketEscape,rubyNestedAngleBrackets
+SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%s\["     end="\]"  skip="\\\\\|\\\]"  contains=rubyBackslashEscape,rubySquareBracketEscape,rubyNestedSquareBrackets
+SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%s("      end=")"   skip="\\\\\|\\)"   contains=rubyBackslashEscape,rubyParenthesisEscape,rubyNestedParentheses
+SynFold '%' syn region rubyString matchgroup=rubyPercentSymbolDelimiter start="%s\z(\s\)" end="\z1" skip="\\\\\|\\\z1" contains=rubyBackslashEscape,rubySpaceEscape
+
+SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%i{"      end="}"   skip="\\\\\|\\}"   contains=rubyBackslashEscape,rubySpaceEscape,rubyCurlyBraceEscape,rubyNestedCurlyBraces
+SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%i<"      end=">"   skip="\\\\\|\\>"   contains=rubyBackslashEscape,rubySpaceEscape,rubyAngleBracketEscape,rubyNestedAngleBrackets
+SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%i\["     end="\]"  skip="\\\\\|\\\]"  contains=rubyBackslashEscape,rubySpaceEscape,rubySquareBracketEscape,rubyNestedSquareBrackets
+SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%i("      end=")"   skip="\\\\\|\\)"   contains=rubyBackslashEscape,rubySpaceEscape,rubyParenthesisEscape,rubyNestedParentheses
+
+" Generalized Double Quoted Strings, Array of Strings, Array of Symbols and Shell Command Output {{{1
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="\%(\%(\w\|[^\x00-\x7F]\|]\)\s*\)\@<!%=" end="="  skip="\\\\\|\\="   contains=@rubyStringSpecial nextgroup=@rubyModifier skipwhite
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%\z([~`!@#$%^&*_\-+|\:;"',.?/]\)"       end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial nextgroup=@rubyModifier skipwhite
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%[QWx]\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial nextgroup=@rubyModifier skipwhite
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%[QWx]\={"                             end="}"   skip="\\\\\|\\}"   contains=@rubyStringSpecial,rubyNestedCurlyBraces
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%[QWx]\=<"                             end=">"   skip="\\\\\|\\>"   contains=@rubyStringSpecial,rubyNestedAngleBrackets
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%[QWx]\=\["                            end="\]"  skip="\\\\\|\\\]"  contains=@rubyStringSpecial,rubyNestedSquareBrackets
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%[QWx]\=("                             end=")"   skip="\\\\\|\\)"   contains=@rubyStringSpecial,rubyNestedParentheses
+SynFold '%' syn region rubyString matchgroup=rubyPercentStringDelimiter start="%[Qx]\z(\s\)"                          end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial
+
+SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%I\z([~`!@#$%^&*_\-+=|\:;"',.?/]\)" end="\z1" skip="\\\\\|\\\z1" contains=@rubyStringSpecial nextgroup=@rubyModifier skipwhite
+SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%I{"                               end="}"   skip="\\\\\|\\}"   contains=@rubyStringSpecial,rubyNestedCurlyBraces
+SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%I<"                               end=">"   skip="\\\\\|\\>"   contains=@rubyStringSpecial,rubyNestedAngleBrackets
+SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%I\["                              end="\]"  skip="\\\\\|\\\]"  contains=@rubyStringSpecial,rubyNestedSquareBrackets
+SynFold '%' syn region rubySymbol matchgroup=rubyPercentSymbolDelimiter start="%I("                               end=")"   skip="\\\\\|\\)"   contains=@rubyStringSpecial,rubyNestedParentheses
+
+" Here Documents {{{1
+syn region rubyHeredocStart matchgroup=rubyHeredocDelimiter start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<[-~]\=\zs\%(\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)+ end=+$+ oneline contains=ALLBUT,@rubyNotTop
+
+syn region rubyHeredocStart matchgroup=rubyHeredocDelimiter start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<[-~]\=\zs"\%([^"]*\)"+                                    end=+$+ oneline contains=ALLBUT,@rubyNotTop
+syn region rubyHeredocStart matchgroup=rubyHeredocDelimiter start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<[-~]\=\zs'\%([^']*\)'+                                    end=+$+ oneline contains=ALLBUT,@rubyNotTop
+syn region rubyHeredocStart matchgroup=rubyHeredocDelimiter start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<[-~]\=\zs`\%([^`]*\)`+                                    end=+$+ oneline contains=ALLBUT,@rubyNotTop
+
+SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<\z(\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2  matchgroup=rubyHeredocDelimiter end=+^\z1$+      contains=rubyHeredocStart,@rubyStringSpecial keepend
+SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<"\z([^"]*\)"\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2                                     matchgroup=rubyHeredocDelimiter end=+^\z1$+       contains=rubyHeredocStart,@rubyStringSpecial keepend
+SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<'\z([^']*\)'\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2                                     matchgroup=rubyHeredocDelimiter end=+^\z1$+       contains=rubyHeredocStart                    keepend
+SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})"'`]\)\s\|\w\)\@<!<<`\z([^`]*\)`\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+2                                     matchgroup=rubyHeredocDelimiter end=+^\z1$+       contains=rubyHeredocStart,@rubyStringSpecial keepend
+
+SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})]\)\s\|\w\)\@<!<<[-~]\z(\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3 matchgroup=rubyHeredocDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart,@rubyStringSpecial keepend
+SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})]\)\s\|\w\)\@<!<<[-~]"\z([^"]*\)"\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3                                    matchgroup=rubyHeredocDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart,@rubyStringSpecial keepend
+SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})]\)\s\|\w\)\@<!<<[-~]'\z([^']*\)'\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3                                    matchgroup=rubyHeredocDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart                    keepend
+SynFold '<<' syn region rubyString start=+\%(\%(class\|::\|\.\@1<!\.\)\_s*\|\%([]})]\)\s\|\w\)\@<!<<[-~]`\z([^`]*\)`\ze\%(.*<<[-~]\=['`"]\=\h\)\@!+hs=s+3                                    matchgroup=rubyHeredocDelimiter end=+^\s*\zs\z1$+ contains=rubyHeredocStart,@rubyStringSpecial keepend
 
 " Module, Class, Method and Alias Declarations {{{1
-syn match  rubyAliasDeclaration    "[^[:space:];#.()]\+" contained contains=rubySymbol,rubyGlobalVariable,rubyPredefinedVariable nextgroup=rubyAliasDeclaration2 skipwhite
-syn match  rubyAliasDeclaration2   "[^[:space:];#.()]\+" contained contains=rubySymbol,rubyGlobalVariable,rubyPredefinedVariable
-syn match  rubyMethodDeclaration   "[^[:space:];#(]\+"  contained contains=rubyConstant,rubyBoolean,rubyPseudoVariable,rubyInstanceVariable,rubyClassVariable,rubyGlobalVariable
-syn match  rubyClassDeclaration    "[^[:space:];#<]\+"  contained contains=rubyClassName,rubyOperator
-syn match  rubyModuleDeclaration   "[^[:space:];#<]\+"  contained contains=rubyModuleName,rubyOperator
-syn match  rubyMethodName "\<[_[:alpha:]][_[:alnum:]]*[?!=]\=[[:alnum:]_.:?!=]\@!" contained containedin=rubyMethodDeclaration
-syn match  rubyMethodName "\%(\s\|^\)\@1<=[_[:alpha:]][_[:alnum:]]*[?!=]\=\%(\s\|$\)\@=" contained containedin=rubyAliasDeclaration,rubyAliasDeclaration2
-syn match  rubyMethodName "\%([[:space:].]\|^\)\@2<=\%(\[\]=\=\|\*\*\|[-+!~]@\=\|[*/%|&^~]\|<<\|>>\|[<>]=\=\|<=>\|===\|[=!]=\|[=!]\~\|!\|`\)\%([[:space:];#(]\|$\)\@=" contained containedin=rubyAliasDeclaration,rubyAliasDeclaration2,rubyMethodDeclaration
+syn match rubyAliasDeclaration "[^[:space:];#.()]\+" contained contains=rubySymbol,@rubyGlobalVariable nextgroup=rubyAliasDeclaration2 skipwhite
+syn match rubyAliasDeclaration2 "[^[:space:];#.()]\+" contained contains=rubySymbol,@rubyGlobalVariable
+syn match rubyMethodDeclaration "[^[:space:];#(]\+"   contained contains=rubyConstant,rubyBoolean,rubyPseudoVariable,rubyInstanceVariable,rubyClassVariable,rubyGlobalVariable
+syn match rubyClassDeclaration "[^[:space:];#<]\+"   contained contains=rubyClassName,rubyScopeOperator nextgroup=rubySuperClassOperator skipwhite skipnl
+syn match rubyModuleDeclaration "[^[:space:];#<]\+"   contained contains=rubyModuleName,rubyScopeOperator
+
+syn match rubyMethodName "\<\%([_[:alpha:]]\|[^\x00-\x7F]\)\%([_[:alnum:]]\|[^\x00-\x7F]\)*[?!=]\=\%([[:alnum:]_.:?!=]\|[^\x00-\x7F]\)\@!"                           contained containedin=rubyMethodDeclaration
+syn match rubyMethodName "\%(\s\|^\)\@1<=\%([_[:alpha:]]\|[^\x00-\x7F]\)\%([_[:alnum:]]\|[^\x00-\x7F]\)*[?!=]\=\%(\s\|$\)\@="                                        contained containedin=rubyAliasDeclaration,rubyAliasDeclaration2
+syn match rubyMethodName "\%([[:space:].]\|^\)\@1<=\%(\[\]=\=\|\*\*\|[-+!~]@\=\|[*/%|&^~]\|<<\|>>\|[<>]=\=\|<=>\|===\|[=!]=\|[=!]\~\|!\|`\)\%([[:space:];#(]\|$\)\@=" contained containedin=rubyAliasDeclaration,rubyAliasDeclaration2,rubyMethodDeclaration
 
-syn cluster rubyDeclaration contains=rubyAliasDeclaration,rubyAliasDeclaration2,rubyMethodDeclaration,rubyModuleDeclaration,rubyClassDeclaration,rubyMethodName,rubyBlockParameter
+syn cluster rubyDeclaration contains=rubyAliasDeclaration,rubyAliasDeclaration2,rubyMethodDeclaration,rubyModuleDeclaration,rubyClassDeclaration,rubyMethodName
 
 " 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\)\>[?!]\@!"
-syn match   rubyOperator       "\<defined?" display
-syn match   rubyKeyword               "\<\%(super\|yield\)\>[?!]\@!"
-syn match   rubyBoolean               "\<\%(true\|false\)\>[?!]\@!"
-syn match   rubyPseudoVariable "\<\%(nil\|self\|__ENCODING__\|__dir__\|__FILE__\|__LINE__\|__callee__\|__method__\)\>[?!]\@!" " TODO: reorganise
-syn match   rubyBeginEnd       "\<\%(BEGIN\|END\)\>[?!]\@!"
+" TODO: reorganise
+syn match rubyControl       "\%#=1\<\%(break\|in\|next\|redo\|retry\|return\)\>"
+syn match rubyKeyword       "\%#=1\<\%(super\|yield\)\>"
+syn match rubyBoolean       "\%#=1\<\%(true\|false\)\>[?!]\@!"
+syn match rubyPseudoVariable "\%#=1\<\(self\|nil\)\>[?!]\@!"
+syn match rubyPseudoVariable "\%#=1\<__\%(ENCODING\|dir\|FILE\|LINE\|callee\|method\)__\>"
+syn match rubyBeginEnd      "\%#=1\<\%(BEGIN\|END\)\>"
 
 " 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 "\<alias\>"  nextgroup=rubyAliasDeclaration  skipwhite skipnl
-  syn match  rubyDefine "\<def\>"    nextgroup=rubyMethodDeclaration skipwhite skipnl
-  syn match  rubyDefine "\<undef\>"  nextgroup=rubyMethodName       skipwhite skipnl
-  syn match  rubyClass "\<class\>"  nextgroup=rubyClassDeclaration  skipwhite skipnl
-  syn match  rubyModule "\<module\>" nextgroup=rubyModuleDeclaration skipwhite skipnl
-
-  if s:foldable('def')
-    syn region rubyMethodBlock start="\<def\>" matchgroup=rubyDefine end="\%(\<def\_s\+\)\@<!\<end\>" contains=ALLBUT,@rubyNotTop fold
-  else
-    syn region rubyMethodBlock start="\<def\>" matchgroup=rubyDefine end="\%(\<def\_s\+\)\@<!\<end\>" contains=ALLBUT,@rubyNotTop
-  endif
-
-  if s:foldable('class')
-    syn region rubyBlock start="\<class\>"     matchgroup=rubyClass end="\<end\>" contains=ALLBUT,@rubyNotTop fold
-  else
-    syn region rubyBlock start="\<class\>"     matchgroup=rubyClass end="\<end\>" contains=ALLBUT,@rubyNotTop
-  endif
+  syn match rubyDefine "\<alias\>"  nextgroup=rubyAliasDeclaration                       skipwhite skipnl
+  syn match rubyDefine "\<def\>"    nextgroup=rubyMethodDeclaration                      skipwhite skipnl
+  syn match rubyDefine "\<undef\>"  nextgroup=rubyMethodName                             skipwhite skipnl
+  syn match rubyClass  "\<class\>"  nextgroup=rubyClassDeclaration,rubyEigenClassOperator skipwhite skipnl
+  syn match rubyModule "\<module\>" nextgroup=rubyModuleDeclaration                      skipwhite skipnl
 
-  if s:foldable('module')
-    syn region rubyBlock start="\<module\>" matchgroup=rubyModule end="\<end\>" contains=ALLBUT,@rubyNotTop fold
-  else
-    syn region rubyBlock start="\<module\>" matchgroup=rubyModule end="\<end\>" contains=ALLBUT,@rubyNotTop
-  endif
+  SynFold 'def'    syn region rubyMethodBlock start="\<def\>"   matchgroup=rubyDefine skip="\<end:\|\%(\<def\_s\+\)\@<=end\>" end="\<end\>" contains=ALLBUT,@rubyNotTop
+  SynFold 'class'  syn region rubyClassBlock  start="\<class\>"  matchgroup=rubyClass  skip="\<end:"                          end="\<end\>" contains=ALLBUT,@rubyNotTop
+  SynFold 'module' syn region rubyModuleBlock start="\<module\>" matchgroup=rubyModule skip="\<end:"                          end="\<end\>" contains=ALLBUT,@rubyNotTop
 
   " modifiers
-  syn match rubyLineContinuation    "\\$" nextgroup=rubyConditionalModifier,rubyRepeatModifier skipwhite skipnl
+  syn match rubyLineContinuation    "\\$" nextgroup=@rubyModifier skipwhite skipnl
   syn match rubyConditionalModifier "\<\%(if\|unless\)\>"
   syn match rubyRepeatModifier     "\<\%(while\|until\)\>"
+  syn match rubyRescueModifier     "\<rescue\>"
 
-  if s:foldable('do')
-    syn region rubyDoBlock matchgroup=rubyControl start="\<do\>" end="\<end\>" contains=ALLBUT,@rubyNotTop fold
-  else
-    syn region rubyDoBlock matchgroup=rubyControl start="\<do\>" end="\<end\>" contains=ALLBUT,@rubyNotTop
-  endif
+  syn cluster rubyModifier contains=rubyConditionalModifier,rubyRepeatModifier,rubyRescueModifier
 
-  " curly bracket block or hash literal
-  if s:foldable('{')
-    syn region rubyCurlyBlock matchgroup=rubyCurlyBlockDelimiter start="{" end="}" contains=ALLBUT,@rubyNotTop fold
-  else
-    syn region rubyCurlyBlock matchgroup=rubyCurlyBlockDelimiter start="{" end="}" contains=ALLBUT,@rubyNotTop
-  endif
+  SynFold 'do' syn region rubyDoBlock matchgroup=rubyControl start="\<do\>" skip="\<end:" end="\<end\>" contains=ALLBUT,@rubyNotTop
 
-  if s:foldable('[')
-    syn region rubyArrayLiteral        matchgroup=rubyArrayDelimiter start="\%(\w\|[\]})]\)\@<!\[" end="]" contains=ALLBUT,@rubyNotTop fold
-  endif
+  " curly bracket block or hash literal
+  SynFold '{' syn region rubyCurlyBlock   matchgroup=rubyCurlyBlockDelimiter start="{"                                             end="}" contains=ALLBUT,@rubyNotTop
+  SynFold '[' syn region rubyArrayLiteral matchgroup=rubyArrayDelimiter      start="\%(\%(\w\|[^\x00-\x7F]\)[?!]\=\|[]})]\)\@2<!\[" end="]" contains=ALLBUT,@rubyNotTop
 
   " statements without 'do'
-  if s:foldable('begin')
-    syn region rubyBlockExpression matchgroup=rubyControl start="\<begin\>" end="\<end\>" contains=ALLBUT,@rubyNotTop fold
-  else
-    syn region rubyBlockExpression matchgroup=rubyControl start="\<begin\>" end="\<end\>" contains=ALLBUT,@rubyNotTop
-  endif
+  SynFold 'begin' syn region rubyBlockExpression matchgroup=rubyControl     start="\<begin\>" skip="\<end:" end="\<end\>" contains=ALLBUT,@rubyNotTop
+  SynFold 'case'  syn region rubyCaseExpression  matchgroup=rubyConditional start="\<case\>"  skip="\<end:" end="\<end\>" contains=ALLBUT,@rubyNotTop
 
-  if s:foldable('case')
-    syn region rubyCaseExpression matchgroup=rubyConditional start="\<case\>" end="\<end\>" contains=ALLBUT,@rubyNotTop fold
-  else
-    syn region rubyCaseExpression matchgroup=rubyConditional start="\<case\>" end="\<end\>" contains=ALLBUT,@rubyNotTop
-  endif
+  SynFold 'if' syn region rubyConditionalExpression matchgroup=rubyConditional start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+=-]\|\<then\s\|\%(\<\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\@<![?!]\)\s*\)\@<=\%(if\|unless\)\>" skip="\<end:" end="\<end\>" contains=ALLBUT,@rubyNotTop
 
-  if s:foldable('if')
-    syn region rubyConditionalExpression matchgroup=rubyConditional start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*%&^|+=-]\|\%(\<[_[:lower:]][_[:alnum:]]*\)\@<![?!]\)\s*\)\@<=\%(if\|unless\)\>" end="\%(\%(\%(\.\@1<!\.\)\|::\)\s*\)\@<!\<end\>" contains=ALLBUT,@rubyNotTop fold
-  else
-    syn region rubyConditionalExpression matchgroup=rubyConditional start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*%&^|+=-]\|\%(\<[_[:lower:]][_[:alnum:]]*\)\@<![?!]\)\s*\)\@<=\%(if\|unless\)\>" end="\%(\%(\%(\.\@1<!\.\)\|::\)\s*\)\@<!\<end\>" contains=ALLBUT,@rubyNotTop
-  endif
+  syn match rubyConditional "\<\%(then\|else\|when\)\>"         contained containedin=rubyCaseExpression
+  syn match rubyConditional "\<\%(then\|else\|elsif\)\>" contained containedin=rubyConditionalExpression
 
-  syn match rubyConditional "\<\%(then\|else\|when\)\>[?!]\@!" contained containedin=rubyCaseExpression
-  syn match rubyConditional "\<\%(then\|else\|elsif\)\>[?!]\@!" contained containedin=rubyConditionalExpression
-
-  syn match rubyExceptional      "\<\%(\%(\%(;\|^\)\s*\)\@<=rescue\|else\|ensure\)\>[?!]\@!" contained containedin=rubyBlockExpression
-  syn match rubyMethodExceptional "\<\%(\%(\%(;\|^\)\s*\)\@<=rescue\|else\|ensure\)\>[?!]\@!" contained containedin=rubyMethodBlock
+  syn match   rubyExceptionHandler  "\<\%(\%(\%(;\|^\)\s*\)\@<=rescue\|else\|ensure\)\>" contained containedin=rubyBlockExpression,rubyDoBlock
+  syn match   rubyExceptionHandler2 "\<\%(\%(\%(;\|^\)\s*\)\@<=rescue\|else\|ensure\)\>" contained containedin=rubyModuleBlock,rubyClassBlock,rubyMethodBlock
+  syn cluster rubyExceptionHandler  contains=rubyExceptionHandler,rubyExceptionHandler2
 
   " statements with optional 'do'
-  syn region rubyOptionalDoLine   matchgroup=rubyRepeat start="\<for\>[?!]\@!" start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+-]\|\%(\<[_[:lower:]][_[:alnum:]]*\)\@<![!=?]\)\s*\)\@<=\<\%(until\|while\)\>" matchgroup=rubyOptionalDo end="\%(\<do\>\)" end="\ze\%(;\|$\)" oneline contains=ALLBUT,@rubyNotTop
+  syn region rubyOptionalDoLine matchgroup=rubyRepeat start="\<for\>" start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+=-]\|\%(\<\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\@<![!?]\)\s*\)\@<=\<\%(until\|while\)\>" matchgroup=rubyOptionalDo end="\<do\>" end="\ze\%(;\|$\)" oneline contains=ALLBUT,@rubyNotTop
 
-  if s:foldable('for')
-    syn region rubyRepeatExpression start="\<for\>[?!]\@!" start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+-]\|\%(\<[_[:lower:]][_[:alnum:]]*\)\@<![!=?]\)\s*\)\@<=\<\%(until\|while\)\>" matchgroup=rubyRepeat end="\<end\>" contains=ALLBUT,@rubyNotTop nextgroup=rubyOptionalDoLine fold
-  else
-    syn region rubyRepeatExpression start="\<for\>[?!]\@!" start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+-]\|\%(\<[_[:lower:]][_[:alnum:]]*\)\@<![!=?]\)\s*\)\@<=\<\%(until\|while\)\>" matchgroup=rubyRepeat end="\<end\>" contains=ALLBUT,@rubyNotTop nextgroup=rubyOptionalDoLine
-  endif
+  SynFold 'for' syn region rubyRepeatExpression start="\<for\>" start="\%(\%(^\|\.\.\.\=\|[{:,;([<>~\*/%&^|+=-]\|\%(\<\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*\)\@<![!?]\)\s*\)\@<=\<\%(until\|while\)\>" matchgroup=rubyRepeat skip="\<end:" end="\<end\>" contains=ALLBUT,@rubyNotTop nextgroup=rubyOptionalDoLine
 
   if !exists("ruby_minlines")
     let ruby_minlines = 500
   endif
-  exec "syn sync minlines=" . ruby_minlines
+  exe "syn sync minlines=" . ruby_minlines
 
 else
-  syn match rubyControl "\<def\>[?!]\@!"    nextgroup=rubyMethodDeclaration skipwhite skipnl
-  syn match rubyControl "\<class\>[?!]\@!"  nextgroup=rubyClassDeclaration  skipwhite skipnl
-  syn match rubyControl "\<module\>[?!]\@!" nextgroup=rubyModuleDeclaration skipwhite skipnl
-  syn match rubyControl "\<\%(case\|begin\|do\|for\|if\|unless\|while\|until\|else\|elsif\|ensure\|then\|when\|end\)\>[?!]\@!"
-  syn match rubyKeyword "\<\%(alias\|undef\)\>[?!]\@!"
+  syn match rubyControl "\<def\>"    nextgroup=rubyMethodDeclaration skipwhite skipnl
+  syn match rubyControl "\<class\>"  nextgroup=rubyClassDeclaration  skipwhite skipnl
+  syn match rubyControl "\<module\>" nextgroup=rubyModuleDeclaration skipwhite skipnl
+  syn match rubyControl "\<\%(case\|begin\|do\|for\|if\|unless\|while\|until\|else\|elsif\|rescue\|ensure\|then\|when\|end\)\>"
+  syn match rubyKeyword "\<\%(alias\|undef\)\>"
 endif
 
 " 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
-  syn match   rubyAttribute "\%(\%(^\|;\)\s*\)\@<=attr\>\(\s*[.=]\)\@!"
-  syn keyword rubyAttribute attr_accessor attr_reader attr_writer
-  syn match   rubyControl   "\<\%(exit!\|\%(abort\|at_exit\|exit\|fork\|loop\|trap\)\>[?!]\@!\)"
-  syn keyword rubyEval     eval class_eval instance_eval module_eval
-  syn keyword rubyException raise fail catch throw
-  syn keyword rubyInclude   autoload gem load require require_relative
-  syn keyword rubyKeyword   callcc caller lambda proc
-  " false positive with 'include?'
-  syn match   rubyMacro     "\<include\>[?!]\@!"
-  syn keyword rubyMacro     extend prepend refine using
-  syn keyword rubyMacro     alias_method define_method define_singleton_method remove_method undef_method
+  syn match rubyAccess   "\<\%(public\|protected\|private\)\>" " use re=2
+  syn match rubyAccess   "\%#=1\<\%(public\|private\)_class_method\>"
+  syn match rubyAccess   "\%#=1\<\%(public\|private\)_constant\>"
+  syn match rubyAccess   "\%#=1\<module_function\>"
+  syn match rubyAttribute "\%#=1\%(\%(^\|;\)\s*\)\@<=attr\>\(\s*[.=]\)\@!" " attr is a common variable name
+  syn match rubyAttribute "\%#=1\<attr_\%(accessor\|reader\|writer\)\>"
+  syn match rubyControl   "\%#=1\<\%(abort\|at_exit\|exit\|fork\|loop\|trap\)\>"
+  syn match rubyEval     "\%#=1\<eval\>"
+  syn match rubyEval     "\%#=1\<\%(class\|instance\|module\)_eval\>"
+  syn match rubyException "\%#=1\<\%(raise\|fail\|catch\|throw\)\>"
+  syn match rubyInclude   "\%#=1\<\%(autoload\|gem\|load\|require\%(_relative\)\=\)\>"
+  syn match rubyKeyword   "\%#=1\<\%(callcc\|caller\|lambda\|proc\)\>"
+  syn match rubyMacro    "\%#=1\<\%(extend\|include\|prepend\|refine\|using\)\>"
+  syn match rubyMacro    "\%#=1\<\%(alias\|define\|define_singleton\|remove\|undef\)_method\>"
 endif
 
 " 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
+syn match   rubySharpBang    "\%^#!.*" display
+syn keyword rubyTodo        FIXME NOTE TODO OPTIMIZE HACK REVIEW XXX todo contained
+syn match   rubyEncoding     "[[:alnum:]-]\+" contained display
+syn match   rubyMagicComment "\c\%<3l#\s*\zs\%(coding\|encoding\):"                                    contained nextgroup=rubyEncoding skipwhite
+syn match   rubyMagicComment "\c\%<10l#\s*\zs\%(frozen_string_literal\|warn_indent\|warn_past_scope\):" contained nextgroup=rubyBoolean  skipwhite
+syn match   rubyComment             "#.*" contains=@rubyCommentSpecial,rubySpaceError,@Spell
+
+syn cluster rubyCommentSpecial contains=rubySharpBang,rubyTodo,rubyMagicComment
+syn cluster rubyCommentNotTop  contains=@rubyCommentSpecial,rubyEncoding
+
 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
+  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
+  syn region rubyDocumentation   start="^=begin\s*$"            end="^=end\s*$"              contains=rubySpaceError,rubyTodo,@Spell
 endif
 
+" {{{1 Useless Line Continuations
+syn match rubyUselessLineContinuation "\%([.:,;{([<>~\*%&^|+=-]\|%(\%(\w\|[^\x00-\x7F]\)\@1<![?!]\)\s*\zs\\$" nextgroup=rubyUselessLineContinuation skipwhite skipempty
+syn match rubyUselessLineContinuation "\\$"                                                                  nextgroup=rubyUselessLineContinuation skipwhite skipempty contained
+
 " 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 "\%(\%(\.\@1<!\.\)\|::\)\_s*\%([_[:lower:]][_[:alnum:]]*\|\<\%(BEGIN\|END\)\>\)" transparent contains=NONE
-syn match rubyKeywordAsMethod "\(defined?\|exit!\)\@!\<[_[:lower:]][_[:alnum:]]*[?!]"                         transparent contains=NONE
+" prevent methods with keyword names being highlighted as keywords when called
+syn match rubyKeywordAsMethod "\%(\%(\.\@1<!\.\)\|&\.\|::\)\_s*\%([_[:lower:]][_[:alnum:]]*\|\%(BEGIN\|END\)\>\)" transparent contains=rubyDotOperator,rubyScopeOperator
 
-" More Symbols {{{1
-syn match  rubySymbol          "\%([{(,]\_s*\)\zs\l\w*[!?]\=::\@!"he=e-1
-syn match  rubySymbol          "[]})\"':]\@1<!\<\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[!?]\=:[[:space:],]\@="he=e-1
-syn match  rubySymbol          "\%([{(,]\_s*\)\zs[[:space:],{]\l\w*[!?]\=::\@!"hs=s+1,he=e-1
-syn match  rubySymbol          "[[:space:],{(]\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[!?]\=:[[:space:],]\@="hs=s+1,he=e-1
+" Bang and Predicate Methods and Operators {{{1
+syn match rubyBangPredicateMethod "\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[?!]"
 
-" __END__ Directive {{{1
-if s:foldable('__END__')
-  syn region rubyData matchgroup=rubyDataDirective start="^__END__$" end="\%$" fold
-else
-  syn region rubyData matchgroup=rubyDataDirective start="^__END__$" end="\%$"
+if !exists("ruby_no_special_methods")
+  syn match rubyControl "\%#=1\<exit!" display
 endif
+syn match rubyDefinedOperator "\%#=1\<defined?" display
+
+" 1.9-style Hash Keys and Keyword Parameters {{{1
+syn match rubySymbol "\%([{(|,]\_s*\)\@<=\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[?!]\=::\@!"he=e-1
+syn match rubySymbol "[]})\"':]\@1<!\<\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[!?]\=:[[:space:],;]\@="he=e-1
+syn match rubySymbol "[[:space:],{(]\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[!?]\=:[[:space:],;]\@="hs=s+1,he=e-1
+
+" __END__ Directive {{{1
+SynFold '__END__' syn region rubyData matchgroup=rubyDataDirective start="^__END__$" end="\%$"
 
 " Default Highlighting {{{1
 hi def link rubyClass                  rubyDefine
 hi def link rubyModule                 rubyDefine
-hi def link rubyMethodExceptional      rubyDefine
+hi def link rubyExceptionHandler2      rubyDefine
 hi def link rubyDefine                 Define
 hi def link rubyAccess                 rubyMacro
 hi def link rubyAttribute              rubyMacro
@@ -488,14 +481,15 @@ hi def link rubyMethodName                rubyFunction
 hi def link rubyFunction               Function
 hi def link rubyConditional            Conditional
 hi def link rubyConditionalModifier    rubyConditional
-hi def link rubyExceptional            rubyConditional
+hi def link rubyExceptionHandler       rubyConditional
+hi def link rubyRescueModifier         rubyExceptionHandler
 hi def link rubyRepeat                 Repeat
 hi def link rubyRepeatModifier         rubyRepeat
 hi def link rubyOptionalDo             rubyRepeat
 hi def link rubyControl                        Statement
 hi def link rubyInclude                        Include
 hi def link rubyInteger                        Number
-hi def link rubyASCIICode              Character
+hi def link rubyCharacter              Character
 hi def link rubyFloat                  Float
 hi def link rubyBoolean                        Boolean
 hi def link rubyException              Exception
@@ -515,39 +509,80 @@ hi def link rubyPredefinedConstant        rubyPredefinedIdentifier
 hi def link rubyPredefinedVariable     rubyPredefinedIdentifier
 hi def link rubySymbol                 Constant
 hi def link rubyKeyword                        Keyword
+
 hi def link rubyOperator               Operator
+hi def link rubyDefinedOperator                rubyOperator
+hi def link rubyEnglishBooleanOperator rubyOperator
+if exists("ruby_operators")
+  hi def link rubyTernaryOperator      rubyOperator
+  hi def link rubyArithmeticOperator   rubyOperator
+  hi def link rubyComparisonOperator   rubyOperator
+  hi def link rubyBitwiseOperator      rubyOperator
+  hi def link rubyBooleanOperator      rubyOperator
+  hi def link rubyRangeOperator                rubyOperator
+  hi def link rubyAssignmentOperator   rubyOperator
+  hi def link rubyEqualityOperator     rubyOperator
+endif
+
+if exists("ruby_pseudo_operators")
+  hi def link rubyPseudoOperator       Special
+  hi def link rubyDotOperator          rubyPseudoOperator
+  hi def link rubyScopeOperator                rubyPseudoOperator
+  hi def link rubySuperClassOperator   rubyPseudoOperator
+  hi def link rubyEigenClassOperator   rubyPseudoOperator
+  hi def link rubyLambdaOperator       rubyPseudoOperator
+  hi def link rubyDoubleSplatOperator  rubyPseudoOperator
+  hi def link rubySplatOperator                rubyPseudoOperator
+  hi def link rubyProcOperator         rubyPseudoOperator
+endif
+
 hi def link rubyBeginEnd               Statement
 hi def link rubyEval                   Statement
 hi def link rubyPseudoVariable         Constant
-hi def link rubyCapitalizedMethod      rubyLocalVariableOrMethod
+hi def link rubyCapitalizedMethod      NONE
 
 hi def link rubyComment                        Comment
+hi def link rubyEncoding               Constant
+hi def link rubyMagicComment           SpecialComment
 hi def link rubyData                   Comment
 hi def link rubyDataDirective          Delimiter
 hi def link rubyDocumentation          Comment
 hi def link rubyTodo                   Todo
 
+hi def link rubyBackslashEscape                rubyStringEscape
 hi def link rubyQuoteEscape            rubyStringEscape
+hi def link rubySpaceEscape            rubyStringEscape
+hi def link rubyParenthesisEscape      rubyStringEscape
+hi def link rubyCurlyBraceEscape       rubyStringEscape
+hi def link rubyAngleBracketEscape     rubyStringEscape
+hi def link rubySquareBracketEscape    rubyStringEscape
 hi def link rubyStringEscape           Special
+
 hi def link rubyInterpolationDelimiter Delimiter
-hi def link rubyNoInterpolation                rubyString
 hi def link rubySharpBang              PreProc
+hi def link rubyStringDelimiter                Delimiter
+hi def link rubyHeredocDelimiter       rubyStringDelimiter
+hi def link rubyPercentRegexpDelimiter rubyRegexpDelimiter
+hi def link rubyPercentStringDelimiter rubyStringDelimiter
+hi def link rubyPercentSymbolDelimiter rubySymbolDelimiter
 hi def link rubyRegexpDelimiter                rubyStringDelimiter
 hi def link rubySymbolDelimiter                rubySymbol
-hi def link rubyStringDelimiter                Delimiter
-hi def link rubyHeredoc                        rubyString
 hi def link rubyString                 String
 hi def link rubyRegexpEscape           rubyRegexpSpecial
 hi def link rubyRegexpQuantifier       rubyRegexpSpecial
 hi def link rubyRegexpAnchor           rubyRegexpSpecial
 hi def link rubyRegexpDot              rubyRegexpCharClass
 hi def link rubyRegexpCharClass                rubyRegexpSpecial
+hi def link rubyRegexpIntersection     rubyRegexpSpecial
 hi def link rubyRegexpSpecial          Special
 hi def link rubyRegexpComment          Comment
 hi def link rubyRegexp                 rubyString
 
-hi def link rubyInvalidVariable                Error
 hi def link rubyError                  Error
+if exists("ruby_line_continuation_error")
+  hi def link rubyUselessLineContinuation rubyError
+endif
+hi def link rubyGlobalVariableError    rubyError
 hi def link rubySpaceError             rubyError
 
 " Postscript {{{1
@@ -556,4 +591,6 @@ let b:current_syntax = "ruby"
 let &cpo = s:cpo_sav
 unlet! s:cpo_sav
 
+delc SynFold
+
 " vim: nowrap sw=2 sts=2 ts=8 noet fdm=marker: