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, #print_count, #print_value, #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, only_prompt: false) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/spellr/interactive.rb', line 29

def call(token, only_prompt: false)
  # 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(token) unless only_prompt

  suggestions = ::Spellr::Suggester.fast_suggestions(token)
  print_suggestions(suggestions) unless only_prompt

  prompt(token, suggestions)
end

#clear_line(lines = 1) ⇒ Object



106
107
108
109
110
111
112
# File 'lib/spellr/interactive.rb', line 106

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



12
13
14
15
16
17
18
19
# File 'lib/spellr/interactive.rb', line 12

def finish
  puts "\n"
  print_count(:checked, 'file')
  print_value(total, 'error', 'found')
  print_count(:total_skipped, 'error', 'skipped', hide_zero: true)
  print_count(:total_fixed, 'error', 'fixed', hide_zero: true)
  print_count(:total_added, 'word', 'added', hide_zero: true)
end

#global_replacementsObject



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

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

#global_skipsObject



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

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

#loop_within(seconds) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/spellr/interactive.rb', line 47

def loop_within(seconds)
  # 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



59
60
61
# File 'lib/spellr/interactive.rb', line 59

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

#number_suggestions(suggestions) ⇒ Object



95
96
97
# File 'lib/spellr/interactive.rb', line 95

def number_suggestions(suggestions)
  suggestions.map.with_index(1) { |word, i| "#{key i.to_s} #{word}" }.join(', ')
end


83
84
85
86
87
# File 'lib/spellr/interactive.rb', line 83

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

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


89
90
91
92
93
# File 'lib/spellr/interactive.rb', line 89

def print_suggestions(suggestions)
  return if suggestions.empty?

  puts "Did you mean: #{number_suggestions(suggestions)}"
end

#prompt(token, suggestions) ⇒ Object



99
100
101
102
103
104
# File 'lib/spellr/interactive.rb', line 99

def prompt(token, suggestions)
  print "#{key 'add'}, #{key 'replace'}, #{key 'skip'}, #{key 'help'}, [^#{bold 'C'}] to exit: "
  prompt_for_key

  handle_response(token, suggestions)
end

#prompt_for_keyObject



43
44
45
# File 'lib/spellr/interactive.rb', line 43

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

#stdin_getch(legal_chars) ⇒ Object

rubocop:disable Metrics/MethodLength



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

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