spellr 0.10.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 21ab4e433d233e14066dd74202d26ce302ea6b61807b06c74d5418f0351f576a
4
- data.tar.gz: 865fe94e51e2ad6b819eef675b2075eaaf15214bc599e14de2c76b376169ad3a
3
+ metadata.gz: 80c20f8d5d6ff7fcbd959c8e416205a1501edf3f409ccc85ac99a4f559e66ef2
4
+ data.tar.gz: c2cf7e43338df821bb39f65a89f989ee68fc53468dfe97cbb40d56ea9ceb0a05
5
5
  SHA512:
6
- metadata.gz: ff244a207751f57b402c1c5080487205935a4c80fd0b2481cd8a58a12ba717412596714c1684fde3e28aac6caff182e8985855243dc02c720463d17e1e533bc8
7
- data.tar.gz: bf87a587fd6cf7ab5ef907645cfc68b627f65098b9e771c09a9fb19360467817c05cb3d61bda17bb01296f81a71e23048f42ec4054e1cd8a96703332571f1ff1
6
+ metadata.gz: 9c51d832b489465d99ebdd2990ff540c91bca34bf7c1e0d7912a9bb9037d5ffa6427c480441ad7394ed918db29e4577df489e7036eee61ec6f68f06f45fdb405
7
+ data.tar.gz: cc7bdff3f7741f3e9adf422a47181d9f376b85aa3a37a369c38478366c699170f48a191853b5fd1596b4f439566a509fd88f39ddeeab19e753e0d0f5dd515319
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ # v0.12.0
2
+
3
+ - Require stringio in the tokenizer (thanks @alexdeng-mp)
4
+ - Remove implicit did_you_mean dependency, inline and tweak what of did_you_mean we were using
5
+ - Test with recent rubies
6
+ - Replace readline dependency with reline
7
+ - Drop support for ruby 2.5 because the reline that works supports 2.6 and up
8
+ - Hints and run statistics are printed to stderr rather than stdout
9
+
10
+ # v0.11.0
11
+ - Remove explicit did_you_mean dependency
12
+ (if you want the suggestions in ruby 2.5 & 2.6, you'll need to add did_you_mean to your Gemfile directly).
13
+ - require 'set' in Spellr::Reporter
14
+ previously we were just were relying on FastIgnore requiring it, and i don't use it there any longer.
15
+
1
16
  # v0.10.1
2
17
  - Resolve fast_ignore follow_symlinks deprecation
3
18
 
data/README.md CHANGED
@@ -27,7 +27,7 @@ However, in a programming context spelling things _consistently_ is useful, wher
27
27
 
28
28
  ## Installation
29
29
 
30
- This is tested against ruby 2.5-3.0.
30
+ This is tested against ruby 2.6-3.4.
31
31
 
32
32
  ### With Bundler
33
33
 
@@ -2,12 +2,12 @@
2
2
 
3
3
  require_relative '../spellr'
4
4
  require_relative 'base_reporter'
5
- require_relative 'suggester'
5
+ require_relative 'maybe_suggester'
6
6
 
7
7
  module Spellr
8
8
  class AutocorrectReporter < BaseReporter
9
9
  def finish
10
- puts "\n"
10
+ warn "\n"
11
11
  print_count(:checked, 'file')
12
12
  print_value(total, 'error', 'found')
13
13
  print_count(:total_fixed, 'error', 'fixed', hide_zero: true)
@@ -27,7 +27,7 @@ module Spellr
27
27
  end
28
28
 
29
29
  def handle_replace(token)
30
- replacement = ::Spellr::Suggester.suggestions(token).first
30
+ replacement = ::Spellr::Suggester.suggestions(token, 1).first
31
31
  return increment(:total_unfixed) unless replacement
32
32
 
33
33
  token.replace(replacement)
@@ -52,7 +52,7 @@ module Spellr
52
52
  end
53
53
 
54
54
  def print_value(value, noun, verb, hide_zero: false)
55
- puts "#{pluralize noun, value} #{verb}" if !hide_zero || value.positive?
55
+ warn "#{pluralize noun, value} #{verb}" if !hide_zero || value.positive?
56
56
  end
57
57
  end
58
58
  end
@@ -5,12 +5,12 @@ require_relative '../spellr'
5
5
  require_relative 'interactive_add'
6
6
  require_relative 'interactive_replacement'
7
7
  require_relative 'base_reporter'
8
- require_relative 'suggester'
8
+ require_relative 'maybe_suggester'
9
9
 
10
10
  module Spellr
11
11
  class Interactive < BaseReporter # rubocop:disable Metrics/ClassLength
12
12
  def finish
13
- puts "\n"
13
+ warn "\n"
14
14
  print_count(:checked, 'file')
15
15
  print_value(total, 'error', 'found')
16
16
  print_count(:total_skipped, 'error', 'skipped', hide_zero: true)
@@ -34,7 +34,7 @@ module Spellr
34
34
 
35
35
  super(token) unless only_prompt
36
36
 
37
- suggestions = ::Spellr::Suggester.fast_suggestions(token)
37
+ suggestions = ::Spellr::Suggester.fast_suggestions(token, 5)
38
38
  print_suggestions(suggestions) unless only_prompt
39
39
 
40
40
  prompt(token, suggestions)
@@ -107,7 +107,7 @@ module Spellr
107
107
  print "\r\e[K"
108
108
  (lines - 1).times do
109
109
  sleep 0.01
110
- print "\r\e[1T\e[2K"
110
+ print "\r\e[0m\e[1T\e[2K"
111
111
  end
112
112
  end
113
113
 
@@ -165,7 +165,7 @@ module Spellr
165
165
  end
166
166
 
167
167
  def handle_replace_with_suggestion(token, suggestions, letter)
168
- replacement = suggestions[letter.to_i - 1].chomp
168
+ replacement = suggestions[letter.to_i - 1]
169
169
 
170
170
  token.replace(replacement)
171
171
  increment(:total_fixed)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'readline'
3
+ require 'reline'
4
4
  require_relative 'string_format'
5
5
 
6
6
  module Spellr
@@ -15,8 +15,8 @@ module Spellr
15
15
  @token = token
16
16
  @token_highlight = red(token)
17
17
  @reporter = reporter
18
- Readline.input = reporter.output.stdin
19
- Readline.output = reporter.output.stdout
18
+ Reline.input = reporter.output.stdin
19
+ Reline.output = reporter.output.stdout
20
20
  end
21
21
 
22
22
  def global_replace
@@ -44,9 +44,9 @@ module Spellr
44
44
  end
45
45
 
46
46
  def prompt_replacement
47
- Readline.pre_input_hook = -> { pre_input_hook(token) }
48
- prompt = " Replace #{'all ' if global?}#{token_highlight} with: \e[32m"
49
- Readline.readline(prompt)
47
+ Reline.pre_input_hook = -> { pre_input_hook(token) }
48
+ prompt = " Replace #{'all ' if global?}#{token_highlight} with: "
49
+ Reline.readline(prompt)
50
50
  rescue Interrupt
51
51
  handle_ctrl_c
52
52
  end
@@ -70,19 +70,15 @@ module Spellr
70
70
 
71
71
  def handle_ctrl_c
72
72
  print "\e[0m"
73
- reporter.clear_line(4)
73
+ reporter.clear_line(5)
74
74
  reporter.call(token, only_prompt: true)
75
75
  end
76
76
 
77
77
  private
78
78
 
79
79
  def pre_input_hook(value)
80
- Readline.refresh_line
81
- Readline.insert_text value.to_s
82
- Readline.redisplay
83
-
84
- # Remove the hook right away.
85
- Readline.pre_input_hook = nil
80
+ Reline.insert_text value.to_s
81
+ Reline.pre_input_hook = nil
86
82
  end
87
83
 
88
84
  def puts(str)
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require_relative 'suggester'
5
+ # :nocov:
6
+ rescue LoadError
7
+ require_relative 'null_suggester'
8
+ Spellr::Suggester = Spellr::NullSuggester
9
+ # :nocov:
10
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spellr
4
+ module NullSuggester
5
+ class << self
6
+ def suggestions(_token, _limit = 0)
7
+ []
8
+ end
9
+
10
+ def fast_suggestions(_token, _limit = 0)
11
+ []
12
+ end
13
+
14
+ def slow?
15
+ true
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'stringio'
3
4
  require_relative 'output'
4
5
 
5
6
  module Spellr
@@ -46,7 +46,7 @@ module Spellr
46
46
  end
47
47
 
48
48
  def write_cli_cmd(argv)
49
- $stdout.puts("\e[2mspellr #{escaped_argv(argv)}\e[0m")
49
+ warn("\e[2mspellr #{escaped_argv(argv)}\e[0m")
50
50
  end
51
51
 
52
52
  def run(argv)
@@ -2,11 +2,12 @@
2
2
 
3
3
  require_relative 'base_reporter'
4
4
  require 'shellwords'
5
+ require 'set'
5
6
 
6
7
  module Spellr
7
8
  class Reporter < Spellr::BaseReporter
8
9
  def finish
9
- puts "\n"
10
+ warn "\n"
10
11
  print_count(:checked, 'file')
11
12
  print_count(:total, 'error', 'found')
12
13
 
@@ -23,12 +24,12 @@ module Spellr
23
24
  private
24
25
 
25
26
  def interactive_command
26
- puts "\nto add or replace words interactively, run:"
27
+ warn "\nto add or replace words interactively, run:"
27
28
  command = ['spellr', '--interactive']
28
29
  # sort is purely for repeatability for tests. so
29
30
  command.concat(counts[:filenames].to_a.sort) unless counts[:filenames].length > 20
30
31
 
31
- puts " #{Shellwords.join(command)}"
32
+ warn " #{Shellwords.join(command)}"
32
33
  end
33
34
 
34
35
  def filenames
@@ -1,59 +1,88 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'did_you_mean'
4
3
  require 'jaro_winkler'
4
+ require 'damerau-levenshtein'
5
+ require_relative 'suggestion'
5
6
 
6
- ::DidYouMean.send(:remove_const, :JaroWinkler)
7
- ::DidYouMean::JaroWinkler = ::JaroWinkler
7
+ # This is inspired by and uses parts of ruby's DidYouMean
8
8
 
9
9
  module Spellr
10
- class Suggester
10
+ module Suggester
11
11
  class << self
12
- def suggestions(token)
12
+ def suggestions(token, limit = 5) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
13
13
  wordlists = token.location.file.wordlists
14
- term = token.spellr_normalize.chomp
15
- words = wordlists.flat_map { |wordlist| wordlist.suggestions(token) }.uniq
16
- words = ::DidYouMean::SpellChecker.new(dictionary: words).correct(term)
17
- words = reduce_suggestions(words, term)
14
+ term = token.spellr_normalize
15
+ jaro_winkler_similarity_threshold = term.length > 4 ? 0.834 : 0.77
16
+ suggestions = wordlists.flat_map do |wordlist|
17
+ all_suggestions(term, jaro_winkler_similarity_threshold, wordlist)
18
+ end
19
+ suggestions.uniq!(&:word)
20
+ suggestions.sort_by! { |suggestion| [-suggestion.jaro_winkler_similarity, suggestion.word] }
21
+
22
+ suggestions = reduce_suggestions(suggestions, term, limit)
18
23
 
19
- words.map { |word| word.send(token.case_method) }
24
+ suggestions.map { |suggestion| suggestion.word.send(token.case_method) }
20
25
  end
21
26
 
22
27
  def slow?
23
28
  return @slow if defined?(@slow)
24
29
 
25
- @slow = ::JaroWinkler.method(:distance).source_location
30
+ @slow = ::JaroWinkler.method(:similarity).source_location
26
31
  end
27
32
 
28
- def fast_suggestions(token)
33
+ def fast_suggestions(token, limit = 5)
29
34
  if slow?
30
35
  []
31
36
  else
32
- suggestions(token)
37
+ suggestions(token, limit)
33
38
  end
34
39
  end
35
40
 
36
41
  private
37
42
 
38
- def reduce_suggestions(words, term)
39
- return words unless words.length > 1
43
+ def all_suggestions(term, jaro_winkler_similarity_threshold, wordlist)
44
+ wordlist.reduce([]) do |acc, word|
45
+ similarity = ::JaroWinkler.similarity(word, term)
46
+ next acc unless similarity >= jaro_winkler_similarity_threshold
40
47
 
41
- threshold = ::JaroWinkler.distance(term, words.first) * 0.98
42
- words.select! { |word| ::JaroWinkler.distance(term, word) > threshold }
43
- words.sort_by! { |word| [-::JaroWinkler.distance(term, word), word] }
44
- words.take(5)
48
+ acc << Suggestion.new(word, similarity)
49
+ end
45
50
  end
46
- end
47
51
 
48
- def initialize(wordlist)
49
- @did_you_mean = ::DidYouMean::SpellChecker.new(dictionary: wordlist.to_a)
50
- @suggestions = {}
51
- end
52
+ def reduce_suggestions(suggestions, term, limit = 5)
53
+ candidate_suggestions = reduce_to_mistypes(suggestions, term, limit)
54
+ if candidate_suggestions.empty?
55
+ candidate_suggestions = reduce_to_misspells(suggestions, term, limit)
56
+ end
57
+ reduce_wild_suggestions(candidate_suggestions)
58
+ end
52
59
 
53
- def suggestions(term)
54
- term = term.spellr_normalize
55
- @suggestions.fetch(term) do
56
- @suggestions[term] = @did_you_mean.correct(term).map(&:chomp)
60
+ def reduce_to_mistypes(suggestions, term, limit = 5)
61
+ # Correct mistypes
62
+ threshold = ((term.length - 1) * 0.25).ceil
63
+ suggestions.lazy.select do |suggestion|
64
+ suggestion.levenshtein_distance ||= DamerauLevenshtein.distance(suggestion.word, term)
65
+ suggestion.levenshtein_distance <= threshold
66
+ end.take(limit).to_a
67
+ end
68
+
69
+ def reduce_to_misspells(suggestions, term, limit = 1)
70
+ # Correct misspells
71
+ suggestions.lazy.select do |suggestion|
72
+ length = term.length < suggestion.word.length ? term.length : suggestion.word.length
73
+
74
+ suggestion.levenshtein_distance ||= DamerauLevenshtein.distance(suggestion.word, term)
75
+ suggestion.levenshtein_distance < length - 1
76
+ end.take(limit).to_a
77
+ end
78
+
79
+ def reduce_wild_suggestions(suggestions)
80
+ return suggestions unless suggestions.length > 1
81
+
82
+ threshold = suggestions.first.jaro_winkler_similarity * 0.98
83
+ suggestions.select do |suggestion|
84
+ suggestion.jaro_winkler_similarity > threshold
85
+ end
57
86
  end
58
87
  end
59
88
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Suggestion
4
+ attr_accessor :levenshtein_distance
5
+ attr_reader :word, :jaro_winkler_similarity
6
+
7
+ def initialize(word, jaro_winkler_similarity)
8
+ @word = word
9
+ @jaro_winkler_similarity = jaro_winkler_similarity
10
+ end
11
+ end
data/lib/spellr/token.rb CHANGED
@@ -8,7 +8,7 @@ class String
8
8
 
9
9
  def spellr_normalize
10
10
  @@spellr_normalize.fetch(to_s) do |term|
11
- @@spellr_normalize[term] = "#{term.strip.downcase.unicode_normalize.tr('’', "'")}\n"
11
+ @@spellr_normalize[term] = term.strip.downcase.unicode_normalize.tr('’', "'").to_s
12
12
  end
13
13
  end
14
14
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'stringio'
3
4
  require_relative 'token'
4
5
  require_relative 'column_location'
5
6
  require_relative 'line_location'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spellr
4
- VERSION = '0.10.1'
4
+ VERSION = '0.12.0'
5
5
  end
@@ -41,23 +41,29 @@ module Spellr
41
41
  touch
42
42
  @include[term] = true
43
43
  insert_sorted(term)
44
- @path.write(words.join) # we don't need to clear the cache
44
+ write(words, clear_cache: false)
45
45
  end
46
46
 
47
47
  def words
48
- @words ||= (exist? ? @path.readlines : [])
48
+ @words ||= if exist?
49
+ @path.readlines(chomp: true)
50
+ else
51
+ []
52
+ end
49
53
  end
50
54
  alias_method :to_a, :words
51
55
 
52
56
  def clean(file = @path)
53
57
  require_relative 'tokenizer'
54
- write(Spellr::Tokenizer.new(file, skip_key: false).normalized_terms.join)
58
+ write(Spellr::Tokenizer.new(file, skip_key: false).normalized_terms)
55
59
  end
56
60
 
57
- def write(content)
61
+ def write(words, clear_cache: true)
62
+ content = words.join("\n")
63
+ content << "\n" unless words.empty?
58
64
  @path.write(content)
59
65
 
60
- clear_cache
66
+ self.clear_cache if clear_cache
61
67
  end
62
68
 
63
69
  def exist?
@@ -70,28 +76,13 @@ module Spellr
70
76
  return if exist?
71
77
 
72
78
  @path.dirname.mkpath
73
- @path.write('')
74
- clear_cache
79
+ write([])
75
80
  end
76
81
 
77
82
  def length
78
83
  to_a.length
79
84
  end
80
85
 
81
- def suggestions(term)
82
- suggester.suggestions(term)
83
- end
84
-
85
- private
86
-
87
- def suggester
88
- @suggester ||= begin
89
- require_relative 'suggester'
90
-
91
- ::Spellr::Suggester.new(self)
92
- end
93
- end
94
-
95
86
  def insert_sorted(term)
96
87
  insert_at = words.bsearch_index { |value| value >= term }
97
88
  insert_at ? words.insert(insert_at, term) : words.push(term)
@@ -99,7 +90,6 @@ module Spellr
99
90
 
100
91
  def clear_cache
101
92
  @words = nil
102
- @suggester = nil
103
93
  @include = {}
104
94
  remove_instance_variable(:@exist) if defined?(@exist)
105
95
  end
@@ -6,7 +6,7 @@ require_relative 'base_reporter'
6
6
  module Spellr
7
7
  class WordlistReporter < Spellr::BaseReporter
8
8
  def finish
9
- puts words.sort.join unless words.empty?
9
+ puts words.sort.join("\n") unless words.empty?
10
10
  end
11
11
 
12
12
  def call(token)
data/spellr.gemspec CHANGED
@@ -33,6 +33,7 @@ Gem::Specification.new do |spec|
33
33
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
34
34
  spec.require_paths = ['lib']
35
35
 
36
+ spec.add_development_dependency 'base64'
36
37
  spec.add_development_dependency 'bundler', '~> 2.0'
37
38
  spec.add_development_dependency 'leftovers', '>= 0.4.0'
38
39
  spec.add_development_dependency 'mime-types', '~> 3.3.1'
@@ -42,13 +43,14 @@ Gem::Specification.new do |spec|
42
43
  spec.add_development_dependency 'rspec', '~> 3.0'
43
44
  spec.add_development_dependency 'rubocop', '~> 0.93.1'
44
45
  spec.add_development_dependency 'rubocop-rspec', '~> 1.44.1'
45
- spec.add_development_dependency 'simplecov', '~> 0.18.5'
46
+ spec.add_development_dependency 'simplecov', '~> 0.22.0'
46
47
  spec.add_development_dependency 'simplecov-console'
47
- spec.add_development_dependency 'tty_string', '>= 1.1.0'
48
+ spec.add_development_dependency 'tty_string', '>= 2.0.3'
48
49
  spec.add_development_dependency 'webmock', '~> 3.8'
49
50
 
50
- spec.add_dependency 'did_you_mean'
51
+ spec.add_dependency 'damerau-levenshtein'
51
52
  spec.add_dependency 'fast_ignore', '>= 0.11.0'
52
- spec.add_dependency 'jaro_winkler'
53
+ spec.add_dependency 'jaro_winkler', '>= 1.6.0'
53
54
  spec.add_dependency 'parallel', '~> 1.0'
55
+ spec.add_dependency 'reline'
54
56
  end
metadata CHANGED
@@ -1,15 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spellr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.1
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dana Sherson
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2022-04-30 00:00:00.000000000 Z
10
+ date: 2025-01-26 00:00:00.000000000 Z
12
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: base64
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
13
26
  - !ruby/object:Gem::Dependency
14
27
  name: bundler
15
28
  requirement: !ruby/object:Gem::Requirement
@@ -142,14 +155,14 @@ dependencies:
142
155
  requirements:
143
156
  - - "~>"
144
157
  - !ruby/object:Gem::Version
145
- version: 0.18.5
158
+ version: 0.22.0
146
159
  type: :development
147
160
  prerelease: false
148
161
  version_requirements: !ruby/object:Gem::Requirement
149
162
  requirements:
150
163
  - - "~>"
151
164
  - !ruby/object:Gem::Version
152
- version: 0.18.5
165
+ version: 0.22.0
153
166
  - !ruby/object:Gem::Dependency
154
167
  name: simplecov-console
155
168
  requirement: !ruby/object:Gem::Requirement
@@ -170,14 +183,14 @@ dependencies:
170
183
  requirements:
171
184
  - - ">="
172
185
  - !ruby/object:Gem::Version
173
- version: 1.1.0
186
+ version: 2.0.3
174
187
  type: :development
175
188
  prerelease: false
176
189
  version_requirements: !ruby/object:Gem::Requirement
177
190
  requirements:
178
191
  - - ">="
179
192
  - !ruby/object:Gem::Version
180
- version: 1.1.0
193
+ version: 2.0.3
181
194
  - !ruby/object:Gem::Dependency
182
195
  name: webmock
183
196
  requirement: !ruby/object:Gem::Requirement
@@ -193,7 +206,7 @@ dependencies:
193
206
  - !ruby/object:Gem::Version
194
207
  version: '3.8'
195
208
  - !ruby/object:Gem::Dependency
196
- name: did_you_mean
209
+ name: damerau-levenshtein
197
210
  requirement: !ruby/object:Gem::Requirement
198
211
  requirements:
199
212
  - - ">="
@@ -226,14 +239,14 @@ dependencies:
226
239
  requirements:
227
240
  - - ">="
228
241
  - !ruby/object:Gem::Version
229
- version: '0'
242
+ version: 1.6.0
230
243
  type: :runtime
231
244
  prerelease: false
232
245
  version_requirements: !ruby/object:Gem::Requirement
233
246
  requirements:
234
247
  - - ">="
235
248
  - !ruby/object:Gem::Version
236
- version: '0'
249
+ version: 1.6.0
237
250
  - !ruby/object:Gem::Dependency
238
251
  name: parallel
239
252
  requirement: !ruby/object:Gem::Requirement
@@ -248,7 +261,20 @@ dependencies:
248
261
  - - "~>"
249
262
  - !ruby/object:Gem::Version
250
263
  version: '1.0'
251
- description:
264
+ - !ruby/object:Gem::Dependency
265
+ name: reline
266
+ requirement: !ruby/object:Gem::Requirement
267
+ requirements:
268
+ - - ">="
269
+ - !ruby/object:Gem::Version
270
+ version: '0'
271
+ type: :runtime
272
+ prerelease: false
273
+ version_requirements: !ruby/object:Gem::Requirement
274
+ requirements:
275
+ - - ">="
276
+ - !ruby/object:Gem::Version
277
+ version: '0'
252
278
  email:
253
279
  - robot@dana.sh
254
280
  executables:
@@ -286,6 +312,8 @@ files:
286
312
  - lib/spellr/language.rb
287
313
  - lib/spellr/line_location.rb
288
314
  - lib/spellr/line_tokenizer.rb
315
+ - lib/spellr/maybe_suggester.rb
316
+ - lib/spellr/null_suggester.rb
289
317
  - lib/spellr/output.rb
290
318
  - lib/spellr/output_stubbed.rb
291
319
  - lib/spellr/pwd.rb
@@ -294,6 +322,7 @@ files:
294
322
  - lib/spellr/reporter.rb
295
323
  - lib/spellr/string_format.rb
296
324
  - lib/spellr/suggester.rb
325
+ - lib/spellr/suggestion.rb
297
326
  - lib/spellr/token.rb
298
327
  - lib/spellr/token_regexps.rb
299
328
  - lib/spellr/tokenizer.rb
@@ -331,7 +360,6 @@ metadata:
331
360
  homepage_uri: http://github.com/robotdana/spellr
332
361
  source_code_uri: http://github.com/robotdana/spellr
333
362
  changelog_uri: http://github.com/robotdana/spellr/blob/main/CHANGELOG.md
334
- post_install_message:
335
363
  rdoc_options: []
336
364
  require_paths:
337
365
  - lib
@@ -346,8 +374,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
346
374
  - !ruby/object:Gem::Version
347
375
  version: '0'
348
376
  requirements: []
349
- rubygems_version: 3.2.15
350
- signing_key:
377
+ rubygems_version: 3.6.2
351
378
  specification_version: 4
352
379
  summary: Spell check your source code
353
380
  test_files: []