diff --git a/doc/ft-ruby-syntax.txt b/doc/ft-ruby-syntax.txt index fdf88a0e..46dc2695 100644 --- a/doc/ft-ruby-syntax.txt +++ b/doc/ft-ruby-syntax.txt @@ -5,7 +5,8 @@ There are a number of options to the Ruby syntax highlighting. 1. Ruby operators |ruby_operators| 2. Whitespace errors |ruby_space_errors| 3. Folds |ruby_fold| -4. Reducing expensive operations |ruby_no_expensive| |ruby_minlines| +4. Foldable groups |ruby_foldable_groups| +5. Reducing expensive operations |ruby_no_expensive| |ruby_minlines| 1. Ruby operators *ruby_operators* @@ -39,7 +40,40 @@ Folds can be enabled by defining "ruby_fold": > This will set the value |foldmethod| to "syntax" locally to the current buffer or window, which will enable syntax-based folding when editing Ruby filetypes. -4. Reducing expensive operations *ruby_no_expensive* +4. Foldable groups *ruby_foldable_groups* + +Default folding is rather detailed, i.e., small syntax units like "if", "do", +"%w[]" may create corresponding fold levels. + +You can set "ruby_foldable_groups" to restrict which groups are foldable: > + + :let ruby_foldable_groups = 'if case %' +< +value is space-separated keywords, known keywords were: + + keyword meaning ~ + -------- ------------------------------------- ~ + ALL Most block syntax (default) + NONE Nothing + if "if" or "unless" block + def "def" block + class "class" block + module "module" block + do "do" block + begin "begin" block + case "case" block + for "for", "while", "until" loops + { Curly bracket block or hash literal + [ Array literal + % Literal with "%" notation, e.g.: %w(STRING), %!STRING! + / Regexp + string String and shell command output (surrounded by ', ", `) + : Symbol + # Multiline comment + << Here documents + __END__ Source code after "__END__" directive + +5. Reducing expensive operations *ruby_no_expensive* By default, the "end" keyword is colorized according to the opening statement of the block it closes. While useful, this feature can be expensive; if you diff --git a/etc/examples/generators/syntax.rb b/etc/examples/generators/syntax.rb new file mode 100755 index 00000000..06cf1600 --- /dev/null +++ b/etc/examples/generators/syntax.rb @@ -0,0 +1,621 @@ +#!/usr/bin/env ruby + +arg = ARGV.pop + + +# Usage example: +# +# ./etc/examples/generators/syntax.rb %Q > etc/examples/syntax/Q.rb +# +# then read the output file with 'foldlevel' 0 + +puts "# Generated by `" << + "./etc/examples/generators/syntax.rb #{arg}" << + " > etc/examples/syntax/#{arg.sub('%', '')}.rb" << + "`\n\n" + + + +# %Q {{{ +# Generalized Double Quoted String and Array of Strings and Shell Command Output +if arg == '%Q' + # Note: %= is not matched here as the beginning of a double quoted string + %Q[~`!@\#$%^&*_-+|:;"',.?/].split(//).each do |s| + puts <<-END.gsub(/^\s{4}/, '') + %#{s} + foo + \\#{s} + \\\\\\#{s} + bar + #{s} + + + END + end + + %w(Q W x).each do |leading| + %Q[~`!@\#$%^&*_-+=|:;"',.?/].split(//).each do |s| + puts <<-END.gsub(/^\s{6}/, '') + %#{leading}#{s} + foo + \\#{s} + \\\\\\#{s} + bar + #{s} + + + END + end + + %w({} <> [] ()).each do |pair| + puts <<-END.gsub(/^\s{6}/, '') + %#{leading}#{pair[0]} + foo + \\#{pair[1]} + \\\\\\#{pair[1]} + bar + #{pair[1]} + + + END + end + + puts " %#{leading} foo\\ \\\\\\ bar\nbaz \n\n" unless leading == 'W' + end +end +# }}} + + + +# %q {{{ +# Generalized Single Quoted String, Symbol and Array of Strings +if arg == '%q' + %w(q w s).each do |leading| + %Q[~`!@\#$%^&*_-+=|:;"',.?/].split(//).each do |s| + puts <<-END.gsub(/^\s{6}/, '') + %#{leading}#{s} + foo + \\#{s} + \\\\\\#{s} + bar + #{s} + + + END + end + + %w({} <> [] ()).each do |pair| + puts <<-END.gsub(/^\s{6}/, '') + %#{leading}#{pair[0]} + foo + \\#{pair[1]} + \\\\\\#{pair[1]} + bar + #{pair[1]} + + + END + end + + puts " %#{leading} foo\\ \\\\\\ bar\nbaz \n\n" unless leading == 'w' + end +end +# }}} + + + +# %r {{{ +# Generalized Regular Expression +if arg == '%r' + %Q[~`!@\#$%^&*_-+=|:;"',.?/].split(//).each do |s| + puts <<-END.gsub(/^\s{4}/, '') + %r#{s} + foo + \\#{s} + \\\\\\#{s} + bar + #{s} + + + END + end + + puts " %r foo\\ \\\\\\ bar\nbaz \n\n" + + %w({} <> [] ()).each do |pair| + puts <<-END.gsub(/^\s{4}/, '') + %r#{pair[0]} + foo + \\#{pair[1]} + \\\\\\#{pair[1]} + bar + #{pair[1]} + + + END + end +end +# }}} + + + +# %i / %I {{{ +# Array of Symbols +# Array of interpolated Symbols +if %w(%i %I).include?(arg) + %w(i I).each do |leading| + %Q[~`!@\#$%^&*_-+=|:;"',.?/].split(//).each do |s| + puts <<-END.gsub(/^\s{6}/, '') + %#{leading}#{s} + foo + \\#{s} + \\\\\\#{s} + bar + #{s} + + + END + end + + %w({} <> [] ()).each do |pair| + puts <<-END.gsub(/^\s{6}/, '') + %#{leading}#{pair[0]} + foo + \\#{pair[1]} + \\\\\\#{pair[1]} + bar + #{pair[1]} + + + END + end + end +end +# }}} + + + +# string {{{ +# Normal String and Shell Command Output +if arg == 'string' + %w(' " `).each do |quote| + puts <<-END.gsub(/^\s{4}/, '') + #{quote} + foo + \\#{quote} + \\\\\\#{quote} + bar + #{quote} + + + END + end +end +# }}} + + + +# regex (Normal Regular Expression) {{{ +if arg == 'regexp' + 'iomxneus'.split('').unshift('').each do |option| + puts "\n# Begin test for option '#{option}' {{{\n\n" + + puts <<-END.gsub(/^\s{4}/, '') + / + foo + \\\/ + \\\\\\\/ + bar + /#{option} + + + END + + %w(and or while until unless if elsif when not then else).each do |s| + puts <<-END.gsub(/^\s{6}/, '') + #{s}/ + foo + \\\/ + \\\\\\\/ + bar + /#{option} + + + END + end + + %w(; \ ~ = ! | \( & , { [ < > ? : * + -).each do |s| + puts <<-END.gsub(/^\s{6}/, '') + #{s}/ + foo + \\\/ + \\\\\\\/ + bar + /#{option} + + + END + end + + [' ', "\t", '=', 'OK'].each do |s| + puts <<-END.gsub(/^\s{6}/, '') + _foo /#{s} + foo + \\\/ + \\\\\\\/ + bar + /#{option} + + + END + end + + puts "# }}} End test for option '#{option}'\n" + end + + puts "\n# Test for ternary operation (8c1c484) {{{\n\n" + puts 'yo = 4 ? /quack#{3}/ : /quack/' + puts "\n# }}} End test for ternary operation\n" +end +# }}} + + + +# symbol {{{ +# Symbol region +if arg == 'symbol' + %w(' ").each do |quote| + %Q_]})\"':_.split(//).unshift('').each do |s| + puts <<-END.gsub(/^\s{6}/, '') + #{s}:#{quote} + foo + \\#{quote} + \\\\\\#{quote} + bar + #{quote} + #{" #{s} # close string to ensure next case clean" if %w(' ").include?(s) && s != quote } + + + END + end + end +end +# }}} + + + +# heredoc {{{ +# Here Documents +if arg == 'heredoc' + puts "\n# Begin of valid cases {{{\n\n" + + %w(' " `).unshift('').each do |quote| + puts <<-END.gsub(/^\s{6}/, '') + <<#{quote}_LABEL#{quote}.?!, foo + bar baz + _LABEL + \n + + <<-#{quote}_LABEL#{quote}.?!, foo + bar baz + _LABEL + \n + + <<~#{quote}_LABEL#{quote}.?!, foo + bar baz + _LABEL + + + END + end + + puts "# }}} End of valid cases'\n\n" + + + puts "\n# Begin of INVALID cases {{{\n\n" + + # NOTE: for simplification, omit test for different quotes " ' `, + # they are all invalid anyway + + %w(class ::).each do |s| + puts <<-END.gsub(/^\s{6}/, '') + #{s}\n <