hookapp 0.0.7 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
- hooker = nil
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
- valid_format = hooker.validate_format(options[:o], valid_formats)
36
- raise 'Invalid output format' unless valid_format
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 = hooker.linked_bookmarks(args, { files_only: options[:f],
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
- raise 'At least 2 files must be specified, or one file with --paste'
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 hooker.link_all(args)
156
+ puts hookapp.link_all(args)
66
157
  else
67
- puts hooker.link_files(args)
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
- raise 'Wrong number of arguments. Requires a path/url or -a APP_NAME' if args.length != 1 && !options[:a]
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 hooker.bookmark_from_app(options[:a], { copy: true, markdown: options[:m] })
182
+ puts hookapp.bookmark_from_app(options[:a], { copy: true, markdown: options[:m] })
86
183
  else
87
- puts hooker.clip_bookmark(args[0], { markdown: options[:m] })
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
- raise "Wrong number of arguments (1 expected, #{args.length} given)" if args.length != 1
205
+ exit_now!("Wrong number of arguments (1 expected, #{args.length} given)", 5) if args.length != 1
103
206
 
104
- puts hooker.bookmark_from_app(args[0], { copy: options[:c], markdown: options[:m] })
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 = hooker.delete_hooks(args, { all: options[:r] })
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
- raise "Wrong number of arguments. Two file paths or urls required (#{args.length} given)" if args.length != 2
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 = hooker.clone_hooks(args)
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
- raise "Wrong number of arguments. One file path or url required (#{args.length} given)" if args.length != 1
252
+ exit_now!("Wrong number of arguments. One file path or url required (#{args.length} given)", 5) if args.length != 1
136
253
 
137
- hooker.open_linked(args[0])
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
- raise "Wrong number of arguments. One file path or url required (#{args.length} given)" if args.length != 1
265
+ exit_now!("Wrong number of arguments. One file path or url required (#{args.length} given)", 5) if args.length != 1
146
266
 
147
- hooker.open_gui(args[0])
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
- hooker = Hooker.new(global)
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
- v0.0.5
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|--[no-]all
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
- spec = Gem::Specification.new do |s|
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('rake','~> 13.0.1')
19
- s.add_development_dependency('rdoc','~> 6.1.2')
20
- s.add_development_dependency('aruba','~> 0.14.14')
21
- s.add_runtime_dependency('gli','2.19.0')
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