spellr 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.rspec +3 -0
- data/.rubocop.yml +186 -0
- data/.ruby-version +1 -0
- data/.spellr.yml +23 -0
- data/.spellr_wordlists/dictionary.txt +120 -0
- data/.spellr_wordlists/english.txt +3 -0
- data/.spellr_wordlists/lorem.txt +4 -0
- data/.spellr_wordlists/ruby.txt +2 -0
- data/.travis.yml +7 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +67 -0
- data/LICENSE.txt +21 -0
- data/README.md +64 -0
- data/Rakefile +8 -0
- data/bin/console +8 -0
- data/bin/fetch_wordlist/english +65 -0
- data/bin/fetch_wordlist/ruby +150 -0
- data/bin/setup +3 -0
- data/exe/spellr +5 -0
- data/lib/.spellr.yml +93 -0
- data/lib/spellr.rb +26 -0
- data/lib/spellr/check.rb +56 -0
- data/lib/spellr/cli.rb +205 -0
- data/lib/spellr/column_location.rb +49 -0
- data/lib/spellr/config.rb +105 -0
- data/lib/spellr/file.rb +27 -0
- data/lib/spellr/file_list.rb +45 -0
- data/lib/spellr/interactive.rb +191 -0
- data/lib/spellr/language.rb +104 -0
- data/lib/spellr/line_location.rb +29 -0
- data/lib/spellr/line_tokenizer.rb +181 -0
- data/lib/spellr/reporter.rb +27 -0
- data/lib/spellr/string_format.rb +43 -0
- data/lib/spellr/token.rb +83 -0
- data/lib/spellr/tokenizer.rb +72 -0
- data/lib/spellr/version.rb +5 -0
- data/lib/spellr/wordlist.rb +100 -0
- data/lib/spellr/wordlist_reporter.rb +21 -0
- data/spellr.gemspec +35 -0
- data/wordlist +2 -0
- data/wordlists/dockerfile.txt +21 -0
- data/wordlists/html.txt +340 -0
- data/wordlists/javascript.txt +64 -0
- data/wordlists/ruby.txt +2344 -0
- data/wordlists/shell.txt +2 -0
- metadata +217 -0
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 Dana Sherson
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# Spellr
|
2
|
+
|
3
|
+
Spell check your source code for fun and occasionally finding bugs
|
4
|
+
|
5
|
+
This is inspired by https://github.com/myint/scspell but i wanted a ruby gem
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'spellr', require: false
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install spellr
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
To start an interactive spell checking session
|
26
|
+
```
|
27
|
+
spellr --interactive
|
28
|
+
```
|
29
|
+
|
30
|
+
## Development
|
31
|
+
|
32
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
33
|
+
|
34
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
35
|
+
|
36
|
+
## Contributing
|
37
|
+
|
38
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/robotdana/spellr.
|
39
|
+
|
40
|
+
## License
|
41
|
+
|
42
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
43
|
+
|
44
|
+
## TODO Before release
|
45
|
+
|
46
|
+
- [x] handle interactive add
|
47
|
+
- [x] handling wordlists per language better
|
48
|
+
- [x] global wordlists
|
49
|
+
- [x] dynamic wordlist (e.g. built from ruby and YOUR Gemfile and stdlib packages)
|
50
|
+
- [x] gem committed semi-dynamic wordlist
|
51
|
+
- [x] gem committed static wordlist
|
52
|
+
- [x] enable/disable
|
53
|
+
- [x] get marketplacer codebase green
|
54
|
+
- [x] escape
|
55
|
+
- [ ] remove default dynamic wordlist nonsense
|
56
|
+
- [x] fix bugs, have specs
|
57
|
+
- [x] attempt key recognition
|
58
|
+
## TODO after release
|
59
|
+
- [ ] throw instead of raise for flow control
|
60
|
+
- [ ] attempt subwords again
|
61
|
+
- [ ] (semi)dynamic js wordlist
|
62
|
+
- [ ] (semi)dynamic html wordlist
|
63
|
+
- [ ] (semi)dynamic bash wordlist
|
64
|
+
- [ ] editor plugins
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'net/http'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
class SCOWLDownloader
|
8
|
+
SIZE_OPTIONS = %w{10 20 35 40 50 55 60 70 80 95}.freeze
|
9
|
+
VARIANT_OPTIONS = %w{none common acceptable seldom-used}.freeze
|
10
|
+
DIACRITIC_OPTIONS = %w{strip keep both}.freeze
|
11
|
+
SPELLING_LANGUAGE_OPTIONS = %w{US GBs GBz CA AU}.freeze
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
set_default_options
|
15
|
+
parse_options
|
16
|
+
puts Net::HTTP.get_response(uri).body
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def set_default_options
|
22
|
+
@options = {
|
23
|
+
max_size: 50,
|
24
|
+
spelling: :US,
|
25
|
+
max_variant: 0,
|
26
|
+
diacritic: :both,
|
27
|
+
hacker: true
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def parse_options # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
32
|
+
# rubocop:disable Metrics/LineLength
|
33
|
+
OptionParser.new do |opts|
|
34
|
+
opts.banner = 'Usage: spellr [options] fetch english [wordlist options]'
|
35
|
+
opts.on('-s', '--max-size', '=SIZE', String, SIZE_OPTIONS, 'Wordlist size. Options: 10 (~5,000 words), 20, 35, 40, 50 (default), 60, 70 (~170,000 words)') { |i| @options[:max_size] = i }
|
36
|
+
opts.on('-v', '--max-variants', '=VARIANTS', String, VARIANT_OPTIONS, 'Spelling variants. Options: none (default), common, acceptable, seldom-used') { |i| @options[:max_variant] = VARIANT_OPTIONS.index(i) }
|
37
|
+
opts.on('-d', '--diacritic', '=DIACRITIC', String, DIACRITIC_OPTIONS, 'Include diacritics in words. Options: strip (café becomes cafe), keep, both (default. cafe & café)') { |s| @options[:diacritic] = s }
|
38
|
+
opts.on('-l', '--language=x,y,z', Array, 'Comma separated list of English variations. Options: US (default), GBs (GB with -ise), GBz (GB with -ize), CA, AU') do |a|
|
39
|
+
raise ArgumentError unless (a - SPELLING_LANGUAGE_OPTIONS).empty?
|
40
|
+
|
41
|
+
@options[:spelling] = a
|
42
|
+
end
|
43
|
+
opts.on('-p', '--[no-]programming', 'include common programming terms like grep (default true)') { |h| @options[:special] = :hacker if h }
|
44
|
+
opts.on_tail('-h', '--help') do
|
45
|
+
warn opts.to_s
|
46
|
+
exit 1
|
47
|
+
end
|
48
|
+
end.parse!
|
49
|
+
# rubocop:enable Metrics/LineLength
|
50
|
+
end
|
51
|
+
|
52
|
+
attr_reader :options
|
53
|
+
|
54
|
+
def uri
|
55
|
+
query = URI.encode_www_form(
|
56
|
+
**options,
|
57
|
+
download: :wordlist,
|
58
|
+
encoding: :'utf-8',
|
59
|
+
format: :inline
|
60
|
+
)
|
61
|
+
URI.parse("http://app.aspell.net/create?#{query}")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
SCOWLDownloader.new
|
@@ -0,0 +1,150 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'optparse'
|
5
|
+
class RubyWords # rubocop:disable Metrics/ClassLength
|
6
|
+
def initialize
|
7
|
+
@strings = []
|
8
|
+
prepare_excluded_classes
|
9
|
+
|
10
|
+
parse_options
|
11
|
+
|
12
|
+
prepare_post_excluded_classes
|
13
|
+
|
14
|
+
puts generate_words
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def prepare_excluded_classes
|
20
|
+
@looked_at = []
|
21
|
+
@looked_at << RubyWords.__id__
|
22
|
+
@looked_at << OptionParser.__id__ # because we're including it here
|
23
|
+
end
|
24
|
+
|
25
|
+
def generate_words
|
26
|
+
$VERBOSE = nil
|
27
|
+
@strings = []
|
28
|
+
generate_words_for(Module)
|
29
|
+
generate_keywords
|
30
|
+
generate_convention_words
|
31
|
+
end
|
32
|
+
|
33
|
+
def generate_words_for(constant)
|
34
|
+
return if @looked_at.include?(constant.__id__) # to prevent endless loops
|
35
|
+
|
36
|
+
@looked_at << constant.__id__
|
37
|
+
|
38
|
+
generate_methods_for(constant)
|
39
|
+
generate_child_constants_for(constant)
|
40
|
+
end
|
41
|
+
|
42
|
+
def generate_methods_for(constant)
|
43
|
+
@strings |= constant.public_instance_methods(false) if constant.respond_to?(:public_instance_methods)
|
44
|
+
@strings |= constant.public_methods(false) if constant.respond_to?(:public_methods)
|
45
|
+
end
|
46
|
+
|
47
|
+
def generate_child_constants_for(constant) # rubocop:disable Metrics/MethodLength
|
48
|
+
return unless constant.respond_to?(:constants)
|
49
|
+
|
50
|
+
constant.constants.each do |child|
|
51
|
+
if autoload?(child)
|
52
|
+
warn "Skipping autoload constant #{constant}::#{child}"
|
53
|
+
next
|
54
|
+
end
|
55
|
+
|
56
|
+
@strings |= [child]
|
57
|
+
child = constant.const_get(child)
|
58
|
+
generate_words_for(child)
|
59
|
+
rescue StandardError, LoadError => e
|
60
|
+
warn "Error loading #{constant}::#{child} => #{e.message}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def generate_keywords
|
65
|
+
@strings |= %w{
|
66
|
+
__ENCODING__ __LINE__ __FILE__ BEGIN END alias and begin break case class def
|
67
|
+
defined? do else elsif end ensure false for if in module next nil not or redo
|
68
|
+
rescue retry return self super then true undef unless until when while yield
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def generate_convention_words
|
73
|
+
@strings |= %w{
|
74
|
+
klass
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
# badly behaved classes that I'll always have to exclude
|
79
|
+
# TODO: use the full class name rather than __id__ so i don't have to load anything
|
80
|
+
def prepare_post_excluded_classes
|
81
|
+
%w{RSpec::Core::Runner I18n::Tests}.each do |exclude|
|
82
|
+
@looked_at << Module.const_get(exclude).__id__
|
83
|
+
rescue StandardError, LoadError # rubocop:disable Lint/HandleExceptions
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def exclude_option(excludes, quiet: false)
|
88
|
+
excludes.each do |exclude|
|
89
|
+
@looked_at << Module.const_get(exclude).__id__
|
90
|
+
rescue StandardError, LoadError => e
|
91
|
+
warn "Error excluding #{exclude} => #{e.message}" unless quiet
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def bundler_option(_)
|
96
|
+
require 'bundler/setup'
|
97
|
+
require_each Bundler.setup.requires.values.flatten(1)
|
98
|
+
end
|
99
|
+
|
100
|
+
def require_each(requirables)
|
101
|
+
requirables.each(&method(:soft_require))
|
102
|
+
end
|
103
|
+
|
104
|
+
def soft_require(requireable)
|
105
|
+
require requireable
|
106
|
+
rescue LoadError => e
|
107
|
+
warn "Error requiring #{requireable} => #{e.message}"
|
108
|
+
end
|
109
|
+
|
110
|
+
def require_option(gems)
|
111
|
+
soft_require 'bundler/setup'
|
112
|
+
require_each(gems)
|
113
|
+
end
|
114
|
+
|
115
|
+
def available_stdlibs
|
116
|
+
%w{
|
117
|
+
abbrev base64 benchmark bigdecimal cgi cmath coverage csv date delegate digest
|
118
|
+
drb/drb e2mmap English erb etc expect fcntl fiddle fileutils find forwardable
|
119
|
+
getoptlong io/console io/nonblock io/wait ipaddr irb json logger matrix mkmf
|
120
|
+
monitor mutex_m net/ftp net/http net/imap net/pop net/smtp net/telnet nkf
|
121
|
+
objspace observer open-uri open3 openssl optionparser optparse ostruct pathname
|
122
|
+
pp prettyprint prime pstore psych pty racc/parser readline resolv ripper rss scanf
|
123
|
+
sdbm securerandom set shell shellwords singleton socket stringio strscan sync syslog
|
124
|
+
tempfile thwait time timeout tmpdir tracer tsort uri weakref webrick yaml zlib
|
125
|
+
}
|
126
|
+
end
|
127
|
+
|
128
|
+
def stdlib_option(stdlibs)
|
129
|
+
stdlibs &= available_stdlibs
|
130
|
+
stdlibs.each { |p| require p }
|
131
|
+
@strings += stdlibs
|
132
|
+
@looked_at -= [OptionParser.__id__] if stdlibs.include?('optparse') # because they might want it too
|
133
|
+
end
|
134
|
+
|
135
|
+
def parse_options # rubocop:disable Metrics/MethodLength
|
136
|
+
OptionParser.new do |opts|
|
137
|
+
opts.set_program_name 'spellr --fetch ruby'
|
138
|
+
opts.on('-r', '--require=x,y,z', Array, 'requires the specified gems', &method(:require_option))
|
139
|
+
opts.on('-s', '--stdlib=x,y,z', Array, 'requires the specified stdlib packages', &method(:stdlib_option))
|
140
|
+
opts.on('-b', '--bundler', 'includes methods and constants required by emfile', &method(:bundler_option))
|
141
|
+
opts.on('-x', '--exclude=x,y,z', Array, 'exclude listing these constants and their methods', &method(:exclude_option)) # rubocop:disable Metrics/LineLength
|
142
|
+
opts.on_tail('-h', '--help', 'Shows this message') do
|
143
|
+
warn opts
|
144
|
+
exit 1
|
145
|
+
end
|
146
|
+
end.parse!
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
RubyWords.new
|
data/bin/setup
ADDED
data/exe/spellr
ADDED
data/lib/.spellr.yml
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
---
|
2
|
+
word_minimum_length: 3
|
3
|
+
|
4
|
+
ignore: # this list is parsed with the .gitignore format
|
5
|
+
- /.git/
|
6
|
+
- .DS_Store
|
7
|
+
- Gemfile.lock
|
8
|
+
- .rspec_status
|
9
|
+
- '*.png'
|
10
|
+
- '*.jpg'
|
11
|
+
- '*.gif'
|
12
|
+
- '*.ico'
|
13
|
+
- .gitkeep
|
14
|
+
- .keep
|
15
|
+
- '*.svg'
|
16
|
+
- '*.eot'
|
17
|
+
- '*.ttf'
|
18
|
+
- '*.woff'
|
19
|
+
- '*.woff2'
|
20
|
+
- '*.zip'
|
21
|
+
- '*.pdf'
|
22
|
+
- '*.xlsx'
|
23
|
+
- '*.gz'
|
24
|
+
|
25
|
+
languages:
|
26
|
+
english:
|
27
|
+
generate: "fetch english"
|
28
|
+
# TODO: don't generate the ruby file until you actually need one
|
29
|
+
ruby:
|
30
|
+
only: # Filtered using File.fn_match
|
31
|
+
- '*.rb'
|
32
|
+
- '*.rake'
|
33
|
+
- '*.gemspec'
|
34
|
+
- '*.erb'
|
35
|
+
- '*.haml'
|
36
|
+
- '*.jbuilder'
|
37
|
+
- '*.builder'
|
38
|
+
- Gemfile
|
39
|
+
- Rakefile
|
40
|
+
- config.ru
|
41
|
+
hashbangs:
|
42
|
+
- ruby
|
43
|
+
html:
|
44
|
+
only:
|
45
|
+
- '*.html'
|
46
|
+
- '*.hml'
|
47
|
+
- '*.jsx'
|
48
|
+
- '*.tsx'
|
49
|
+
- '*.js'
|
50
|
+
- '*.ts'
|
51
|
+
- '*.coffee'
|
52
|
+
- '*.haml'
|
53
|
+
- '*.erb'
|
54
|
+
- '*.rb'
|
55
|
+
- '*.builder'
|
56
|
+
- '*.css'
|
57
|
+
- '*.scss'
|
58
|
+
- '*.sass'
|
59
|
+
- '*.less'
|
60
|
+
js:
|
61
|
+
only:
|
62
|
+
- '*.html'
|
63
|
+
- '*.hml'
|
64
|
+
- '*.jsx'
|
65
|
+
- '*.tsx'
|
66
|
+
- '*.js'
|
67
|
+
- '*.ts'
|
68
|
+
- '*.coffee'
|
69
|
+
- '*.haml'
|
70
|
+
- '*.erb'
|
71
|
+
- '*.json'
|
72
|
+
shell:
|
73
|
+
only:
|
74
|
+
- '*.sh'
|
75
|
+
- Dockerfile
|
76
|
+
hashbangs:
|
77
|
+
- bash
|
78
|
+
- sh
|
79
|
+
dockerfile:
|
80
|
+
only:
|
81
|
+
- Dockerfile
|
82
|
+
css:
|
83
|
+
only:
|
84
|
+
- '*.css'
|
85
|
+
- '*.sass'
|
86
|
+
- '*.scss'
|
87
|
+
xml:
|
88
|
+
only:
|
89
|
+
- '*.xml'
|
90
|
+
- '*.html'
|
91
|
+
- '*.haml'
|
92
|
+
- '*.hml'
|
93
|
+
- '*.svg'
|
data/lib/spellr.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spellr
|
4
|
+
class Error < StandardError; end
|
5
|
+
class DidReplacement < Spellr::Error
|
6
|
+
attr_reader :token
|
7
|
+
|
8
|
+
def initialize(token = nil)
|
9
|
+
@token = token
|
10
|
+
end
|
11
|
+
end
|
12
|
+
class DidAdd < Spellr::Error
|
13
|
+
attr_reader :token
|
14
|
+
|
15
|
+
def initialize(token = nil)
|
16
|
+
@token = token
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module_function
|
21
|
+
|
22
|
+
def config
|
23
|
+
require_relative 'spellr/config'
|
24
|
+
@config ||= Spellr::Config.new
|
25
|
+
end
|
26
|
+
end
|