diff --git a/bin/wag b/bin/wag deleted file mode 100755 index a150c586..00000000 --- a/bin/wag +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env ruby - -# A hacky script that allows you to search with ag -# and edit the results in -# $EDITOR. The changes are propagated to all listed files, if any. -# -# Usage: wag [pattern] -# -# TODO Also rename files whose names have been changed - -if ARGV.empty? - puts "You didn't enter in anything!" - exit 1 -end - -require 'tempfile' -require 'shellwords' - -t = Tempfile.new('.ag-results') -out = system("ag #{ARGV.join(' ')} --nogroup --nocolor > #{t.path}") -if [false, nil].include? out - puts "No matches" if out === false - - t.unlink - exit 1 -end - -old_lines = File.open(t.path).readlines -system("#{ENV['EDITOR']} #{t.path}") -lines = File.open(t.path).readlines -t.unlink - -if old_lines.length != lines.length - puts "There was a line-number mismatch. Abort! Abort! Abort!" - exit 2 -end - -i = nil -lines.each_with_index do |line, i| - next if line.empty? || line.eql?(old_lines[i]) - - l = line.split(":", 3) - unless l.length == 3 - puts "Line #{i} is malformed as was skipped" - next - end - - filename = Shellwords.escape(l[0]) - lineno = Shellwords.escape(l[1]) - content = l[2].gsub("'", "\\'") - - if system("sed -i .bak '#{lineno}c\\ -#{content}' #{filename}") - puts "Replaced line #{lineno} in #{filename}" - else - puts "Failed to replace line #{lineno} in #{filename}" - end - - system("rm -f #{filename}.bak") if File.exists?("#{filename}.bak") -end - -if i === nil - puts "Didn't do nuthin'" -else - puts "Done!" -end diff --git a/bin/wrag b/bin/wrag new file mode 100755 index 00000000..195046a3 --- /dev/null +++ b/bin/wrag @@ -0,0 +1,107 @@ +#!/usr/bin/env ruby + +# A hacky script that allows you to search with ag +# and edit the results in +# $EDITOR. The changes are propagated to all listed files, if any. +# +# Usage: wrag [pattern] +# +# TODO Also rename changed filenames +# TODO Assemble sed string to make this atomic + +require 'optparse' +require 'tempfile' +require 'shellwords' + +def usage + puts "Usage: #{File.basename($0)} [-f|--rename-files] [-b|--backup] search_string" + puts "\nAny of ag's flags will work with wrag" + exit +end + +usage if ARGV.empty? + +options = {:rename => false, + :backup => false} + +opt = OptionParser.new +opt.on('-f', '--rename-files') { options[:rename] = true } +opt.on('-b', '--backup') { options[:backup] = true } + +t = Tempfile.new('.ag-results') +out = system("ag #{ARGV.join(' ')} --group --nocolor > #{t.path}") +if [false, nil].include? out + puts "No matches" if out === false + + t.unlink + exit 1 +end + +old_lines = File.open(t.path).readlines +system("#{ENV['EDITOR']} #{t.path}") +lines = File.open(t.path).readlines +t.unlink + +if old_lines.length != lines.length + puts "There was a line-number mismatch. Abort! Abort! Abort!" + exit 2 +end + +i = nil +current_filename = nil +lines.each_with_index do |line, i| + line.strip! + + next if line.empty? + + if line =~ /^([0-9]+):(.+)/ # make sure it isn't actually a file + filename = current_filename + lineno = $1 + content = $2 + elsif line =~ /^(.+):([0-9]+):(.+)/ + if current_file + puts "Mixing and matching groups and non-groups! Aborting." + exit 3 + end + + filename = $1 + lineno = $2 + content = $3 + elsif File.exists?(line) + if File.readable?(line) + current_filename = line + else + puts "#{line} isn't readable. Skipping." + end + next + else + puts "Malformed line: #{line}" + exit 4 + end + + next if line.eql?(old_lines[i].strip) + + filename = Shellwords.escape(filename) + lineno = Shellwords.escape(lineno) + content = content.gsub("'", "\\'") + + puts "#{filename}:#{lineno}:#{content}" + + if system("sed -i .bak '#{lineno}c\\ +#{content} + ' #{filename}") + puts "Replaced: line #{lineno} in #{filename}" + else + puts "Failed to replace line #{lineno} in #{filename}" + end + + unless options[:backup] + system("rm -f #{filename}.bak") if File.exists?("#{filename}.bak") + end +end + +if i === nil + puts "Didn't do nuthin'" +else + puts "Done!" +end