snibbets 2.0.29 → 2.0.30
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -64
- data/Gemfile.lock +1 -1
- data/README.md +4 -1
- data/bin/snibbets +4 -0
- data/lib/snibbets/array.rb +1 -1
- data/lib/snibbets/config.rb +1 -0
- data/lib/snibbets/menu.rb +4 -8
- data/lib/snibbets/os.rb +3 -3
- data/lib/snibbets/string.rb +50 -37
- data/lib/snibbets/version.rb +1 -1
- data/lib/snibbets.rb +24 -17
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a633139ac4f908c760dc709e91937cfeb6d77c8a3a2aebdfc0e9acec1760a25b
|
4
|
+
data.tar.gz: efc77b72771c37c1cda78a6fb66d4af532b9b2c31648e6b7fce4854a2310204e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af5ac5a46200ee38bc3fc20daed4bfdc2ca47841cc665883ac7837629436fe42e77a0b953f1d5c3615d0622f2a08e2672771876eb89a86e93afb66d8e89d265d
|
7
|
+
data.tar.gz: 89292879a4cd79acb7b30a24a7ed760557b6b26493a3311abbc42eeef097348d36b0b7c2b69475e5aa0d0729d493885647673675cf46b435fabfa7a4d0661fcb
|
data/CHANGELOG.md
CHANGED
@@ -1,96 +1,43 @@
|
|
1
|
-
### 2.0.
|
1
|
+
### 2.0.30
|
2
2
|
|
3
|
-
2023-04-
|
3
|
+
2023-04-19 06:44
|
4
4
|
|
5
5
|
#### NEW
|
6
6
|
|
7
|
-
- `--
|
7
|
+
- Added `--notes` option and accompanying `all_notes` config option to allow display of all notes instead of just code blocks in each snippet
|
8
8
|
|
9
9
|
#### IMPROVED
|
10
10
|
|
11
|
-
-
|
12
|
-
- Allow `--edit` with `--paste` to open the new snippet in your editor immediately
|
13
|
-
- Better removal of extra leading/trailing newlines
|
14
|
-
|
15
|
-
#### FIXED
|
16
|
-
|
17
|
-
- Code indentation with `--paste`
|
18
|
-
- Nil error when highlighting without extension
|
19
|
-
- When detecting indented code blocks, require a blank line (or start of file) before them, to avoid picking up lines within indented lists
|
20
|
-
- Selecting 'All snippets' could return blank results in some cases
|
21
|
-
|
22
|
-
### 2.0.28
|
23
|
-
|
24
|
-
2023-04-18 09:18
|
11
|
+
- Previously if multiple snippets were output, titles of snippets would go to STDERR so they weren't copied. Now they go to STDOUT as well.
|
25
12
|
|
26
|
-
|
13
|
+
### 2.0.29
|
27
14
|
|
28
|
-
-
|
15
|
+
2023-04-18 10:45
|
29
16
|
|
30
17
|
#### IMPROVED
|
31
18
|
|
32
|
-
-
|
33
|
-
- Allow `--edit` with `--paste` to open the new snippet in your editor immediately
|
19
|
+
- Better removal of extra leading/trailing newlines
|
34
20
|
|
35
21
|
#### FIXED
|
36
22
|
|
37
|
-
-
|
38
|
-
- Nil error when highlighting without extension
|
39
|
-
- When detecting indented code blocks, require a blank line (or start of file) before them, to avoid picking up lines within indented lists
|
40
|
-
|
41
|
-
### 2.0.27
|
42
|
-
|
43
|
-
2023-04-17 15:54
|
44
|
-
|
45
|
-
#### NEW
|
46
|
-
|
47
|
-
- `--nvultra` will open the selected snippet in nvUltra
|
23
|
+
- Selecting 'All snippets' could return blank results in some cases
|
48
24
|
|
49
|
-
|
25
|
+
### 2.0.28
|
50
26
|
|
51
|
-
-
|
52
|
-
- Allow `--edit` with `--paste` to open the new snippet in your editor immediately
|
27
|
+
2023-04-18 09:18
|
53
28
|
|
54
29
|
#### FIXED
|
55
30
|
|
56
|
-
-
|
57
|
-
- Nil error when highlighting without extension
|
31
|
+
- When detecting indented code blocks, require a blank line (or start of file) before them, to avoid picking up lines within indented lists
|
58
32
|
|
59
33
|
### 2.0.26
|
60
34
|
|
61
35
|
2023-04-16 11:18
|
62
36
|
|
63
|
-
#### NEW
|
64
|
-
|
65
|
-
- `--nvultra` will open the selected snippet in nvUltra
|
66
|
-
|
67
|
-
#### IMPROVED
|
68
|
-
|
69
|
-
- Use Readline for entering info with `--paste`, allows for better editing experience
|
70
|
-
- Allow `--edit` with `--paste` to open the new snippet in your editor immediately
|
71
|
-
|
72
37
|
#### FIXED
|
73
38
|
|
74
|
-
- Code indentation with `--paste`
|
75
39
|
- Nil error when highlighting without extension
|
76
40
|
|
77
|
-
### 2.0.25
|
78
|
-
|
79
|
-
2023-04-16 11:09
|
80
|
-
|
81
|
-
#### NEW
|
82
|
-
|
83
|
-
- `--nvultra` will open the selected snippet in nvUltra
|
84
|
-
|
85
|
-
#### IMPROVED
|
86
|
-
|
87
|
-
- Use Readline for entering info with `--paste`, allows for better editing experience
|
88
|
-
- Allow `--edit` with `--paste` to open the new snippet in your editor immediately
|
89
|
-
|
90
|
-
#### FIXED
|
91
|
-
|
92
|
-
- Code indentation with `--paste`
|
93
|
-
|
94
41
|
### 2.0.24
|
95
42
|
|
96
43
|
2023-04-16 10:49
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -102,6 +102,8 @@ Set the `source` key to the folder where you keep your Markdown snippets. Option
|
|
102
102
|
|
103
103
|
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.
|
104
104
|
|
105
|
+
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`.
|
106
|
+
|
105
107
|
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].
|
106
108
|
|
107
109
|
[xclip]: https://ostechnix.com/access-clipboard-contents-using-xclip-and-xsel-in-linux/
|
@@ -157,13 +159,14 @@ Snibbet's implementation of Skylighting has limited but better-looking themes, a
|
|
157
159
|
### Usage
|
158
160
|
|
159
161
|
```
|
160
|
-
Snibbets v2.0.
|
162
|
+
Snibbets v2.0.30
|
161
163
|
|
162
164
|
Usage: snibbets [options] query
|
163
165
|
-a, --all If a file contains multiple snippets, output all of them (no menu)
|
164
166
|
-c, --[no-]copy Copy the output to the clibpoard (also displays on STDOUT)
|
165
167
|
-e, --edit Open the selected snippet in your configured editor
|
166
168
|
-n, --[no-]name-only Only search file names, not content
|
169
|
+
--[no-]notes Display the full content of the snippet
|
167
170
|
-o, --output FORMAT Output format (json|launchbar|*raw)
|
168
171
|
-p, --paste, --new Interactively create a new snippet from clipboard contents (Mac only)
|
169
172
|
-q, --quiet Skip menus and display first match
|
data/bin/snibbets
CHANGED
@@ -46,6 +46,10 @@ module Snibbets
|
|
46
46
|
options[:name_only] = v
|
47
47
|
end
|
48
48
|
|
49
|
+
opts.on('--[no-]notes', 'Display the full content of the snippet') do |v|
|
50
|
+
options[:all_notes] = v
|
51
|
+
end
|
52
|
+
|
49
53
|
opts.on('-o', '--output FORMAT', 'Output format (json|launchbar|*raw)') do |outformat|
|
50
54
|
valid = %w[json launchbar lb raw]
|
51
55
|
if outformat.downcase =~ /(launchbar|lb)/
|
data/lib/snibbets/array.rb
CHANGED
data/lib/snibbets/config.rb
CHANGED
data/lib/snibbets/menu.rb
CHANGED
@@ -14,9 +14,7 @@ module Snibbets
|
|
14
14
|
def remove_items_without_query(filename, res, query)
|
15
15
|
q = find_query_in_options(filename, res, query).split(/ /)
|
16
16
|
res.delete_if do |opt|
|
17
|
-
q.none?
|
18
|
-
"#{filename} #{opt['title']}" =~ /#{word}/i
|
19
|
-
end
|
17
|
+
q.none? { |word| "#{filename} #{opt['title']}" =~ /#{word}/i }
|
20
18
|
end
|
21
19
|
res
|
22
20
|
end
|
@@ -28,16 +26,14 @@ module Snibbets
|
|
28
26
|
end
|
29
27
|
|
30
28
|
if res.count.zero?
|
31
|
-
warn 'No matches found'
|
29
|
+
warn 'No matches found' if Snibbets.options[:interactive]
|
32
30
|
Process.exit 1
|
33
31
|
end
|
34
32
|
|
35
33
|
options = res.map { |m| m['title'] }
|
36
34
|
|
37
35
|
puts title
|
38
|
-
args = [
|
39
|
-
"--height=#{options.count}"
|
40
|
-
]
|
36
|
+
args = ["--height=#{options.count}"]
|
41
37
|
selection = `echo #{Shellwords.escape(options.join("\n"))} | #{executable} filter #{args.join(' ')}`.strip
|
42
38
|
Process.exit 1 if selection.empty?
|
43
39
|
|
@@ -82,7 +78,7 @@ module Snibbets
|
|
82
78
|
end
|
83
79
|
|
84
80
|
if res.count.zero?
|
85
|
-
warn 'No matches found'
|
81
|
+
warn 'No matches found' if Snibbets.options[:interactive]
|
86
82
|
Process.exit 1
|
87
83
|
end
|
88
84
|
|
data/lib/snibbets/os.rb
CHANGED
@@ -31,12 +31,12 @@ module Snibbets
|
|
31
31
|
os = RbConfig::CONFIG['target_os']
|
32
32
|
case os
|
33
33
|
when /darwin.*/i
|
34
|
-
`pbpaste -pboard general -Prefer txt
|
34
|
+
`pbpaste -pboard general -Prefer txt`.strip_newlines
|
35
35
|
else
|
36
36
|
if TTY::Which.exist?('xclip')
|
37
|
-
`xclip -o -sel c
|
37
|
+
`xclip -o -sel c`.strip_newlines
|
38
38
|
elsif TTY::Which.exist('xsel')
|
39
|
-
`xsel -ob
|
39
|
+
`xsel -ob`.strip_newlines
|
40
40
|
else
|
41
41
|
puts 'Paste not supported on this system, please install xclip or xsel.'
|
42
42
|
end
|
data/lib/snibbets/string.rb
CHANGED
@@ -61,7 +61,7 @@ module Snibbets
|
|
61
61
|
|
62
62
|
# if it's a fenced code block, just discard the fence and everything
|
63
63
|
# outside it
|
64
|
-
if block.fenced?
|
64
|
+
if block.fenced? && !Snibbets.options[:all_notes]
|
65
65
|
code_blocks = block.scan(/(`{3,})(\w+)?\s*\n(.*?)\n\1/m)
|
66
66
|
code_blocks.map! { |b| b[2].strip }
|
67
67
|
return code_blocks.join("\n\n")
|
@@ -90,11 +90,9 @@ module Snibbets
|
|
90
90
|
|
91
91
|
indent = code[0].match(/^( {4,}|\t+)(?=\S)/)
|
92
92
|
|
93
|
-
if indent
|
94
|
-
|
95
|
-
|
96
|
-
self
|
97
|
-
end
|
93
|
+
return self if indent.nil?
|
94
|
+
|
95
|
+
code.map! { |line| line.sub(/(?mi)^#{indent[1]}/, '') }.join("\n")
|
98
96
|
end
|
99
97
|
|
100
98
|
def replace_blocks
|
@@ -129,46 +127,34 @@ module Snibbets
|
|
129
127
|
[sans_blocks, code_blocks]
|
130
128
|
end
|
131
129
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
# return [{ 'title' => '', 'code' => content.clean_code.strip }] unless multiple?
|
138
|
-
|
139
|
-
# Split content by ATX headers. Everything on the line after the #
|
140
|
-
# becomes the title, code is gleaned from text between that and the
|
141
|
-
# next ATX header (or end)
|
142
|
-
sections = []
|
143
|
-
|
144
|
-
sans_blocks, code_blocks = content.replace_blocks
|
145
|
-
|
146
|
-
content = []
|
147
|
-
if sans_blocks =~ /<block\d+>/
|
148
|
-
sans_blocks.each_line do |line|
|
149
|
-
content << line if line =~ /^#/ || line =~ /<block\d+>/
|
150
|
-
end
|
151
|
-
|
152
|
-
parts = content.join("\n").split(/^#+/)
|
153
|
-
else
|
154
|
-
parts = sans_blocks.gsub(/\n{2,}/, "\n\n").split(/^#+/)
|
130
|
+
def parse_lang_marker(block)
|
131
|
+
lang = nil
|
132
|
+
if block =~ /<lang:(.*?)>/
|
133
|
+
lang = Regexp.last_match(1)
|
134
|
+
block = block.gsub(/<lang:.*?>\n+/, '').strip_empty
|
155
135
|
end
|
156
136
|
|
157
|
-
|
137
|
+
[lang, block]
|
138
|
+
end
|
139
|
+
|
140
|
+
def restore_blocks(parts, code_blocks)
|
141
|
+
sections = []
|
158
142
|
|
159
143
|
parts.each do |part|
|
160
144
|
lines = part.split(/\n/).strip_empty
|
161
|
-
next if lines.blocks
|
145
|
+
next if lines.blocks.zero?
|
162
146
|
|
163
147
|
title = lines.count > 1 && lines[0] !~ /<block\d+>/ ? lines.shift.strip.sub(/[.:]$/, '') : 'Default snippet'
|
164
|
-
block = lines.join("\n").gsub(/<(block\d+)>/) { code_blocks[Regexp.last_match(1)] }
|
165
148
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
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```" }
|
151
|
+
else
|
152
|
+
lines.join("\n").gsub(/<(block\d+)>/) { code_blocks[Regexp.last_match(1)].strip_empty }
|
153
|
+
end
|
154
|
+
|
155
|
+
# block = lines.join("\n").gsub(/<(block\d+)>/) { code_blocks[Regexp.last_match(1)] }
|
171
156
|
|
157
|
+
lang, block = parse_lang_marker(block)
|
172
158
|
code = block.clean_code
|
173
159
|
|
174
160
|
next unless code && !code.empty?
|
@@ -182,5 +168,32 @@ module Snibbets
|
|
182
168
|
|
183
169
|
sections
|
184
170
|
end
|
171
|
+
|
172
|
+
# Returns an array of snippets. Single snippets are returned without a
|
173
|
+
# title, multiple snippets get titles from header lines
|
174
|
+
def snippets
|
175
|
+
content = dup.remove_meta
|
176
|
+
# If there's only one snippet, just clean it and return
|
177
|
+
# return [{ 'title' => '', 'code' => content.clean_code.strip }] unless multiple?
|
178
|
+
|
179
|
+
# Split content by ATX headers. Everything on the line after the #
|
180
|
+
# becomes the title, code is gleaned from text between that and the
|
181
|
+
# next ATX header (or end)
|
182
|
+
sans_blocks, code_blocks = content.replace_blocks
|
183
|
+
|
184
|
+
parts = if Snibbets.options[:all_notes]
|
185
|
+
sans_blocks.split(/^#+/)
|
186
|
+
elsif sans_blocks =~ /<block\d+>/
|
187
|
+
sans_blocks.split(/\n/).each_with_object([]) do |line, arr|
|
188
|
+
arr << line if line =~ /^#/ || line =~ /<block\d+>/
|
189
|
+
end.join("\n").split(/^#+/)
|
190
|
+
else
|
191
|
+
sans_blocks.gsub(/\n{2,}/, "\n\n").split(/^#+/)
|
192
|
+
end
|
193
|
+
|
194
|
+
# parts.shift if parts.count > 1
|
195
|
+
|
196
|
+
restore_blocks(parts, code_blocks)
|
197
|
+
end
|
185
198
|
end
|
186
199
|
end
|
data/lib/snibbets/version.rb
CHANGED
data/lib/snibbets.rb
CHANGED
@@ -153,7 +153,7 @@ module Snibbets
|
|
153
153
|
end
|
154
154
|
|
155
155
|
def new_snippet_from_clipboard
|
156
|
-
return false unless $
|
156
|
+
return false unless $stdout.isatty
|
157
157
|
|
158
158
|
trap('SIGINT') do
|
159
159
|
Howzit.console.info "\nCancelled"
|
@@ -248,7 +248,7 @@ module Snibbets
|
|
248
248
|
else
|
249
249
|
filepath = nil
|
250
250
|
if results.empty?
|
251
|
-
warn 'No results'
|
251
|
+
warn 'No results' if Snibbets.options[:interactive]
|
252
252
|
Process.exit 0
|
253
253
|
elsif results.length == 1 || !Snibbets.options[:interactive]
|
254
254
|
filepath = results[0]['path']
|
@@ -272,7 +272,7 @@ module Snibbets
|
|
272
272
|
snippets = input.snippets
|
273
273
|
|
274
274
|
if snippets.empty?
|
275
|
-
warn 'No snippets found'
|
275
|
+
warn 'No snippets found' if Snibbets.options[:interactive]
|
276
276
|
Process.exit 0
|
277
277
|
elsif snippets.length == 1 || !Snibbets.options[:interactive]
|
278
278
|
if Snibbets.options[:output] == 'json'
|
@@ -280,9 +280,11 @@ module Snibbets
|
|
280
280
|
else
|
281
281
|
snippets.each do |snip|
|
282
282
|
header = File.basename(filepath, '.md')
|
283
|
-
|
284
|
-
|
285
|
-
|
283
|
+
if $stdout.isatty
|
284
|
+
puts header
|
285
|
+
puts '-' * header.length
|
286
|
+
puts ''
|
287
|
+
end
|
286
288
|
code = snip['code']
|
287
289
|
lang = snip['language']
|
288
290
|
print(code, filepath, lang)
|
@@ -307,19 +309,23 @@ module Snibbets
|
|
307
309
|
if Snibbets.options[:output] == 'json'
|
308
310
|
print(snippets.to_json, filepath)
|
309
311
|
else
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
312
|
+
if $stdout.isatty
|
313
|
+
header = File.basename(filepath, '.md')
|
314
|
+
warn header
|
315
|
+
warn '=' * header.length
|
316
|
+
warn ''
|
317
|
+
end
|
314
318
|
print_all(snippets, filepath)
|
315
319
|
end
|
316
320
|
elsif Snibbets.options[:output] == 'json'
|
317
321
|
print(answer.to_json, filepath)
|
318
322
|
else
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
+
if $stdout.isatty
|
324
|
+
header = "#{File.basename(filepath, '.md')}: #{answer['title']}"
|
325
|
+
warn header
|
326
|
+
warn '-' * header.length
|
327
|
+
warn ''
|
328
|
+
end
|
323
329
|
code = answer['code']
|
324
330
|
lang = answer['language']
|
325
331
|
print(code, filepath, lang)
|
@@ -333,9 +339,10 @@ module Snibbets
|
|
333
339
|
|
334
340
|
snippets.each do |snippet|
|
335
341
|
lang = snippet['language']
|
336
|
-
|
337
|
-
|
338
|
-
|
342
|
+
|
343
|
+
puts "### #{snippet['title']} ###"
|
344
|
+
puts ''
|
345
|
+
|
339
346
|
print(snippet['code'], filepath, lang)
|
340
347
|
puts
|
341
348
|
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.
|
4
|
+
version: 2.0.30
|
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-
|
11
|
+
date: 2023-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|