Skip to content

fix if/else folding bug #468

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 23 additions & 33 deletions spec/folding/basic_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

63 changes: 40 additions & 23 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
require 'vimrunner/rspec'

class Buffer
FOLD_PLACEHOLDER = '<!-- FOLD -->'.freeze

def initialize(vim, type)
@file = ".fixture.#{type}"
@vim = vim
Expand Down Expand Up @@ -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*//<CR>")
end
end

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion syntax/elixir.vim
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ syn match elixirAtomInterpolated ':\("\)\@=' contains=elixirString
syn match elixirString "\(\w\)\@<!?\%(\\\(x\d{1,2}\|\h{1,2}\h\@!\>\|0[0-7]{0,2}[0-7]\@!\>\|[^x0MC]\)\|(\\[MC]-)+\w\|[^\s\\]\)"

syn region elixirBlock matchgroup=elixirBlockDefinition start="\<do\>:\@!" end="\<end\>" contains=ALLBUT,@elixirNotTop fold
syn region elixirElseBlock matchgroup=elixirBlockDefinition start="\<else\>:\@!" end="\<end\>" contains=ALLBUT,@elixirNotTop fold
syn region elixirAnonymousFunction matchgroup=elixirBlockDefinition start="\<fn\>" end="\<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
Expand Down