snibbets 2.0.30 → 2.0.32

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: a633139ac4f908c760dc709e91937cfeb6d77c8a3a2aebdfc0e9acec1760a25b
4
- data.tar.gz: efc77b72771c37c1cda78a6fb66d4af532b9b2c31648e6b7fce4854a2310204e
3
+ metadata.gz: e6701119f370f7f3a6190d811e5278799c973ed65b7f69a096b2675c91a2a124
4
+ data.tar.gz: 6954526979c677af6c5cf3fece76c0df0eae2f83ae2975c00e2884e99a5a2cda
5
5
  SHA512:
6
- metadata.gz: af5ac5a46200ee38bc3fc20daed4bfdc2ca47841cc665883ac7837629436fe42e77a0b953f1d5c3615d0622f2a08e2672771876eb89a86e93afb66d8e89d265d
7
- data.tar.gz: 89292879a4cd79acb7b30a24a7ed760557b6b26493a3311abbc42eeef097348d36b0b7c2b69475e5aa0d0729d493885647673675cf46b435fabfa7a4d0661fcb
6
+ metadata.gz: 4e3cf0a812450aacd9dd69863bb4ba02880fb57049e396ab7d02eb31b024ed12aabe1f84dd4ace68b5ccc3d2c29e09c114776fde050b4bdc5708fcf01dfe5af9
7
+ data.tar.gz: 761105292b069c127ec2e32f0d39235883c4bd75d88b395d1a20b83b7fc6819aec0e9b5df67af14c7a2990196e5611aabf212afead13587ed2d62c2356489d34
@@ -0,0 +1,11 @@
1
+ ARG VARIANT="3"
2
+
3
+ FROM mcr.microsoft.com/vscode/devcontainers/ruby:${VARIANT}
4
+
5
+ USER vscode
6
+ WORKDIR /home/vscode
7
+
8
+ RUN mkdir -p .config/git \
9
+ && echo ".vscode/*" >> .config/git/ignore \
10
+ && echo "*.code-workspace" >> .config/git/ignore \
11
+ && echo ".history/" >> .config/git/ignore
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "Ruby",
3
+ "build": {
4
+ "dockerfile": "Dockerfile",
5
+ "args": {
6
+ "VARIANT": "3"
7
+ }
8
+ },
9
+ "extensions": [
10
+ "rebornix.Ruby",
11
+ "ms-vsliveshare.vsliveshare",
12
+ "EditorConfig.EditorConfig",
13
+ "esbenp.prettier-vscode"
14
+ ],
15
+ "postCreateCommand": "bundle install",
16
+ "remoteUser": "vscode"
17
+ }
data/.editorconfig ADDED
@@ -0,0 +1,9 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ trim_trailing_whitespace = true
8
+ indent_style = space
9
+ indent_size = 2
data/.irbrc ADDED
@@ -0,0 +1,2 @@
1
+ require_relative 'lib/snibbets'
2
+ include Snibbets
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
4
+ --pattern "{spec,lib}/**/*_spec.rb"
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.0.1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ ### 2.0.32
2
+
3
+ 2023-04-25 17:14
4
+
5
+ #### FIXED
6
+
7
+ - Don't highlight code sent to `--copy`
8
+
9
+ ### 2.0.31
10
+
11
+ 2023-04-20 10:20
12
+
13
+ #### IMPROVED
14
+
15
+ - Syntax highlight blocks individually, so multiple languages can exist within one snippet
16
+ - If outputting notes, wrap code in backticks to differentiate
17
+
18
+ #### FIXED
19
+
20
+ - Handle cases where snippet contains `\k<name>` and breaks regex replacement even with Regexp.escape
21
+ - Remove fences from single snippet when not syntax highlighting
22
+
1
23
  ### 2.0.30
2
24
 
3
25
  2023-04-19 06:44
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- snibbets (2.0.30)
4
+ snibbets (2.0.32)
5
5
  mdless (~> 1.0, >= 1.0.32)
6
6
  tty-reader (~> 0.9, >= 0.9.0)
7
7
  tty-which (~> 0.5, >= 0.5.0)
data/README.md CHANGED
@@ -159,7 +159,7 @@ Snibbet's implementation of Skylighting has limited but better-looking themes, a
159
159
  ### Usage
160
160
 
161
161
  ```
162
- Snibbets v2.0.30
162
+ Snibbets v2.0.32
163
163
 
164
164
  Usage: snibbets [options] query
165
165
  -a, --all If a file contains multiple snippets, output all of them (no menu)
@@ -0,0 +1,49 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>CFBundleIdentifier</key>
6
+ <string>com.brettterpstra.LaunchBar.action.Snibbets</string>
7
+ <key>CFBundleName</key>
8
+ <string>Snibbets</string>
9
+ <key>LBAbbreviation</key>
10
+ <string>snib</string>
11
+ <key>LBDebugLogEnabled</key>
12
+ <true/>
13
+ <key>LBDescription</key>
14
+ <dict>
15
+ <key>LBAuthor</key>
16
+ <string>Brett Terpstra</string>
17
+ <key>LBEmail</key>
18
+ <string>me@brettterpstra.com</string>
19
+ <key>LBSummary</key>
20
+ <string>Search a folder of plain text code snippets and paste results</string>
21
+ <key>LBTwitter</key>
22
+ <string>@ttscoff</string>
23
+ <key>LBWebsiteURL</key>
24
+ <string></string>
25
+ </dict>
26
+ <key>LBScripts</key>
27
+ <dict>
28
+ <key>LBDefaultScript</key>
29
+ <dict>
30
+ <key>LBAcceptedArgumentTypes</key>
31
+ <array>
32
+ <string>string</string>
33
+ </array>
34
+ <key>LBKeepWindowActive</key>
35
+ <true/>
36
+ <key>LBResultType</key>
37
+ <string>unknown</string>
38
+ <key>LBReturnsResult</key>
39
+ <true/>
40
+ <key>LBScriptName</key>
41
+ <string>default.js</string>
42
+ </dict>
43
+ </dict>
44
+ <key>LBTextInputTitle</key>
45
+ <string>Search snippets</string>
46
+ <key>NSHumanReadableCopyright</key>
47
+ <string>Brett Terpstra 2019</string>
48
+ </dict>
49
+ </plist>
@@ -0,0 +1,52 @@
1
+ // LaunchBar Action Script
2
+
3
+ function run() {
4
+ settingsItem = {
5
+ 'title' : 'Choose Snippets Folder',
6
+ 'action' : 'setFolder',
7
+ 'label' : 'Choose',
8
+ 'subtitle' : ''
9
+ }
10
+ if (Action.preferences.snippetsFolder) {
11
+ settingsItem.subtitle = Action.preferences.snippetsFolder;
12
+ }
13
+ return [settingsItem];
14
+ }
15
+
16
+ function runWithString(string) {
17
+ var folder = Action.preferences.snippetsFolder;
18
+ var result = LaunchBar.execute('/usr/bin/env', 'ruby' , 'snibbets.rb', '-o', 'launchbar', '-s', encodeURI(folder), encodeURI(string));
19
+ if (result)
20
+ return JSON.parse(result);
21
+ else
22
+ return {'title': 'No matches'}
23
+ }
24
+
25
+ function copyIt(item) {
26
+ LaunchBar.setClipboardString(item);
27
+ LaunchBar.openCommandURL('hide'); // for some reason LaunchBar.hide() doesn't execute, but this does. Sometimes.
28
+ LaunchBar.hide();
29
+ }
30
+
31
+ function pasteIt(item) {
32
+ LaunchBar.paste(item.code);
33
+ LaunchBar.openCommandURL('hide');
34
+ LaunchBar.hide();
35
+ }
36
+
37
+ function setFolder(item) {
38
+ LaunchBar.displayInLargeType({
39
+ title: 'Choosing folder'
40
+ });
41
+ var defaultFolder = LaunchBar.homeDirectory;
42
+ if (Action.preferences.snippetsFolder) {
43
+ defaultFolder = Action.preferences.snippetsFolder;
44
+ }
45
+ var k = LaunchBar.executeAppleScript(
46
+ 'set _default to POSIX file "' + defaultFolder + '" as alias \n' +
47
+ 'set _folder to choose folder with prompt "Select Snippets Folder" default location _default \n' +
48
+ ' return POSIX path of _folder');
49
+ if (k && k.length > 0) {
50
+ Action.preferences.snippetsFolder = k.trim();
51
+ }
52
+ }
@@ -0,0 +1,420 @@
1
+ #!/usr/bin/env ruby
2
+ # Snibbets 2.0.0
3
+
4
+ require 'optparse'
5
+ require 'readline'
6
+ require 'json'
7
+ require 'cgi'
8
+ require 'shellwords'
9
+
10
+ $search_path = File.expand_path("~/Desktop/Code/Snippets")
11
+
12
+ class String
13
+ # Are there multiple snippets (indicated by ATX headers)
14
+ def multiple?
15
+ return self.scan(/^#+/).length > 1
16
+ end
17
+
18
+ # Is the snippet in this block fenced?
19
+ def fenced?
20
+ count = self.scan(/^```/).length
21
+ return count > 1 && count.even?
22
+ end
23
+
24
+ def rx
25
+ return ".*" + self.gsub(/\s+/,'.*') + ".*"
26
+ end
27
+
28
+ # remove outside comments, fences, and indentation
29
+ def clean_code
30
+ block = self
31
+
32
+ # if it's a fenced code block, just discard the fence and everything
33
+ # outside it
34
+ if block.fenced?
35
+ return block.gsub(/(?:^|.*?\n)(`{3,})(\w+)?(.*?)\n\1.*/m) {|m| $3.strip }
36
+ end
37
+
38
+ # assume it's indented code, discard non-indented lines and outdent
39
+ # the rest
40
+ indent = nil
41
+ inblock = false
42
+ code = []
43
+ block.split(/\n/).each {|line|
44
+ if line =~ /^\s*$/ && inblock
45
+ code.push(line)
46
+ elsif line =~ /^( {4,}|\t+)/
47
+ inblock = true
48
+ indent ||= Regexp.new("^#{$1}")
49
+ code.push(line.sub(indent,''))
50
+ else
51
+ inblock = false
52
+ end
53
+ }
54
+ code.join("\n")
55
+ end
56
+
57
+ # Returns an array of snippets. Single snippets are returned without a
58
+ # title, multiple snippets get titles from header lines
59
+ def snippets
60
+ content = self.dup
61
+ # If there's only one snippet, just clean it and return
62
+ unless self.multiple?
63
+ return [{"title" => "", "code" => content.clean_code.strip}]
64
+ end
65
+
66
+ # Split content by ATX headers. Everything on the line after the #
67
+ # becomes the title, code is gleaned from text between that and the
68
+ # next ATX header (or end)
69
+ sections = []
70
+ parts = content.split(/^#+/)
71
+ parts.shift
72
+
73
+ parts.each do |p|
74
+ lines = p.split(/\n/)
75
+ title = lines.shift.strip.sub(/[.:]$/, '')
76
+ block = lines.join("\n")
77
+ code = block.clean_code
78
+ next unless code && !code.empty?
79
+
80
+ sections << {
81
+ 'title' => title,
82
+ 'code' => code.strip
83
+ }
84
+ end
85
+ return sections
86
+ end
87
+ end
88
+
89
+ def gum_menu(executable, res, title)
90
+ options = res.map { |m| m['title'] }
91
+ puts title
92
+ selection = `echo #{Shellwords.escape(options.join("\n"))} | #{executable} choose --limit 1`.strip
93
+ Process.exit 1 if selection.empty?
94
+
95
+ res.select { |m| m['title'] =~ /#{selection}/ }[0]
96
+ end
97
+
98
+ def fzf_menu(executable, res, title)
99
+ options = res.map { |m| m['title'] }
100
+ args = [
101
+ "--height=#{options.count + 2}",
102
+ %(--prompt="#{title} > "),
103
+ '-1'
104
+ ]
105
+ selection = `echo #{Shellwords.escape(options.join("\n"))} | #{executable} #{args.join(' ')}`.strip
106
+ Process.exit 1 if selection.empty?
107
+
108
+ res.select { |m| m['title'] =~ /#{selection}/ }[0]
109
+ end
110
+
111
+ def menu(res, title = 'Select one')
112
+ fzf = `which fzf`.strip
113
+ return fzf_menu(fzf, res, title) unless fzf.empty?
114
+
115
+ gum = `which gum`.strip
116
+ return gum_menu(gum, res, title) unless gum.empty?
117
+
118
+ console_menu(res, title)
119
+ end
120
+
121
+ # Generate a numbered menu, items passed must have a title property
122
+ def console_menu(res, title)
123
+ stty_save = `stty -g`.chomp
124
+
125
+ trap('INT') do
126
+ system('stty', stty_save)
127
+ Process.exit 1
128
+ end
129
+
130
+ # Generate a numbered menu, items passed must have a title property('INT') { system('stty', stty_save); exit }
131
+ counter = 1
132
+ $stderr.puts
133
+ res.each do |m|
134
+ $stderr.printf("%<counter>2d) %<title>s\n", counter: counter, title: m['title'])
135
+ counter += 1
136
+ end
137
+ $stderr.puts
138
+
139
+ begin
140
+ $stderr.printf(title.sub(/:?$/, ': '), res.length)
141
+ while (line = Readline.readline('', true))
142
+ unless line =~ /^[0-9]/
143
+ system('stty', stty_save) # Restore
144
+ exit
145
+ end
146
+ line = line.to_i
147
+ return res[line - 1] if line.positive? && line <= res.length
148
+
149
+ warn 'Out of range'
150
+ menu(res, title)
151
+ end
152
+ rescue Interrupt
153
+ system('stty', stty_save)
154
+ exit
155
+ end
156
+ end
157
+
158
+ # Search the snippets directory for query using find and grep
159
+ def search(query, folder, try = 0)
160
+ # First try only search by filenames
161
+ # Second try search with grep
162
+ # Third try search with Spotlight name only
163
+ # Fourth try search with Spotlight all contents
164
+ cmd = case try
165
+ when 0
166
+ %(find "#{folder}" -iregex '#{query.rx}')
167
+ when 1
168
+ %(grep -iEl '#{query.rx}' "#{folder}/"*.md)
169
+ when 2
170
+ %(mdfind -onlyin "#{folder}" -name '#{query}' 2>/dev/null)
171
+ when 3
172
+ %(mdfind -onlyin "#{folder}" '#{query}' 2>/dev/null)
173
+ end
174
+
175
+ matches = `#{cmd}`.strip
176
+
177
+ results = []
178
+
179
+ if !matches.empty?
180
+ lines = matches.split(/\n/)
181
+ lines.each do |l|
182
+ results << {
183
+ 'title' => File.basename(l, '.*'),
184
+ 'path' => l
185
+ }
186
+ end
187
+ results
188
+ else
189
+ return [] if try > 2
190
+
191
+ # if no results on the first try, try again searching all text
192
+ search(query, folder, try + 1)
193
+ end
194
+ end
195
+
196
+ def highlight_pygments(executable, code, syntax, theme)
197
+ syntax = syntax.empty? ? '-g' : "-l #{syntax}"
198
+ `echo #{Shellwords.escape(code)} | #{executable} #{syntax}`
199
+ end
200
+
201
+ def highlight_skylight(executable, code, syntax, theme)
202
+ return code if syntax.empty?
203
+
204
+ `echo #{Shellwords.escape(code)} | #{executable} --syntax #{syntax}`
205
+ end
206
+
207
+ def highlight(code, filename, theme = 'monokai')
208
+ syntax = syntax_from_extension(filename)
209
+
210
+ skylight = `which skylighting`.strip
211
+ return highlight_skylight(skylight, code, syntax, theme) unless skylight.empty?
212
+
213
+ pygments = `which pygmentize`.strip
214
+ return highlight_pygments(pygments, code, syntax, theme) unless pygments.empty?
215
+
216
+ code
217
+ end
218
+
219
+ def ext_to_lang(ext)
220
+ case ext
221
+ when /^(as|applescript|scpt)$/
222
+ 'applescript'
223
+ when /^m$/
224
+ 'objective-c'
225
+ when /^(pl|perl)$/
226
+ 'perl'
227
+ when /^py$/
228
+ 'python'
229
+ when /^(js|jq(uery)?|jxa)$/
230
+ 'javascript'
231
+ when /^rb$/
232
+ 'ruby'
233
+ when /^cc$/
234
+ 'c'
235
+ when /^(ba|fi|z|c)?sh$/
236
+ 'bash'
237
+ when /^pl$/
238
+ 'perl'
239
+ else
240
+ if %w[awk sed css sass scss less cpp php c sh swift html erb json xpath sql htaccess].include?(ext)
241
+ ext
242
+ else
243
+ ''
244
+ end
245
+ end
246
+ end
247
+
248
+ def syntax_from_extension(filename)
249
+ ext_to_lang(filename.split(/\./)[1])
250
+ end
251
+
252
+ options = {
253
+ interactive: true,
254
+ launchbar: false,
255
+ output: 'raw',
256
+ source: $search_path,
257
+ highlight: false,
258
+ all: false
259
+ }
260
+
261
+ optparse = OptionParser.new do |opts|
262
+ opts.banner = "Usage: #{File.basename(__FILE__)} [options] query"
263
+
264
+ opts.on('-q', '--quiet', 'Skip menus and display first match') do
265
+ options[:interactive] = false
266
+ options[:launchbar] = false
267
+ end
268
+
269
+ opts.on('-a', '--all', 'If a file contains multiple snippets, output all of them (no menu)') do
270
+ options[:all] = true
271
+ end
272
+
273
+ opts.on('-o', '--output FORMAT', 'Output format (launchbar or raw)') do |outformat|
274
+ valid = %w[json launchbar lb raw]
275
+ if outformat.downcase =~ /(launchbar|lb)/
276
+ options[:launchbar] = true
277
+ options[:interactive] = false
278
+ elsif valid.include?(outformat.downcase)
279
+ options[:output] = outformat.downcase
280
+ end
281
+ end
282
+
283
+ opts.on('-s', '--source FOLDER', 'Snippets folder to search') do |folder|
284
+ options[:source] = File.expand_path(folder)
285
+ end
286
+
287
+ opts.on('--highlight', 'Use pygments or skylighting to syntax highlight (if installed)') do
288
+ options[:highlight] = true
289
+ end
290
+
291
+ opts.on('-h', '--help', 'Display this screen') do
292
+ puts optparse
293
+ Process.exit 0
294
+ end
295
+ end
296
+
297
+ optparse.parse!
298
+
299
+ query = ''
300
+
301
+ if options[:launchbar]
302
+ query = if $stdin.stat.size.positive?
303
+ $stdin.read.force_encoding('utf-8')
304
+ else
305
+ ARGV.join(' ')
306
+ end
307
+ elsif ARGV.length
308
+ query = ARGV.join(' ')
309
+ end
310
+
311
+ query = CGI.unescape(query)
312
+
313
+ if query.strip.empty?
314
+ puts 'No search query'
315
+ puts optparse
316
+ Process.exit 1
317
+ end
318
+
319
+ results = search(query, options[:source], 0)
320
+
321
+ if options[:launchbar]
322
+ output = []
323
+
324
+ if results.empty?
325
+ out = {
326
+ 'title' => 'No matching snippets found'
327
+ }.to_json
328
+ puts out
329
+ Process.exit
330
+ end
331
+
332
+ results.each do |result|
333
+ input = IO.read(result['path'])
334
+ snippets = input.snippets
335
+ next if snippets.empty?
336
+
337
+ children = []
338
+
339
+ if snippets.length == 1
340
+ output << {
341
+ 'title' => result['title'],
342
+ 'path' => result['path'],
343
+ 'action' => 'copyIt',
344
+ 'actionArgument' => snippets[0]['code'],
345
+ 'label' => 'Copy'
346
+ }
347
+ next
348
+ end
349
+
350
+ snippets.each { |s|
351
+ children << {
352
+ 'title' => s['title'],
353
+ 'path' => result['path'],
354
+ 'action' => 'copyIt',
355
+ 'actionArgument' => s['code'],
356
+ 'label' => 'Copy'
357
+ }
358
+ }
359
+
360
+ output << {
361
+ 'title' => result['title'],
362
+ 'path' => result['path'],
363
+ 'children' => children
364
+ }
365
+ end
366
+
367
+ puts output.to_json
368
+ else
369
+ filepath = nil
370
+ if results.empty?
371
+ warn 'No results'
372
+ Process.exit 0
373
+ elsif results.length == 1 || !options[:interactive]
374
+ filepath = results[0]['path']
375
+ input = IO.read(filepath)
376
+ else
377
+ answer = menu(results, 'Select a file')
378
+ filepath = answer['path']
379
+ input = IO.read(filepath)
380
+ end
381
+
382
+ snippets = input.snippets
383
+
384
+ if snippets.empty?
385
+ warn 'No snippets found'
386
+ Process.exit 0
387
+ elsif snippets.length == 1 || !options[:interactive]
388
+ if options[:output] == 'json'
389
+ $stdout.puts snippets.to_json
390
+ else
391
+ snippets.each do |snip|
392
+ code = snip['code']
393
+ code = highlight(code, filepath) if options[:highlight]
394
+ $stdout.puts code
395
+ end
396
+ end
397
+ elsif snippets.length > 1
398
+ if options[:all]
399
+ if options[:output] == 'json'
400
+ $stdout.puts snippets.to_json
401
+ else
402
+ snippets.each do |snippet|
403
+ $stdout.puts snippet['title']
404
+ $stdout.puts '------'
405
+ $stdout.puts snippet['code']
406
+ $stdout.puts
407
+ end
408
+ end
409
+ else
410
+ answer = menu(snippets, 'Select snippet')
411
+ if options[:output] == 'json'
412
+ $stdout.puts answer.to_json
413
+ else
414
+ code = answer['code']
415
+ code = highlight(code, filepath) if options[:highlight]
416
+ $stdout.puts code
417
+ end
418
+ end
419
+ end
420
+ end
@@ -4,6 +4,10 @@ module Snibbets
4
4
  select { |el| el =~ /^<block\d+>$/ }.count
5
5
  end
6
6
 
7
+ def notes
8
+ select { |el| el !~ /^<block\d+>$/ && el !~ /^```/ && !el.strip.empty? }.count
9
+ end
10
+
7
11
  def strip_empty
8
12
  remove_leading_empty_elements.remove_trailing_empty_elements
9
13
  end
@@ -41,8 +41,24 @@ module Snibbets
41
41
  # `echo #{Shellwords.escape(code)} | #{executable} #{theme}--syntax #{syntax}`
42
42
  end
43
43
 
44
+ def highlight_fences(code, filename, syntax)
45
+ content = code.dup
46
+
47
+ content.fences.each do |f|
48
+ rx = Regexp.new(Regexp.escape(f[:code]))
49
+ highlighted = highlight(f[:code].gsub(/\\k</, '\k\<'), filename, f[:lang] || syntax).strip
50
+ code.sub!(/#{rx}/, highlighted)
51
+ end
52
+
53
+ Snibbets.options[:all_notes] ? code.gsub(/k\\</, 'k<') : code.gsub(/k\\</, 'k<').clean_code
54
+ end
55
+
44
56
  def highlight(code, filename, syntax, theme = nil)
45
- return code unless $stdout.isatty
57
+ unless $stdout.isatty
58
+ return Snibbets.options[:all_notes] && code.replace_blocks[0].notes? ? code : code.clean_code
59
+ end
60
+
61
+ return highlight_fences(code, filename, syntax) if code.fenced?
46
62
 
47
63
  theme ||= Snibbets.options[:highlight_theme] || 'monokai'
48
64
  syntax ||= Lexers.syntax_from_extension(filename)
@@ -47,6 +47,28 @@ module Snibbets
47
47
  count > 1 && count.even?
48
48
  end
49
49
 
50
+ def blocks
51
+ replace_blocks[1].count
52
+ end
53
+
54
+ def blocks?
55
+ blocks.positive?
56
+ end
57
+
58
+ def notes?
59
+ replace_blocks[0].split("\n").notes.positive?
60
+ end
61
+
62
+ # Return array of fenced code blocks
63
+ def fences
64
+ return [] unless fenced?
65
+
66
+ rx = /(?mi)^(?<fence>`{3,})(?<lang> *\S+)? *\n(?<code>[\s\S]*?)\n\k<fence> *(?=\n|\Z)/
67
+ matches = []
68
+ scan(rx) { matches << Regexp.last_match }
69
+ matches.each_with_object([]) { |m, fenced| fenced.push({ code: m['code'], lang: m['lang'] }) }
70
+ end
71
+
50
72
  def indented?
51
73
  self =~ /^( {4,}|\t+)/
52
74
  end
@@ -61,7 +83,7 @@ module Snibbets
61
83
 
62
84
  # if it's a fenced code block, just discard the fence and everything
63
85
  # outside it
64
- if block.fenced? && !Snibbets.options[:all_notes]
86
+ if block.fenced?
65
87
  code_blocks = block.scan(/(`{3,})(\w+)?\s*\n(.*?)\n\1/m)
66
88
  code_blocks.map! { |b| b[2].strip }
67
89
  return code_blocks.join("\n\n")
@@ -142,23 +164,29 @@ module Snibbets
142
164
 
143
165
  parts.each do |part|
144
166
  lines = part.split(/\n/).strip_empty
145
- next if lines.blocks.zero?
146
167
 
147
- title = lines.count > 1 && lines[0] !~ /<block\d+>/ ? lines.shift.strip.sub(/[.:]$/, '') : 'Default snippet'
168
+ notes = part.notes?
148
169
 
149
- block = if Snibbets.options[:all_notes]
150
- lines.join("\n").gsub(/<(block\d+)>/) { "\n```\n#{code_blocks[Regexp.last_match(1)].strip_empty}\n```" }
170
+ next if lines.blocks.zero? && !notes
171
+
172
+ title = if lines.count > 1 && lines[0] !~ /<block\d+>/ && lines[0] =~ /^ +/
173
+ lines.shift.strip.sub(/[.:]$/, '')
151
174
  else
152
- lines.join("\n").gsub(/<(block\d+)>/) { code_blocks[Regexp.last_match(1)].strip_empty }
175
+ 'Default snippet'
153
176
  end
154
177
 
155
- # block = lines.join("\n").gsub(/<(block\d+)>/) { code_blocks[Regexp.last_match(1)] }
178
+ block = lines.join("\n").gsub(/<(block\d+)>/) do
179
+ code = code_blocks[Regexp.last_match(1)].strip_empty
180
+ lang, code = parse_lang_marker(code)
181
+ "\n```#{lang}\n#{code.strip}\n```"
182
+ end
156
183
 
157
- lang, block = parse_lang_marker(block)
158
- code = block.clean_code
184
+ lang, code = parse_lang_marker(block)
159
185
 
160
186
  next unless code && !code.empty?
161
187
 
188
+ # code = code.clean_code unless notes || code.fences.count > 1
189
+
162
190
  sections << {
163
191
  'title' => title,
164
192
  'code' => code.strip_empty,
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # RSpec.describe Snibbets::Todo do
4
+ # subject(:todo) { Snibbets::Todo.new }
5
+
6
+ # describe ".todo" do
7
+ # it "returns todo" do
8
+ # expect(todo.todo).to be "TODO"
9
+ # end
10
+ # end
11
+ # end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Snibbets
4
- VERSION = '2.0.30'
4
+ VERSION = '2.0.32'
5
5
  end
data/lib/snibbets.rb CHANGED
@@ -116,7 +116,6 @@ module Snibbets
116
116
  notebook = Snibbets.options[:source].gsub(/ /, '%20')
117
117
  note = ERB::Util.url_encode(File.basename(filepath, '.md'))
118
118
  url = "x-nvultra://open?notebook=#{notebook}&note=#{note}"
119
- puts url
120
119
  `open '#{url}'`
121
120
  end
122
121
 
@@ -287,6 +286,7 @@ module Snibbets
287
286
  end
288
287
  code = snip['code']
289
288
  lang = snip['language']
289
+
290
290
  print(code, filepath, lang)
291
291
  end
292
292
  end
@@ -350,14 +350,14 @@ module Snibbets
350
350
  end
351
351
 
352
352
  def print(output, filepath, syntax = nil)
353
+ if Snibbets.options[:copy]
354
+ OS.copy(Snibbets.options[:all_notes] ? output : output.clean_code)
355
+ warn 'Copied to clipboard'
356
+ end
353
357
  if Snibbets.options[:highlight] && Snibbets.options[:output] == 'raw'
354
358
  $stdout.puts(Highlight.highlight(output, filepath, syntax))
355
359
  else
356
- $stdout.puts(output)
357
- end
358
- if Snibbets.options[:copy]
359
- OS.copy(output)
360
- $stderr.puts "Copied to clipboard"
360
+ $stdout.puts(Snibbets.options[:all_notes] ? output : output.clean_code)
361
361
  end
362
362
  end
363
363
  end
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ current_ver = `rake cver`
5
+ src = 'src/_README.md'
6
+ dest = 'README.md'
7
+
8
+ readme = IO.read(src).force_encoding('ASCII-8BIT').encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')
9
+
10
+ content = readme.match(/(?<=\<!--README-->)(.*?)(?=\<!--END README-->)/m)[0]
11
+
12
+ content.gsub!(/<!--VER-->(.*?)<!--END VER-->/, current_ver)
13
+ content.gsub!(/<!--GITHUB-->(.*?)<!--END GITHUB-->/m, '\1')
14
+ content.gsub!(/<!--JEKYLL(.*?)-->/m, '')
15
+
16
+ content.gsub!(/^@cli\((.*?)\)/) do
17
+ cmd = Regexp.last_match(1)
18
+ `#{cmd}`.strip.gsub(/\n{2,}/, "\n\n")
19
+ end
20
+
21
+ File.open(dest, 'w') { |f| f.puts(content) }
22
+
23
+ Process.exit 0
data/snibbets.gemspec CHANGED
@@ -27,9 +27,9 @@ Gem::Specification.new do |spec|
27
27
  spec.bindir = "bin"
28
28
  spec.executables << 'snibbets'
29
29
 
30
- spec.files = Dir["lib/**/*.rb"].reject { |f| f.end_with?("_spec.rb") }
31
- spec.files += Dir["lib/themes/*.theme"]
32
- spec.files += Dir["[A-Z]*"]
30
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
31
+ `git ls-files -z`.split("\x0").reject { |f| f.strip =~ %r{^((test|spec|features)/|\.git|buildnotes|.*\.taskpaper)} }
32
+ end
33
33
 
34
34
  spec.add_development_dependency "bundler", "~> 2.0"
35
35
  spec.add_development_dependency "awesome_print", "~> 1.9"
@@ -1,22 +1,20 @@
1
+ # Snibbets
1
2
 
2
-
3
+ <!--README-->
4
+ <!--GITHUB-->
3
5
  [![RubyGems.org](https://img.shields.io/gem/v/snibbets)](https://rubygems.org/gems/snibbets)
4
- <<<<<<< HEAD
5
- [![GitHub Actions](https://github.com/ttscoff/snibbets/actions/workflows/check.yml/badge.svg)](https://github.com/ttscoff/snibbets/actions/workflows/check.yml)
6
- =======
7
6
  <!-- [![GitHub Actions](https://github.com/ttscoff/snibbets/actions/workflows/check.yml/badge.svg)](https://github.com/ttscoff/snibbets/actions/workflows/check.yml) -->
8
- >>>>>>> develop
9
-
7
+ <!--END GITHUB-->
10
8
  A tool for accessing code snippets contained in a folder of plain text Markdown files.
11
9
 
12
10
  Snibbets allows me to keep code snippets in raw files, not relying on a dedicated code snippet app. I can collect and edit my snippets using a text editor, nvALT (nvUltra), or simply by saving snippets from my clipboard to a text file using *NIX redirection on the command line. I can add descriptive names and extended descriptions/notes to code snippets using standard Markdown.
13
11
 
14
12
  What Snibbets does is simply allow a quick search for a specific snippet that I can either output to the terminal, pipe to my clipboard, or access via LaunchBar (via the included LaunchBar Action). It's basically a wrapper for `find` and `grep` with the ability to separate code blocks from other text in my Markdown files.
15
13
 
16
-
14
+ <!--GITHUB-->
17
15
  ![Snibbets in action](https://cdn3.brettterpstra.com/uploads/2023/04/snibbets2.gif)
18
-
19
-
16
+ <!--END GITHUB-->
17
+ <!--JEKYLL{% gif /uploads/2023/04/snibbets2.gif %}-->
20
18
 
21
19
  ## Collecting Snippets
22
20
 
@@ -28,7 +26,7 @@ The name of the file should be the description of the snippet, at least in the c
28
26
 
29
27
  You can combine multiple snippets in a file, though. For example, I have a file called 'Ruby hash snippets.rb.md'. That file contains an array of useful snippets, and each one has a descriptive title in an h3 header above it. Those (ATX) headers are used to split the file, and when you search from the command line, you'll get a menu of all of the snippets in the selected file. (And if you have [fzf](https://github.com/junegunn/fzf) or [gum](https://github.com/charmbracelet/gum) installed, you can quickly filter through with fuzzy searching and find exactly what you need.)
30
28
 
31
- If a file contains multiple snippets, they should be separated by ATX-style headers (one or more `#`) describing the snippets. Additional descriptions can be included outside of the code block. For example:
29
+ If a file contains multiple snippets, they should be separated by ATX-style headers (one or more `#`) describing the snippets. Additional descriptions and notes can be included outside of the code block. Notes are not output on the console, only the code is displayed. If you want a note to be included in console output, make it a blockquote by preceding it with `>`.
32
30
 
33
31
  A file titled `unix find.bash.md`:
34
32
 
@@ -49,22 +47,22 @@ A file titled `unix find.bash.md`:
49
47
 
50
48
  find /dir/dir -type f -mtime +540 -mtime -720 -printf \"%p\",\"%s\",\"%AD\",|"%TD\"\\n > /dir/dir/output.csv
51
49
 
52
- You can include MultiMarkdown metadata in your snippets, either in a YAML block or just at the top of the file with raw key/value pairs. I mostly use this for adding tags, which are then synced to macOS tags when I save. It makes it easy to search for snippets in [nvUltra](https://nvultra.com/), and also allows you to do searches like `snibbets tag:javascript url parser` in Snibbets.
50
+ You can include MultiMarkdown metadata in your snippets, either in a YAML block or just at the top of the file with raw key/value pairs. I mostly use this for adding tags, which are then synced to macOS tags when I save. It makes it easy to search for snippets in [nvUltra](https://nvultra.com/), and also allows you to do searches like `snibbets tag:javascript url parser` with Snibbets.
53
51
 
54
52
  ## CLI
55
53
 
56
54
  ### Dependencies
57
55
 
58
- Snibbets requires Ruby 3.0+. On recent versions of macOS, this is not included by default. You can install it via the Command Line Tools from Apple. On macOS and most other systems, you can use something like [Homebrew], [rbenv], [rvm], or [asdf] to install Ruby 3.
56
+ Snibbets requires Ruby 3.0+. On recent versions of macOS, this is not included by default. You can install it via the Command Line Tools from Apple. On macOS and most other systems, you can also use something like [Homebrew], [rbenv], [rvm], or [asdf] to install Ruby 3.
59
57
 
60
58
  If available, menus are generated by [fzf] or [gum]. If neither are available, a basic Readline menu system will be displayed, so neither are required, just nice to have as they provide fuzzy filtering, scrolling, and type-ahead completion.
61
59
 
62
- [homebrew]: https://brew.sh/ "Homebrew???The Missing Package Manager for macOS (or Linux)"
60
+ [homebrew]: https://brew.sh/ "HomebrewThe Missing Package Manager for macOS (or Linux)"
63
61
  [rbenv]: https://github.com/rbenv/rbenv "rbenv/rbenv:Manage your app's Ruby environment"
64
62
  [rvm]: https://rvm.io/ "Ruby Version Manager"
65
63
  [asdf]: https://asdf-vm.com/ "ASDF environment manager"
66
64
  [fzf]: https://github.com/junegunn/fzf "junegunn/fzf:A command-line fuzzy finder"
67
- [gum]: https://github.com/charmbracelet/gum "charmbracelet/gum:A tool for glamorous shell scripts ????"
65
+ [gum]: https://github.com/charmbracelet/gum "charmbracelet/gum:A tool for glamorous shell scripts 🎀"
68
66
 
69
67
  ### Installation
70
68
 
@@ -106,14 +104,14 @@ Set the `source` key to the folder where you keep your Markdown snippets. Option
106
104
 
107
105
  The `all` setting determines how Snibbets handles files containing multiple snippets. If `all` is true, then it will always display every snippet in the selected file. If false, it will offer a menu and let you choose which snippet to display. You can use `--all` on the command line to just enable this once.
108
106
 
107
+ By default, Snibbets displays only the code from each snippet (and optionally block quotes, see below). If you set `all_notes` to true, then the full content of each snippet containing a code block will be returned, allowing you to see additional notes on the command line. This can be toggled at runtime with `--notes` or `--no-notes`.
108
+
109
109
  The `copy` setting determines whether the output is copied to the clipboard in addition to being displayed on STDOUT. This is the equivalent of running `snibbets QUERY | pbcopy` (macOS) or `snibbets QUERY | xclip` (Linux). This can be enabled for just one run with `--copy` on the command line. Setting it to true in the config will copy to the clipboard every time a snippet is displayed. On Mac this will work automatically, on Windows/Linux you may need to [install `xclip` or `xsel`][xclip].
110
110
 
111
111
  [xclip]: https://ostechnix.com/access-clipboard-contents-using-xclip-and-xsel-in-linux/
112
112
 
113
113
  The `editor` setting is used to open the config file, and to open snippets for editing when using the `--edit` flag. This setting can be any command line utility (`code`, `subl`, `vim`, `nano`, etc.), or on macOS it can be an application name (`BBEdit`, `VS Code`, etc.) or a bundle identifier (`com.sublimetext.4`, `com.microsoft.VSCode`, etc.). If no editor is set, then the file will be opened by whatever the system default is (using `open` on macOS, `start` on Windows, or `xdg-open`on Linux).
114
114
 
115
- The `highlight` key turns on syntax highlighting. This requires that either `pygmentize` or `skyligting` is available on your system (both available via package managers like Homebrew). This feature is still in development and results may be mixed.
116
-
117
115
  The `include_blockquotes` setting determines whether blockquotes are included in the output. By default, Snibbets removes everything other than code blocks (indented or fenced) from the output it displays. But if you want to include a note that you'll see on the command line, you can put it in a block quote by preceding each line you want to preserve with a right angle bracket (`>`).
118
116
 
119
117
  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.
@@ -122,26 +120,48 @@ The `menus` setting will determine what method is used for displaying interactiv
122
120
 
123
121
  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.
124
122
 
123
+ #### Syntax Highlighting
124
+
125
+ The `highlight` key turns on syntax highlighting. This requires that either `pygmentize` or `skylighting` is available on your system (both available via package managers like Homebrew). This feature is still in development and results may be mixed. You can also set `highlighter` to `pygments` or `skylight` to force using one highlighter over the other.
126
+
127
+ Highlighting using Skylighting requires that your snippets be named with extra extensions defining the lexer to use. The last extension before `.md` (or whatever your snippet extension is set to) should be the one that the highlighter will recognize as a valid lexer, e.g. `my code.jquery.js.md`.
128
+
129
+ You can also define languages in your fenced code blocks by putting the lexer name right after the opening fence. When defining multiple snippets in one file that are of different languages, this method will ensure that each one is properly highlighted.
130
+
131
+ If you don't use either extensions or fenced code labels with Skylighting, code won't get highlighted.
132
+
133
+ To define a snippet as python code, for example:
134
+
135
+ ```python
136
+ class EmlServer(SMTPServer):
137
+ no = 0
138
+ def process_message(self, peer, mailfrom, rcpttos, data):
139
+ filename = '%s-%d.eml' % (datetime.now().strftime('%Y%m%d%H%M%S'),
140
+ self.no)
141
+ f = open(filename, 'w')
142
+ ```
143
+
144
+ You can also define a color scheme with `highlight_theme`. If you're using Pygments, run `pygmentize -L styles` to see available options. If you're using Skylighting, you can reference any theme in the [KDE repository]. Skylighting themes are included in Snibbets and can be referenced by their filename without `.theme`, or you can install your own themes and reference them with a full path. (I recommend `nord` when using Sylighting.)
145
+
146
+ [KDE repository]: https://github.com/KDE/syntax-highlighting/tree/master/data/themes
147
+
148
+ You can turn highlighting on or off for a single run using `--highlight` or `--no-highlight`. Syntax highlighting definitely affects copyable output, so it's automatically disabled when piping/redirecting output. When using `--copy`, the code sent to the clipboard is not highlighted.
149
+
150
+ ##### Installing a Syntax Highlighter
151
+
152
+ Snibbet's implementation of Skylighting has limited but better-looking themes, and has some lexers that Pygments lacks. However, Pygments has _more_ lexers and a wider array of themes. It also can determine the target syntax automatically better than Skylighting (which requires the syntax to be specified -- it's pulled from the extensions of your snippets), which is why Pygments is the default if it's installed and you don't configure it otherwise.
153
+
154
+ - Install [Skylighting] with [Homebrew] (`brew install skylighting`) or [apt-get].
155
+ - Install [Pygments] using [Homebrew] (`brew install pygments`) or `pip install pygments`.
156
+
157
+ [Skylighting]: https://github.com/jgm/skylighting
158
+ [apt-get]: https://installati.one/install-skylighting-ubuntu-22-04/
159
+ [Pygments]: https://pygments.org/
160
+
125
161
  ### Usage
126
162
 
127
163
  ```
128
- Snibbets v2.0.14
129
-
130
- Usage: snibbets [options] query
131
- -a, --all If a file contains multiple snippets, output all of them (no menu)
132
- -c, --[no-]copy Copy the output to the clibpoard (also displays on STDOUT)
133
- -e, --edit Open the selected snippet in your configured editor
134
- -n, --[no-]name-only Only search file names, not content
135
- -o, --output FORMAT Output format (json|launchbar|*raw)
136
- -p, --paste, --new Interactively create a new snippet from clipboard contents (Mac only)
137
- -q, --quiet Skip menus and display first match
138
- -s, --source FOLDER Snippets folder to search
139
- --configure Open the configuration file in your default editor
140
- --[no-]blockquotes Include block quotes in output
141
- --highlight Use pygments or skylighting to syntax highlight (if installed)
142
- --save Save the current command line options to the YAML configuration
143
- -h, --help Display this screen
144
- -v, --version Display version information
164
+ @cli(bundle exec bin/snibbets -h)
145
165
  ```
146
166
 
147
167
  If your Snippets folder is set in the config, simply running `snibbets [search query]` will perform the search and output the code blocks, presenting a menu if more than one match is found or the target file contains more than one snippet. Selected contents are output raw to STDOUT.
@@ -175,7 +195,7 @@ Any time you specify things like a source folder with the `--source` flag, or tu
175
195
 
176
196
  _I'm currently reworking the LaunchBar action, and it doesn't function very well at this time. I'll update when I have a chance._
177
197
 
178
- ### Installation
198
+ <!-- ### Installation
179
199
 
180
200
  The LaunchBar action can be installed simply by double clicking the `.lbaction` file in Finder. The CLI is not required for the LaunchBar action to function.
181
201
 
@@ -183,4 +203,5 @@ Once installed, run the action (type `snib` and hit return on the result) to sel
183
203
 
184
204
  ### Usage
185
205
 
186
- Type `snib` to bring the Action up, then hit Space to enter your query text. Matching files will be presented. If the selected file contains more than one snippet, a list of snippets (based on ATX headers in the file) will be presented as a child menu. Selecting a snippet and hitting return will copy the associated code block to the clipboard.
206
+ Type `snib` to bring the Action up, then hit Space to enter your query text. Matching files will be presented. If the selected file contains more than one snippet, a list of snippets (based on ATX headers in the file) will be presented as a child menu. Selecting a snippet and hitting return will copy the associated code block to the clipboard. -->
207
+ <!--END README-->
@@ -0,0 +1,3 @@
1
+ def source
2
+ return
3
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snibbets
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.30
4
+ version: 2.0.32
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-19 00:00:00.000000000 Z
11
+ date: 2023-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -238,17 +238,23 @@ extensions: []
238
238
  extra_rdoc_files:
239
239
  - README.md
240
240
  files:
241
+ - ".devcontainer/Dockerfile"
242
+ - ".devcontainer/devcontainer.json"
243
+ - ".editorconfig"
244
+ - ".irbrc"
245
+ - ".rspec"
246
+ - ".ruby-version"
241
247
  - CHANGELOG.md
242
248
  - Gemfile
243
249
  - Gemfile.lock
244
- - Gemfile.lock.orig
245
250
  - LICENSE.txt
246
251
  - README.md
247
- - README.md.orig
248
252
  - README.rdoc
249
253
  - Rakefile
254
+ - Snibbets.lbaction/Contents/Info.plist
255
+ - Snibbets.lbaction/Contents/Scripts/default.js
256
+ - Snibbets.lbaction/Contents/Scripts/snibbets.rb
250
257
  - bin/snibbets
251
- - buildnotes.md
252
258
  - lib/snibbets.rb
253
259
  - lib/snibbets/array.rb
254
260
  - lib/snibbets/config.rb
@@ -259,6 +265,7 @@ files:
259
265
  - lib/snibbets/menu.rb
260
266
  - lib/snibbets/os.rb
261
267
  - lib/snibbets/string.rb
268
+ - lib/snibbets/todo_spec.rb
262
269
  - lib/snibbets/version.rb
263
270
  - lib/snibbets/which.rb
264
271
  - lib/themes/atom-one-dark.theme
@@ -287,8 +294,10 @@ files:
287
294
  - lib/themes/solarized-dark.theme
288
295
  - lib/themes/solarized-light.theme
289
296
  - lib/themes/vim-dark.theme
297
+ - scripts/fixreadme.rb
290
298
  - snibbets.gemspec
291
- - snibbets.taskpaper
299
+ - src/_README.md
300
+ - yard_templates/default/method_details/setup.rb
292
301
  homepage: https://github.com/ttscoff/snibbets
293
302
  licenses:
294
303
  - MIT
data/Gemfile.lock.orig DELETED
@@ -1,107 +0,0 @@
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/buildnotes.md DELETED
@@ -1,47 +0,0 @@
1
- template: gem, git, gli, project
2
- executable: na
3
- readme: src/_README.md
4
- changelog: CHANGELOG.md
5
- project: snibbets
6
-
7
- # Snibbets
8
-
9
- A plain text snippet manager
10
-
11
- ## Develop
12
-
13
- @run(subl .)
14
-
15
- ## Dummy
16
-
17
- @run(bundle exec bin/snibbets $@)
18
-
19
- ## Deploy
20
-
21
- You no longer need to manually bump the version, it will be incremented when this task runs.
22
-
23
- ```run Update Changelog
24
- #!/bin/bash
25
-
26
- changelog -u
27
- ```
28
-
29
- @include(project:Update GitHub README)
30
-
31
- ```run Update README
32
- #!/bin/bash
33
-
34
- changelog | git commit -a -F -
35
- git pull
36
- git push
37
- ```
38
-
39
- @include(gem:Release Gem) Release Gem
40
- @include(project:Update Blog Project) Update Blog Project
41
- @run(rake bump[patch]) Bump Version
42
-
43
- @run(git commit -am 'Version bump')
44
-
45
- @after
46
- Don't forget to publish the website!
47
- @end
data/snibbets.taskpaper DELETED
@@ -1,14 +0,0 @@
1
- Inbox:
2
- - handle multiple code blocks within a section separately for highlighting @maybe @na
3
- If a header contains multiple snippets, create an array with a language specifier for each snippet, and then pass the array to the print function to handle individually highlighting each code block. Have a special language specifier for blockquote notes to avoid highlighting them at all.
4
- Could possibly just highlight each block as its found, and save an original copy in memory for uncolored output, or just write a decoloring method. Skip highlighting if it's not enabled, but decolor ouput sent to non-tty or --copy.
5
- snibbets:
6
- Feature Requests:
7
- Ideas:
8
- Bugs:
9
- Archive:
10
- Search Definitions:
11
- Top Priority @search(@priority = 5 and not @done)
12
- High Priority @search(@priority > 3 and not @done)
13
- Maybe @search(@maybe)
14
- Next @search(@na and not @done and not project = "Archive")