blob: f53c57a4d161d4cea00936bb5eabd9a788eb6292 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
# frozen_string_literal: true
module SyntaxSuggest
module Capture
# Shows surrounding kw/end pairs
#
# The purpose of showing these extra pairs is due to cases
# of ambiguity when only one visible line is matched.
#
# For example:
#
# 1 class Dog
# 2 def bark
# 4 def eat
# 5 end
# 6 end
#
# In this case either line 2 could be missing an `end` or
# line 4 was an extra line added by mistake (it happens).
#
# When we detect the above problem it shows the issue
# as only being on line 2
#
# 2 def bark
#
# Showing "neighbor" keyword pairs gives extra context:
#
# 2 def bark
# 4 def eat
# 5 end
#
#
# Example:
#
# lines = BeforeAfterKeywordEnds.new(
# block: block,
# code_lines: code_lines
# ).call()
#
class BeforeAfterKeywordEnds
def initialize(code_lines:, block:)
@scanner = ScanHistory.new(code_lines: code_lines, block: block)
@original_indent = block.current_indent
end
def call
lines = []
@scanner.scan(
up: ->(line, kw_count, end_count) {
next true if line.empty?
break if line.indent < @original_indent
next true if line.indent != @original_indent
# If we're going up and have one complete kw/end pair, stop
if kw_count != 0 && kw_count == end_count
lines << line
break
end
lines << line if line.is_kw? || line.is_end?
true
},
down: ->(line, kw_count, end_count) {
next true if line.empty?
break if line.indent < @original_indent
next true if line.indent != @original_indent
# if we're going down and have one complete kw/end pair,stop
if kw_count != 0 && kw_count == end_count
lines << line
break
end
lines << line if line.is_kw? || line.is_end?
true
}
)
@scanner.stash_changes
lines
end
end
end
end
|