howzit 1.2.13 → 1.2.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36a27d1566deff8857d39035c0e40f696a29d78b7ae24274a73ceacc54541321
4
- data.tar.gz: 7b13d6644bf397e10f629689b159102a33dd5aa2c3610f368819de3dc8736007
3
+ metadata.gz: 3858dec6b009f75173d3d72067a94c330cb826b0e367109c7416b2db19065fa8
4
+ data.tar.gz: 2e05520b1ff9d5da82aba03b1af3ed31ee0a635f3fe42c50b3a515c45337c38b
5
5
  SHA512:
6
- metadata.gz: 9da1ea212df950e75a34006a44b0ade09c02fd4fe7c02ea0fddfffcf2936e6ca5db0d7f0c9e6cc44aac3d65eb4544aa9d4c03c156487f9311f39f08ee12199d4
7
- data.tar.gz: 99f9be58ff9184a2f96e7db6fed83e3fc19f0945e31c9d58daa32db022b175a8c99a329a9c023528af52100f46583ac892091eb04ed5d9e9e791087fe8f8c82d
6
+ metadata.gz: 90cb7e647c7956823e73eac6e4884a1ffe26875acd531cc70be6a1b334aa9653213cafbf0830cd69a634579c7fa61553585bbbc95f997a02b0192d093a85be1b
7
+ data.tar.gz: bfba515bc66d5f15ae33d967866e83e2e9e4c887160d0c66269542ee909acf8383742fd0e64f5639013a1ccdc16253664a3c90cd150fd5a67529280473ed1a88
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ### 1.2.14
2
+
3
+ 2022-08-02 11:01
4
+
5
+ #### NEW
6
+
7
+ - Config option and flag to determine how to handle multiple results (first, best, all, choose)
8
+ - --config-get and --config-set flags for working with config options
9
+
10
+ #### IMPROVED
11
+
12
+ - Allow multiple selections when using fzf
13
+ - Clean up newlines in output
14
+
1
15
  ### 1.2.13
2
16
 
3
17
  2022-08-01 20:50
data/README.md CHANGED
@@ -24,11 +24,10 @@ Howzit is a tool that allows you to keep Markdown-formatted notes about a projec
24
24
 
25
25
  ## Getting Started
26
26
 
27
- Howzit is a simple, self-contained script (at least until I get stupid and make a gem out of it).
28
-
29
27
  ### Prerequisites
30
28
 
31
29
  - Ruby 2.4+ (It probably works on older Rubys, but is untested prior to 2.4.1.)
30
+ - Optional: if [`fzf`](https://github.com/junegunn/fzf) is available, it will be used for handling multiple choice selections
32
31
  - Optional: if [`bat`](https://github.com/sharkdp/bat) is available it will page with that
33
32
  - Optional: [`mdless`](https://github.com/ttscoff/mdless) or [`mdcat`](https://github.com/lunaryorn/mdcat) for formatting output
34
33
 
@@ -200,6 +199,10 @@ Include a topic name to see just that topic, or no argument to display all.
200
199
 
201
200
  howzit build
202
201
 
202
+ You can combine multiple topic searches by separating with a comma. When multiple results are returned, the `:multiple_results:` configuration determines how they're handled.
203
+
204
+ howzit build,deploy
205
+
203
206
  Use `-l` to list all topics.
204
207
 
205
208
  howzit -l
@@ -216,12 +219,15 @@ Other options:
216
219
 
217
220
  Options:
218
221
  -c, --create Create a skeleton build note in the current working directory
219
- -e, --edit Edit buildnotes file in current working directory using editor.sh
222
+ -e, --edit Edit buildnotes file in current working directory
223
+ using $EDITOR
220
224
  --grep PATTERN Display sections matching a search pattern
221
225
  -L, --list-completions List topics for completion
222
226
  -l, --list List available topics
223
227
  -m, --matching TYPE Topics matching type
224
228
  (partial, exact, fuzzy, beginswith)
229
+ --multiple TYPE Multiple result handling
230
+ (first, all, choose)
225
231
  -R, --list-runnable List topics containing @ directives (verbose)
226
232
  -r, --run Execute @run, @open, and/or @copy commands for given topic
227
233
  -s, --select Select topic from menu
@@ -229,10 +235,10 @@ Other options:
229
235
  -t, --title Output title with build notes
230
236
  -q, --quiet Silence info message
231
237
  --verbose Show all messages
232
- -u, --upstream Traverse up parent directories for additional build notes
238
+ -u, --[no-]upstream Traverse up parent directories for additional build notes
233
239
  --show-code Display the content of fenced run blocks
234
240
  -w, --wrap COLUMNS Wrap to specified width (default 80, 0 to disable)
235
- --edit-config Edit configuration file using editor.sh
241
+ --edit-config Edit configuration file using default $EDITOR
236
242
  --title-only Output title only
237
243
  --templates List available templates
238
244
  --[no-]color Colorize output (default on)
@@ -240,6 +246,7 @@ Other options:
240
246
  --[no-]pager Paginate output (default on)
241
247
  -h, --help Display this screen
242
248
  -v, --version Display version number
249
+ --default Answer all prompts with default response
243
250
 
244
251
 
245
252
  ## Configuration
@@ -257,6 +264,7 @@ Some of the command line options can be set as defaults. The first time you run
257
264
  :matching: partial
258
265
  :include_upstream: false
259
266
  :log_level: 1
267
+ :multiple_matches: choose
260
268
 
261
269
  If `:color:` is false, output will not be colored, and markdown highlighting will be bypassed.
262
270
 
@@ -272,6 +280,8 @@ If `:include_upstream:` is true, build note files in parent directories will be
272
280
 
273
281
  Set `:log_level:` to 0 for debug messages, or 3 to suppress superfluous info messages.
274
282
 
283
+ `:multiple_matches:` determines how howzit will handle cases where a search results in multiple matches. It can be set to "first" (first match in notes), "best" (shortest topic match), "all" (display all results), or "choose" (displays a menu of results). Default is "choose." When grepping for results, only "all" or "choose" are valid, if the default is something else, "choose" will be used. Can be overridden with the `--multiple TYPE` flag.
284
+
275
285
  ### Matching
276
286
 
277
287
  All matching is case insensitive. This setting can be overridden by the `--matching TYPE` flag on the command line.
@@ -124,7 +124,7 @@ module Howzit
124
124
  pipes = "|#{hl}" if hl
125
125
  end
126
126
 
127
- output = `echo #{Shellwords.escape(string.strip)}#{pipes}`
127
+ output = `echo #{Shellwords.escape(string.strip)}#{pipes}`.strip
128
128
 
129
129
  if @options[:paginate]
130
130
  page(output)
@@ -356,7 +356,9 @@ module Howzit
356
356
  end
357
357
  output.push("Ran #{tasks} #{tasks == 1 ? 'task' : 'tasks'}") if @options[:log_level] < 2
358
358
 
359
- puts postreqs.join("\n\n")
359
+ puts postreqs.join("\n\n") unless postreqs.empty?
360
+
361
+ output
360
362
  end
361
363
 
362
364
  # Output a topic with fancy title and bright white text.
@@ -382,12 +384,12 @@ module Howzit
382
384
  unless matches.empty?
383
385
  if opt[:single]
384
386
  title = "From #{matches[0]}:"
385
- color = '{yK}'
386
- rule = '{kK}'
387
+ color = '{Kyd}'
388
+ rule = '{kKd}'
387
389
  else
388
390
  title = "Include #{matches[0]}"
389
- color = '{yK}'
390
- rule = '{x}'
391
+ color = '{Kyd}'
392
+ rule = '{kKd}'
391
393
  end
392
394
  output.push(format_header("#{'> ' * @nest_level}#{title}", { color: color, hr: '.', border: rule })) unless @included.include?(matches[0])
393
395
 
@@ -449,7 +451,7 @@ module Howzit
449
451
  else
450
452
  output_topic(key, {single: single})
451
453
  end
452
- output.nil? ? '' : output.join("\n")
454
+ output.nil? ? '' : output.join("\n").strip
453
455
  end
454
456
 
455
457
  # Output a list of topic titles
@@ -700,7 +702,8 @@ module Howzit
700
702
  choose: false,
701
703
  quiet: false,
702
704
  verbose: false,
703
- default: false
705
+ default: false,
706
+ grep: nil
704
707
  }
705
708
 
706
709
  defaults = {
@@ -715,7 +718,7 @@ module Howzit
715
718
  show_all_on_error: false,
716
719
  include_upstream: false,
717
720
  show_all_code: false,
718
- grep: nil,
721
+ multiple_matches: 'choose',
719
722
  log_level: 1 # 0: debug, 1: info, 2: warn, 3: error
720
723
  }
721
724
 
@@ -767,6 +770,11 @@ module Howzit
767
770
  @options[:matching] = c
768
771
  end
769
772
 
773
+ opts.on('--multiple TYPE', MULTIPLE_OPTIONS,
774
+ 'Multiple result handling', "(#{MULTIPLE_OPTIONS.join(', ')}, default choose)") do |c|
775
+ @options[:multiple_matches] = c.to_sym
776
+ end
777
+
770
778
  opts.on('-R', '--list-runnable', 'List topics containing @ directives (verbose)') do
771
779
  @options[:list_runnable] = true
772
780
  end
@@ -808,6 +816,39 @@ module Howzit
808
816
  @options[:wrap] = w.to_i
809
817
  end
810
818
 
819
+ opts.on('--config-get [KEY]', 'Display the configuration settings or setting for a specific key') do |k|
820
+
821
+ if k.nil?
822
+ config.sort_by { |key, _| key }.each do |key, val|
823
+ print "#{key}: "
824
+ p val
825
+ end
826
+ else
827
+ k.sub!(/^:/, '')
828
+ if config.key?(k.to_sym)
829
+ puts config[k.to_sym]
830
+ else
831
+ puts "Key #{k} not found"
832
+ end
833
+ end
834
+ Process.exit 0
835
+ end
836
+
837
+ opts.on('--config-set KEY=VALUE', 'Set a config value (must be a valid key)') do |key|
838
+ raise 'Argument must be KEY=VALUE' unless key =~ /\S=\S/
839
+
840
+ k, v = key.split(/=/)
841
+ k.sub!(/^:/, '')
842
+
843
+ if config.key?(k.to_sym)
844
+ config[k.to_sym] = v.to_config_value(config[k.to_sym])
845
+ else
846
+ puts "Key #{k} not found"
847
+ end
848
+ write_config(config)
849
+ Process.exit 0
850
+ end
851
+
811
852
  opts.on('--edit-config', "Edit configuration file using default $EDITOR") do
812
853
  edit_config(defaults)
813
854
  Process.exit 0
@@ -869,6 +910,8 @@ module Howzit
869
910
  end
870
911
  end.parse!(args)
871
912
 
913
+ @options[:multiple_matches] = @options[:multiple_matches].to_sym
914
+
872
915
  @cli_args = args
873
916
  end
874
917
 
@@ -1001,12 +1044,20 @@ module Howzit
1001
1044
 
1002
1045
  def choose(matches)
1003
1046
  if command_exist?('fzf')
1004
- res = `echo #{Shellwords.escape(matches.join("\n"))} | fzf -0 -1 --height #{matches.count + 2} --prompt 'Select a section > '`.strip
1047
+ settings = [
1048
+ '-0',
1049
+ '-1',
1050
+ '-m',
1051
+ "--height=#{matches.count + 2}",
1052
+ '--header="Use tab to mark multiple selections, enter to display/run"',
1053
+ '--prompt="Select a section > "'
1054
+ ]
1055
+ res = `echo #{Shellwords.escape(matches.join("\n"))} | fzf #{settings.join(' ')}`.strip
1005
1056
  if res.nil? || res.empty?
1006
1057
  warn 'Cancelled'
1007
1058
  Process.exit 0
1008
1059
  end
1009
- return res
1060
+ return res.split(/\n/)
1010
1061
  end
1011
1062
 
1012
1063
  res = matches[0..9]
@@ -1107,7 +1158,7 @@ module Howzit
1107
1158
  out = get_note_title(20)
1108
1159
  $stdout.print(out.strip)
1109
1160
  Process.exit(0)
1110
- elsif @options[:output_title]
1161
+ elsif @options[:output_title] && !@options[:run]
1111
1162
  title = get_note_title
1112
1163
  if title && !title.empty?
1113
1164
  header = format_header(title, { hr: "\u{2550}", color: '{bwK}' })
@@ -1136,33 +1187,49 @@ module Howzit
1136
1187
  Process.exit(0)
1137
1188
  end
1138
1189
 
1139
- topic_match = nil
1190
+ topic_matches = []
1140
1191
  if @options[:grep]
1141
- topic_match = choose(grep_topics(@options[:grep]))
1192
+ matches = grep_topics(@options[:grep])
1193
+ case @options[:multiple_matches]
1194
+ when :all
1195
+ topic_matches.concat(matches.sort)
1196
+ else
1197
+ topic_matches.concat(choose(matches))
1198
+ end
1142
1199
  elsif @options[:choose]
1143
- topic_match = choose(topics.keys)
1200
+ topic_matches.concat(choose(topics.keys))
1144
1201
  # If there are arguments use those to search for a matching topic
1145
1202
  elsif !@cli_args.empty?
1203
+ search = @cli_args.join(' ').strip.downcase.split(/ *, */).map(&:strip)
1146
1204
 
1147
- search = @cli_args.join(' ').strip.downcase
1148
- matches = match_topic(search)
1205
+ search.each do |s|
1206
+ matches = match_topic(s)
1149
1207
 
1150
- if matches.empty?
1151
- output.push(Color.template(%({bR}ERROR:{xr} No topic match found for {bw}#{search}{x}\n)))
1152
- unless @options[:show_all_on_error]
1153
- show(output.join("\n"), { color: true, highlight: false, paginate: false, wrap: 0 })
1154
- Process.exit 1
1208
+ if matches.empty?
1209
+ output.push(Color.template(%({bR}ERROR:{xr} No topic match found for {bw}#{s}{x}\n)))
1210
+ else
1211
+ case @options[:multiple_matches]
1212
+ when :first
1213
+ topic_matches.push(matches[0])
1214
+ when :best
1215
+ topic_matches.push(matches.sort.min_by(&:length))
1216
+ when :all
1217
+ topic_matches.concat(matches)
1218
+ else
1219
+ topic_matches.concat(choose(matches))
1220
+ end
1155
1221
  end
1156
- elsif matches.length == 1
1157
- topic_match = matches[0]
1158
- else
1159
- topic_match = choose(matches)
1222
+ end
1223
+
1224
+ if topic_matches.empty? && !@options[:show_all_on_error]
1225
+ show(output.join("\n"), { color: true, highlight: false, paginate: false, wrap: 0 })
1226
+ Process.exit 1
1160
1227
  end
1161
1228
  end
1162
1229
 
1163
- if topic_match
1230
+ if !topic_matches.empty?
1164
1231
  # If we found a match
1165
- output.push(process_topic(topic_match, @options[:run], true))
1232
+ topic_matches.each { |topic_match| output.push(process_topic(topic_match, @options[:run], true)) }
1166
1233
  else
1167
1234
  # If there's no argument or no match found, output all
1168
1235
  topics.each_key { |k| output.push(process_topic(k, false, false)) }
data/lib/howzit/colors.rb CHANGED
@@ -232,7 +232,7 @@ module Howzit
232
232
  y: yellow, c: cyan, m: magenta, r: red,
233
233
  W: bgwhite, K: bgblack, G: bggreen, L: bgblue,
234
234
  Y: bgyellow, C: bgcyan, M: bgmagenta, R: bgred,
235
- b: bold, u: underline, i: italic, x: reset }
235
+ d: dark, b: bold, u: underline, i: italic, x: reset }
236
236
 
237
237
  format(fmt, colors)
238
238
  end
@@ -3,6 +3,31 @@
3
3
  module Howzit
4
4
  # String Extensions
5
5
  module StringUtils
6
+ # Convert a string to a valid YAML value
7
+ def to_config_value(orig_value = nil)
8
+ if orig_value
9
+ case orig_value.class.to_s
10
+ when /Integer/
11
+ to_i
12
+ when /(True|False)Class/
13
+ self =~ /^(t(rue)?|y(es)?|1)$/i ? true : false
14
+ else
15
+ self
16
+ end
17
+ else
18
+ case self
19
+ when /^[0-9]+$/
20
+ to_i
21
+ when /^(t(rue)?|y(es)?)$/i
22
+ true
23
+ when /^(f(alse)?|n(o)?)$/i
24
+ false
25
+ else
26
+ self
27
+ end
28
+ end
29
+ end
30
+
6
31
  # Just strip out color codes when requested
7
32
  def uncolor
8
33
  gsub(/\e\[[\d;]+m/, '').gsub(/\e\]1337;SetMark/,'')
@@ -2,5 +2,5 @@
2
2
  # Primary module for this gem.
3
3
  module Howzit
4
4
  # Current Howzit version.
5
- VERSION = '1.2.13'.freeze
5
+ VERSION = '1.2.14'.freeze
6
6
  end
data/lib/howzit.rb CHANGED
@@ -16,3 +16,4 @@ CONFIG_DIR = '~/.config/howzit'
16
16
  CONFIG_FILE = 'howzit.yaml'
17
17
  IGNORE_FILE = 'ignore.yaml'
18
18
  MATCHING_OPTIONS = %w[partial exact fuzzy beginswith].freeze
19
+ MULTIPLE_OPTIONS = %w[first best all choose].freeze
@@ -23,14 +23,14 @@ describe Howzit::BuildNotes do
23
23
  end
24
24
 
25
25
  describe ".grep_topics" do
26
- it "found editable" do
26
+ it "finds editable" do
27
27
  expect(subject.grep_topics('editable')).to include('File Structure')
28
28
  expect(subject.grep_topics('editable')).not_to include('Build')
29
29
  end
30
30
  end
31
31
 
32
32
  describe ".list_topic_titles" do
33
- it "found 4 topics" do
33
+ it "finds 4 topics" do
34
34
  expect(subject.topics.keys.count).to eq 4
35
35
  end
36
36
  it "outputs a newline-separated string" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: howzit
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.13
4
+ version: 1.2.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra