hookapp 2.0.5 → 2.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/AUTHORS.md +4 -0
  3. data/CHANGELOG.md +9 -0
  4. data/Gemfile.lock +35 -40
  5. data/LICENSE +21 -0
  6. data/README.md +52 -19
  7. data/Rakefile +7 -3
  8. data/bin/hook +102 -65
  9. data/buildnotes.md +30 -0
  10. data/hook.rdoc +35 -11
  11. data/hookapp.gemspec +1 -0
  12. data/html/App.html +1 -1
  13. data/html/GLI/Commands/Doc.html +1 -1
  14. data/html/GLI/Commands/MarkdownDocumentListener.html +27 -17
  15. data/html/GLI/Commands.html +1 -1
  16. data/html/GLI.html +1 -1
  17. data/html/Hook.html +1 -1
  18. data/html/HookApp.html +106 -44
  19. data/html/Hooker.html +2 -2
  20. data/html/README_rdoc.html +47 -18
  21. data/html/String.html +23 -1
  22. data/html/created.rid +9 -8
  23. data/html/index.html +39 -12
  24. data/html/js/navigation.js.gz +0 -0
  25. data/html/js/search_index.js +1 -1
  26. data/html/js/search_index.js.gz +0 -0
  27. data/html/js/searcher.js.gz +0 -0
  28. data/html/table_of_contents.html +71 -7
  29. data/lib/hook/hookapp.rb +40 -22
  30. data/lib/hook/hooker.rb +1 -0
  31. data/lib/hook/markdown_document_listener.rb +12 -2
  32. data/lib/hook/prompt.rb +113 -0
  33. data/lib/hook/string.rb +4 -0
  34. data/lib/hook/version.rb +1 -1
  35. data/lib/hook.rb +2 -0
  36. data/test/helpers/hook-helpers.rb +76 -0
  37. data/test/hook_clip_test.rb +24 -0
  38. data/test/hook_clone_test.rb +30 -0
  39. data/test/hook_encode_test.rb +30 -0
  40. data/test/hook_link_test.rb +40 -0
  41. data/test/hook_list_test.rb +25 -0
  42. data/test/hook_remove_test.rb +34 -0
  43. data/test/hook_scripts_test.rb +21 -0
  44. metadata +33 -16
  45. data/lib/helpers/fuzzyfilefinder +0 -0
  46. data/test/default_test.rb +0 -14
  47. data/test/hookfiles/01.test +0 -0
  48. data/test/hookfiles/02.test +0 -0
  49. data/test/hookfiles/03.test +0 -0
  50. data/test/hookfiles/04.test +0 -0
  51. data/test/hookfiles/05.test +0 -0
  52. data/test/hookfiles/06.test +0 -0
  53. data/test/hookfiles/07.test +0 -0
  54. data/test/hookfiles/08.test +0 -0
  55. data/test/hookfiles/09.test +0 -0
  56. data/test/hookfiles/10.test +0 -0
  57. data/test/hookfiles/11.test +0 -0
  58. data/test/hookfiles/12.test +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 06acc4dd72c5ca227e0cbf252542ca79e42a31d624b5e78f609cfb019220f3c3
4
- data.tar.gz: 6f2f660014f3486dd80a0fd06c52aa6822844097580780b6addf247ee0ee8cee
3
+ metadata.gz: 5a5b6a517bd76ec8ddfc8ef6ffb98d6690dc56c2d5133bb1ad88635d72aaf55e
4
+ data.tar.gz: ddd95cde21eba658a09a98c04c49a03e98853bc450b257d2f6ad843cdf084f35
5
5
  SHA512:
6
- metadata.gz: 4c3c57b1879c66c9ce671bf3eb7a676e9d543962a50c0647ade2d451f93207c071d34c67a93ccdde8fcf5d19e54a0bb53a056e8cba928e5c6b6cdf69868b69ab
7
- data.tar.gz: 5ba08b7b5ef07d6d0062fc18cfea73957d83146194185de9e1d1cbaf8f5680f230792a919a954099b03e26c023fe204766ece2429acc9fe4de1b0e233418d76a
6
+ metadata.gz: 2ab5784b34f8a8380b37202cd1a674c78083e6ec1748f3320f4292933a7cc20cd20db520daa7fd697dade590fa32d5f7d21224e1ebae4396fe5ec2aaff7f6081
7
+ data.tar.gz: b45ce5ede9b4fa988f660fb5943b0ce1a7ee8e7bfffd9d0d5a45b0a4138c1db812a8f36dffcba02159e20f370e64e2b611e2e968a61fbf2d763ec03295d927d2
data/AUTHORS.md ADDED
@@ -0,0 +1,4 @@
1
+ ## Authors
2
+
3
+ - Brett Terpstra <me@brettterpstra.com>
4
+ - Josh Nichols <joshua.nichols@gmail.com>
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ #### 2.0.9
2
+
3
+ - Fix fzf integration across platforms
4
+
5
+ #### 2.0.8
6
+
7
+ - Bug fixes
8
+ - New tests
9
+
1
10
  #### 2.0.3
2
11
 
3
12
  - Incorporate `fzf` for selecting and filtering hooks
data/Gemfile.lock CHANGED
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hookapp (2.0.4)
4
+ hookapp (2.0.9)
5
5
  gli (~> 2.20.1)
6
+ tty-which (~> 0.5, >= 0.5.0)
6
7
 
7
8
  GEM
8
9
  remote: http://rubygems.org/
@@ -17,53 +18,47 @@ GEM
17
18
  builder (3.2.4)
18
19
  childprocess (3.0.0)
19
20
  contracts (0.17)
20
- cucumber (7.0.0)
21
+ cucumber (8.0.0)
21
22
  builder (~> 3.2, >= 3.2.4)
22
- cucumber-core (~> 10.0, >= 10.0.1)
23
- cucumber-create-meta (~> 6.0, >= 6.0.1)
24
- cucumber-cucumber-expressions (~> 12.1, >= 12.1.1)
25
- cucumber-gherkin (~> 20.0, >= 20.0.1)
26
- cucumber-html-formatter (~> 16.0, >= 16.0.1)
27
- cucumber-messages (~> 17.0, >= 17.0.1)
28
- cucumber-wire (~> 6.0, >= 6.0.1)
29
- diff-lcs (~> 1.4, >= 1.4.4)
30
- mime-types (~> 3.3, >= 3.3.1)
31
- multi_test (~> 0.1, >= 0.1.2)
23
+ cucumber-ci-environment (~> 9.0, >= 9.0.4)
24
+ cucumber-core (~> 11.0, >= 11.0.0)
25
+ cucumber-cucumber-expressions (~> 15.1, >= 15.1.1)
26
+ cucumber-gherkin (~> 23.0, >= 23.0.1)
27
+ cucumber-html-formatter (~> 19.1, >= 19.1.0)
28
+ cucumber-messages (~> 18.0, >= 18.0.0)
29
+ diff-lcs (~> 1.5, >= 1.5.0)
30
+ mime-types (~> 3.4, >= 3.4.1)
31
+ multi_test (~> 1.1, >= 1.1.0)
32
32
  sys-uname (~> 1.2, >= 1.2.2)
33
- cucumber-core (10.0.1)
34
- cucumber-gherkin (~> 20.0, >= 20.0.1)
35
- cucumber-messages (~> 17.0, >= 17.0.1)
36
- cucumber-tag-expressions (~> 3.0, >= 3.0.1)
37
- cucumber-create-meta (6.0.1)
38
- cucumber-messages (~> 17.0, >= 17.0.1)
39
- sys-uname (~> 1.2, >= 1.2.2)
40
- cucumber-cucumber-expressions (12.1.3)
41
- cucumber-gherkin (20.0.1)
42
- cucumber-messages (~> 17.0, >= 17.0.1)
43
- cucumber-html-formatter (16.0.1)
44
- cucumber-messages (~> 17.0, >= 17.0.1)
45
- cucumber-messages (17.1.1)
46
- cucumber-tag-expressions (3.0.1)
47
- cucumber-wire (6.1.1)
48
- cucumber-core (~> 10.0, >= 10.0.1)
49
- cucumber-cucumber-expressions (~> 12.1, >= 12.1.2)
50
- cucumber-messages (~> 17.0, >= 17.0.1)
51
- diff-lcs (1.4.4)
52
- ffi (1.15.4)
33
+ cucumber-ci-environment (9.0.4)
34
+ cucumber-core (11.0.0)
35
+ cucumber-gherkin (~> 23.0, >= 23.0.1)
36
+ cucumber-messages (~> 18.0, >= 18.0.0)
37
+ cucumber-tag-expressions (~> 4.1, >= 4.1.0)
38
+ cucumber-cucumber-expressions (15.2.0)
39
+ cucumber-gherkin (23.0.1)
40
+ cucumber-messages (~> 18.0, >= 18.0.0)
41
+ cucumber-html-formatter (19.1.0)
42
+ cucumber-messages (~> 18.0, >= 18.0.0)
43
+ cucumber-messages (18.0.0)
44
+ cucumber-tag-expressions (4.1.0)
45
+ diff-lcs (1.5.0)
46
+ ffi (1.15.5)
53
47
  gli (2.20.1)
54
- mime-types (3.3.1)
48
+ mime-types (3.4.1)
55
49
  mime-types-data (~> 3.2015)
56
- mime-types-data (3.2021.0901)
57
- multi_test (0.1.2)
50
+ mime-types-data (3.2022.0105)
51
+ multi_test (1.1.0)
58
52
  rake (13.0.6)
59
- rdoc (6.3.2)
60
- rspec-expectations (3.10.1)
53
+ rdoc (6.3.3)
54
+ rspec-expectations (3.11.0)
61
55
  diff-lcs (>= 1.2.0, < 2.0)
62
- rspec-support (~> 3.10.0)
63
- rspec-support (3.10.2)
56
+ rspec-support (~> 3.11.0)
57
+ rspec-support (3.11.0)
64
58
  sys-uname (1.2.2)
65
59
  ffi (~> 1.1)
66
- thor (1.1.0)
60
+ thor (1.2.1)
61
+ tty-which (0.5.0)
67
62
 
68
63
  PLATFORMS
69
64
  ruby
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Brett Terpstra
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -2,9 +2,11 @@
2
2
 
3
3
  CLI interface for Hook.app (macOS)
4
4
 
5
- > Hook.app is a productivity tool for macOS <https://hookproductivity.com/>. This gem includes a `hook` binary that allows interaction with the features of Hook.app.
5
+ > Hook.app is a productivity tool for macOS <https://hookproductivity.com/>.
6
6
 
7
- *v2.0.3*
7
+ This gem includes a `hook` binary that allows interaction with the features of Hook.app.
8
+
9
+ *v2.0.9*
8
10
 
9
11
  ## Installation
10
12
 
@@ -99,13 +101,13 @@ Display the program version
99
101
 
100
102
  ## Commands
101
103
 
102
- ### `$ hook` <mark>`clip|cp`</mark> ` FILE_OR_URL`
104
+ ### `$ hook` <mark>`clip|cp`</mark> `FILE_OR_URL`
103
105
 
104
106
  *Copy Hook URL for file/url to clipboard*
105
107
 
106
108
  > Creates a bookmark for the specified file or URL and copies its Hook URL to the clipboard.
107
109
  >
108
- > The copied Hook URL can be used to link to other files (use `hook link --paste FILE/URL),
110
+ > The copied Hook URL can be used to link to other files (use `hook link --paste FILE/URL`,
109
111
  > or to paste into another app as a link. Use the -m flag to copy a full Markdown link.
110
112
 
111
113
  #### Options
@@ -120,15 +122,17 @@ Copy as Markdown
120
122
 
121
123
  * * * * * *
122
124
 
123
- ### `$ hook` <mark>`clone`</mark> ` SOURCE TARGET`
125
+ ### `$ hook` <mark>`clone`</mark> `SOURCE TARGET`
124
126
 
125
127
  *Clone all hooks from one file or url onto another*
126
128
 
127
- > Copy all the files and urls that the first file is hooked to onto another file. Exactly two arguments (SOURCE, TARGET) required.
129
+ > Copy all the files and urls that the first file is hooked to onto another file.
130
+ >
131
+ > Exactly two arguments (SOURCE, TARGET) required.
128
132
 
129
133
  * * * * * *
130
134
 
131
- ### `$ hook` <mark>`find|search`</mark> ` SEARCH_STRING`
135
+ ### `$ hook` <mark>`find|search`</mark> `[SEARCH_STRING]`
132
136
 
133
137
  *Search bookmarks*
134
138
 
@@ -138,7 +142,7 @@ Copy as Markdown
138
142
 
139
143
  #### Options
140
144
 
141
- ##### `-o` | `--output_format` format
145
+ ##### `-o` | `--output_format` FORMAT
142
146
 
143
147
  Output format [(h)ooks, (p)aths, (m)arkdown, (v)erbose]
144
148
 
@@ -158,7 +162,7 @@ Separate results with NULL separator, only applies with "paths" output for singl
158
162
 
159
163
  * * * * * *
160
164
 
161
- ### `$ hook` <mark>`from`</mark> ` APPLICATION_NAME`
165
+ ### `$ hook` <mark>`from`</mark> `APPLICATION_NAME`
162
166
 
163
167
  *Get a Hook URL for the frontmost window of an app*
164
168
 
@@ -179,7 +183,7 @@ Output as Markdown
179
183
 
180
184
  * * * * * *
181
185
 
182
- ### `$ hook` <mark>`help`</mark> ` command`
186
+ ### `$ hook` <mark>`help`</mark> `command`
183
187
 
184
188
  *Shows a list of commands or help for one command*
185
189
 
@@ -193,7 +197,7 @@ List commands one per line, to assist with shell completion
193
197
 
194
198
  * * * * * *
195
199
 
196
- ### `$ hook` <mark>`link|ln`</mark> ` SOURCE [SOURCE...] TARGET`
200
+ ### `$ hook` <mark>`link|ln`</mark> `SOURCE... TARGET`
197
201
 
198
202
  *Create bidirectional hooks between two or more files/urls*
199
203
 
@@ -217,7 +221,7 @@ Paste URL from clipboard
217
221
 
218
222
  * * * * * *
219
223
 
220
- ### `$ hook` <mark>`list|ls`</mark> ` FILE_OR_URL [FILE_OR_URL...]`
224
+ ### `$ hook` <mark>`list|ls`</mark> `[FILE_OR_URL]...`
221
225
 
222
226
  *List hooks on a file or url*
223
227
 
@@ -227,7 +231,7 @@ Paste URL from clipboard
227
231
 
228
232
  #### Options
229
233
 
230
- ##### `-o` | `--output_format` format
234
+ ##### `-o` | `--output_format` FORMAT
231
235
 
232
236
  Output format [(h)ooks, (p)aths, (m)arkdown, (v)erbose]
233
237
 
@@ -249,15 +253,35 @@ Generate a menu to select hook(s) for opening
249
253
 
250
254
  * * * * * *
251
255
 
252
- ### `$ hook` <mark>`open|gui`</mark> ` FILE_OR_URL`
256
+ ### `$ hook` <mark>`open|gui`</mark> `FILE_OR_URL`
253
257
 
254
258
  *Open the specified file or url in Hook GUI*
255
259
 
256
- > Opens Hook.app on the specified file/URL for browsing and performing actions. Exactly one argument (File/URL) required.
260
+ > Opens Hook.app on the specified file/URL for browsing and performing actions.
261
+ >
262
+ > Exactly one argument (File/URL) required.
263
+
264
+ * * * * * *
265
+
266
+ ### `$ hook` <mark>`percent`</mark> `STRING`
267
+
268
+ *Percent encode/decode a string*
269
+
270
+ > Use encode or decode to apply Hook's url encoding to a string argument. Use '-' to read input from STDIN.
271
+
272
+ #### Commands
273
+
274
+ ##### `$ hook` <mark>`percent decode`</mark> `STRING`
275
+
276
+ *decode a percent-encoded string*
277
+
278
+ ##### `$ hook` <mark>`percent encode`</mark> `STRING`
279
+
280
+ *percent encode a string*
257
281
 
258
282
  * * * * * *
259
283
 
260
- ### `$ hook` <mark>`remove|rm`</mark> ` ITEM_1 ITEM_2`
284
+ ### `$ hook` <mark>`remove|rm`</mark> `FILE_OR_URL...`
261
285
 
262
286
  *Remove a hook between two files/urls*
263
287
 
@@ -271,9 +295,13 @@ Generate a menu to select hook(s) for opening
271
295
 
272
296
  Remove ALL links on files, requires confirmation
273
297
 
298
+ ##### `-f`|`--force`
299
+
300
+
301
+
274
302
  * * * * * *
275
303
 
276
- ### `$ hook` <mark>`scripts`</mark> ` SHELL`
304
+ ### `$ hook` <mark>`scripts`</mark> `SHELL`
277
305
 
278
306
  *Shell completion examples*
279
307
 
@@ -281,7 +309,7 @@ Remove ALL links on files, requires confirmation
281
309
 
282
310
  * * * * * *
283
311
 
284
- ### `$ hook` <mark>`select`</mark> ` FILE_OR_URL`
312
+ ### `$ hook` <mark>`select`</mark> `FILE_OR_URL`
285
313
 
286
314
  *Select from hooks on a file/url and open in default application*
287
315
 
@@ -292,6 +320,11 @@ Remove ALL links on files, requires confirmation
292
320
  * * * * * *
293
321
 
294
322
  #### [Default Command] help
323
+ ## Authors
324
+
325
+ - Brett Terpstra <me@brettterpstra.com>
326
+ - Josh Nichols <joshua.nichols@gmail.com>
327
+
295
328
  ## Credits
296
329
 
297
330
  HookApp embeds [Fuzzy Finder](https://github.com/junegunn/fzf) under the [MIT License](https://github.com/junegunn/fzf/blob/master/LICENSE)
@@ -325,5 +358,5 @@ This software is licensed under the MIT License.
325
358
  THE SOFTWARE.
326
359
 
327
360
 
328
- Documentation generated 2021-09-18 12:29
361
+ Documentation generated 2022-05-26 08:29
329
362
 
data/Rakefile CHANGED
@@ -4,6 +4,7 @@ require 'rubygems/package_task'
4
4
  require 'rdoc/task'
5
5
  require 'cucumber'
6
6
  require 'cucumber/rake/task'
7
+ require 'rake/testtask'
7
8
  Rake::RDocTask.new do |rd|
8
9
  rd.main = "README.rdoc"
9
10
  rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
@@ -14,6 +15,7 @@ spec = eval(File.read('hookapp.gemspec'))
14
15
 
15
16
  Gem::PackageTask.new(spec) do |pkg|
16
17
  end
18
+
17
19
  CUKE_RESULTS = 'results.html'
18
20
  CLEAN << CUKE_RESULTS
19
21
  desc 'Run features'
@@ -35,10 +37,12 @@ end
35
37
  task :cucumber => :features
36
38
  task 'cucumber:wip' => 'features:wip'
37
39
  task :wip => 'features:wip'
38
- require 'rake/testtask'
40
+
39
41
  Rake::TestTask.new do |t|
40
- t.libs << "test"
42
+ t.libs << ['test', 'test/helpers']
41
43
  t.test_files = FileList['test/*_test.rb']
44
+ t.verbose = ENV['VERBOSE'] =~ /(true|1)/i ? true : false
42
45
  end
43
46
 
44
- task :default => [:test,:features]
47
+ # task :default => [:test,:features]
48
+ task :default => [:test]
data/bin/hook CHANGED
@@ -1,14 +1,17 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/env ruby -W1
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'hook'
5
+ require 'shellwords'
5
6
 
6
7
  # Main class for GLI app
7
8
  class App
8
9
  extend GLI::App
9
10
 
10
11
  program_desc 'CLI interface for Hook.app (macOS)'
11
- program_long_desc 'Hook.app is a productivity tool for macOS <https://hookproductivity.com/>. This gem includes a `hook` binary that allows interaction with the features of Hook.app.'
12
+ program_long_desc 'Hook.app is a productivity tool for macOS <https://hookproductivity.com/>.
13
+
14
+ This gem includes a `hook` binary that allows interaction with the features of Hook.app.'
12
15
  default_command 'help'
13
16
  autocomplete_commands = true
14
17
  synopsis_format(:terminal)
@@ -19,14 +22,13 @@ class App
19
22
  arguments :strict
20
23
 
21
24
  hookapp = nil
25
+ stdin = nil
22
26
 
23
27
  desc 'List hooks on a file or url'
24
- long_desc %{
25
- Output a list of all hooks attached to given url(s) or file(s) in the specified format (default "paths").
26
-
27
- Run `hook list` with no file/url argument to list all bookmarks.}
28
+ long_desc %(Output a list of all hooks attached to given url(s) or file(s) in the specified format (default "paths").
28
29
 
29
- arg_name 'FILE_OR_URL [FILE_OR_URL...]'
30
+ Run `hook list` with no file/url argument to list all bookmarks.)
31
+ arg_name 'FILE_OR_URL', [:optional, :multiple]
30
32
  command %i[list ls] do |c|
31
33
  c.desc 'Generate a menu to select hook(s) for opening'
32
34
  c.long_desc 'This option is a shortcut to `hook select` and overrides any other arguments.'
@@ -41,20 +43,22 @@ Run `hook list` with no file/url argument to list all bookmarks.}
41
43
  valid_formats = %w[hooks paths markdown verbose]
42
44
  fmt_list = valid_formats.map { |fmt| fmt.sub(/^(.)(.*?)$/, '(\1)\2') }.join(', ')
43
45
  c.desc "Output format [#{fmt_list}]"
44
- c.flag %i[o output_format], { arg_name: 'format', default_value: 'paths' }
46
+ c.arg_name 'FORMAT'
47
+ c.flag %i[o output_format], { arg_name: 'FORMAT', default_value: 'paths' }
45
48
 
46
49
  c.action do |_global_options, options, args|
47
50
  if options[:s]
48
- return hookapp.open_linked(args[0])
49
- end
50
- valid_format = hookapp.validate_format(options[:o], valid_formats)
51
- exit_now!("Invalid output format: \"#{options[:o]}\"", 6) unless valid_format
51
+ hookapp.open_linked(args[0])
52
+ else
53
+ valid_format = hookapp.validate_format(options[:o], valid_formats)
54
+ help_now!("Invalid output format: \"#{options[:o]}\"", 6) unless valid_format
52
55
 
53
- result = hookapp.linked_bookmarks(args, { files_only: options[:f],
54
- format: valid_format,
55
- null_separator: options[:null] })
56
+ result = hookapp.linked_bookmarks(args, { files_only: options[:f],
57
+ format: valid_format,
58
+ null_separator: options[:null] })
56
59
 
57
- puts result
60
+ puts result
61
+ end
58
62
  end
59
63
  end
60
64
 
@@ -62,25 +66,21 @@ Run `hook list` with no file/url argument to list all bookmarks.}
62
66
  # the full shell name as the extension, e.g. "hook_completion.bash".
63
67
  desc 'Shell completion examples'
64
68
  valid_shells = %w[bash zsh fish]
65
- long_desc %{
66
- Output completion script example for the specified shell (#{valid_shells.join(', ')})
67
- }
69
+ long_desc %(Output completion script example for the specified shell (#{valid_shells.join(', ')}))
68
70
  arg_name 'SHELL'
69
71
  command %i[scripts] do |c|
70
72
  c.action do |_global_options, _options, args|
71
73
  if args.length > 1
72
- exit_now!("Invalid number of arguments, (expected 1)", 5)
74
+ help_now!('Invalid number of arguments, (expected 1)', 5)
73
75
  elsif args.nil? || args.empty?
74
- exit_now!("Specify a shell (#{valid_shells.join(', ')})", 0)
76
+ help_now!("Specify a shell (#{valid_shells.join(', ')})", 0)
77
+ elsif valid_shells.include?(args[0])
78
+ base_dir = File.expand_path(File.join(File.dirname(__FILE__), '../lib/completion'))
79
+ completion = File.join(base_dir, "hook_completion.#{args[0]}")
80
+ script = IO.read(completion)
81
+ $stdout.puts script
75
82
  else
76
- if valid_shells.include?(args[0])
77
- base_dir = File.expand_path(File.join(File.dirname(__FILE__), '../lib/completion'))
78
- completion = File.join(base_dir, "hook_completion.#{args[0]}")
79
- script = IO.read(completion)
80
- $stdout.puts script
81
- else
82
- exit_now!("Invalid shell name, must be one of #{valid_shells.join(', ')}", 1)
83
- end
83
+ help_now!("Invalid shell name, must be one of #{valid_shells.join(', ')}", 1)
84
84
  end
85
85
  end
86
86
  end
@@ -88,11 +88,10 @@ Output completion script example for the specified shell (#{valid_shells.join(',
88
88
 
89
89
 
90
90
  desc 'Search bookmarks'
91
- long_desc %{
92
- Search bookmark urls and names for a string and output in specified format (default "paths").
91
+ long_desc %(Search bookmark urls and names for a string and output in specified format (default "paths").
93
92
 
94
- Run `hook find` with no search argument to list all bookmarks.}
95
- arg_name 'SEARCH_STRING'
93
+ Run `hook find` with no search argument to list all bookmarks.)
94
+ arg_name 'SEARCH_STRING', :optional
96
95
  command %i[find search] do |c|
97
96
  c.desc 'Output only bookmarks with file paths (exclude e.g. emails)'
98
97
  c.switch %i[f files_only], { negatable: false, default_value: false }
@@ -104,7 +103,7 @@ Run `hook find` with no search argument to list all bookmarks.}
104
103
  fmt_list = valid_formats.map { |fmt| fmt.sub(/^(.)(.*?)$/, '(\1)\2') }.join(', ')
105
104
 
106
105
  c.desc "Output format [#{fmt_list}]"
107
- c.flag %i[o output_format], { arg_name: 'format', default_value: 'paths' }
106
+ c.flag %i[o output_format], { arg_name: 'FORMAT', default_value: 'paths' }
108
107
 
109
108
  c.desc "Search only bookmark names"
110
109
  c.switch %i[n names_only], { negatable: false, default_value: false }
@@ -123,16 +122,15 @@ Run `hook find` with no search argument to list all bookmarks.}
123
122
  end
124
123
 
125
124
  desc 'Create bidirectional hooks between two or more files/urls'
126
- long_desc %{
127
- If two files/urls are provided, links will be bi-directional.
125
+ long_desc 'If two files/urls are provided, links will be bi-directional.
128
126
  If three or more are provided, `link` defaults to creating bi-directional
129
127
  links between each file and the last file in the list. Use `-a` to create
130
128
  bi-directional links between every file in the list.
131
129
 
132
130
  If using `--paste`, the URL/hook link in the clipboard will be used as one argument,
133
131
  to be combined with one or more file/url arguments.
134
- }
135
- arg_name 'SOURCE [SOURCE...] TARGET'
132
+ '
133
+ arg_name 'SOURCE... TARGET'
136
134
  command %i[link ln] do |c|
137
135
  c.desc 'Link every listed file or url to every other'
138
136
  c.switch %i[a all], { negatable: false, default_value: false }
@@ -158,12 +156,10 @@ to be combined with one or more file/url arguments.
158
156
  end
159
157
 
160
158
  desc 'Copy Hook URL for file/url to clipboard'
161
- long_desc %{
162
- Creates a bookmark for the specified file or URL and copies its Hook URL to the clipboard.
159
+ long_desc %{Creates a bookmark for the specified file or URL and copies its Hook URL to the clipboard.
163
160
 
164
- The copied Hook URL can be used to link to other files (use `hook link --paste FILE/URL),
165
- or to paste into another app as a link. Use the -m flag to copy a full Markdown link.
166
- }
161
+ The copied Hook URL can be used to link to other files (use `hook link --paste FILE/URL`,
162
+ or to paste into another app as a link. Use the -m flag to copy a full Markdown link.}
167
163
  arg_name 'FILE_OR_URL'
168
164
  command %i[clip cp] do |c|
169
165
  c.desc 'Copy as Markdown'
@@ -184,12 +180,10 @@ or to paste into another app as a link. Use the -m flag to copy a full Markdown
184
180
  end
185
181
 
186
182
  desc 'Get a Hook URL for the frontmost window of an app'
187
- long_desc %{
188
- Specify an application by name (without '.app') to bring that app to the foreground and create a bookmark
183
+ long_desc %(Specify an application by name (without '.app') to bring that app to the foreground and create a bookmark
189
184
  for the active document, note, task, etc., returning a Hook URL.
190
185
 
191
- Use -m to get the response as Markdown, and/or -c to copy the result directly to the clipboard.
192
- }
186
+ Use -m to get the response as Markdown, and/or -c to copy the result directly to the clipboard.)
193
187
  arg_name 'APPLICATION_NAME'
194
188
  command %i[from] do |c|
195
189
  c.desc 'Output as Markdown'
@@ -206,26 +200,25 @@ Use -m to get the response as Markdown, and/or -c to copy the result directly to
206
200
  end
207
201
 
208
202
  desc 'Remove a hook between two files/urls'
209
- long_desc %{
210
- Remove a hook between two files or URLs. If you use --all, all hooks on a given file will be removed.
203
+ long_desc %(Remove a hook between two files or URLs. If you use --all, all hooks on a given file will be removed.
211
204
 
212
- If --all isn't specified, exactly two arguments (Files/URLs) are required.
213
- }
214
- arg_name 'ITEM_1 ITEM_2'
205
+ If --all isn't specified, exactly two arguments (Files/URLs) are required.)
206
+ arg_name 'FILE_OR_URL', :multiple
215
207
  command %i[remove rm] do |c|
216
208
  c.desc 'Remove ALL links on files, requires confirmation'
217
209
  c.switch %i[a all], { negatable: false, default_value: false }
210
+ c.switch %i[f force], { negatable: false, default_value: false }
218
211
 
219
212
  c.action do |_global_options, options, args|
220
- result = hookapp.delete_hooks(args, { all: options[:a] })
213
+ result = hookapp.delete_hooks(args, { all: options[:all], force: options[:force] })
221
214
  puts result
222
215
  end
223
216
  end
224
217
 
225
218
  desc 'Clone all hooks from one file or url onto another'
226
- long_desc %{
227
- Copy all the files and urls that the first file is hooked to onto another file. Exactly two arguments (SOURCE, TARGET) required.
228
- }
219
+ long_desc 'Copy all the files and urls that the first file is hooked to onto another file.
220
+
221
+ Exactly two arguments (SOURCE, TARGET) required.'
229
222
  arg_name 'SOURCE TARGET'
230
223
  command %i[clone] do |c|
231
224
  c.action do |_global_options, _options, args|
@@ -237,39 +230,83 @@ Copy all the files and urls that the first file is hooked to onto another file.
237
230
  end
238
231
 
239
232
  desc 'Select from hooks on a file/url and open in default application'
240
- long_desc %{
241
- If the target file/URL has hooked items, a menu will be provided. Selecting one or more files
233
+ long_desc %(If the target file/URL has hooked items, a menu will be provided. Selecting one or more files
242
234
  from this menu will open the item(s) using the default application assigned to the
243
- filetype by macOS. Allows multiple selections with tab key, and type-ahead fuzzy filtering of results.
244
- }
235
+ filetype by macOS. Allows multiple selections with tab key, and type-ahead fuzzy filtering of results.)
245
236
  arg_name 'FILE_OR_URL'
246
237
  command %i[select] do |c|
247
238
  c.action do |_global_options, _options, args|
248
- exit_now!("Wrong number of arguments. One file path or url required (#{args.length} given)", 5) if args.length != 1
239
+ help_now!("Wrong number of arguments. One file path or url required (#{args.length} given)", 5) if args.length != 1
249
240
 
250
241
  hookapp.open_linked(args[0])
251
242
  end
252
243
  end
253
244
 
254
245
  desc 'Open the specified file or url in Hook GUI'
255
- long_desc %{
256
- Opens Hook.app on the specified file/URL for browsing and performing actions. Exactly one argument (File/URL) required.
257
- }
246
+ long_desc 'Opens Hook.app on the specified file/URL for browsing and performing actions.
247
+
248
+ Exactly one argument (File/URL) required.'
258
249
  arg_name 'FILE_OR_URL'
259
250
  command %i[open gui] do |c|
260
251
  c.action do |_global_options, _options, args|
261
- exit_now!("Wrong number of arguments. One file path or url required (#{args.length} given)", 5) if args.length != 1
252
+ if args.length != 1
253
+ help_now!("Wrong number of arguments. One file path
254
+ or url required (#{args.length} given)", 5)
255
+ end
262
256
 
263
257
  hookapp.open_gui(args[0])
264
258
  end
265
259
  end
266
260
 
261
+ desc 'Percent encode/decode a string'
262
+ long_desc %(Use encode or decode to apply Hook's url encoding to a string argument. Use '-' to read input from STDIN.)
263
+ arg_name 'STRING'
264
+ command :percent do |c|
265
+ c.desc 'percent encode a string'
266
+ c.arg_name 'STRING'
267
+ c.command :encode do |enc|
268
+ enc.action do |_global_options, _options, args|
269
+ if stdin
270
+ string = stdin
271
+ else
272
+ help_now!('No string provided') unless args.size.positive?
273
+
274
+ string = args.join(' ').strip
275
+ end
276
+
277
+ print hookapp.encode(string)
278
+ end
279
+ end
280
+
281
+ c.desc 'decode a percent-encoded string'
282
+ c.arg_name 'STRING'
283
+ c.command :decode do |dec|
284
+ dec.action do |_global_options, _options, args|
285
+ if stdin
286
+ string = stdin
287
+ else
288
+ help_now!('no string provided') unless args.size.positive?
289
+
290
+ string = args.join(' ').strip
291
+ end
292
+
293
+ print hookapp.decode(string)
294
+ end
295
+ end
296
+
297
+ # c.default_command :encode
298
+ end
299
+
267
300
  pre do |global, _command, _options, _args|
268
301
  # Pre logic here
269
302
  # Return true to proceed; false to abort and not call the
270
303
  # chosen command
271
304
  # Use skips_pre before a command to skip this block
272
305
  # on that command only
306
+ if !STDIN.tty?
307
+ stdin = STDIN.read.strip
308
+ end
309
+
273
310
  hookapp = HookApp.new
274
311
  true
275
312
  end