Class: Spellr::Interactive

Inherits:
Object
  • Object
show all
Includes:
StringFormat
Defined in:
lib/spellr/interactive.rb

Overview

rubocop:disable Metrics/ClassLength

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from StringFormat

aqua, bold, color_enabled?, normal, pluralize, red

Constructor Details

#initializeInteractive

Returns a new instance of Interactive.



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

def initialize
  @global_replacements = {}
  @global_insensitive_replacements = {}
  @global_skips = []
  @global_insensitive_skips = []
  @total_skipped = 0
  @total_fixed = 0
  @total_added = 0
end

Instance Attribute Details

#global_insensitive_replacementsObject (readonly)

Returns the value of attribute global_insensitive_replacements.



14
15
16
# File 'lib/spellr/interactive.rb', line 14

def global_insensitive_replacements
  @global_insensitive_replacements
end

#global_insensitive_skipsObject (readonly)

Returns the value of attribute global_insensitive_skips.



15
16
17
# File 'lib/spellr/interactive.rb', line 15

def global_insensitive_skips
  @global_insensitive_skips
end

#global_replacementsObject (readonly)

Returns the value of attribute global_replacements.



13
14
15
# File 'lib/spellr/interactive.rb', line 13

def global_replacements
  @global_replacements
end

#global_skipsObject (readonly)

Returns the value of attribute global_skips.



13
14
15
# File 'lib/spellr/interactive.rb', line 13

def global_skips
  @global_skips
end

#total_addedObject

Returns the value of attribute total_added.



18
19
20
# File 'lib/spellr/interactive.rb', line 18

def total_added
  @total_added
end

#total_fixedObject

Returns the value of attribute total_fixed.



17
18
19
# File 'lib/spellr/interactive.rb', line 17

def total_fixed
  @total_fixed
end

#total_skippedObject

Returns the value of attribute total_skipped.



16
17
18
# File 'lib/spellr/interactive.rb', line 16

def total_skipped
  @total_skipped
end

Instance Method Details

#attempt_global_replacement(token) ⇒ Object



67
68
69
70
71
72
73
74
75
# File 'lib/spellr/interactive.rb', line 67

def attempt_global_replacement(token)
  global_replacement = global_replacements[token.to_s]
  global_replacement ||= global_insensitive_replacements[token.normalize]
  return unless global_replacement

  token.replace(global_replacement)
  self.total_fixed += 1
  raise Spellr::DidReplacement, token
end

#attempt_global_skip(token) ⇒ Object



60
61
62
63
64
65
# File 'lib/spellr/interactive.rb', line 60

def attempt_global_skip(token)
  return unless global_skips.include?(token.to_s) ||
    global_insensitive_skips.include?(token.normalize)

  self.total_skipped += 1
end

#call(token) ⇒ Object



43
44
45
46
47
48
49
50
# File 'lib/spellr/interactive.rb', line 43

def call(token)
  return if attempt_global_replacement(token)
  return if attempt_global_skip(token)

  Spellr::Reporter.new.call(token)

  prompt(token)
end

#clear_current_lineObject



77
78
79
# File 'lib/spellr/interactive.rb', line 77

def clear_current_line
  print "\r\e[K"
end

#finish(checked) ⇒ Object

rubocop:disable Metrics/AbcSize



20
21
22
23
24
25
26
27
# File 'lib/spellr/interactive.rb', line 20

def finish(checked) # rubocop:disable Metrics/AbcSize
  puts "\n"
  puts "#{pluralize 'file', checked} checked"
  puts "#{pluralize 'error', total} found"
  puts "#{pluralize 'error', total_skipped} skipped" if total_skipped.positive?
  puts "#{pluralize 'error', total_fixed} fixed" if total_fixed.positive?
  puts "#{pluralize 'word', total_added} added" if total_added.positive?
end

#handle_add(token) ⇒ Object

TODO: handle more than 16 options



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/spellr/interactive.rb', line 118

def handle_add(token) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  puts "Add #{red(token)} to wordlist:"
  wordlists = Spellr.config.languages_for(token.location.file).flat_map(&:addable_wordlists)

  wordlists.each_with_index do |wordlist, i|
    puts "[#{i.to_s(16)}] #{wordlist.name}"
  end
  choice = STDIN.getch
  clear_current_line
  case choice
  when "\u0003" # ctrl c
    puts '^C again to exit'
    call(token)
  when /\h/
    wl = wordlists[choice.to_i(16)]
    return handle_add(token) unless wl

    wl.add(token)
    self.total_added += 1
    raise Spellr::DidAdd, token
  else
    handle_add(token)
  end
end

#handle_help(token) ⇒ Object

rubocop:disable Metrics/AbcSize



170
171
172
173
174
175
176
177
178
179
# File 'lib/spellr/interactive.rb', line 170

def handle_help(token) # rubocop:disable Metrics/AbcSize
  puts "#{bold '[r]'} Replace #{red token}"
  puts "#{bold '[R]'} Replace all future instances of #{red token}"
  puts "#{bold '[s]'} Skip #{red token}"
  puts "#{bold '[S]'} Skip all future instances of #{red token}"
  puts "#{bold '[a]'} Add #{red token} to a word list"
  puts "#{bold '[e]'} Edit the whole line"
  puts "#{bold '[?]'} Show this help"
  handle_response(token)
end

#handle_replace_line(token) ⇒ Object



163
164
165
166
167
168
# File 'lib/spellr/interactive.rb', line 163

def handle_replace_line(token)
  handle_replacement(
    token.line,
    original_token: token
  )
end

#handle_replacement(token, original_token: token) ⇒ Object

rubocop:disable Metrics/MethodLength, Metrics/AbcSize



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/spellr/interactive.rb', line 143

def handle_replacement(token, original_token: token) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
  readline_editable_print(token.chomp)
  highlighted_token = token == original_token ? red(token) : token.highlight(original_token.char_range)
  puts "#{aqua '>>'} #{highlighted_token.chomp}"
  prompt = "#{aqua '=>'} "
  replacement = Readline.readline(prompt)
  if replacement.empty?
    call(token)
  else
    full_replacement = token == original_token ? replacement : replacement + "\n"
    token.replace(full_replacement)
    yield replacement if block_given?
    self.total_fixed += 1
    raise Spellr::DidReplacement, token
  end
rescue Interrupt
  puts '^C again to exit'
  call(original_token)
end

#handle_response(token) ⇒ Object

rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/spellr/interactive.rb', line 81

def handle_response(token) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
  task = STDIN.getch
  clear_current_line

  case task
  when "\u0003" # ctrl c
    exit 1
  when 'a'
    handle_add(token)
  when 's', "\u0004" # ctrl d
    handle_skip(token)
  when 'S'
    handle_skip(token) { |skip_token| global_skips << skip_token.to_s }
  when 'i'
    handle_skip(token) { |skip_token| global_insensitive_skips << skip_token.downcase }
  when 'R'
    handle_replacement(token) { |replacement| global_replacements[token.to_s] = replacement }
  when 'I'
    handle_replacement(token) { |replacement| global_insensitive_replacements[token.normalize] = replacement }
  when 'r'
    handle_replacement(token)
  when 'e'
    handle_replace_line(token)
  when '?'
    handle_help(token)
  else
    clear_current_line
    call(token)
  end
end

#handle_skip(token) {|token| ... } ⇒ Object

Yields:

  • (token)


112
113
114
115
# File 'lib/spellr/interactive.rb', line 112

def handle_skip(token)
  self.total_skipped += 1
  yield token if block_given?
end

#prompt(token) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/spellr/interactive.rb', line 52

def prompt(token)
  print bold('[a,s,S,r,R,e,?]')

  handle_response(token)
rescue Interrupt
  puts '^C again to exit'
end

#readline_editable_print(string) ⇒ Object



181
182
183
184
185
186
187
188
189
190
# File 'lib/spellr/interactive.rb', line 181

def readline_editable_print(string)
  Readline.pre_input_hook = lambda {
    Readline.refresh_line
    Readline.insert_text string.to_s
    Readline.redisplay

    # Remove the hook right away.
    Readline.pre_input_hook = nil
  }
end

#totalObject



29
30
31
# File 'lib/spellr/interactive.rb', line 29

def total
  total_skipped + total_fixed + total_added
end