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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
# File 'lib/headless_browser_tool/tools/search_source_tool.rb', line 20
def execute(query:, case_sensitive: false, regex: false, context_lines: 2, show_line_numbers: true)
source = browser.html
lines = source.split("\n")
pattern = if regex
Regexp.new(query, case_sensitive ? nil : Regexp::IGNORECASE)
else
escaped_query = Regexp.escape(query)
Regexp.new(escaped_query, case_sensitive ? nil : Regexp::IGNORECASE)
end
matches = []
lines.each_with_index do |line, index|
next unless line =~ pattern
start_idx = [0, index - context_lines].max
end_idx = [lines.length - 1, index + context_lines].min
match_entry = {
line_number: index + 1,
line: line,
match_count: line.scan(pattern).size
}
if context_lines.positive?
context_before = []
context_after = []
(start_idx...index).each do |i|
context_line = show_line_numbers ? "#{i + 1}: #{lines[i]}" : lines[i]
context_before << context_line
end
((index + 1)..end_idx).each do |i|
context_line = show_line_numbers ? "#{i + 1}: #{lines[i]}" : lines[i]
context_after << context_line
end
match_entry[:context] = {
before: context_before,
after: context_after
}
end
highlighted_line = line.gsub(pattern) { |match| ">>#{match}<<" }
match_entry[:highlighted] = highlighted_line
matches << match_entry
end
match_analysis = analyze_matches(matches, lines, pattern)
{
query: query,
total_matches: matches.sum { |m| m[:match_count] },
total_lines_with_matches: matches.size,
matches: matches.map do |match|
result = {
line_number: match[:line_number],
line: match[:line].strip,
highlighted: match[:highlighted].strip,
occurrences: match[:match_count]
}
result[:context] = match[:context] if match[:context]
result
end,
analysis: match_analysis
}
end
|