Browse Source

Initial commit

master
Dylan Baker 4 years ago
commit
07ca578cc8
1 changed files with 147 additions and 0 deletions
  1. 147
    0
      grep-around.rb

+ 147
- 0
grep-around.rb View File

@@ -0,0 +1,147 @@
1
+#!/usr/bin/env ruby
2
+require 'optparse'
3
+
4
+args = Array.new
5
+rg_args = Array.new
6
+add_to_rg_args = false
7
+
8
+ARGV.each do |arg|
9
+  if arg == "--"
10
+    add_to_rg_args = true
11
+  else
12
+    if add_to_rg_args
13
+      rg_args << arg
14
+    else
15
+      args << arg
16
+    end
17
+  end
18
+end
19
+
20
+options = {}
21
+OptionParser.new do |opts|
22
+  opts.banner = "Usage: grep-around.rb [options] -- [rg options]\n" \
23
+    "All options after -- will be passed through to ripgrep"
24
+  options[:stdin] = false
25
+  options[:around] = 1
26
+
27
+  opts.on("--stdin", "Read input from standard in") do |stdin|
28
+    options[:stdin] = stdin
29
+  end
30
+
31
+  opts.on("--around [LINES]", "Lines around") do |around|
32
+    options[:around] = around.to_i
33
+  end
34
+
35
+  opts.on("--up [LINES]", "Lines up") do |up|
36
+    options[:up] = up.to_i
37
+  end
38
+
39
+  opts.on("--down [LINES]", "Lines down") do |down|
40
+    options[:down] = down.to_i
41
+  end
42
+end.parse!(args)
43
+
44
+%i[up down].each { |n| options[n] = options[:around] } if options[:around]
45
+
46
+GREEN = "\u001b[32m"
47
+RED = "\u001b[31m"
48
+RESET = "\u001b[0m"
49
+
50
+class GrepAround
51
+  def initialize(options, rg_args)
52
+    @options = options
53
+    @rg_args = rg_args
54
+    @hit = nil
55
+    @current_line_number = nil
56
+    @file_cache = Hash.new
57
+  end
58
+
59
+  def run
60
+    results = run_ripgrep
61
+    blocks = Array.new
62
+    results.split("\n").each do |line|
63
+      @hit = if line.match(/\A\d+:/)
64
+               {
65
+                 :file_name => :stdin,
66
+                 :line_number => line.match(/\A\d+/)[0].to_i
67
+               }
68
+             else
69
+               parse_metadata(line)
70
+             end
71
+      blocks << get_block
72
+    end
73
+    puts blocks.join("\n\n")
74
+  end
75
+
76
+  def run_ripgrep
77
+    if @options[:stdin]
78
+      contents = STDIN.read
79
+      @file_cache[:stdin] = contents.split("\n")
80
+      `echo '#{contents}' | rg -n #{@rg_args.join(' ')}`
81
+    else
82
+      `rg -n #{@rg_args.join(' ')}`
83
+    end
84
+  end
85
+
86
+  def get_contents(key)
87
+    if @file_cache.has_key?(key)
88
+      @file_cache[key]
89
+    else
90
+      contents = File.readlines(@hit[:file_name])
91
+      @file_cache[@hit[:file_name]] = contents
92
+      contents
93
+    end
94
+  end
95
+
96
+  def get_lines(contents, line_number)
97
+    starting_line_number = line_number - @options[:up] - 1
98
+    ending_line_number = line_number + @options[:down] - 1
99
+    contents[starting_line_number..ending_line_number]
100
+  end
101
+
102
+  def parse_metadata(source)
103
+    metadata = source.split(': ').first.split(':')
104
+    file = metadata[0]
105
+    line = metadata[1]
106
+    {
107
+      :file_name => file,
108
+      :line_number => line.to_i,
109
+    }
110
+  end
111
+
112
+  def get_block
113
+    contents = get_contents(@hit[:file_name])
114
+    lines = get_lines(contents, @hit[:line_number])
115
+
116
+    block = Array.new
117
+    block << block_header
118
+    @current_line_number = @hit[:line_number] - @options[:up]
119
+    lines.each do |line|
120
+      block << build_output(line, @current_line_number)
121
+      @current_line_number += 1
122
+    end
123
+
124
+    block.join("\n")
125
+  end
126
+
127
+  def block_header
128
+    "#{RED}#{@hit[:file_name]}:#{RESET}"
129
+  end
130
+
131
+  def build_output(line, line_number)
132
+    output = String.new
133
+    output << line_number.to_s
134
+    output << ' '
135
+    output << GREEN if is_target_line
136
+    output << line.gsub("\n", "")
137
+    output << RESET if is_target_line
138
+
139
+    output
140
+  end
141
+
142
+  def is_target_line
143
+    @current_line_number == @hit[:line_number]
144
+  end
145
+end
146
+
147
+GrepAround.new(options, rg_args).run

Loading…
Cancel
Save