require 'tempfile' require 'readline' require 'getoptlong' require 'curses' require 'rrb/rrb' require 'rrb/completion' class String def trim split(/\s+/).find{|s| s != ""} end end module RRB module CUI USAGE = <= @str.size - 1 @cursor += 1 scroll_down if @cursor - @top >= Curses.lines end # scroll up the screen def scroll_up return if @top <= 0 @top -= 1 @cursor = @top + Curses.lines - 1 if @cursor > @top + Curses.lines - 1 end def cursor_up return if @cursor <= 0 @cursor -= 1 scroll_up if @cursor < @top end end class UI def initialize(files, diff_file) @script = Script.new_from_filenames(*files) @diff_file = diff_file end def output_diff system("touch #{@diff_file}") @script.files.find_all{|sf| sf.new_script != nil}.each do |sf| tmp = Tempfile.new("rrbcui") begin tmp.print(sf.new_script) tmp.close system("diff -u #{sf.path} #{tmp.path} >> #{@diff_file}") ensure tmp.close(true) end end end def select_one(prompt, words) CUI.select_one(prompt, words) end def input_str(prompt) Readline.completion_proc = proc{ [] } Readline.readline(prompt).trim end def select_region(scriptfile) Screen.new(scriptfile.input).select_region end end class RenameLocalVariable < UI def methods @script.refactable_methods.map{|method| method.name} end def vars(method) @script.refactable_methods.find{|m| m.name == method}.local_vars.to_a end def run method = select_one("Refactored method: ", methods) old_var = select_one("Old variable: ", vars(method)) new_var = input_str("New variable: ") unless @script.rename_local_var?(Method[method], old_var, new_var) STDERR.print(script.error_message, "\n") exit end @script.rename_local_var(Method[method], old_var, new_var) output_diff end end class RenameInstanceVariable < UI def classes @script.refactable_classes end def ivars(target) @script.refactable_classes_instance_vars.each do |classname, cvars| return cvars if classname == target end return [] end def run namespace = select_one("Refactared class: ", classes) old_var = select_one("Old variable: ", ivars(namespace)) new_var = input_str("New variable: ") unless @script.rename_instance_var?(namespace, old_var, new_var) STDERR.print(script.error_message, "\n") exit end @script.rename_instance_var(namespace, old_var, new_var) output_diff end end class ExtractMethod < UI def files @script.files.map{|sf| sf.path} end def run path = select_one("What file?: ", files) region = select_region(@script.files.find{|sf| sf.path == path}) new_method = input_str("New method: ") unless @script.extract_method?(path, new_method, region.begin, region.end) STDERR.print(script.error_message, "\n") exit end @script.extract_method(path, new_method, region.begin, region.end) output_diff end end end end if $0 == __FILE__ exit if ARGV.empty? screen = RRB::CUI::Screen.new(File.read(ARGV[0])) p screen.select_region end