class Spellr::Interactive

Constants

ALPHABET
CTRL
CTRL_STR

Public Instance Methods

call(token) click to toggle source
Calls superclass method Spellr::BaseReporter#call
# File lib/spellr/interactive.rb, line 30
def call(token)
  # if attempt_global_replacement succeeds, then it throws,
  # it acts like a guard clause all by itself.
  attempt_global_replacement(token)
  return if attempt_global_skip(token)

  super

  prompt(token)
end
clear_line(lines = 1) click to toggle source
# File lib/spellr/interactive.rb, line 94
def clear_line(lines = 1)
  print "\r\e[K"
  (lines - 1).times do
    sleep 0.01
    print "\r\e[1T\e[2K"
  end
end
finish() click to toggle source
# File lib/spellr/interactive.rb, line 11
def finish # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  puts "\n"
  puts "#{pluralize 'file', counts[:checked]} checked"
  puts "#{pluralize 'error', total} found"
  if counts[:total_skipped].positive?
    puts "#{pluralize 'error', counts[:total_skipped]} skipped"
  end
  puts "#{pluralize 'error', counts[:total_fixed]} fixed" if counts[:total_fixed].positive?
  puts "#{pluralize 'word', counts[:total_added]} added" if counts[:total_added].positive?
end
global_replacements() click to toggle source
# File lib/spellr/interactive.rb, line 22
def global_replacements
  @global_replacements ||= counts[:global_replacements] = {}
end
global_skips() click to toggle source
# File lib/spellr/interactive.rb, line 26
def global_skips
  @global_skips ||= counts[:global_skips] = []
end
loop_within(seconds) { |until start_time + seconds < monotonic_time| ... } click to toggle source
# File lib/spellr/interactive.rb, line 45
def loop_within(seconds) # rubocop:disable Metrics/MethodLength
  # timeout is just because it gets stuck sometimes
  Timeout.timeout(seconds * 10) do
    start_time = monotonic_time
    yield until start_time + seconds < monotonic_time
  end
rescue Timeout::Error
  # :nocov:
  nil
  # :nocov:
end
monotonic_time() click to toggle source
# File lib/spellr/interactive.rb, line 57
def monotonic_time
  Process.clock_gettime(Process::CLOCK_MONOTONIC)
end
print_keypress(char) click to toggle source
prompt(token) click to toggle source
# File lib/spellr/interactive.rb, line 87
def prompt(token)
  print "#{key 'add'}, #{key 'replace'}, #{key 'skip'}, #{key 'help'}, [^#{bold 'C'}] to exit: "
  prompt_for_key

  handle_response(token)
end
prompt_for_key() click to toggle source
# File lib/spellr/interactive.rb, line 41
def prompt_for_key
  print "[ ]\e[2D"
end
stdin_getch(legal_chars) click to toggle source
# File lib/spellr/interactive.rb, line 61
def stdin_getch(legal_chars) # rubocop:disable Metrics/MethodLength
  choice = output.stdin.getch

  if legal_chars.include?(choice)
    puts "\e[0K#{bold print_keypress(choice)}]\e[1C"
    choice
  elsif choice == "\e" # mac sends \e[A when up is pressed. thanks.
    print "\a"
    loop_within(0.001) { output.stdin.getch }

    stdin_getch(legal_chars)
  else
    print "\a"
    stdin_getch(legal_chars)
  end
end

Private Instance Methods

attempt_global_replacement(token, replacement = global_replacements[token.to_s]) click to toggle source
# File lib/spellr/interactive.rb, line 115
def attempt_global_replacement(token, replacement = global_replacements[token.to_s])
  return unless replacement

  token.replace(replacement)
  increment(:total_fixed)
  puts "Automatically replaced #{red(token)} with #{green(replacement)}"
  throw :check_file_from, token
end
attempt_global_skip(token) click to toggle source
# File lib/spellr/interactive.rb, line 108
def attempt_global_skip(token)
  return unless global_skips.include?(token.to_s)

  puts "Automatically skipped #{red(token)}"
  increment(:total_skipped)
end
handle_help(token) click to toggle source
# File lib/spellr/interactive.rb, line 151
def handle_help(token) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  clear_line(2)
  puts ''
  puts "#{key 'a'} Add #{red token} to a word list"
  puts "#{key 'r'} Replace #{red token}"
  puts "#{key 'R'} Replace this and all future instances of #{red token}"
  puts "#{key 's'} Skip #{red token}"
  puts "#{key 'S'} Skip this and all future instances of #{red token}"
  puts "#{key 'h'} Show this help"
  puts "[ctrl] + #{key 'C'} Exit spellr"
  puts ''
  print "What do you want to do? [ ]\e[2D"
  handle_response(token)
end
handle_response(token) click to toggle source
# File lib/spellr/interactive.rb, line 124
def handle_response(token) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
  # :nocov:
  case stdin_getch("qaAsSrR?h\u0003\u0004")
  # :nocov:
  when 'q', "\u0003" # ctrl c
    Spellr.exit 1
  when 'a', 'A'
    Spellr::InteractiveAdd.new(token, self)
  when 's', "\u0004" # ctrl d
    handle_skip(token)
  when 'S'
    handle_skip(token) { |skip_token| global_skips << skip_token.to_s }
  when 'R'
    Spellr::InteractiveReplacement.new(token, self).global_replace
  when 'r'
    Spellr::InteractiveReplacement.new(token, self).replace
  when '?', 'h'
    handle_help(token)
  end
end
handle_skip(token) { |token| ... } click to toggle source
# File lib/spellr/interactive.rb, line 145
def handle_skip(token)
  increment(:total_skipped)
  yield token if block_given?
  puts "Skipped #{red(token)}"
end
total() click to toggle source
# File lib/spellr/interactive.rb, line 104
def total
  counts[:total_skipped] + counts[:total_fixed] + counts[:total_added]
end