hookapp 0.0.7 → 2.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +50 -67
- data/LICENSE.md +31 -0
- data/OVERVIEW.md +80 -0
- data/README.md +305 -21
- data/Rakefile +8 -4
- data/bin/hook +185 -22
- data/buildnotes.md +59 -0
- data/hook.rdoc +81 -3
- data/hookapp.gemspec +9 -8
- data/lib/completion/hook_completion.bash +22 -0
- data/lib/completion/hook_completion.fish +31 -0
- data/lib/completion/hook_completion.zsh +22 -0
- data/lib/helpers/fuzzyfilefinder +0 -0
- data/lib/hook/hookapp.rb +508 -0
- data/lib/hook/hooker.rb +4 -344
- data/lib/hook/markdown_document_listener.rb +164 -0
- data/lib/hook/string.rb +64 -0
- data/lib/hook/version.rb +3 -1
- data/lib/hook.rb +7 -2
- data/test/helpers/hook-helpers.rb +76 -0
- data/test/hook_clip_test.rb +24 -0
- data/test/hook_clone_test.rb +30 -0
- data/test/hook_encode_test.rb +30 -0
- data/test/hook_link_test.rb +39 -0
- data/test/hook_list_test.rb +25 -0
- data/test/hook_remove_test.rb +34 -0
- data/test/hook_scripts_test.rb +21 -0
- metadata +34 -29
- data/test/default_test.rb +0 -14
- data/test/hookfiles/01.test +0 -0
- data/test/hookfiles/02.test +0 -0
- data/test/hookfiles/03.test +0 -0
- data/test/hookfiles/04.test +0 -0
- data/test/hookfiles/05.test +0 -0
- data/test/hookfiles/06.test +0 -0
- data/test/hookfiles/07.test +0 -0
- data/test/hookfiles/08.test +0 -0
- data/test/hookfiles/09.test +0 -0
- data/test/hookfiles/10.test +0 -0
- data/test/hookfiles/11.test +0 -0
- data/test/hookfiles/12.test +0 -0
data/bin/hook
CHANGED
@@ -1,25 +1,40 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require 'gli'
|
5
4
|
require 'hook'
|
5
|
+
require 'shellwords'
|
6
6
|
|
7
7
|
# Main class for GLI app
|
8
8
|
class App
|
9
9
|
extend GLI::App
|
10
10
|
|
11
11
|
program_desc 'CLI interface for Hook.app (macOS)'
|
12
|
+
program_long_desc 'Hook.app is a productivity tool for macOS <https://hookproductivity.com/>.
|
13
|
+
This gem includes a `hook` binary that allows interaction with the features of Hook.app.'
|
14
|
+
default_command 'help'
|
15
|
+
autocomplete_commands = true
|
16
|
+
synopsis_format(:terminal)
|
12
17
|
|
13
18
|
version Hook::VERSION
|
14
19
|
|
15
20
|
subcommand_option_handling :normal
|
16
21
|
arguments :strict
|
17
22
|
|
18
|
-
|
23
|
+
hookapp = nil
|
24
|
+
stdin = nil
|
19
25
|
|
20
26
|
desc 'List hooks on a file or url'
|
27
|
+
long_desc %{
|
28
|
+
Output a list of all hooks attached to given url(s) or file(s) in the specified format (default "paths").
|
29
|
+
|
30
|
+
Run `hook list` with no file/url argument to list all bookmarks.}
|
31
|
+
|
21
32
|
arg_name 'FILE_OR_URL [FILE_OR_URL...]'
|
22
33
|
command %i[list ls] do |c|
|
34
|
+
c.desc 'Generate a menu to select hook(s) for opening'
|
35
|
+
c.long_desc 'This option is a shortcut to `hook select` and overrides any other arguments.'
|
36
|
+
c.switch %i[s select]
|
37
|
+
|
23
38
|
c.desc 'Output only bookmarks with file paths (exclude e.g. emails)'
|
24
39
|
c.switch %i[f files_only], { negatable: false, default_value: false }
|
25
40
|
|
@@ -32,10 +47,13 @@ class App
|
|
32
47
|
c.flag %i[o output_format], { arg_name: 'format', default_value: 'paths' }
|
33
48
|
|
34
49
|
c.action do |_global_options, options, args|
|
35
|
-
|
36
|
-
|
50
|
+
if options[:s]
|
51
|
+
return hookapp.open_linked(args[0])
|
52
|
+
end
|
53
|
+
valid_format = hookapp.validate_format(options[:o], valid_formats)
|
54
|
+
exit_now!("Invalid output format: \"#{options[:o]}\"", 6) unless valid_format
|
37
55
|
|
38
|
-
result =
|
56
|
+
result = hookapp.linked_bookmarks(args, { files_only: options[:f],
|
39
57
|
format: valid_format,
|
40
58
|
null_separator: options[:null] })
|
41
59
|
|
@@ -43,7 +61,80 @@ class App
|
|
43
61
|
end
|
44
62
|
end
|
45
63
|
|
64
|
+
# Shell completion scripts are located in lib/completion/ and named "hook_completion" with
|
65
|
+
# the full shell name as the extension, e.g. "hook_completion.bash".
|
66
|
+
desc 'Shell completion examples'
|
67
|
+
valid_shells = %w[bash zsh fish]
|
68
|
+
long_desc %{
|
69
|
+
Output completion script example for the specified shell (#{valid_shells.join(', ')})
|
70
|
+
}
|
71
|
+
arg_name 'SHELL'
|
72
|
+
command %i[scripts] do |c|
|
73
|
+
c.action do |_global_options, _options, args|
|
74
|
+
if args.length > 1
|
75
|
+
exit_now!("Invalid number of arguments, (expected 1)", 5)
|
76
|
+
elsif args.nil? || args.empty?
|
77
|
+
exit_now!("Specify a shell (#{valid_shells.join(', ')})", 0)
|
78
|
+
else
|
79
|
+
if valid_shells.include?(args[0])
|
80
|
+
base_dir = File.expand_path(File.join(File.dirname(__FILE__), '../lib/completion'))
|
81
|
+
completion = File.join(base_dir, "hook_completion.#{args[0]}")
|
82
|
+
script = IO.read(completion)
|
83
|
+
$stdout.puts script
|
84
|
+
else
|
85
|
+
exit_now!("Invalid shell name, must be one of #{valid_shells.join(', ')}", 1)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
desc 'Search bookmarks'
|
94
|
+
long_desc %{
|
95
|
+
Search bookmark urls and names for a string and output in specified format (default "paths").
|
96
|
+
|
97
|
+
Run `hook find` with no search argument to list all bookmarks.}
|
98
|
+
arg_name 'SEARCH_STRING'
|
99
|
+
command %i[find search] do |c|
|
100
|
+
c.desc 'Output only bookmarks with file paths (exclude e.g. emails)'
|
101
|
+
c.switch %i[f files_only], { negatable: false, default_value: false }
|
102
|
+
|
103
|
+
c.desc 'Separate results with NULL separator, only applies with "paths" output for single file argument'
|
104
|
+
c.switch %i[null], { negatable: false, default_value: false }
|
105
|
+
|
106
|
+
valid_formats = %w[hooks paths markdown verbose]
|
107
|
+
fmt_list = valid_formats.map { |fmt| fmt.sub(/^(.)(.*?)$/, '(\1)\2') }.join(', ')
|
108
|
+
|
109
|
+
c.desc "Output format [#{fmt_list}]"
|
110
|
+
c.flag %i[o output_format], { arg_name: 'format', default_value: 'paths' }
|
111
|
+
|
112
|
+
c.desc "Search only bookmark names"
|
113
|
+
c.switch %i[n names_only], { negatable: false, default_value: false }
|
114
|
+
|
115
|
+
c.action do |_global_options, options, args|
|
116
|
+
valid_format = hookapp.validate_format(options[:o], valid_formats)
|
117
|
+
exit_now!("Invalid output format: \"#{options[:o]}\"", 6) unless valid_format
|
118
|
+
|
119
|
+
result = hookapp.search_bookmarks(args.join(" "), { files_only: options[:f],
|
120
|
+
format: valid_format,
|
121
|
+
null_separator: options[:null],
|
122
|
+
names_only: options[:n] })
|
123
|
+
|
124
|
+
puts result
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
46
128
|
desc 'Create bidirectional hooks between two or more files/urls'
|
129
|
+
long_desc %{
|
130
|
+
If two files/urls are provided, links will be bi-directional.
|
131
|
+
If three or more are provided, `link` defaults to creating bi-directional
|
132
|
+
links between each file and the last file in the list. Use `-a` to create
|
133
|
+
bi-directional links between every file in the list.
|
134
|
+
|
135
|
+
If using `--paste`, the URL/hook link in the clipboard will be used as one argument,
|
136
|
+
to be combined with one or more file/url arguments.
|
137
|
+
}
|
47
138
|
arg_name 'SOURCE [SOURCE...] TARGET'
|
48
139
|
command %i[link ln] do |c|
|
49
140
|
c.desc 'Link every listed file or url to every other'
|
@@ -59,17 +150,23 @@ class App
|
|
59
150
|
args.push(clipboard) if clipboard
|
60
151
|
end
|
61
152
|
if args.length < 2
|
62
|
-
|
153
|
+
exit_now!('Wrong number of arguments. At least 2 files must be specified, or one file with --paste', 5)
|
63
154
|
end
|
64
155
|
if options[:a]
|
65
|
-
puts
|
156
|
+
puts hookapp.link_all(args)
|
66
157
|
else
|
67
|
-
puts
|
158
|
+
puts hookapp.link_files(args)
|
68
159
|
end
|
69
160
|
end
|
70
161
|
end
|
71
162
|
|
72
163
|
desc 'Copy Hook URL for file/url to clipboard'
|
164
|
+
long_desc %{
|
165
|
+
Creates a bookmark for the specified file or URL and copies its Hook URL to the clipboard.
|
166
|
+
|
167
|
+
The copied Hook URL can be used to link to other files (use `hook link --paste FILE/URL),
|
168
|
+
or to paste into another app as a link. Use the -m flag to copy a full Markdown link.
|
169
|
+
}
|
73
170
|
arg_name 'FILE_OR_URL'
|
74
171
|
command %i[clip cp] do |c|
|
75
172
|
c.desc 'Copy as Markdown'
|
@@ -79,17 +176,23 @@ class App
|
|
79
176
|
c.flag %i[a app], { arg_name: 'APP_NAME' }
|
80
177
|
|
81
178
|
c.action do |_global_options, options, args|
|
82
|
-
|
179
|
+
exit_now!('Wrong number of arguments. Requires a path/url or -a APP_NAME', 5) if args.length != 1 && !options[:a]
|
83
180
|
|
84
181
|
if options[:a]
|
85
|
-
puts
|
182
|
+
puts hookapp.bookmark_from_app(options[:a], { copy: true, markdown: options[:m] })
|
86
183
|
else
|
87
|
-
puts
|
184
|
+
puts hookapp.clip_bookmark(args[0], { markdown: options[:m] })
|
88
185
|
end
|
89
186
|
end
|
90
187
|
end
|
91
188
|
|
92
189
|
desc 'Get a Hook URL for the frontmost window of an app'
|
190
|
+
long_desc %{
|
191
|
+
Specify an application by name (without '.app') to bring that app to the foreground and create a bookmark
|
192
|
+
for the active document, note, task, etc., returning a Hook URL.
|
193
|
+
|
194
|
+
Use -m to get the response as Markdown, and/or -c to copy the result directly to the clipboard.
|
195
|
+
}
|
93
196
|
arg_name 'APPLICATION_NAME'
|
94
197
|
command %i[from] do |c|
|
95
198
|
c.desc 'Output as Markdown'
|
@@ -99,62 +202,122 @@ class App
|
|
99
202
|
c.switch %i[c copy], { negatable: false, default_value: false }
|
100
203
|
|
101
204
|
c.action do |_global_options, options, args|
|
102
|
-
|
205
|
+
exit_now!("Wrong number of arguments (1 expected, #{args.length} given)", 5) if args.length != 1
|
103
206
|
|
104
|
-
puts
|
207
|
+
puts hookapp.bookmark_from_app(args[0], { copy: options[:c], markdown: options[:m] })
|
105
208
|
end
|
106
209
|
end
|
107
210
|
|
108
211
|
desc 'Remove a hook between two files/urls'
|
212
|
+
long_desc %{
|
213
|
+
Remove a hook between two files or URLs. If you use --all, all hooks on a given file will be removed.
|
214
|
+
|
215
|
+
If --all isn't specified, exactly two arguments (Files/URLs) are required.
|
216
|
+
}
|
109
217
|
arg_name 'ITEM_1 ITEM_2'
|
110
218
|
command %i[remove rm] do |c|
|
111
219
|
c.desc 'Remove ALL links on files, requires confirmation'
|
112
|
-
c.switch %i[a all]
|
220
|
+
c.switch %i[a all], { negatable: false, default_value: false }
|
221
|
+
c.switch %i[f force], { negatable: false, default_value: false }
|
113
222
|
|
114
223
|
c.action do |_global_options, options, args|
|
115
|
-
result =
|
224
|
+
result = hookapp.delete_hooks(args, { all: options[:all], force: options[:force] })
|
116
225
|
puts result
|
117
226
|
end
|
118
227
|
end
|
119
228
|
|
120
229
|
desc 'Clone all hooks from one file or url onto another'
|
230
|
+
long_desc %{
|
231
|
+
Copy all the files and urls that the first file is hooked to onto another file. Exactly two arguments (SOURCE, TARGET) required.
|
232
|
+
}
|
121
233
|
arg_name 'SOURCE TARGET'
|
122
234
|
command %i[clone] do |c|
|
123
235
|
c.action do |_global_options, _options, args|
|
124
|
-
|
236
|
+
exit_now!("Wrong number of arguments. Two file paths or urls required (#{args.length} given)", 5) if args.length != 2
|
125
237
|
|
126
|
-
result =
|
238
|
+
result = hookapp.clone_hooks(args)
|
127
239
|
puts result
|
128
240
|
end
|
129
241
|
end
|
130
242
|
|
131
243
|
desc 'Select from hooks on a file/url and open in default application'
|
244
|
+
long_desc %{
|
245
|
+
If the target file/URL has hooked items, a menu will be provided. Selecting one or more files
|
246
|
+
from this menu will open the item(s) using the default application assigned to the
|
247
|
+
filetype by macOS. Allows multiple selections with tab key, and type-ahead fuzzy filtering of results.
|
248
|
+
}
|
132
249
|
arg_name 'FILE_OR_URL'
|
133
250
|
command %i[select] do |c|
|
134
251
|
c.action do |_global_options, _options, args|
|
135
|
-
|
252
|
+
exit_now!("Wrong number of arguments. One file path or url required (#{args.length} given)", 5) if args.length != 1
|
136
253
|
|
137
|
-
|
254
|
+
hookapp.open_linked(args[0])
|
138
255
|
end
|
139
256
|
end
|
140
257
|
|
141
258
|
desc 'Open the specified file or url in Hook GUI'
|
259
|
+
long_desc %{
|
260
|
+
Opens Hook.app on the specified file/URL for browsing and performing actions. Exactly one argument (File/URL) required.
|
261
|
+
}
|
142
262
|
arg_name 'FILE_OR_URL'
|
143
263
|
command %i[open gui] do |c|
|
144
264
|
c.action do |_global_options, _options, args|
|
145
|
-
|
265
|
+
exit_now!("Wrong number of arguments. One file path or url required (#{args.length} given)", 5) if args.length != 1
|
146
266
|
|
147
|
-
|
267
|
+
hookapp.open_gui(args[0])
|
148
268
|
end
|
149
269
|
end
|
150
270
|
|
271
|
+
desc 'Percent encode/decode a string'
|
272
|
+
long_desc %{Use encode or decode to apply Hook's url encoding to a string argument. Use '-' to read input from STDIN.}
|
273
|
+
arg_name 'STRING'
|
274
|
+
command :percent do |c|
|
275
|
+
c.desc 'percent encode a string'
|
276
|
+
c.arg_name 'STRING'
|
277
|
+
c.command :encode do |enc|
|
278
|
+
enc.action do |_global_options, _options, args|
|
279
|
+
if stdin
|
280
|
+
string = stdin
|
281
|
+
else
|
282
|
+
exit_now!('no string provided') unless args.size.positive?
|
283
|
+
|
284
|
+
string = args.join(' ').strip
|
285
|
+
end
|
286
|
+
|
287
|
+
print hookapp.encode(string)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
c.desc 'decode a percent-encoded string'
|
292
|
+
c.arg_name 'STRING'
|
293
|
+
c.command :decode do |dec|
|
294
|
+
dec.action do |_global_options, _options, args|
|
295
|
+
if stdin
|
296
|
+
string = stdin
|
297
|
+
else
|
298
|
+
exit_now! ('no string provided') unless args.size.positive?
|
299
|
+
|
300
|
+
string = args.join(' ').strip
|
301
|
+
end
|
302
|
+
|
303
|
+
print hookapp.decode(string)
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
# c.default_command :encode
|
308
|
+
end
|
309
|
+
|
151
310
|
pre do |global, _command, _options, _args|
|
152
311
|
# Pre logic here
|
153
312
|
# Return true to proceed; false to abort and not call the
|
154
313
|
# chosen command
|
155
314
|
# Use skips_pre before a command to skip this block
|
156
315
|
# on that command only
|
157
|
-
|
316
|
+
if !STDIN.tty?
|
317
|
+
stdin = STDIN.read.strip
|
318
|
+
end
|
319
|
+
|
320
|
+
hookapp = HookApp.new
|
158
321
|
true
|
159
322
|
end
|
160
323
|
|
data/buildnotes.md
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# hookapp
|
2
|
+
|
3
|
+
Hook.app CLI
|
4
|
+
|
5
|
+
## Editing
|
6
|
+
|
7
|
+
Main executable is located in `bin/hook`. All commands are defined here.
|
8
|
+
|
9
|
+
Helpers and main classes are in `lib/`.
|
10
|
+
|
11
|
+
@run(subl -p hookapp.sublime-project)
|
12
|
+
|
13
|
+
## Building the Gem
|
14
|
+
|
15
|
+
@run(rake clobber rdoc package)
|
16
|
+
|
17
|
+
## Deploy
|
18
|
+
|
19
|
+
1. Bump version
|
20
|
+
2. Commit and push to GitHub
|
21
|
+
3. See Updating the Docs
|
22
|
+
4. Package the gem (See Building the Gem)
|
23
|
+
5. Push the gem with `gem push pkg/hookapp-[VERSION].gem`
|
24
|
+
|
25
|
+
## Updating the Docs
|
26
|
+
|
27
|
+
Update the docs with `bundle exec bin/hook _doc --format=markdown` and `bundle exec bin/hook _doc --format=rdoc`, then run `rake rerdoc`
|
28
|
+
|
29
|
+
@run(bundle exec bin/hook _doc --format=rdoc && bundle exec bin/hook _doc --format=markdown && rake rerdoc)
|
30
|
+
|
31
|
+
## Test
|
32
|
+
|
33
|
+
Run all tests using `rake test`.
|
34
|
+
|
35
|
+
Run verbose using `rake test TESTOPT="-v"`
|
36
|
+
|
37
|
+
Run a single test using `rake test TEST=test/TEST_FILE.rb`
|
38
|
+
|
39
|
+
This howzit task accepts an optional argument pointing to a specific test (just the test part of the filename, e.g. archive runs `test/doing_archive_test.rb`).
|
40
|
+
|
41
|
+
`howzit -r test -- archive` (or `bld test archive` with the Fish function)
|
42
|
+
|
43
|
+
```run
|
44
|
+
#!/bin/bash
|
45
|
+
if [[ -n $1 ]]; then
|
46
|
+
rake test TESTOPT="-v" TEST=test/hook_$1_test.rb
|
47
|
+
if [[ $? != 0 ]]; then
|
48
|
+
echo "Available tests"
|
49
|
+
echo -e "\033[1;32;40m"
|
50
|
+
FILES="test/hook_*_test.rb"
|
51
|
+
for file in $FILES; do
|
52
|
+
echo $(basename $file ".rb") | sed -E 's/hook_(.*)_test/- \1/'
|
53
|
+
done
|
54
|
+
echo -e "\033[0m"
|
55
|
+
fi
|
56
|
+
else
|
57
|
+
rake test TESTOPT="-v"
|
58
|
+
fi
|
59
|
+
```
|
data/hook.rdoc
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
== hook - CLI interface for Hook.app (macOS)
|
2
2
|
|
3
|
-
|
3
|
+
Hook.app is a productivity tool for macOS <https://hookproductivity.com/>.
|
4
|
+
This gem includes a `hook` binary that allows interaction with the features of Hook.app.
|
5
|
+
|
6
|
+
v2.0.7
|
4
7
|
|
5
8
|
=== Global Options
|
6
9
|
=== --help
|
@@ -17,7 +20,10 @@ Display the program version
|
|
17
20
|
==== Command: <tt>clip|cp FILE_OR_URL</tt>
|
18
21
|
Copy Hook URL for file/url to clipboard
|
19
22
|
|
23
|
+
Creates a bookmark for the specified file or URL and copies its Hook URL to the clipboard.
|
20
24
|
|
25
|
+
The copied Hook URL can be used to link to other files (use `hook link --paste FILE/URL),
|
26
|
+
or to paste into another app as a link. Use the -m flag to copy a full Markdown link.
|
21
27
|
===== Options
|
22
28
|
===== -a|--app APP_NAME
|
23
29
|
|
@@ -34,11 +40,43 @@ Copy as Markdown
|
|
34
40
|
==== Command: <tt>clone SOURCE TARGET</tt>
|
35
41
|
Clone all hooks from one file or url onto another
|
36
42
|
|
43
|
+
Copy all the files and urls that the first file is hooked to onto another file. Exactly two arguments (SOURCE, TARGET) required.
|
44
|
+
==== Command: <tt>find|search SEARCH_STRING</tt>
|
45
|
+
Search bookmarks
|
46
|
+
|
47
|
+
Search bookmark urls and names for a string and output in specified format (default "paths").
|
48
|
+
|
49
|
+
Run `hook find` with no search argument to list all bookmarks.
|
50
|
+
===== Options
|
51
|
+
===== -o|--output_format format
|
52
|
+
|
53
|
+
Output format [(h)ooks, (p)aths, (m)arkdown, (v)erbose]
|
54
|
+
|
55
|
+
[Default Value] paths
|
56
|
+
|
57
|
+
|
58
|
+
===== -f|--files_only
|
59
|
+
Output only bookmarks with file paths (exclude e.g. emails)
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
===== -n|--names_only
|
64
|
+
Search only bookmark names
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
===== --null
|
69
|
+
Separate results with NULL separator, only applies with "paths" output for single file argument
|
70
|
+
|
71
|
+
|
37
72
|
|
38
73
|
==== Command: <tt>from APPLICATION_NAME</tt>
|
39
74
|
Get a Hook URL for the frontmost window of an app
|
40
75
|
|
76
|
+
Specify an application by name (without '.app') to bring that app to the foreground and create a bookmark
|
77
|
+
for the active document, note, task, etc., returning a Hook URL.
|
41
78
|
|
79
|
+
Use -m to get the response as Markdown, and/or -c to copy the result directly to the clipboard.
|
42
80
|
===== Options
|
43
81
|
===== -c|--copy
|
44
82
|
Copy to clipboard
|
@@ -63,7 +101,13 @@ List commands one per line, to assist with shell completion
|
|
63
101
|
==== Command: <tt>link|ln SOURCE [SOURCE...] TARGET</tt>
|
64
102
|
Create bidirectional hooks between two or more files/urls
|
65
103
|
|
104
|
+
If two files/urls are provided, links will be bi-directional.
|
105
|
+
If three or more are provided, `link` defaults to creating bi-directional
|
106
|
+
links between each file and the last file in the list. Use `-a` to create
|
107
|
+
bi-directional links between every file in the list.
|
66
108
|
|
109
|
+
If using `--paste`, the URL/hook link in the clipboard will be used as one argument,
|
110
|
+
to be combined with one or more file/url arguments.
|
67
111
|
===== Options
|
68
112
|
===== -a|--all
|
69
113
|
Link every listed file or url to every other
|
@@ -78,7 +122,9 @@ Paste URL from clipboard
|
|
78
122
|
==== Command: <tt>list|ls FILE_OR_URL [FILE_OR_URL...]</tt>
|
79
123
|
List hooks on a file or url
|
80
124
|
|
125
|
+
Output a list of all hooks attached to given url(s) or file(s) in the specified format (default "paths").
|
81
126
|
|
127
|
+
Run `hook list` with no file/url argument to list all bookmarks.
|
82
128
|
===== Options
|
83
129
|
===== -o|--output_format format
|
84
130
|
|
@@ -97,21 +143,53 @@ Separate results with NULL separator, only applies with "paths" output for singl
|
|
97
143
|
|
98
144
|
|
99
145
|
|
146
|
+
===== -s|--[no-]select
|
147
|
+
Generate a menu to select hook(s) for opening
|
148
|
+
|
149
|
+
This option is a shortcut to `hook select` and overrides any other arguments.
|
150
|
+
|
100
151
|
==== Command: <tt>open|gui FILE_OR_URL</tt>
|
101
152
|
Open the specified file or url in Hook GUI
|
102
153
|
|
154
|
+
Opens Hook.app on the specified file/URL for browsing and performing actions. Exactly one argument (File/URL) required.
|
155
|
+
==== Command: <tt>percent STRING</tt>
|
156
|
+
Percent encode/decode a string
|
157
|
+
|
158
|
+
Use encode or decode to apply Hook's url encoding to a string argument. Use '-' to read input from STDIN.
|
159
|
+
===== Commands
|
160
|
+
====== Command: <tt>decode STRING</tt>
|
161
|
+
decode a percent-encoded string
|
162
|
+
|
163
|
+
|
164
|
+
====== Command: <tt>encode STRING</tt>
|
165
|
+
percent encode a string
|
166
|
+
|
103
167
|
|
104
168
|
==== Command: <tt>remove|rm ITEM_1 ITEM_2</tt>
|
105
169
|
Remove a hook between two files/urls
|
106
170
|
|
171
|
+
Remove a hook between two files or URLs. If you use --all, all hooks on a given file will be removed.
|
107
172
|
|
173
|
+
If --all isn't specified, exactly two arguments (Files/URLs) are required.
|
108
174
|
===== Options
|
109
|
-
===== -a|--
|
175
|
+
===== -a|--all
|
110
176
|
Remove ALL links on files, requires confirmation
|
111
177
|
|
112
178
|
|
113
179
|
|
180
|
+
===== -f|--force
|
181
|
+
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
==== Command: <tt>scripts SHELL</tt>
|
186
|
+
Shell completion examples
|
187
|
+
|
188
|
+
Output completion script example for the specified shell (bash, zsh, fish)
|
114
189
|
==== Command: <tt>select FILE_OR_URL</tt>
|
115
190
|
Select from hooks on a file/url and open in default application
|
116
191
|
|
117
|
-
|
192
|
+
If the target file/URL has hooked items, a menu will be provided. Selecting one or more files
|
193
|
+
from this menu will open the item(s) using the default application assigned to the
|
194
|
+
filetype by macOS. Allows multiple selections with tab key, and type-ahead fuzzy filtering of results.
|
195
|
+
[Default Command] help
|
data/hookapp.gemspec
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Ensure we require the local version and not one we might have installed already
|
2
4
|
require File.join([File.dirname(__FILE__), 'lib', 'hook', 'version.rb'])
|
3
|
-
|
5
|
+
Gem::Specification.new do |s|
|
4
6
|
s.name = 'hookapp'
|
5
7
|
s.version = Hook::VERSION
|
6
8
|
s.author = 'Brett Terpstra'
|
@@ -8,15 +10,14 @@ spec = Gem::Specification.new do |s|
|
|
8
10
|
s.homepage = 'https://brettterpstra.com'
|
9
11
|
s.platform = Gem::Platform::RUBY
|
10
12
|
s.summary = 'A CLI for Hook.app (macOS)'
|
11
|
-
s.files = `git ls-files`.split("
|
12
|
-
")
|
13
|
+
s.files = `git ls-files`.split("\n")
|
13
14
|
s.require_paths << 'lib'
|
14
|
-
s.extra_rdoc_files = ['README.rdoc','hook.rdoc']
|
15
|
+
s.extra_rdoc_files = ['README.rdoc', 'hook.rdoc']
|
15
16
|
s.rdoc_options << '--title' << 'hook' << '--main' << 'README.rdoc' << '-ri'
|
16
17
|
s.bindir = 'bin'
|
17
18
|
s.executables << 'hook'
|
18
|
-
s.add_development_dependency('
|
19
|
-
s.add_development_dependency('
|
20
|
-
s.add_development_dependency('
|
21
|
-
s.add_runtime_dependency('gli','2.
|
19
|
+
s.add_development_dependency('aruba', '~> 0.14.14')
|
20
|
+
s.add_development_dependency('rake', '~> 13.0.1')
|
21
|
+
s.add_development_dependency('rdoc', '~> 6.3.2')
|
22
|
+
s.add_runtime_dependency('gli', '~> 2.20.1')
|
22
23
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Source this script from ~/.bash_profile
|
2
|
+
_hook_targets()
|
3
|
+
{
|
4
|
+
local cmds cur ff
|
5
|
+
if (($COMP_CWORD == 1))
|
6
|
+
then
|
7
|
+
cur="${COMP_WORDS[1]}"
|
8
|
+
cmds="$(hook help -c)"
|
9
|
+
COMPREPLY=($(compgen -W "$cmds" -- "$cur"))
|
10
|
+
COMPREPLY=( "${COMPREPLY[@]/%/ }" )
|
11
|
+
else
|
12
|
+
# get all matching files and directories
|
13
|
+
COMPREPLY=($(compgen -f -- "${COMP_WORDS[$COMP_CWORD]}"))
|
14
|
+
|
15
|
+
for ((ff=0; ff<${#COMPREPLY[@]}; ff++)); do
|
16
|
+
[[ -d ${COMPREPLY[$ff]} ]] && COMPREPLY[$ff]+='/'
|
17
|
+
[[ -f ${COMPREPLY[$ff]} ]] && COMPREPLY[$ff]+=' '
|
18
|
+
done
|
19
|
+
fi
|
20
|
+
}
|
21
|
+
|
22
|
+
complete -o bashdefault -o default -o nospace -F _hook_targets hook
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Save this script in ~/.config/fish/completions/hook.fish
|
2
|
+
function __fish_hook_needs_command
|
3
|
+
# Figure out if the current invocation already has a command.
|
4
|
+
|
5
|
+
set -l opts h-help v-version
|
6
|
+
set cmd (commandline -opc)
|
7
|
+
set -e cmd[1]
|
8
|
+
argparse -s $opts -- $cmd 2>/dev/null
|
9
|
+
or return 0
|
10
|
+
# These flags function as commands, effectively.
|
11
|
+
if set -q argv[1]
|
12
|
+
# Also print the command, so this can be used to figure out what it is.
|
13
|
+
echo $argv[1]
|
14
|
+
return 1
|
15
|
+
end
|
16
|
+
return 0
|
17
|
+
end
|
18
|
+
|
19
|
+
function __fish_hook_using_command
|
20
|
+
set -l cmd (__fish_hook_needs_command)
|
21
|
+
test -z "$cmd"
|
22
|
+
and return 1
|
23
|
+
contains -- $cmd $argv
|
24
|
+
and return 0
|
25
|
+
end
|
26
|
+
|
27
|
+
function __fish_hook_subcommands
|
28
|
+
hook help -c
|
29
|
+
end
|
30
|
+
|
31
|
+
complete -xc hook -n '__fish_hook_needs_command' -a '(__fish_hook_subcommands)'
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Source this script from ~/.zshrc
|
2
|
+
_hook_targets()
|
3
|
+
{
|
4
|
+
local cmds cur ff
|
5
|
+
if (($COMP_CWORD == 1))
|
6
|
+
then
|
7
|
+
cur="${COMP_WORDS[1]}"
|
8
|
+
cmds="$(hook help -c)"
|
9
|
+
COMPREPLY=($(compgen -W "$cmds" -- "$cur"))
|
10
|
+
COMPREPLY=( "${COMPREPLY[@]/%/ }" )
|
11
|
+
else
|
12
|
+
# get all matching files and directories
|
13
|
+
COMPREPLY=($(compgen -f -- "${COMP_WORDS[$COMP_CWORD]}"))
|
14
|
+
|
15
|
+
for ((ff=0; ff<${#COMPREPLY[@]}; ff++)); do
|
16
|
+
[[ -d ${COMPREPLY[$ff]} ]] && COMPREPLY[$ff]+='/'
|
17
|
+
[[ -f ${COMPREPLY[$ff]} ]] && COMPREPLY[$ff]+=' '
|
18
|
+
done
|
19
|
+
fi
|
20
|
+
}
|
21
|
+
|
22
|
+
complete -o bashdefault -o default -o nospace -F _hook_targets hook
|
Binary file
|