snibbets 2.0.7 → 2.0.9

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: b4b5be01b0a7d1768bef21a63ffd7c1f1f176a77d6d3fa1be5ff84db7b0b27eb
4
- data.tar.gz: 7c65f52ecb3dacbeea62c8225f9dc70db7d90d358a4c284050b7149a9b19fe75
3
+ metadata.gz: e721debb0d3122f59722537839a728cc81e532c8039edeca696b46f19c91d920
4
+ data.tar.gz: ab7261e014473773db55aa1e56f392ba11dc2b423c2d281216d18b57bf51378e
5
5
  SHA512:
6
- metadata.gz: e4adffb0b196b8f891ac9363fdcb91a67dccfc579530568e336dd1ced2d7d8f6c7f4496fa1c4cbe992e24655a37a7808bd49c48e44d75623a2c1fa0fb1615bb9
7
- data.tar.gz: 796ec5249c2c7332132ac2138d5281c05aab7259b75726319f247499543a15c4b839d6929e764850a8bbc907747a42a179d3b61625e4b4fff7ca90f698c24509
6
+ metadata.gz: 9f991baaab2bbe857bb1f2f0edb924ebc241faa58ffb20dec1084283a54d5e7c0163e1aac0368cb051b6b8bc3fe90d7db18517ff48176956e98b6889d7c918bb
7
+ data.tar.gz: 01175aaaa465ae16bafff11a8a1d891b188c288042073f667f34a597e28bce105fd3e73e2a56683ed3780c12f7520d525694a1075af728f609e8a28803aad614
data/CHANGELOG.md CHANGED
@@ -1,6 +1,30 @@
1
- ### 2.0.7
1
+ ### 2.0.9
2
2
 
3
- 2023-04-15 12:02
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/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- snibbets (2.0.3)
4
+ snibbets (2.0.7)
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)
@@ -76,11 +77,15 @@ GEM
76
77
  thor (1.2.1)
77
78
  tty-which (0.5.0)
78
79
  unicode-display_width (2.4.2)
80
+ webrick (1.7.0)
81
+ yard (0.9.28)
82
+ webrick (~> 1.7.0)
79
83
 
80
84
  PLATFORMS
81
85
  arm64-darwin-20
82
86
 
83
87
  DEPENDENCIES
88
+ awesome_print (~> 1.9)
84
89
  bundler (~> 2.0)
85
90
  gem-release (~> 2.2)
86
91
  parse_gemspec-cli (~> 1.0)
@@ -91,6 +96,7 @@ DEPENDENCIES
91
96
  simplecov-console (~> 0.9)
92
97
  snibbets!
93
98
  standard (~> 1.3)
99
+ yard (~> 0.9, >= 0.9.26)
94
100
 
95
101
  BUNDLED WITH
96
102
  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
@@ -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
@@ -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 Which.exist?('fzf')
32
+ return 'gum' if 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
@@ -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)
@@ -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 |p|
135
- lines = p.split(/\n/)
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)] }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Snibbets
4
- VERSION = '2.0.7'
4
+ VERSION = '2.0.9'
5
5
  end
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 = 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 '#{@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(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,6 +31,7 @@ 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"
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.7
4
+ version: 2.0.9
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
@@ -194,6 +208,7 @@ files:
194
208
  - bin/snibbets
195
209
  - buildnotes.md
196
210
  - lib/snibbets.rb
211
+ - lib/snibbets/array.rb
197
212
  - lib/snibbets/config.rb
198
213
  - lib/snibbets/hash.rb
199
214
  - lib/snibbets/highlight.rb