mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
Add support for showing code context lines (#181)
* Add support for showing code context lines * Show context lines only in ExplainFormatter * Add spec coverage for context_lines option
This commit is contained in:
parent
9bc6c13d11
commit
c4d34d74d8
3 changed files with 96 additions and 13 deletions
|
@ -22,7 +22,38 @@ module Ameba::Formatter
|
|||
a = 1
|
||||
)
|
||||
location = Crystal::Location.new("filename", 1, 1)
|
||||
subject.affected_code(source, location).should eq "> a = 1\n \e[33m^\e[0m"
|
||||
subject.deansify(subject.affected_code(source, location))
|
||||
.should eq "> a = 1\n ^"
|
||||
end
|
||||
|
||||
it "returns correct line if it is found" do
|
||||
source = Source.new <<-EOF
|
||||
# pre:1
|
||||
# pre:2
|
||||
# pre:3
|
||||
# pre:4
|
||||
# pre:5
|
||||
a = 1
|
||||
# post:1
|
||||
# post:2
|
||||
# post:3
|
||||
# post:4
|
||||
# post:5
|
||||
EOF
|
||||
|
||||
location = Crystal::Location.new("filename", 6, 1)
|
||||
subject.deansify(subject.affected_code(source, location, context_lines: 3))
|
||||
.should eq <<-STR
|
||||
> # pre:3
|
||||
> # pre:4
|
||||
> # pre:5
|
||||
> a = 1
|
||||
^
|
||||
> # post:1
|
||||
> # post:2
|
||||
> # post:3
|
||||
|
||||
STR
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -49,7 +49,7 @@ module Ameba::Formatter
|
|||
@location.to_s.colorize(:cyan).to_s,
|
||||
]
|
||||
|
||||
if affected_code = affected_code(source, @location)
|
||||
if affected_code = affected_code(source, @location, context_lines: 3)
|
||||
output_title "AFFECTED CODE"
|
||||
output_paragraph affected_code
|
||||
end
|
||||
|
|
|
@ -1,22 +1,74 @@
|
|||
module Ameba::Formatter
|
||||
module Util
|
||||
def affected_code(source, location, max_length = 100, placeholder = " ...", prompt = "> ")
|
||||
line, column = location.line_number, location.column_number
|
||||
affected_line = source.lines[line - 1]?.presence
|
||||
def deansify(message : String?) : String?
|
||||
message.try &.gsub(/\x1b[^m]*m/, "").presence
|
||||
end
|
||||
|
||||
return unless affected_line
|
||||
def affected_code(source, location, context_lines = 0, max_length = 100, placeholder = " ...", prompt = "> ")
|
||||
lines = source.lines
|
||||
lineno, column =
|
||||
location.line_number, location.column_number
|
||||
|
||||
if affected_line.size > max_length && column < max_length
|
||||
affected_line = affected_line[0, max_length - placeholder.size - 1] + placeholder
|
||||
return unless affected_line = lines[lineno - 1]?.presence
|
||||
|
||||
trim_line = Proc(String, String).new do |line|
|
||||
if line.size > max_length
|
||||
line = line[0, max_length - placeholder.size - 1] + placeholder
|
||||
end
|
||||
line
|
||||
end
|
||||
|
||||
stripped = affected_line.lstrip
|
||||
position = column - (affected_line.size - stripped.size) + prompt.size
|
||||
if column < max_length
|
||||
affected_line = trim_line.call(affected_line)
|
||||
end
|
||||
|
||||
show_context = context_lines > 0
|
||||
if show_context
|
||||
pre_context, post_context = %w[], %w[]
|
||||
|
||||
lines.each_with_index do |line, i|
|
||||
case i + 1
|
||||
when lineno - context_lines...lineno
|
||||
pre_context << trim_line.call(line)
|
||||
when lineno
|
||||
#
|
||||
when lineno + 1..lineno + context_lines
|
||||
post_context << trim_line.call(line)
|
||||
end
|
||||
end
|
||||
|
||||
# remove empty lines at the beginning/end
|
||||
pre_context.shift? unless pre_context.first?.presence
|
||||
post_context.pop? unless post_context.last?.presence
|
||||
end
|
||||
|
||||
String.build do |str|
|
||||
str << prompt << stripped << '\n'
|
||||
str << " " * (position - 1)
|
||||
str << "^".colorize(:yellow)
|
||||
if show_context
|
||||
pre_context.try &.each do |line|
|
||||
str << prompt
|
||||
str.puts(line.colorize(:dark_gray))
|
||||
end
|
||||
|
||||
str << prompt
|
||||
str.puts(affected_line.colorize(:white))
|
||||
|
||||
str << " " * (prompt.size + column - 1)
|
||||
str.puts("^".colorize(:yellow))
|
||||
|
||||
post_context.try &.each do |line|
|
||||
str << prompt
|
||||
str.puts(line.colorize(:dark_gray))
|
||||
end
|
||||
else
|
||||
stripped = affected_line.lstrip
|
||||
position = column - (affected_line.size - stripped.size) + prompt.size
|
||||
|
||||
str << prompt
|
||||
str.puts(stripped)
|
||||
|
||||
str << " " * (position - 1)
|
||||
str << "^".colorize(:yellow)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue