snibbets 2.0.7 → 2.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -2
- data/CHANGELOG.md.orig +56 -0
- data/Gemfile.lock +8 -3
- data/Gemfile.lock.orig +107 -0
- data/README.md +3 -0
- data/bin/snibbets +0 -284
- data/buildnotes.md +0 -1
- data/lib/snibbets/array.rb +39 -0
- data/lib/snibbets/config.rb +9 -0
- data/lib/snibbets/menu.rb +14 -2
- data/lib/snibbets/string.rb +8 -2
- data/lib/snibbets/version.rb +1 -1
- data/lib/snibbets.rb +285 -0
- data/snibbets.gemspec +2 -1
- metadata +20 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f07f0d4772b8d611c0e29da125b4e6915d3909479c4384348699eedc2e1baf90
|
4
|
+
data.tar.gz: e9abdf59d66f3c099c0c25f20a912efc53b690c7c45a5f4ada2b18355c3d473c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac873395a3735c827164f03b497f21f06e8af227b515e299c40eb8a4eeff26c907a5893077e1ee1a528200ef4ef9e6fe7c5ac1c9ddfecf7522ed0d772e6fd6eb
|
7
|
+
data.tar.gz: ca65c353589adda9fb4af59d390e98e277e5ba1523d746ab3f5cce19119cfa541b2db36045a90ecddd73be7224665dd96dd8642a2d7c010c438e6e9141a79d6a
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,30 @@
|
|
1
|
-
### 2.0.
|
1
|
+
### 2.0.9
|
2
2
|
|
3
|
-
2023-04-15
|
3
|
+
2023-04-15 15:44
|
4
|
+
|
5
|
+
#### IMPROVED
|
6
|
+
|
7
|
+
- Allow setting `menus` config key to force Snibbets to use fzf, gum, or console menus
|
8
|
+
- Allow setting `menus` config key to force Snibbets to use fzf, gum, or console menus
|
9
|
+
|
10
|
+
#### FIXED
|
11
|
+
|
12
|
+
- If a header section contains no code blocks, don't display it in menu
|
13
|
+
- Remove leading and trailing newlines without affecting indentation
|
14
|
+
|
15
|
+
### 2.0.8
|
16
|
+
|
17
|
+
2023-04-15 15:41
|
18
|
+
|
19
|
+
#### IMPROVED
|
20
|
+
|
21
|
+
- Allow setting `menus` config key to force Snibbets to use fzf, gum, or console menus
|
22
|
+
- Allow setting `menus` config key to force Snibbets to use fzf, gum, or console menus
|
23
|
+
|
24
|
+
#### FIXED
|
25
|
+
|
26
|
+
- If a header section contains no code blocks, don't display it in menu
|
27
|
+
- Remove leading and trailing newlines without affecting indentation
|
4
28
|
|
5
29
|
### 2.0.6
|
6
30
|
|
data/CHANGELOG.md.orig
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
### 2.0.10
|
2
|
+
|
3
|
+
2023-04-15 16:28
|
4
|
+
|
5
|
+
#### FIXED
|
6
|
+
|
7
|
+
- Update dependencies for security
|
8
|
+
- Incorporate fixes from @robjwells addressing #3 and #4
|
9
|
+
- Incorporate fixes from @robjwells addressing #3 and #4
|
10
|
+
- Best menu CLI determination missing modules
|
11
|
+
|
12
|
+
<<<<<<< HEAD
|
13
|
+
### 2.0.7
|
14
|
+
|
15
|
+
2023-04-15 12:02
|
16
|
+
=======
|
17
|
+
### 2.0.9
|
18
|
+
|
19
|
+
2023-04-15 15:44
|
20
|
+
|
21
|
+
#### IMPROVED
|
22
|
+
|
23
|
+
- Allow setting `menus` config key to force Snibbets to use fzf, gum, or console menus
|
24
|
+
- Allow setting `menus` config key to force Snibbets to use fzf, gum, or console menus
|
25
|
+
|
26
|
+
#### FIXED
|
27
|
+
|
28
|
+
- If a header section contains no code blocks, don't display it in menu
|
29
|
+
- Remove leading and trailing newlines without affecting indentation
|
30
|
+
|
31
|
+
### 2.0.8
|
32
|
+
|
33
|
+
2023-04-15 15:41
|
34
|
+
|
35
|
+
#### IMPROVED
|
36
|
+
|
37
|
+
- Allow setting `menus` config key to force Snibbets to use fzf, gum, or console menus
|
38
|
+
- Allow setting `menus` config key to force Snibbets to use fzf, gum, or console menus
|
39
|
+
|
40
|
+
#### FIXED
|
41
|
+
|
42
|
+
- If a header section contains no code blocks, don't display it in menu
|
43
|
+
- Remove leading and trailing newlines without affecting indentation
|
44
|
+
>>>>>>> release/2.0.9
|
45
|
+
|
46
|
+
### 2.0.6
|
47
|
+
|
48
|
+
2023-04-15 11:55
|
49
|
+
|
50
|
+
#### IMPROVED
|
51
|
+
|
52
|
+
- Refactor script as modules and classes
|
53
|
+
|
54
|
+
## 2.0.2
|
55
|
+
|
56
|
+
Initial release as a gem
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
snibbets (2.0.
|
4
|
+
snibbets (2.0.10)
|
5
5
|
tty-which (~> 0.5, >= 0.5.0)
|
6
6
|
|
7
7
|
GEM
|
@@ -9,6 +9,7 @@ GEM
|
|
9
9
|
specs:
|
10
10
|
ansi (1.5.0)
|
11
11
|
ast (2.4.2)
|
12
|
+
awesome_print (1.9.2)
|
12
13
|
diff-lcs (1.5.0)
|
13
14
|
docile (1.4.0)
|
14
15
|
gem-release (2.2.2)
|
@@ -25,7 +26,7 @@ GEM
|
|
25
26
|
ast (~> 2.4.1)
|
26
27
|
rainbow (3.1.1)
|
27
28
|
rake (13.0.6)
|
28
|
-
rdoc (
|
29
|
+
rdoc (6.3.3)
|
29
30
|
regexp_parser (2.7.0)
|
30
31
|
rexml (3.2.5)
|
31
32
|
rspec (3.12.0)
|
@@ -76,21 +77,25 @@ GEM
|
|
76
77
|
thor (1.2.1)
|
77
78
|
tty-which (0.5.0)
|
78
79
|
unicode-display_width (2.4.2)
|
80
|
+
yard (0.9.34)
|
79
81
|
|
80
82
|
PLATFORMS
|
81
83
|
arm64-darwin-20
|
84
|
+
x86_64-linux
|
82
85
|
|
83
86
|
DEPENDENCIES
|
87
|
+
awesome_print (~> 1.9)
|
84
88
|
bundler (~> 2.0)
|
85
89
|
gem-release (~> 2.2)
|
86
90
|
parse_gemspec-cli (~> 1.0)
|
87
91
|
rake (~> 13.0)
|
88
|
-
rdoc (~>
|
92
|
+
rdoc (~> 6.3.1)
|
89
93
|
rspec (~> 3.0)
|
90
94
|
simplecov (~> 0.21)
|
91
95
|
simplecov-console (~> 0.9)
|
92
96
|
snibbets!
|
93
97
|
standard (~> 1.3)
|
98
|
+
yard (~> 0.9, >= 0.9.26)
|
94
99
|
|
95
100
|
BUNDLED WITH
|
96
101
|
2.2.29
|
data/Gemfile.lock.orig
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
snibbets (2.0.10)
|
5
|
+
tty-which (~> 0.5, >= 0.5.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
ansi (1.5.0)
|
11
|
+
ast (2.4.2)
|
12
|
+
awesome_print (1.9.2)
|
13
|
+
diff-lcs (1.5.0)
|
14
|
+
docile (1.4.0)
|
15
|
+
gem-release (2.2.2)
|
16
|
+
json (2.6.3)
|
17
|
+
language_server-protocol (3.17.0.3)
|
18
|
+
multi_json (1.15.0)
|
19
|
+
parallel (1.22.1)
|
20
|
+
parse_gemspec (1.0.0)
|
21
|
+
parse_gemspec-cli (1.0.0)
|
22
|
+
multi_json
|
23
|
+
parse_gemspec
|
24
|
+
thor
|
25
|
+
parser (3.2.2.0)
|
26
|
+
ast (~> 2.4.1)
|
27
|
+
rainbow (3.1.1)
|
28
|
+
rake (13.0.6)
|
29
|
+
<<<<<<< HEAD
|
30
|
+
rdoc (6.3.1)
|
31
|
+
=======
|
32
|
+
rdoc (6.3.3)
|
33
|
+
>>>>>>> af6f234 (Update rdoc)
|
34
|
+
regexp_parser (2.7.0)
|
35
|
+
rexml (3.2.5)
|
36
|
+
rspec (3.12.0)
|
37
|
+
rspec-core (~> 3.12.0)
|
38
|
+
rspec-expectations (~> 3.12.0)
|
39
|
+
rspec-mocks (~> 3.12.0)
|
40
|
+
rspec-core (3.12.1)
|
41
|
+
rspec-support (~> 3.12.0)
|
42
|
+
rspec-expectations (3.12.2)
|
43
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
44
|
+
rspec-support (~> 3.12.0)
|
45
|
+
rspec-mocks (3.12.5)
|
46
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
47
|
+
rspec-support (~> 3.12.0)
|
48
|
+
rspec-support (3.12.0)
|
49
|
+
rubocop (1.48.1)
|
50
|
+
json (~> 2.3)
|
51
|
+
parallel (~> 1.10)
|
52
|
+
parser (>= 3.2.0.0)
|
53
|
+
rainbow (>= 2.2.2, < 4.0)
|
54
|
+
regexp_parser (>= 1.8, < 3.0)
|
55
|
+
rexml (>= 3.2.5, < 4.0)
|
56
|
+
rubocop-ast (>= 1.26.0, < 2.0)
|
57
|
+
ruby-progressbar (~> 1.7)
|
58
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
59
|
+
rubocop-ast (1.28.0)
|
60
|
+
parser (>= 3.2.1.0)
|
61
|
+
rubocop-performance (1.16.0)
|
62
|
+
rubocop (>= 1.7.0, < 2.0)
|
63
|
+
rubocop-ast (>= 0.4.0)
|
64
|
+
ruby-progressbar (1.13.0)
|
65
|
+
simplecov (0.22.0)
|
66
|
+
docile (~> 1.1)
|
67
|
+
simplecov-html (~> 0.11)
|
68
|
+
simplecov_json_formatter (~> 0.1)
|
69
|
+
simplecov-console (0.9.1)
|
70
|
+
ansi
|
71
|
+
simplecov
|
72
|
+
terminal-table
|
73
|
+
simplecov-html (0.12.3)
|
74
|
+
simplecov_json_formatter (0.1.4)
|
75
|
+
standard (1.26.0)
|
76
|
+
language_server-protocol (~> 3.17.0.2)
|
77
|
+
rubocop (~> 1.48.1)
|
78
|
+
rubocop-performance (~> 1.16.0)
|
79
|
+
terminal-table (3.0.2)
|
80
|
+
unicode-display_width (>= 1.1.1, < 3)
|
81
|
+
thor (1.2.1)
|
82
|
+
tty-which (0.5.0)
|
83
|
+
unicode-display_width (2.4.2)
|
84
|
+
webrick (1.7.0)
|
85
|
+
yard (0.9.28)
|
86
|
+
webrick (~> 1.7.0)
|
87
|
+
|
88
|
+
PLATFORMS
|
89
|
+
arm64-darwin-20
|
90
|
+
x86_64-linux
|
91
|
+
|
92
|
+
DEPENDENCIES
|
93
|
+
awesome_print (~> 1.9)
|
94
|
+
bundler (~> 2.0)
|
95
|
+
gem-release (~> 2.2)
|
96
|
+
parse_gemspec-cli (~> 1.0)
|
97
|
+
rake (~> 13.0)
|
98
|
+
rdoc (~> 6.3.1)
|
99
|
+
rspec (~> 3.0)
|
100
|
+
simplecov (~> 0.21)
|
101
|
+
simplecov-console (~> 0.9)
|
102
|
+
snibbets!
|
103
|
+
standard (~> 1.3)
|
104
|
+
yard (~> 0.9, >= 0.9.26)
|
105
|
+
|
106
|
+
BUNDLED WITH
|
107
|
+
2.2.29
|
data/README.md
CHANGED
@@ -88,6 +88,7 @@ extension: md
|
|
88
88
|
highlight: false
|
89
89
|
interactive: true
|
90
90
|
launchbar: false
|
91
|
+
menus:
|
91
92
|
name_only: false
|
92
93
|
output: raw
|
93
94
|
source: "~/Dropbox/Snippets"
|
@@ -111,6 +112,8 @@ The `highlight` key turns on syntax highlighting. This requires that either `pyg
|
|
111
112
|
|
112
113
|
The `interactive` setting determines whether menus will be displayed. This should generally be true, but if you want silent operation that just displays the best match automatically, set it to false.
|
113
114
|
|
115
|
+
The `menus` setting will determine what method is used for displaying interactive menus. If this is not set, it will be automatically determined in the order of `fzf`, `gum`, and `console`. You can manually choose to use one of these options over another by making it the `menus` setting.
|
116
|
+
|
114
117
|
The `name_only` key will permanently set Snibbets to only search for snippets by their filename rather than examining their contents. You can enable this at runtime using `--name-only` in the command.
|
115
118
|
|
116
119
|
### Usage
|
data/bin/snibbets
CHANGED
@@ -4,290 +4,6 @@
|
|
4
4
|
$LOAD_PATH.unshift File.join(__dir__, '..', 'lib')
|
5
5
|
require 'snibbets'
|
6
6
|
|
7
|
-
module Snibbets
|
8
|
-
class << self
|
9
|
-
# Search the snippets directory for query using find and grep
|
10
|
-
def search(try: 0)
|
11
|
-
folder = Snibbets.options[:source]
|
12
|
-
# start by doing a spotlight search, if that fails, start trying:
|
13
|
-
# First try only search by filenames
|
14
|
-
# Second try search with grep
|
15
|
-
ext = Snibbets.options[:extension] || 'md'
|
16
|
-
cmd = case try
|
17
|
-
when 1
|
18
|
-
%(find "#{folder}" -iregex '#{@query.rx}' -name '*.#{ext}')
|
19
|
-
when 2
|
20
|
-
rg = TTY::Which.which('rg')
|
21
|
-
ag = TTY::Which.which('ag')
|
22
|
-
ack = TTY::Which.which('ack')
|
23
|
-
grep = TTY::Which.which('grep')
|
24
|
-
if Snibbets.options[:name_only]
|
25
|
-
nil
|
26
|
-
elsif !rg.empty?
|
27
|
-
%(#{rg} -li --color=never --glob='*.#{ext}' '#{@query.rx}' "#{folder}")
|
28
|
-
elsif !ag.empty?
|
29
|
-
%(#{ag} -li --nocolor -G '.*.#{ext}' '#{@query.rx}' "#{folder}")
|
30
|
-
elsif !ack.empty?
|
31
|
-
%(#{ack} -li --nocolor --markdown '#{@query.rx}' "#{folder}")
|
32
|
-
elsif !grep.empty?
|
33
|
-
%(#{grep} -iEl '#{@query.rx}' "#{folder}"/**/*.#{ext})
|
34
|
-
else
|
35
|
-
nil
|
36
|
-
end
|
37
|
-
else
|
38
|
-
mdfind = TTY::Which.which('mdfind')
|
39
|
-
if mdfind.empty?
|
40
|
-
nil
|
41
|
-
else
|
42
|
-
name_only = Snibbets.options[:name_only] ? '-name ' : ''
|
43
|
-
%(mdfind -onlyin #{folder} #{name_only}'#{@query} filename:.#{ext}' 2>/dev/null)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
if try == 2 && cmd.nil?
|
48
|
-
puts "No search method available on this system. Please install ripgrep, silver surfer, ack, or grep."
|
49
|
-
Process.exit 1
|
50
|
-
end
|
51
|
-
|
52
|
-
res = cmd.nil? ? '' : `#{cmd}`.strip
|
53
|
-
|
54
|
-
matches = []
|
55
|
-
|
56
|
-
unless res.empty?
|
57
|
-
lines = res.split(/\n/)
|
58
|
-
lines.each do |l|
|
59
|
-
matches << {
|
60
|
-
'title' => File.basename(l, '.*'),
|
61
|
-
'path' => l
|
62
|
-
}
|
63
|
-
end
|
64
|
-
|
65
|
-
matches.sort_by! { |a| a['title'] }.uniq!
|
66
|
-
|
67
|
-
return matches unless matches.empty?
|
68
|
-
end
|
69
|
-
|
70
|
-
return matches if try == 2
|
71
|
-
|
72
|
-
# if no results on the first try, try again searching all text
|
73
|
-
search(try: try + 1) if matches.empty?
|
74
|
-
end
|
75
|
-
|
76
|
-
def open_snippet_in_editor(filepath)
|
77
|
-
editor = Snibbets.options[:editor] || Snibbets::Config.best_editor
|
78
|
-
|
79
|
-
os = RbConfig::CONFIG['target_os']
|
80
|
-
|
81
|
-
if editor.nil?
|
82
|
-
OS.open(filepath)
|
83
|
-
else
|
84
|
-
if os =~ /darwin.*/i
|
85
|
-
if editor =~ /^TextEdit/
|
86
|
-
`open -a TextEdit "#{filepath}"`
|
87
|
-
elsif TTY::Which.bundle_id?(editor)
|
88
|
-
`open -b "#{editor}" "#{filepath}"`
|
89
|
-
elsif TTY::Which.app?(editor)
|
90
|
-
`open -a "#{editor}" "#{filepath}"`
|
91
|
-
elsif TTY::Which.exist?(editor)
|
92
|
-
editor = TTY::Which.which(editor)
|
93
|
-
system %(#{editor} "#{filepath}") if editor
|
94
|
-
else
|
95
|
-
puts "No editor configured, or editor is missing"
|
96
|
-
Process.exit 1
|
97
|
-
end
|
98
|
-
elsif TTY::Which.exist?(editor)
|
99
|
-
editor = TTY::Which.which(editor)
|
100
|
-
system %(#{editor} "#{filepath}") if editor
|
101
|
-
else
|
102
|
-
puts "No editor configured, or editor is missing"
|
103
|
-
Process.exit 1
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def new_snippet_from_clipboard
|
109
|
-
trap('SIGINT') do
|
110
|
-
Howzit.console.info "\nCancelled"
|
111
|
-
exit!
|
112
|
-
end
|
113
|
-
|
114
|
-
build_lexers
|
115
|
-
|
116
|
-
pb = OS.paste.outdent
|
117
|
-
|
118
|
-
printf 'What does this snippet do? '
|
119
|
-
input = $stdin.gets.chomp
|
120
|
-
title = input unless input.empty?
|
121
|
-
|
122
|
-
printf 'What language(s) does it use (separate with spaces, full names or file extensions will work)? '
|
123
|
-
input = $stdin.gets.chomp
|
124
|
-
langs = input.split(/ +/).map(&:strip) unless input.empty?
|
125
|
-
exts = langs.map { |lang| Snibbets::Lexers.lang_to_ext(lang) }
|
126
|
-
tags = langs.map { |lang| Snibbets::Lexers.ext_to_lang(lang) }.concat(langs).sort.uniq
|
127
|
-
|
128
|
-
filename ="#{title}.#{exts.join('.')}.#{Snibbets.options[:extension]}"
|
129
|
-
|
130
|
-
File.open(File.join(Snibbets.options[:source], filename), 'w') do |f|
|
131
|
-
f.puts "tags: #{tags.join(', ')}
|
132
|
-
|
133
|
-
```
|
134
|
-
#{pb}
|
135
|
-
```"
|
136
|
-
end
|
137
|
-
|
138
|
-
puts "New snippet written to #{filename}."
|
139
|
-
end
|
140
|
-
|
141
|
-
def handle_launchbar(results)
|
142
|
-
output = []
|
143
|
-
|
144
|
-
if results.empty?
|
145
|
-
out = {
|
146
|
-
'title' => 'No matching snippets found'
|
147
|
-
}.to_json
|
148
|
-
puts out
|
149
|
-
Process.exit
|
150
|
-
end
|
151
|
-
|
152
|
-
results.each do |result|
|
153
|
-
input = IO.read(result['path'])
|
154
|
-
snippets = input.snippets
|
155
|
-
next if snippets.empty?
|
156
|
-
|
157
|
-
children = []
|
158
|
-
|
159
|
-
if snippets.length == 1
|
160
|
-
output << {
|
161
|
-
'title' => result['title'],
|
162
|
-
'path' => result['path'],
|
163
|
-
'action' => 'copyIt',
|
164
|
-
'actionArgument' => snippets[0]['code'],
|
165
|
-
'label' => 'Copy'
|
166
|
-
}
|
167
|
-
next
|
168
|
-
end
|
169
|
-
|
170
|
-
snippets.each { |s|
|
171
|
-
children << {
|
172
|
-
'title' => s['title'],
|
173
|
-
'path' => result['path'],
|
174
|
-
'action' => 'copyIt',
|
175
|
-
'actionArgument' => s['code'],
|
176
|
-
'label' => 'Copy'
|
177
|
-
}
|
178
|
-
}
|
179
|
-
|
180
|
-
output << {
|
181
|
-
'title' => result['title'],
|
182
|
-
'path' => result['path'],
|
183
|
-
'children' => children
|
184
|
-
}
|
185
|
-
end
|
186
|
-
|
187
|
-
puts output.to_json
|
188
|
-
end
|
189
|
-
|
190
|
-
def handle_results(results)
|
191
|
-
if Snibbets.options[:launchbar]
|
192
|
-
handle_launchbar(results)
|
193
|
-
else
|
194
|
-
filepath = nil
|
195
|
-
if results.empty?
|
196
|
-
warn 'No results'
|
197
|
-
Process.exit 0
|
198
|
-
elsif results.length == 1 || !Snibbets.options[:interactive]
|
199
|
-
filepath = results[0]['path']
|
200
|
-
input = IO.read(filepath)
|
201
|
-
else
|
202
|
-
answer = Snibbets::Menu.menu(results, title: 'Select a file')
|
203
|
-
filepath = answer['path']
|
204
|
-
input = IO.read(filepath)
|
205
|
-
end
|
206
|
-
|
207
|
-
if @arguments[:edit_snippet]
|
208
|
-
open_snippet_in_editor(filepath)
|
209
|
-
Process.exit 0
|
210
|
-
end
|
211
|
-
|
212
|
-
snippets = input.snippets
|
213
|
-
|
214
|
-
if snippets.empty?
|
215
|
-
warn 'No snippets found'
|
216
|
-
Process.exit 0
|
217
|
-
elsif snippets.length == 1 || !Snibbets.options[:interactive]
|
218
|
-
if Snibbets.options[:output] == 'json'
|
219
|
-
print(snippets.to_json)
|
220
|
-
else
|
221
|
-
snippets.each do |snip|
|
222
|
-
header = File.basename(filepath, '.md')
|
223
|
-
warn header
|
224
|
-
warn '-' * header.length
|
225
|
-
code = snip['code']
|
226
|
-
code = highlight(code, filepath) if Snibbets.options[:highlight]
|
227
|
-
print(code)
|
228
|
-
end
|
229
|
-
end
|
230
|
-
elsif snippets.length > 1
|
231
|
-
if Snibbets.options[:all]
|
232
|
-
if Snibbets.options[:output] == 'json'
|
233
|
-
print(snippets.to_json)
|
234
|
-
else
|
235
|
-
output = []
|
236
|
-
snippets.each do |snippet|
|
237
|
-
output << snippet['title']
|
238
|
-
output << '-' * snippet['title'].length
|
239
|
-
output << snippet['code']
|
240
|
-
output << "\n"
|
241
|
-
end
|
242
|
-
print(output.join("\n"))
|
243
|
-
end
|
244
|
-
else
|
245
|
-
snippets.push({ 'title' => 'All snippets', 'code' => '' })
|
246
|
-
|
247
|
-
answer = Snibbets::Menu.menu(snippets, filename: File.basename(filepath, '.md'), title: 'Select snippet', query: @query)
|
248
|
-
|
249
|
-
if answer['title'] == 'All snippets'
|
250
|
-
snippets.delete_if { |s| s['title'] == 'All snippets'}
|
251
|
-
if Snibbets.options[:output] == 'json'
|
252
|
-
print(snippets.to_json)
|
253
|
-
else
|
254
|
-
header = File.basename(filepath, '.md')
|
255
|
-
warn header
|
256
|
-
warn '=' * header.length
|
257
|
-
output = []
|
258
|
-
snippets.each do |snippet|
|
259
|
-
output << snippet['title']
|
260
|
-
output << '-' * snippet['title'].length
|
261
|
-
output << snippet['code']
|
262
|
-
output << "\n"
|
263
|
-
end
|
264
|
-
print(output.join("\n"))
|
265
|
-
end
|
266
|
-
elsif Snibbets.options[:output] == 'json'
|
267
|
-
print(answer.to_json)
|
268
|
-
else
|
269
|
-
header = "#{File.basename(filepath, '.md')}: #{answer['title']}"
|
270
|
-
warn header
|
271
|
-
warn '-' * header.length
|
272
|
-
code = answer['code']
|
273
|
-
code = highlight(code, filepath) if Snibbets.options[:highlight]
|
274
|
-
print(code)
|
275
|
-
end
|
276
|
-
end
|
277
|
-
end
|
278
|
-
end
|
279
|
-
end
|
280
|
-
|
281
|
-
def print(output)
|
282
|
-
$stdout.puts(output)
|
283
|
-
if Snibbets.options[:copy]
|
284
|
-
OS.copy(output)
|
285
|
-
$stderr.puts "Copied to clipboard"
|
286
|
-
end
|
287
|
-
end
|
288
|
-
end
|
289
|
-
end
|
290
|
-
|
291
7
|
module Snibbets
|
292
8
|
class << self
|
293
9
|
attr_reader :arguments, :query
|
data/buildnotes.md
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
module Snibbets
|
2
|
+
class ::Array
|
3
|
+
def blocks
|
4
|
+
select { |el| el =~ /^<block\d+>$/ }.count
|
5
|
+
end
|
6
|
+
|
7
|
+
def strip_empty
|
8
|
+
remove_leading_empty_elements.remove_trailing_empty_elements
|
9
|
+
end
|
10
|
+
|
11
|
+
def strip_empty!
|
12
|
+
replace strip_empty
|
13
|
+
end
|
14
|
+
|
15
|
+
def remove_leading_empty_elements
|
16
|
+
output = []
|
17
|
+
|
18
|
+
each do |line|
|
19
|
+
next if line =~ /^\s*$/ || line.empty?
|
20
|
+
|
21
|
+
output << line
|
22
|
+
end
|
23
|
+
|
24
|
+
output
|
25
|
+
end
|
26
|
+
|
27
|
+
def remove_trailing_empty_elements
|
28
|
+
output = []
|
29
|
+
|
30
|
+
reverse.each do |line|
|
31
|
+
next if line =~ /^\s*$/ || line.empty?
|
32
|
+
|
33
|
+
output << line
|
34
|
+
end
|
35
|
+
|
36
|
+
output.reverse
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/snibbets/config.rb
CHANGED
@@ -12,6 +12,7 @@ module Snibbets
|
|
12
12
|
highlight: false,
|
13
13
|
interactive: true,
|
14
14
|
launchbar: false,
|
15
|
+
menus: nil,
|
15
16
|
name_only: false,
|
16
17
|
output: 'raw',
|
17
18
|
source: File.expand_path('~/Dropbox/Snippets')
|
@@ -21,9 +22,17 @@ module Snibbets
|
|
21
22
|
custom_config = read_config
|
22
23
|
@options = DEFAULT_OPTIONS.merge(custom_config)
|
23
24
|
@options[:editor] ||= best_editor
|
25
|
+
@options[:menus] ||= best_menu
|
26
|
+
|
24
27
|
write_config unless @options.equal?(custom_config)
|
25
28
|
end
|
26
29
|
|
30
|
+
def best_menu
|
31
|
+
return 'fzf' if TTY::Which.exist?('fzf')
|
32
|
+
return 'gum' if TTY::Which.exist?('gum')
|
33
|
+
'console'
|
34
|
+
end
|
35
|
+
|
27
36
|
def best_editor
|
28
37
|
if ENV['EDITOR']
|
29
38
|
ENV['EDITOR']
|
data/lib/snibbets/menu.rb
CHANGED
@@ -113,7 +113,7 @@ module Snibbets
|
|
113
113
|
return res[line - 1] if line.positive? && line <= res.length
|
114
114
|
|
115
115
|
warn 'Out of range'
|
116
|
-
console_menu(res, title)
|
116
|
+
return console_menu(res, title, filename, query: query)
|
117
117
|
end
|
118
118
|
rescue Interrupt
|
119
119
|
system('stty', stty_save)
|
@@ -122,11 +122,23 @@ module Snibbets
|
|
122
122
|
end
|
123
123
|
|
124
124
|
def menu(res, filename: nil, title: 'Select one', query: nil)
|
125
|
+
menu_opt = Snibbets.options[:menus]
|
125
126
|
query&.remove_spotlight_tags!
|
127
|
+
|
126
128
|
fzf = TTY::Which.which('fzf')
|
129
|
+
gum = TTY::Which.which('gum')
|
130
|
+
|
131
|
+
case menu_opt
|
132
|
+
when /fzf/
|
133
|
+
return fzf_menu(fzf, res, title, query, filename) unless fzf.empty?
|
134
|
+
when /gum/
|
135
|
+
return gum_menu(gum, res, title, query, filename) unless gum.empty?
|
136
|
+
when /console/
|
137
|
+
return console_menu(res, title, filename, query: query)
|
138
|
+
end
|
139
|
+
|
127
140
|
return fzf_menu(fzf, res, title, query, filename) unless fzf.empty?
|
128
141
|
|
129
|
-
gum = TTY::Which.which('gum')
|
130
142
|
return gum_menu(gum, res, title, query, filename) unless gum.empty?
|
131
143
|
|
132
144
|
console_menu(res, title, filename, query: query)
|
data/lib/snibbets/string.rb
CHANGED
@@ -28,6 +28,10 @@ module Snibbets
|
|
28
28
|
lines.join("\n")
|
29
29
|
end
|
30
30
|
|
31
|
+
def strip_newlines
|
32
|
+
split(/\n/).strip_empty.join("\n")
|
33
|
+
end
|
34
|
+
|
31
35
|
# Are there multiple snippets (indicated by ATX headers)
|
32
36
|
def multiple?
|
33
37
|
gsub(/(`{3,}).*?\n\1/m, '').scan(/^#+/).length > 1
|
@@ -131,8 +135,10 @@ module Snibbets
|
|
131
135
|
|
132
136
|
parts.shift if parts.count > 1
|
133
137
|
|
134
|
-
parts.each do |
|
135
|
-
lines =
|
138
|
+
parts.each do |part|
|
139
|
+
lines = part.split(/\n/).strip_empty
|
140
|
+
|
141
|
+
next if lines.blocks == 0
|
136
142
|
|
137
143
|
title = lines.count > 1 ? lines.shift.strip.sub(/[.:]$/, '') : 'Default snippet'
|
138
144
|
block = lines.join("\n").gsub(/<(block\d+)>/) { code_blocks[Regexp.last_match(1)] }
|
data/lib/snibbets/version.rb
CHANGED
data/lib/snibbets.rb
CHANGED
@@ -13,6 +13,7 @@ require_relative 'snibbets/config'
|
|
13
13
|
require_relative 'snibbets/which'
|
14
14
|
require_relative 'snibbets/string'
|
15
15
|
require_relative 'snibbets/hash'
|
16
|
+
require_relative 'snibbets/array'
|
16
17
|
require_relative 'snibbets/menu'
|
17
18
|
require_relative 'snibbets/os'
|
18
19
|
require_relative 'snibbets/highlight'
|
@@ -30,3 +31,287 @@ module Snibbets
|
|
30
31
|
end
|
31
32
|
end
|
32
33
|
end
|
34
|
+
|
35
|
+
module Snibbets
|
36
|
+
class << self
|
37
|
+
# Search the snippets directory for query using find and grep
|
38
|
+
def search(try: 0)
|
39
|
+
folder = File.expand_path(Snibbets.options[:source])
|
40
|
+
# start by doing a spotlight search, if that fails, start trying:
|
41
|
+
# First try only search by filenames
|
42
|
+
# Second try search with grep
|
43
|
+
ext = Snibbets.options[:extension] || 'md'
|
44
|
+
cmd = case try
|
45
|
+
when 1
|
46
|
+
%(find "#{folder}" -iregex '^#{Regexp.escape(folder)}/#{@query.rx}' -name '*.#{ext}')
|
47
|
+
when 2
|
48
|
+
rg = TTY::Which.which('rg')
|
49
|
+
ag = TTY::Which.which('ag')
|
50
|
+
ack = TTY::Which.which('ack')
|
51
|
+
grep = TTY::Which.which('grep')
|
52
|
+
if Snibbets.options[:name_only]
|
53
|
+
nil
|
54
|
+
elsif !rg.empty?
|
55
|
+
%(#{rg} -li --color=never --glob='*.#{ext}' '#{@query.rx}' "#{folder}")
|
56
|
+
elsif !ag.empty?
|
57
|
+
%(#{ag} -li --nocolor -G '.*.#{ext}' '#{@query.rx}' "#{folder}")
|
58
|
+
elsif !ack.empty?
|
59
|
+
%(#{ack} -li --nocolor --markdown '#{@query.rx}' "#{folder}")
|
60
|
+
elsif !grep.empty?
|
61
|
+
%(#{grep} -iEl '#{@query.rx}' "#{folder}"/**/*.#{ext})
|
62
|
+
else
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
else
|
66
|
+
mdfind = TTY::Which.which('mdfind')
|
67
|
+
if mdfind.empty?
|
68
|
+
nil
|
69
|
+
else
|
70
|
+
name_only = Snibbets.options[:name_only] ? '-name ' : ''
|
71
|
+
%(mdfind -onlyin #{folder} #{name_only}'#{@query} filename:.#{ext}' 2>/dev/null)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
if try == 2 && cmd.nil?
|
76
|
+
puts "No search method available on this system. Please install ripgrep, silver surfer, ack, or grep."
|
77
|
+
Process.exit 1
|
78
|
+
end
|
79
|
+
|
80
|
+
res = cmd.nil? ? '' : `#{cmd}`.strip
|
81
|
+
|
82
|
+
matches = []
|
83
|
+
|
84
|
+
unless res.empty?
|
85
|
+
lines = res.split(/\n/)
|
86
|
+
lines.each do |l|
|
87
|
+
matches << {
|
88
|
+
'title' => File.basename(l, '.*'),
|
89
|
+
'path' => l
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
matches.sort_by! { |a| a['title'] }.uniq!
|
94
|
+
|
95
|
+
return matches unless matches.empty?
|
96
|
+
end
|
97
|
+
|
98
|
+
return matches if try == 2
|
99
|
+
|
100
|
+
# if no results on the first try, try again searching all text
|
101
|
+
search(try: try + 1) if matches.empty?
|
102
|
+
end
|
103
|
+
|
104
|
+
def open_snippet_in_editor(filepath)
|
105
|
+
editor = Snibbets.options[:editor] || Snibbets::Config.best_editor
|
106
|
+
|
107
|
+
os = RbConfig::CONFIG['target_os']
|
108
|
+
|
109
|
+
if editor.nil?
|
110
|
+
OS.open(filepath)
|
111
|
+
else
|
112
|
+
if os =~ /darwin.*/i
|
113
|
+
if editor =~ /^TextEdit/
|
114
|
+
`open -a TextEdit "#{filepath}"`
|
115
|
+
elsif TTY::Which.bundle_id?(editor)
|
116
|
+
`open -b "#{editor}" "#{filepath}"`
|
117
|
+
elsif TTY::Which.app?(editor)
|
118
|
+
`open -a "#{editor}" "#{filepath}"`
|
119
|
+
elsif TTY::Which.exist?(editor)
|
120
|
+
editor = TTY::Which.which(editor)
|
121
|
+
system %(#{editor} "#{filepath}") if editor
|
122
|
+
else
|
123
|
+
puts "No editor configured, or editor is missing"
|
124
|
+
Process.exit 1
|
125
|
+
end
|
126
|
+
elsif TTY::Which.exist?(editor)
|
127
|
+
editor = TTY::Which.which(editor)
|
128
|
+
system %(#{editor} "#{filepath}") if editor
|
129
|
+
else
|
130
|
+
puts "No editor configured, or editor is missing"
|
131
|
+
Process.exit 1
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def new_snippet_from_clipboard
|
137
|
+
trap('SIGINT') do
|
138
|
+
Howzit.console.info "\nCancelled"
|
139
|
+
exit!
|
140
|
+
end
|
141
|
+
|
142
|
+
build_lexers
|
143
|
+
|
144
|
+
pb = OS.paste.outdent
|
145
|
+
|
146
|
+
printf 'What does this snippet do? '
|
147
|
+
input = $stdin.gets.chomp
|
148
|
+
title = input unless input.empty?
|
149
|
+
|
150
|
+
printf 'What language(s) does it use (separate with spaces, full names or file extensions will work)? '
|
151
|
+
input = $stdin.gets.chomp
|
152
|
+
langs = input.split(/ +/).map(&:strip) unless input.empty?
|
153
|
+
exts = langs.map { |lang| Snibbets::Lexers.lang_to_ext(lang) }
|
154
|
+
tags = langs.map { |lang| Snibbets::Lexers.ext_to_lang(lang) }.concat(langs).sort.uniq
|
155
|
+
|
156
|
+
filename ="#{title}.#{exts.join('.')}.#{Snibbets.options[:extension]}"
|
157
|
+
|
158
|
+
File.open(File.join(File.expand_path(Snibbets.options[:source]), filename), 'w') do |f|
|
159
|
+
f.puts "tags: #{tags.join(', ')}
|
160
|
+
|
161
|
+
```
|
162
|
+
#{pb}
|
163
|
+
```"
|
164
|
+
end
|
165
|
+
|
166
|
+
puts "New snippet written to #{filename}."
|
167
|
+
end
|
168
|
+
|
169
|
+
def handle_launchbar(results)
|
170
|
+
output = []
|
171
|
+
|
172
|
+
if results.empty?
|
173
|
+
out = {
|
174
|
+
'title' => 'No matching snippets found'
|
175
|
+
}.to_json
|
176
|
+
puts out
|
177
|
+
Process.exit
|
178
|
+
end
|
179
|
+
|
180
|
+
results.each do |result|
|
181
|
+
input = IO.read(result['path'])
|
182
|
+
snippets = input.snippets
|
183
|
+
next if snippets.empty?
|
184
|
+
|
185
|
+
children = []
|
186
|
+
|
187
|
+
if snippets.length == 1
|
188
|
+
output << {
|
189
|
+
'title' => result['title'],
|
190
|
+
'path' => result['path'],
|
191
|
+
'action' => 'copyIt',
|
192
|
+
'actionArgument' => snippets[0]['code'],
|
193
|
+
'label' => 'Copy'
|
194
|
+
}
|
195
|
+
next
|
196
|
+
end
|
197
|
+
|
198
|
+
snippets.each { |s|
|
199
|
+
children << {
|
200
|
+
'title' => s['title'],
|
201
|
+
'path' => result['path'],
|
202
|
+
'action' => 'copyIt',
|
203
|
+
'actionArgument' => s['code'],
|
204
|
+
'label' => 'Copy'
|
205
|
+
}
|
206
|
+
}
|
207
|
+
|
208
|
+
output << {
|
209
|
+
'title' => result['title'],
|
210
|
+
'path' => result['path'],
|
211
|
+
'children' => children
|
212
|
+
}
|
213
|
+
end
|
214
|
+
|
215
|
+
puts output.to_json
|
216
|
+
end
|
217
|
+
|
218
|
+
def handle_results(results)
|
219
|
+
if Snibbets.options[:launchbar]
|
220
|
+
handle_launchbar(results)
|
221
|
+
else
|
222
|
+
filepath = nil
|
223
|
+
if results.empty?
|
224
|
+
warn 'No results'
|
225
|
+
Process.exit 0
|
226
|
+
elsif results.length == 1 || !Snibbets.options[:interactive]
|
227
|
+
filepath = results[0]['path']
|
228
|
+
input = IO.read(filepath)
|
229
|
+
else
|
230
|
+
answer = Snibbets::Menu.menu(results, title: 'Select a file')
|
231
|
+
filepath = answer['path']
|
232
|
+
input = IO.read(filepath)
|
233
|
+
end
|
234
|
+
|
235
|
+
if @arguments[:edit_snippet]
|
236
|
+
open_snippet_in_editor(filepath)
|
237
|
+
Process.exit 0
|
238
|
+
end
|
239
|
+
|
240
|
+
snippets = input.snippets
|
241
|
+
|
242
|
+
if snippets.empty?
|
243
|
+
warn 'No snippets found'
|
244
|
+
Process.exit 0
|
245
|
+
elsif snippets.length == 1 || !Snibbets.options[:interactive]
|
246
|
+
if Snibbets.options[:output] == 'json'
|
247
|
+
print(snippets.to_json)
|
248
|
+
else
|
249
|
+
snippets.each do |snip|
|
250
|
+
header = File.basename(filepath, '.md')
|
251
|
+
warn header
|
252
|
+
warn '-' * header.length
|
253
|
+
code = snip['code']
|
254
|
+
code = highlight(code, filepath) if Snibbets.options[:highlight]
|
255
|
+
print(code)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
elsif snippets.length > 1
|
259
|
+
if Snibbets.options[:all]
|
260
|
+
if Snibbets.options[:output] == 'json'
|
261
|
+
print(snippets.to_json)
|
262
|
+
else
|
263
|
+
output = []
|
264
|
+
snippets.each do |snippet|
|
265
|
+
output << snippet['title']
|
266
|
+
output << '-' * snippet['title'].length
|
267
|
+
output << snippet['code']
|
268
|
+
output << "\n"
|
269
|
+
end
|
270
|
+
print(output.join("\n"))
|
271
|
+
end
|
272
|
+
else
|
273
|
+
snippets.push({ 'title' => 'All snippets', 'code' => '' })
|
274
|
+
|
275
|
+
answer = Snibbets::Menu.menu(snippets, filename: File.basename(filepath, '.md'), title: 'Select snippet', query: @query)
|
276
|
+
|
277
|
+
if answer['title'] == 'All snippets'
|
278
|
+
snippets.delete_if { |s| s['title'] == 'All snippets'}
|
279
|
+
if Snibbets.options[:output] == 'json'
|
280
|
+
print(snippets.to_json)
|
281
|
+
else
|
282
|
+
header = File.basename(filepath, '.md')
|
283
|
+
warn header
|
284
|
+
warn '=' * header.length
|
285
|
+
output = []
|
286
|
+
snippets.each do |snippet|
|
287
|
+
output << snippet['title']
|
288
|
+
output << '-' * snippet['title'].length
|
289
|
+
output << snippet['code']
|
290
|
+
output << "\n"
|
291
|
+
end
|
292
|
+
print(output.join("\n"))
|
293
|
+
end
|
294
|
+
elsif Snibbets.options[:output] == 'json'
|
295
|
+
print(answer.to_json)
|
296
|
+
else
|
297
|
+
header = "#{File.basename(filepath, '.md')}: #{answer['title']}"
|
298
|
+
warn header
|
299
|
+
warn '-' * header.length
|
300
|
+
code = answer['code']
|
301
|
+
code = highlight(code, filepath) if Snibbets.options[:highlight]
|
302
|
+
print(code)
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def print(output)
|
310
|
+
$stdout.puts(output)
|
311
|
+
if Snibbets.options[:copy]
|
312
|
+
OS.copy(output)
|
313
|
+
$stderr.puts "Copied to clipboard"
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
data/snibbets.gemspec
CHANGED
@@ -31,10 +31,11 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.files += Dir["[A-Z]*"]
|
32
32
|
|
33
33
|
spec.add_development_dependency "bundler", "~> 2.0"
|
34
|
+
spec.add_development_dependency "awesome_print", "~> 1.9"
|
34
35
|
spec.add_development_dependency "gem-release", "~> 2.2"
|
35
36
|
spec.add_development_dependency "parse_gemspec-cli", "~> 1.0"
|
36
37
|
spec.add_development_dependency "rake", "~> 13.0"
|
37
|
-
spec.add_development_dependency 'rdoc', '~>
|
38
|
+
spec.add_development_dependency 'rdoc', '~> 6.3.1'
|
38
39
|
spec.add_development_dependency 'yard', '~> 0.9', '>= 0.9.26'
|
39
40
|
spec.add_development_dependency "rspec", "~> 3.0"
|
40
41
|
spec.add_development_dependency "simplecov", "~> 0.21"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: snibbets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: awesome_print
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.9'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.9'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: gem-release
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +86,14 @@ dependencies:
|
|
72
86
|
requirements:
|
73
87
|
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
89
|
+
version: 6.3.1
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
94
|
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
96
|
+
version: 6.3.1
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: yard
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -185,8 +199,10 @@ extra_rdoc_files:
|
|
185
199
|
- README.md
|
186
200
|
files:
|
187
201
|
- CHANGELOG.md
|
202
|
+
- CHANGELOG.md.orig
|
188
203
|
- Gemfile
|
189
204
|
- Gemfile.lock
|
205
|
+
- Gemfile.lock.orig
|
190
206
|
- LICENSE.txt
|
191
207
|
- README.md
|
192
208
|
- README.rdoc
|
@@ -194,6 +210,7 @@ files:
|
|
194
210
|
- bin/snibbets
|
195
211
|
- buildnotes.md
|
196
212
|
- lib/snibbets.rb
|
213
|
+
- lib/snibbets/array.rb
|
197
214
|
- lib/snibbets/config.rb
|
198
215
|
- lib/snibbets/hash.rb
|
199
216
|
- lib/snibbets/highlight.rb
|