howzit 2.1.16 → 2.1.21

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3bf24c1aae4ef114065b9138801a83f07777932a38a5894b4ae63be3c02960f4
4
- data.tar.gz: 18a7bf1b8eb988b204479531618219fba11d49a70248cde01a1857b6bd9205ae
3
+ metadata.gz: a6cac91a8b188ff256fa863ad94e134e820ed2aa2eb766a10fea38ee745de750
4
+ data.tar.gz: 90799282be7a348b595df19a5c09850db8ac4d653bd81063d49f1830e6cb0761
5
5
  SHA512:
6
- metadata.gz: 5b43837936520805796c48529de8a88af3ceeaa455259e0ffbba351f4d2bc98706c1381974c072953438db8a38a215d9b817907783f62fd0ac24301e9d05fe94
7
- data.tar.gz: 9c2afbc1c49a902e65e9818ad6f8ce9df1b724c149307fe2d718abd1b9ef61405f1340403fde901c3cb8b67d877db793cedaaac752b2b974ba1881bde0efb21c
6
+ metadata.gz: 6b98ee5eb923878803f0268080ad1d56f4f9aed7279e6dcb245f13659e3a947348212741b3409861aacff145bc5abb19af7dd9810a854626e6b5067fc33ad954
7
+ data.tar.gz: 9be180170d36f0f415e3f0977b5b951368f7498fe630cd4f900626bf852c5678b860cea8ac63472dec0c03c41531cf70eb58a5002298a5ed9f5661204aa6d7cb
data/CHANGELOG.md CHANGED
@@ -1,3 +1,77 @@
1
+ ### 2.1.21
2
+
3
+ 2025-12-13 05:03
4
+
5
+ #### NEW
6
+
7
+ - Prefer exact whole-word topic matches over fuzzy matches
8
+ - Display run summary after executing tasks
9
+
10
+ #### IMPROVED
11
+
12
+ - Topic matching now handles colons/commas in topic titles
13
+ - Smart splitting of multiple topics preserves separators in titles
14
+ - Single match from choose now auto-selects without menu
15
+ - Combined output from multiple topics paginated together
16
+ - Menu prompt shows the search term being matched
17
+
18
+ #### FIXED
19
+
20
+ - String uncolor deleting characters
21
+ - Broken pipe error when quitting pager early
22
+
23
+ ### 2.1.20
24
+
25
+ 2025-12-13 05:01
26
+
27
+ #### NEW
28
+
29
+ - Prefer exact whole-word topic matches over fuzzy matches
30
+ - Display run summary after executing tasks
31
+
32
+ #### IMPROVED
33
+
34
+ - Topic matching now handles colons/commas in topic titles
35
+ - Smart splitting of multiple topics preserves separators in titles
36
+ - Single match from choose now auto-selects without menu
37
+ - Combined output from multiple topics paginated together
38
+ - Menu prompt shows the search term being matched
39
+
40
+ #### FIXED
41
+
42
+ - String uncolor deleting characters
43
+ - Broken pipe error when quitting pager early
44
+
45
+ ### 2.1.19
46
+
47
+ 2025-12-13 05:01
48
+
49
+ #### NEW
50
+
51
+ - Prefer exact whole-word topic matches over fuzzy matches
52
+ - Display run summary after executing tasks
53
+
54
+ #### IMPROVED
55
+
56
+ - Topic matching now handles colons/commas in topic titles
57
+ - Smart splitting of multiple topics preserves separators in titles
58
+ - Single match from choose now auto-selects without menu
59
+ - Combined output from multiple topics paginated together
60
+ - Menu prompt shows the search term being matched
61
+
62
+ #### FIXED
63
+
64
+ - String uncolor deleting characters
65
+ - Broken pipe error when quitting pager early
66
+
67
+ ### 2.1.18
68
+
69
+ 2025-01-01 09:53
70
+
71
+ #### IMPROVED
72
+
73
+ - Include named arguments when listing runnable topics
74
+
1
75
  ### 2.1.16
2
76
 
3
77
  2024-08-13 10:59
data/bin/howzit CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- $LOAD_PATH.unshift File.join(__dir__, '..', 'lib')
5
- require 'howzit'
4
+ $LOAD_PATH.unshift File.join(__dir__, "..", "lib")
5
+ require "howzit"
6
6
 
7
7
  Howzit::Color.coloring = $stdout.isatty
8
8
 
@@ -13,127 +13,127 @@ Howzit.named_arguments = {}
13
13
 
14
14
  OptionParser.new do |opts|
15
15
  opts.banner = "Usage: #{File.basename(__FILE__)} [OPTIONS] [TOPIC]"
16
- opts.separator ''
17
- opts.separator 'Show build notes for the current project (buildnotes.md).
18
- Include a topic name to see just that topic, or no argument to display all.'
19
- opts.separator ''
20
- opts.separator 'Options:'
16
+ opts.separator ""
17
+ opts.separator "Show build notes for the current project (buildnotes.md).
18
+ Include a topic name to see just that topic, or no argument to display all."
19
+ opts.separator ""
20
+ opts.separator "Options:"
21
21
 
22
22
  opts.separator " Behavior:\n\n" #=================================================================== BEHAVIOR
23
23
 
24
- opts.on('--ask', 'Request confirmation for all tasks when running a topic') { Howzit.options[:ask] = true }
24
+ opts.on("--ask", "Request confirmation for all tasks when running a topic") { Howzit.options[:ask] = true }
25
25
 
26
- opts.on('--default', 'Answer all prompts with default response') do
27
- raise '--default cannot be used with --yes or --no' if Howzit.options[:yes] || Howzit.options[:no]
26
+ opts.on("--default", "Answer all prompts with default response") do
27
+ raise "--default cannot be used with --yes or --no" if Howzit.options[:yes] || Howzit.options[:no]
28
28
 
29
29
  Howzit.options[:default] = true
30
30
  end
31
31
 
32
- opts.on('-f', '--force', 'Continue executing after an error') { Howzit.options[:force] = true }
32
+ opts.on("-f", "--force", "Continue executing after an error") { Howzit.options[:force] = true }
33
33
 
34
- opts.on('-m', '--matching TYPE', MATCHING_OPTIONS,
35
- 'Topics matching type', "(#{MATCHING_OPTIONS.join(', ')})") do |c|
34
+ opts.on("-m", "--matching TYPE", MATCHING_OPTIONS,
35
+ "Topics matching type", "(#{MATCHING_OPTIONS.join(", ").sub(/#{Howzit.options[:matching]}/, "*#{Howzit.options[:matching]}")})") do |c|
36
36
  Howzit.options[:matching] = c
37
37
  end
38
38
 
39
- opts.on('--multiple TYPE', MULTIPLE_OPTIONS,
40
- 'Multiple result handling', "(#{MULTIPLE_OPTIONS.join(', ')}, default choose)") do |c|
39
+ opts.on("--multiple TYPE", MULTIPLE_OPTIONS,
40
+ "Multiple result handling", "(#{MULTIPLE_OPTIONS.join(", ").sub(/#{Howzit.options[:multiple_matches]}/, "*#{Howzit.options[:multiple_matches]}")}, default choose)") do |c|
41
41
  Howzit.options[:multiple_matches] = c.to_sym
42
42
  end
43
43
 
44
- opts.on('-u', '--[no-]upstream', 'Traverse up parent directories for additional build notes') do |p|
44
+ opts.on("-u", "--[no-]upstream", "Traverse up parent directories for additional build notes") do |p|
45
45
  Howzit.options[:include_upstream] = p
46
46
  end
47
47
 
48
- opts.on('-y', '--yes', 'Answer yes to all prompts') do
49
- raise '--default cannot be used with --yes' if Howzit.options[:default]
48
+ opts.on("-y", "--yes", "Answer yes to all prompts") do
49
+ raise "--default cannot be used with --yes" if Howzit.options[:default]
50
50
 
51
51
  Howzit.options[:yes] = true
52
52
  end
53
53
 
54
- opts.on('-n', '--no', 'Answer no to all prompts') do
55
- raise '--default cannot be used with --no' if Howzit.options[:default]
54
+ opts.on("-n", "--no", "Answer no to all prompts") do
55
+ raise "--default cannot be used with --no" if Howzit.options[:default]
56
56
 
57
57
  Howzit.options[:no] = true
58
58
  end
59
59
 
60
60
  opts.separator "\n Listing:\n\n" #=================================================================== LISTING
61
61
 
62
- opts.on('-L', '--list-completions', 'List topics (completion-compatible)') do
62
+ opts.on("-L", "--list-completions", "List topics (completion-compatible)") do
63
63
  Howzit.options[:list_topics] = true
64
64
  Howzit.options[:list_topic_titles] = true
65
65
  end
66
66
 
67
- opts.on('-l', '--list', 'List available topics') do
67
+ opts.on("-l", "--list", "List available topics") do
68
68
  Howzit.options[:list_topics] = true
69
69
  end
70
70
 
71
- opts.on('-R', '--list-runnable [PATTERN]', 'List topics containing @ directives (verbose)') do |pat|
71
+ opts.on("-R", "--list-runnable [PATTERN]", "List topics containing @ directives (verbose)") do |pat|
72
72
  Howzit.options[:for_topic] = pat
73
73
  Howzit.options[:list_runnable] = true
74
74
  end
75
75
 
76
- opts.on('-T', '--task-list', 'List topics containing @ directives (completion-compatible)') do
76
+ opts.on("-T", "--task-list", "List topics containing @ directives (completion-compatible)") do
77
77
  Howzit.options[:list_runnable] = true
78
78
  Howzit.options[:list_runnable_titles] = true
79
79
  end
80
80
 
81
- opts.on('--templates', 'List available templates') do
81
+ opts.on("--templates", "List available templates") do
82
82
  out = []
83
83
  Dir.chdir(Howzit.config.template_folder)
84
- Dir.glob('*.md').each do |file|
85
- template = File.basename(file, '.md')
84
+ Dir.glob("*.md").each do |file|
85
+ template = File.basename(file, ".md")
86
86
  out.push(Howzit::Color.template("{Mk}template:{Yk}#{template}{x}"))
87
- out.push(Howzit::Color.template('{bk}[{bl}tasks{bk}]──────────────────────────────────────┐{x}'))
87
+ out.push(Howzit::Color.template("{bk}[{bl}tasks{bk}]──────────────────────────────────────┐{x}"))
88
88
  metadata = file.extract_metadata
89
89
  topics = Howzit::BuildNote.new(file: file).topics
90
90
  topics.each do |topic|
91
- out.push(Howzit::Color.template(" {bk}│{bw}-{x} {bcK}#{template}:#{topic.title.sub(/^.*?:/, '')}{x}"))
91
+ out.push(Howzit::Color.template(" {bk}│{bw}-{x} {bcK}#{template}:#{topic.title.sub(/^.*?:/, "")}{x}"))
92
92
  end
93
93
  unless metadata.empty?
94
94
  meta = []
95
- meta << metadata['required'].split(/\s*,\s*/).map { |m| "*{bw}#{m}{xw}" } if metadata.key?('required')
96
- meta << metadata['optional'].split(/\s*,\s*/).map(&:to_s) if metadata.key?('optional')
97
- out.push(Howzit::Color.template('{bk}[{bl}meta{bk}]───────────────────────────────────────┤{x}'))
98
- out.push(Howzit::Color.template(" {bk}│ {xw}#{meta.join(', ')}{x}"))
95
+ meta << metadata["required"].split(/\s*,\s*/).map { |m| "*{bw}#{m}{xw}" } if metadata.key?("required")
96
+ meta << metadata["optional"].split(/\s*,\s*/).map(&:to_s) if metadata.key?("optional")
97
+ out.push(Howzit::Color.template("{bk}[{bl}meta{bk}]───────────────────────────────────────┤{x}"))
98
+ out.push(Howzit::Color.template(" {bk}│ {xw}#{meta.join(", ")}{x}"))
99
99
  end
100
- out.push(Howzit::Color.template(' {bk}└───────────────────────────────────────────┘{x}'))
100
+ out.push(Howzit::Color.template(" {bk}└───────────────────────────────────────────┘{x}"))
101
101
  end
102
102
  Howzit::Util.page out.join("\n")
103
103
  Process.exit 0
104
104
  end
105
105
 
106
- opts.on('--templates-c', 'List available templates in a format for completion') do
106
+ opts.on("--templates-c", "List available templates in a format for completion") do
107
107
  out = []
108
108
  Dir.chdir(Howzit.config.template_folder)
109
- Dir.glob('*.md').each do |file|
110
- template = File.basename(file, '.md')
109
+ Dir.glob("*.md").each do |file|
110
+ template = File.basename(file, ".md")
111
111
  out.push(template)
112
112
  end
113
113
  puts out.join("\n")
114
114
  Process.exit 0
115
115
  end
116
116
 
117
- opts.on('--title-only', 'Output title only') do
117
+ opts.on("--title-only", "Output title only") do
118
118
  Howzit.options[:output_title] = true
119
119
  Howzit.options[:title_only] = true
120
120
  end
121
121
 
122
122
  opts.separator("\n Commands:\n\n") #=================================================================== COMMANDS
123
123
 
124
- opts.on('-c', '--create', 'Create a skeleton build note in the current working directory') do
124
+ opts.on("-c", "--create", "Create a skeleton build note in the current working directory") do
125
125
  Howzit.buildnote.create_note
126
126
  Process.exit 0
127
127
  end
128
128
 
129
- opts.on('--config-get [KEY]', 'Display the configuration settings or setting for a specific key') do |k|
129
+ opts.on("--config-get [KEY]", "Display the configuration settings or setting for a specific key") do |k|
130
130
  if k.nil?
131
131
  Howzit::Config::DEFAULTS.sort_by { |key, _| key }.each do |key, _|
132
132
  print "#{key}: "
133
133
  p Howzit.options[key]
134
134
  end
135
135
  else
136
- k.sub!(/^:/, '')
136
+ k.sub!(/^:/, "")
137
137
  if Howzit.options.key?(k.to_sym)
138
138
  puts Howzit.options[k.to_sym]
139
139
  else
@@ -143,12 +143,12 @@ OptionParser.new do |opts|
143
143
  Process.exit 0
144
144
  end
145
145
 
146
- opts.on('--config-set KEY=VALUE', 'Set a config value (must be a valid key)') do |key|
147
- raise 'Argument must be KEY=VALUE' unless key =~ /\S=\S/
146
+ opts.on("--config-set KEY=VALUE", "Set a config value (must be a valid key)") do |key|
147
+ raise "Argument must be KEY=VALUE" unless key =~ /\S=\S/
148
148
 
149
149
  parts = key.split(/=/)
150
- k = parts.shift.sub(/^:/, '')
151
- v = parts.join(' ')
150
+ k = parts.shift.sub(/^:/, "")
151
+ v = parts.join(" ")
152
152
 
153
153
  if Howzit.options.key?(k.to_sym)
154
154
  Howzit.options[k.to_sym] = v.to_config_value(Howzit.options[k.to_sym])
@@ -160,103 +160,103 @@ OptionParser.new do |opts|
160
160
  end
161
161
 
162
162
  desc = %(Edit buildnotes file in current working directory using default editor)
163
- opts.on('-e', '--edit', desc) do
163
+ opts.on("-e", "--edit", desc) do
164
164
  Howzit.buildnote.edit
165
165
  Process.exit 0
166
166
  end
167
167
 
168
- opts.on('--edit-config', "Edit configuration file using default editor") do
168
+ opts.on("--edit-config", "Edit configuration file using default editor") do
169
169
  Howzit.config.editor
170
170
  Process.exit 0
171
171
  end
172
172
 
173
- opts.on('--edit-template NAME', 'Create or edit a template') do |template|
173
+ opts.on("--edit-template NAME", "Create or edit a template") do |template|
174
174
  Howzit.buildnote.edit_template(template)
175
175
  Process.exit 0
176
176
  end
177
177
 
178
- opts.on('--grep PATTERN', 'Display sections matching a search pattern') do |pat|
178
+ opts.on("--grep PATTERN", "Display sections matching a search pattern") do |pat|
179
179
  Howzit.options[:grep] = pat
180
180
  end
181
181
 
182
- opts.on('--hook', 'Copy a link to the build note file, ready for pasting into Hook.app or other notes') do
182
+ opts.on("--hook", "Copy a link to the build note file, ready for pasting into Hook.app or other notes") do
183
183
  Howzit.buildnote.hook
184
184
  Process.exit 0
185
185
  end
186
186
 
187
- opts.on('-r', '--run', 'Execute @run, @open, and/or @copy commands for given topic') do
187
+ opts.on("-r", "--run", "Execute @run, @open, and/or @copy commands for given topic") do
188
188
  Howzit.options[:run] = true
189
189
  end
190
190
 
191
- opts.on('-s', '--select', 'Select topic from menu') do
191
+ opts.on("-s", "--select", "Select topic from menu") do
192
192
  Howzit.options[:choose] = true
193
193
  end
194
194
 
195
195
  opts.separator("\n Formatting:\n\n") #=================================================================== FORMATTING
196
196
 
197
- opts.on('--[no-]color', 'Colorize output (default on)') do |c|
197
+ opts.on("--[no-]color", "Colorize output (default on)") do |c|
198
198
  Howzit.options[:color] = c
199
199
  Howzit.options[:highlight] = false unless c
200
200
  end
201
201
 
202
- opts.on('--header-format TYPE', HEADER_FORMAT_OPTIONS,
203
- "Formatting style for topic titles (#{HEADER_FORMAT_OPTIONS.join(', ')})") do |t|
202
+ opts.on("--header-format TYPE", HEADER_FORMAT_OPTIONS,
203
+ "Formatting style for topic titles (#{HEADER_FORMAT_OPTIONS.join(", ")})") do |t|
204
204
  Howzit.options[:header_format] = t
205
205
  end
206
206
 
207
- opts.on('--[no-]md-highlight', 'Highlight Markdown syntax (default on), requires mdless or mdcat') do |m|
207
+ opts.on("--[no-]md-highlight", "Highlight Markdown syntax (default on), requires mdless or mdcat") do |m|
208
208
  Howzit.options[:highlight] = Howzit.options[:color] ? m : false
209
209
  end
210
210
 
211
- opts.on('--[no-]pager', 'Paginate output (default on)') do |p|
211
+ opts.on("--[no-]pager", "Paginate output (default on)") do |p|
212
212
  Howzit.options[:paginate] = p
213
213
  end
214
214
 
215
- opts.on('--show-code', 'Display the content of fenced run blocks') do
215
+ opts.on("--show-code", "Display the content of fenced run blocks") do
216
216
  Howzit.options[:show_all_code] = true
217
217
  end
218
218
 
219
- opts.on('-t', '--title', 'Output title with build notes') do
219
+ opts.on("-t", "--title", "Output title with build notes") do
220
220
  Howzit.options[:output_title] = true
221
221
  end
222
222
 
223
- opts.on('-w', '--wrap COLUMNS', 'Wrap to specified width (default 80, 0 to disable)') do |w|
223
+ opts.on("-w", "--wrap COLUMNS", "Wrap to specified width (default 80, 0 to disable)") do |w|
224
224
  Howzit.options[:wrap] = w.to_i
225
225
  end
226
226
 
227
227
  opts.separator("\n Logging:\n\n") #=================================================================== LOGGING
228
228
 
229
- opts.on('-d', '--debug', 'Show debug messages (and all messages)') do
229
+ opts.on("-d", "--debug", "Show debug messages (and all messages)") do
230
230
  Howzit.options[:log_level] = 0
231
231
  Howzit.console.reset_level
232
232
  end
233
233
 
234
- opts.on('-q', '--quiet', 'Silence info message') do
234
+ opts.on("-q", "--quiet", "Silence info message") do
235
235
  Howzit.options[:log_level] = 4
236
236
  Howzit.console.reset_level
237
237
  end
238
238
 
239
- opts.on('--verbose', 'Show all messages') do
239
+ opts.on("--verbose", "Show all messages") do
240
240
  Howzit.options[:log_level] = 1
241
241
  Howzit.console.reset_level
242
242
  end
243
243
 
244
244
  opts.separator("\n Misc:\n\n") #=================================================================== MISC
245
245
 
246
- opts.on('-h', '--help', 'Display this screen') do
246
+ opts.on("-h", "--help", "Display this screen") do
247
247
  Howzit::Util.page opts.to_s
248
248
  Process.exit 0
249
249
  end
250
250
 
251
- opts.on('-v', '--version', 'Display version number') do
251
+ opts.on("-v", "--version", "Display version number") do
252
252
  puts "#{File.basename(__FILE__)} v#{Howzit::VERSION}"
253
253
  Process.exit 0
254
254
  end
255
255
  end.parse!(args)
256
256
 
257
- trap('INT') do
257
+ trap("INT") do
258
258
  puts
259
- puts 'Cancelled'
259
+ puts "Cancelled"
260
260
  Process.exit 0
261
261
  end
262
262
 
data/howzit.gemspec CHANGED
@@ -16,7 +16,9 @@ Gem::Specification.new do |spec|
16
16
  spec.homepage = 'https://github.com/ttscoff/howzit'
17
17
  spec.license = 'MIT'
18
18
 
19
- spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |path|
20
+ path.split('/').any? { |segment| segment.start_with?('.') } || path.end_with?('.bak')
21
+ end
20
22
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
23
  spec.test_files = spec.files.grep(%r{^(features|spec|test)/})
22
24
  spec.require_paths = ['lib']