diff --git a/spec/folding/basic_spec.rb b/spec/folding/basic_spec.rb index b3e2406f..67995bb1 100644 --- a/spec/folding/basic_spec.rb +++ b/spec/folding/basic_spec.rb @@ -3,56 +3,46 @@ require 'spec_helper' describe 'Basic folding' do - def self.it_folds_lines(content, lines, tags = nil) - it("folds #{lines} lines on \n#{content}", tags) do - expect(content).to fold_lines(lines, tags) + def self.fold(content) + it("properly folds \n#{content}") do + expect(content).to fold_lines end end - it_folds_lines(<<~EOF, 2) - defmodule M do - end + fold <<~EOF + defmodule M do # fold + end # fold "not in fold" EOF - it_folds_lines(<<~EOF, 4) - defmodule M do - def some_func do - end - end + fold <<~EOF + defmodule M do # fold + def some_func do # fold + end # fold + end # fold "not in fold" EOF - it_folds_lines(<<~EOF, 2, on_line: 2) + fold <<~EOF defmodule M do - def some_func do - end + def some_func do # fold + end # fold end "not in fold" EOF - it_folds_lines(<<~EOF, 2) - if true do - end + fold <<~EOF + if true do # fold + end # fold "not in fold" EOF - it_folds_lines(<<~EOF, 3, on_line: 3) - if true do - nil - else - nil - end - "not in fold" - EOF - - it_folds_lines(<<~EOF, 5, skip: "broken") - if true do - nil - else - nil - end + fold <<~EOF + if true do # fold + nil # fold + else # fold + nil # fold + end # fold "not in fold" EOF end - diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 01d60634..7c946134 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -6,6 +6,8 @@ require 'vimrunner/rspec' class Buffer + FOLD_PLACEHOLDER = ''.freeze + def initialize(vim, type) @file = ".fixture.#{type}" @vim = vim @@ -60,15 +62,15 @@ def syntax(content, pattern) syngroups.gsub!(/["'\[\]]/, '').split(', ') end - def fold_and_delete(content, opts) - start_line = opts[:on_line] + def fold_and_replace(content, fold_on_line) with_file content do @vim.command("set foldmethod=syntax") @vim.normal("zO") - @vim.normal("#{start_line}G") + @vim.normal("#{fold_on_line}G") @vim.normal("zc") - @vim.normal("dd") + @vim.normal("cc#{FOLD_PLACEHOLDER}") + @vim.normal(":.s/\s*//") end end @@ -135,14 +137,14 @@ def self.new end failure_message do |code| - <<~EOM - Expected + <<~EOM + Expected - #{@typed} - to be indented as + #{@typed} + to be indented as - #{code} - EOM + #{code} + EOM end end @@ -204,27 +206,42 @@ def self.new end end -RSpec::Matchers.define :fold_lines do |lines, opts| +RSpec::Matchers.define :fold_lines do buffer = Buffer.new(VIM, :ex) - opts ||= {} - start_line = opts[:on_line] ||= 1 - - after = nil match do |code| - after = buffer.fold_and_delete(code, opts) + @code = code + + pattern = /# fold\s*$/ + + placeholder_set = false + @expected = code.each_line.reduce([]) do |acc, line| + if line =~ pattern + if !placeholder_set + placeholder_set = true + acc << (Buffer::FOLD_PLACEHOLDER + "\n") + end + else + acc << line + end + + acc + end.join + + fold_on_line = code.each_line.find_index { |l| l =~ pattern } + 1 + @actual = buffer.fold_and_replace(code, fold_on_line) - code.lines.count - after.lines.count == lines + @expected == @actual end failure_message do |code| <<~EOF - expected - #{code} - to fold #{lines} lines at line #{start_line}, - but after folding at line #{start_line} and deleting a line I got - #{after} - back + Folded + + #{@code} + and unexpectedly got + + #{@actual} EOF end end diff --git a/syntax/elixir.vim b/syntax/elixir.vim index b3666b31..a1bc17dd 100644 --- a/syntax/elixir.vim +++ b/syntax/elixir.vim @@ -82,7 +82,6 @@ syn match elixirAtomInterpolated ':\("\)\@=' contains=elixirString syn match elixirString "\(\w\)\@\|0[0-7]{0,2}[0-7]\@!\>\|[^x0MC]\)\|(\\[MC]-)+\w\|[^\s\\]\)" syn region elixirBlock matchgroup=elixirBlockDefinition start="\:\@!" end="\" contains=ALLBUT,@elixirNotTop fold -syn region elixirElseBlock matchgroup=elixirBlockDefinition start="\:\@!" end="\" contains=ALLBUT,@elixirNotTop fold syn region elixirAnonymousFunction matchgroup=elixirBlockDefinition start="\" end="\" contains=ALLBUT,@elixirNotTop fold syn region elixirArguments start="(" end=")" contained contains=elixirOperator,elixirAtom,elixirPseudoVariable,elixirAlias,elixirBoolean,elixirVariable,elixirUnusedVariable,elixirNumber,elixirDocString,elixirAtomInterpolated,elixirRegex,elixirString,elixirStringDelimiter,elixirRegexDelimiter,elixirInterpolationDelimiter,elixirSigil,elixirAnonymousFunction,elixirComment