spellr 0.10.1 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
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: []