Open text editor on offenses found by RuboCop
I’ve recently added RuboCop to one of my existing, large Ruby projects. A lot of the style adjustments RuboCop was able to apply automatically, but a significant number of files was still left for me to fix.
Opening each file manually seemed like a hassle so I’ve prepared this script that opens $EDITOR on each offense, waits for user to modify the file and goes to the next offense. It’s tuned for MacVim/Vim, but any editor that doesn’t detach from shell should work. This saved me tremendous amounts of time.
require "rubocop"
class OpenEditor < RuboCop::Formatter::ProgressFormatter
VimFamily = %w{vim gvim mvim}
def report_file file, offenses
super
if editor_supports_lines?
offenses.each do |offense|
run_editor file, offense unless offense.corrected?
end
else
run_editor file
end
end
def editor
ENV["EDITOR"]
end
def editor_supports_lines?
VimFamily.include? editor
end
def run_editor file, offense = nil
if offense
args = args_with_offense file, offense
else
args = args_without_offense file
end
original_modification_time = File.mtime file
system editor, *args
return if original_modification_time != File.mtime(file)
output.puts "No changes made to the file. Aborting."
exit 1
end
def args_with_offense file, offense
case editor
when *VimFamily
# Text vim will hide our console output, so we need to echo the message again
# inside vim.
message = offense.message.to_s
.gsub('"', "double quote")
.gsub("'", "quote")
[
"+#{offense.line}", # go to line
"-f", # gvim/mvim will not detach from shell
"-c", "echomsg '#{message}'",
file
]
else
[file]
end
end
def args_without_offense file
[file]
end
endAnd use it like this:
rubocop -r ./editor.rb -f OpenEditor