Class: Spellr::Interactive

Inherits:
BaseReporter show all
Defined in:
lib/spellr/interactive.rb

Overview

rubocop:disable Metrics/ClassLength

Constant Summary collapse

ALPHABET =
('A'..'Z').to_a.join
CTRL =
("\u0001".."\u0026").freeze
CTRL_STR =
CTRL.to_a.join

Instance Method Summary collapse

Methods inherited from BaseReporter

#counts, #exit_code, #increment, #initialize, #output, #print, #puts, #warn

Methods included from StringFormat

aqua, bold, green, key, lighten, normal, pluralize, red

Constructor Details

This class inherits a constructor from Spellr::BaseReporter

Instance Method Details

#call(token) ⇒ Object



30
31
32
33
34
35
36
37
38
39
# 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) ⇒ Object



94
95
96
97
98
99
100
# 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

#finishObject

rubocop:disable Metrics/AbcSize, Metrics/MethodLength



11
12
13
14
15
16
17
18
19
20
# 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_replacementsObject



22
23
24
# File 'lib/spellr/interactive.rb', line 22

def global_replacements
  @global_replacements ||= counts[:global_replacements] = {}
end

#global_skipsObject



26
27
28
# File 'lib/spellr/interactive.rb', line 26

def global_skips
  @global_skips ||= counts[:global_skips] = []
end

#loop_within(seconds) ⇒ Object

rubocop:disable Metrics/MethodLength



45
46
47
48
49
50
51
52
53
54
55
# 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_timeObject



57
58
59
# File 'lib/spellr/interactive.rb', line 57

def monotonic_time
  Process.clock_gettime(Process::CLOCK_MONOTONIC)
end


81
82
83
84
85
# File 'lib/spellr/interactive.rb', line 81

def print_keypress(char)
  return char unless CTRL.cover?(char)

  "^#{char.tr(CTRL_STR, ALPHABET)}"
end

#prompt(token) ⇒ Object



87
88
89
90
91
92
# 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_keyObject



41
42
43
# File 'lib/spellr/interactive.rb', line 41

def prompt_for_key
  print "[ ]\e[2D"
end

#stdin_getch(legal_chars) ⇒ Object

rubocop:disable Metrics/MethodLength, Metrics/AbcSize



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/spellr/interactive.rb', line 61

def stdin_getch(legal_chars) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
  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