doing 1.0.74 → 1.0.79

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: 652cc285b42ce068d4640a6aff95d2058d1fba60715e41ce4599bfcbe7051507
4
- data.tar.gz: 7a940801f8fa9d78b27688b6c92f4fcdb4b5765c28888cb6f1218245d4535376
3
+ metadata.gz: 24a207b31d2f64fc81c00b1484f62a5ab2609ded162fc9733cb54463c652d63e
4
+ data.tar.gz: dfc767b0d8cec0229e9ad3823f5853d81c343261198c6638e364331920dc7989
5
5
  SHA512:
6
- metadata.gz: df8f8c529b18238a5d069b79c9e43382f2751d18f1dd022e7d918467f31dadd6b6a50780034b516d4d9b321ddcc4d3ebb7a40db9b96a4059adf49eda119663f9
7
- data.tar.gz: b67333df19e976fe0cbde7645c6cc8a9098813a023090f7e52bd60052283202f2dff8406beacb28d921d7c947dac2d885caab7fe3388c578a17b73181a4cbbc5
6
+ metadata.gz: 1f64972ed2d157a0b52afa882d257190d236ebb5805d0ff8049d3ab65ca92974a1cbe2e11ba2ee1ea9cd04b751bd4cc6874f409d442cdfb9347c37bacb6fc47c
7
+ data.tar.gz: 9d3432a35cd14d44474ef32e90df40943a2a9ed7eb7c232a2361816aba255b7ed39992dc7b4cfa000afb93abbe4cea3036c9eec244a2fe141f7dca70ce400095
data/README.md CHANGED
@@ -27,7 +27,7 @@ If there's something I want to look at later but doesn't need to be added to a t
27
27
 
28
28
  ## Installation
29
29
 
30
- The current version of `doing` is <!--VER-->1.0.73<!--END VER-->.
30
+ The current version of `doing` is <!--VER-->1.0.78<!--END VER-->.
31
31
 
32
32
  $ [sudo] gem install doing
33
33
 
@@ -268,7 +268,7 @@ You can add additional custom views. Just nest them under the `views` key (inden
268
268
  count: 5
269
269
  wrap_width: 0
270
270
  date_format: '%F %_I:%M%P'
271
- template: '%date | %title%note'
271
+ template: '%date | %title%note'
272
272
 
273
273
  The `section` key is the default section to pull entries from. Count and section can be overridden at runtime with the `-c` and `-s` flags. Setting `section` to `All` will combine all sections in the output.
274
274
 
@@ -505,7 +505,7 @@ You can include a `transform` section in the autotag config which contains pairs
505
505
  transform:
506
506
  - (\w+)-\d+:$1
507
507
 
508
- This creates a search pattern looking for a string of word characters followed by a hyphen and one or more digits, e.g. `@projecttag-12`. Do not include the @ symbol in the pattern. The replacement (`$1`) indicates that the first matched group (in parenthesis) should be used to generate the new tag, resulting in `@projecttag` being added to the entry.
508
+ This creates a search pattern looking for a string of word characters followed by a hyphen and one or more digits, e.g. `@projecttag-12`. Do not include the @ symbol in the pattern. The replacement (`$l`) indicates that the first matched group (in parenthesis) should be used to generate the new tag, resulting in `@projecttag` being added to the entry.
509
509
 
510
510
  ##### Annotating
511
511
 
@@ -619,11 +619,14 @@ Now you can run `doing import --type timing -s SECTION PATH`, where SECTION is t
619
619
 
620
620
  #### Interactive Usage
621
621
 
622
- If you have `fzf` installed (<https://github.com/junegunn/fzf>), you can use `doing select` to get a menu of all your items (or items in a given section) which can be searched with fuzzy matching. The menu allows multiple selections to be acted on directly.
622
+ FuzzyFileFinder (`fzf`) is included with doing (<https://github.com/junegunn/fzf>), and you can use `doing select` to get a menu of all your items (or items in a given section) which can be searched with fuzzy matching. The menu allows multiple selections to be acted on directly.
623
+
624
+ To use the menu, type a search string or use the arrow keys to navigate up and down. Tip: searching is "fuzzy" by default, but you can start your search with a single quote (`'`) to force an exact match. Press tab on an entry you'd like to perform an action on. A marker will show up on the left indicating the entry is selected. Repeat the process and select as many entries as needed. When you hit Return, the selection will be passed back to doing. Use Control-A to select all visible entries.
623
625
 
624
- To use the menu, type a search string or use the arrow keys to navigate up and down. Press tab on an entry you'd like to perform an action on. A marker will show up on the left indicating the entry is selected. Repeat the process and select as many entries as needed. When you hit Return, the selection will be passed back to doing.
626
+ Doing can perform several functions with this menu. Not all of doing's features are available, but the core functionality you'd need is there, plus you can open the selected entries on one page in your text editor, make changes to them, and when you save and close the entries are updated accordingly. This allows editing of everything from timestamps to tags to notes.
625
627
 
626
- Doing can perform several functions with this menu. Not all of doing's features are available, but the core functionality you'd need is there, plus you can open all selected entries in your editor, make changes to them, and when you save and close the entries are updated accordingly. This allows editing of everything from timestamps to tags to notes.
628
+ If no actions are specified, an interactive menu of options will be
629
+ presented.
627
630
 
628
631
  Run `doing help select` for a list of options:
629
632
 
@@ -634,13 +637,19 @@ Run `doing help select` for a list of options:
634
637
  -f, --finish - Add @done with current time to selected item(s)
635
638
  --flag - Add flag to selected item(s)
636
639
  -m, --move=SECTION - Move selected items to section (default: none)
640
+ -o, --output=FORMAT - Output format for export (doing|taskpaper|csv|html|json|template|timeline) (default: none)
641
+ -q, --query=QUERY - Initial search query for filtering (default: none)
642
+ -r, --remove - Reverse -c, -f, --flag, and -t (remove instead of adding)
637
643
  -s, --section=SECTION - Select from a specific section (default: none)
644
+ --save_to=FILE - Save selected entries to file using --output format (default: none)
638
645
  -t, --tag=TAG - Tag selected entries (default: none)
639
646
 
640
647
  For example, `doing select -d -a` would present the menu, and then mark selected entries as @done (with timestamp) and move them to the Archive section.
641
648
 
642
649
  Multiple actions can be performed at once by combining options. You can also combine the `--editor` switch with any other options. Other actions will be performed first, then the entries --- with any modifications performed --- will be presented in the editor for tweaking.
643
650
 
651
+ **Note:** when using the `--editor` flag to open selections in your text editor, entries will be separated by `---` lines. These must remain in place for doing to track the changes. You can do anything you want to the entries, modify dates, change text, add notes, etc., as long as you leave the dividers in place. You can even delete an entry entirely, leaving the dividers around the missing line and the entry will be removed from your doing file when you save and exit the editor.
652
+
644
653
  ---
645
654
 
646
655
  ## Extras
data/bin/doing CHANGED
@@ -257,9 +257,9 @@ command :template do |c|
257
257
  end
258
258
 
259
259
  desc 'Display an interactive menu to perform operations (requires fzf)'
260
- long_desc 'Requires that `fzf` be installed and available in your path. <https://github.com/junegunn/fzf>
260
+ long_desc 'List all entries and select with typeahead fuzzy matching.
261
261
 
262
- List all entries and select with typeahead fuzzy matching. Multiple selections are allowed, hit tab to add the highlighted entry to the selection. Return processes the selected entries.'
262
+ Multiple selections are allowed, hit tab to add the highlighted entry to the selection. Return processes the selected entries.'
263
263
  command :select do |c|
264
264
  c.desc 'Select from a specific section'
265
265
  c.arg_name 'SECTION'
@@ -269,6 +269,9 @@ command :select do |c|
269
269
  c.arg_name 'TAG'
270
270
  c.flag %i[t tag]
271
271
 
272
+ c.desc 'Reverse -c, -f, --flag, and -t (remove instead of adding)'
273
+ c.switch %i[r remove], negatable: false
274
+
272
275
  # c.desc 'Add @done to selected item(s), using start time of next item as the finish time'
273
276
  # c.switch %i[a auto], negatable: false, default_value: false
274
277
 
@@ -279,6 +282,10 @@ command :select do |c|
279
282
  c.arg_name 'SECTION'
280
283
  c.flag %i[m move]
281
284
 
285
+ c.desc 'Initial search query for filtering'
286
+ c.arg_name 'QUERY'
287
+ c.flag %i[q query]
288
+
282
289
  c.desc 'Cancel selected items (add @done without timestamp)'
283
290
  c.switch %i[c cancel], negatable: false, default_value: false
284
291
 
@@ -294,9 +301,15 @@ command :select do |c|
294
301
  c.desc 'Add flag to selected item(s)'
295
302
  c.switch %i[flag], negatable: false, default_value: false
296
303
 
304
+ c.desc 'Save selected entries to file using --output format'
305
+ c.arg_name 'FILE'
306
+ c.flag %i[save_to]
307
+
308
+ c.desc 'Output format for export (doing|taskpaper|csv|html|json|template|timeline)'
309
+ c.arg_name 'FORMAT'
310
+ c.flag %i[o output], must_match: /^(?:doing|taskpaper|html|csv|json|template|timeline)$/i
311
+
297
312
  c.action do |_global_options, options, args|
298
- section = options[:section] || 'All'
299
- edit = options[:editor]
300
313
  wwid.interactive(options)
301
314
  end
302
315
  end
data/lib/doing/helpers.rb CHANGED
@@ -92,7 +92,7 @@ class ::String
92
92
  def link_urls(opt = {})
93
93
  opt[:format] ||= :html
94
94
  if opt[:format] == :html
95
- gsub(%r{(?mi)((http|https)://)?([\w\-_]+(\.[\w\-_]+)+)([\w\-.,@?^=%&amp;:/~+#]*[\w\-@^=%&amp;/~+#])?}) do |_match|
95
+ gsub(%r{(?mi)((http|https)://)([\w\-_]+(\.[\w\-_]+)+)([\w\-.,@?^=%&amp;:/~+#]*[\w\-@^=%&amp;/~+#])?}) do |_match|
96
96
  m = Regexp.last_match
97
97
  proto = m[1].nil? ? 'http://' : ''
98
98
  %(<a href="#{proto}#{m[0]}" title="Link to #{m[0]}">[#{m[3]}]</a>)
data/lib/doing/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Doing
2
- VERSION = '1.0.74'
2
+ VERSION = '1.0.79'
3
3
  end
data/lib/doing/wwid.rb CHANGED
@@ -300,7 +300,7 @@ class WWID
300
300
  tmpfile.unlink
301
301
  end
302
302
 
303
- input.split(/\n/).delete_if {|line| line =~ /^#/ }.join("\n").strip
303
+ input.split(/\n/).delete_if {|line| line =~ /^#/ }.join("\n")
304
304
  end
305
305
 
306
306
  #
@@ -462,7 +462,7 @@ class WWID
462
462
  ## @return (Bool) yes or no
463
463
  ##
464
464
  def yn(question, default_response: false)
465
- default = default_response ? 'y' : 'n'
465
+ default = default_response ? default_response : 'n'
466
466
 
467
467
  # if this isn't an interactive shell, answer default
468
468
  return default.downcase == 'y' unless $stdout.isatty
@@ -766,6 +766,22 @@ class WWID
766
766
  all_items.max_by { |item| item['date'] }
767
767
  end
768
768
 
769
+ ##
770
+ ## @brief Generate a menu of options and allow user selection
771
+ ##
772
+ ## @return (String) The selected option
773
+ ##
774
+ def choose_from(options, prompt)
775
+ puts prompt
776
+ options.each_with_index do |section, i|
777
+ puts format('% 3d: %s', i + 1, section)
778
+ end
779
+ print "#{colors['green']}> #{colors['default']}"
780
+ num = STDIN.gets
781
+ return false if num =~ /^[a-z ]*$/i
782
+
783
+ options[num.to_i - 1]
784
+ end
769
785
 
770
786
  ##
771
787
  ## @brief Display an interactive menu of entries
@@ -773,7 +789,7 @@ class WWID
773
789
  ## @param opt (Hash) Additional options
774
790
  ##
775
791
  def interactive(opt = {})
776
- exit_now! "Select command requires that fzf be installed" unless exec_available('fzf')
792
+ fzf = File.join(File.dirname(__FILE__), '../helpers/fuzzyfilefinder')
777
793
 
778
794
  section = opt[:section] ? guess_section(opt[:section]) : 'All'
779
795
 
@@ -807,7 +823,7 @@ class WWID
807
823
  out.join('')
808
824
  end
809
825
 
810
- res = `echo #{Shellwords.escape(options.join("\n"))}|fzf -m`
826
+ res = `echo #{Shellwords.escape(options.join("\n"))}|#{fzf} --header="Arrows to navigate, tab to mark for selection, enter to perform action" --prompt="Select entries to act on> " -m --bind ctrl-a:select-all -q "#{opt[:query]}"`
811
827
  selected = []
812
828
  res.split(/\n/).each do |item|
813
829
  idx = item.match(/^(\d+)\)/)[1].to_i
@@ -819,6 +835,68 @@ class WWID
819
835
  return
820
836
  end
821
837
 
838
+ actions = %i[editor delete tag flag finish cancel tag archive output save_to]
839
+ has_action = false
840
+ actions.each do |a|
841
+ if opt[a]
842
+ has_action = true
843
+ break
844
+ end
845
+ end
846
+
847
+ unless has_action
848
+ action = choose_from(
849
+ [
850
+ "add tag",
851
+ "remove tag",
852
+ "archive",
853
+ "cancel",
854
+ "delete",
855
+ "edit",
856
+ "finish",
857
+ "flag",
858
+ "move",
859
+ "output format"
860
+ ],
861
+ 'What do you want to do with the selected items?')
862
+ case action
863
+ when /(add|remove) tag/
864
+ print "Enter tag: "
865
+ tag = STDIN.gets
866
+ return if tag =~ /^ *$/
867
+ opt[:tag] = tag.strip
868
+ opt[:remove] = true if action =~ /remove tag/
869
+ when /output format/
870
+ output_format = choose_from(%w[doing taskpaper json timeline html csv], 'Which output format?')
871
+ return if tag =~ /^ *$/
872
+ opt[:output] = output_format.strip
873
+ res = yn("Save to file?", default_response: 'n')
874
+ if res
875
+ print "File path/name: "
876
+ filename = STDIN.gets.strip
877
+ return if filename.empty?
878
+ opt[:save_to] = filename
879
+ end
880
+ when /archive/
881
+ opt[:archive] = true
882
+ when /delete/
883
+ opt[:delete] = true
884
+ when /edit/
885
+ opt[:editor] = true
886
+ when /finish/
887
+ opt[:finish] = true
888
+ when /cancel/
889
+ opt[:cancel] = true
890
+ when /move/
891
+ section = choose_section.strip
892
+ return if section =~ /^ *$/
893
+ opt[:move] = section.strip
894
+ when /flag/
895
+ opt[:flag] = true
896
+ end
897
+ end
898
+
899
+
822
900
  if opt[:delete]
823
901
  res = yn("Delete #{selected.size} items?", default_response: 'y')
824
902
  if res
@@ -830,17 +908,35 @@ class WWID
830
908
 
831
909
  if opt[:flag]
832
910
  tag = @config['marker_tag'] || 'flagged'
833
- selected.map! {|item| tag_item(item, tag, date: false) }
911
+ selected.map! do |item|
912
+ if opt[:remove]
913
+ untag_item(item, tag)
914
+ else
915
+ tag_item(item, tag, date: false)
916
+ end
917
+ end
834
918
  end
835
919
 
836
920
  if opt[:finish] || opt[:cancel]
837
921
  tag = 'done'
838
- selected.map! {|item| tag_item(item, tag, date: !opt[:cancel])}
922
+ selected.map! do |item|
923
+ if opt[:remove]
924
+ untag_item(item, tag)
925
+ else
926
+ tag_item(item, tag, date: !opt[:cancel])
927
+ end
928
+ end
839
929
  end
840
930
 
841
931
  if opt[:tag]
842
932
  tag = opt[:tag]
843
- selected.map! {|item| tag_item(item, tag, date: false)}
933
+ selected.map! do |item|
934
+ if opt[:remove]
935
+ untag_item(item, tag)
936
+ else
937
+ tag_item(item, tag, date: false)
938
+ end
939
+ end
844
940
  end
845
941
 
846
942
  if opt[:archive] || opt[:move]
@@ -860,13 +956,17 @@ class WWID
860
956
  editable += "\n#{old_note}" unless old_note.nil?
861
957
  editable_items << editable
862
958
  end
959
+ divider = "\n-----------\n"
960
+ input = editable_items.map(&:strip).join(divider) + "\n\n# You may delete entries, but leave all divider lines in place"
863
961
 
864
- new_items = fork_editor(editable_items.join("\n---\n") + "\n\n# You may delete entries, but leave all --- lines in place").split(/\n---\n/)
962
+ new_items = fork_editor(input).split(/#{divider}/)
865
963
 
866
964
  new_items.each_with_index do |new_item, i|
965
+
867
966
  input_lines = new_item.split(/[\n\r]+/).delete_if {|line| line =~ /^#/ || line =~ /^\s*$/ }
868
967
  title = input_lines[0]&.strip
869
- if title.nil? || title =~ /^---$/ || title.strip.empty?
968
+
969
+ if title.nil? || title =~ /^#{divider.strip}$/ || title.strip.empty?
870
970
  delete_item(selected[i])
871
971
  else
872
972
  note = input_lines.length > 1 ? input_lines[1..-1] : []
@@ -880,13 +980,47 @@ class WWID
880
980
  item = selected[i].dup
881
981
  item['title'] = title
882
982
  item['note'] = note
883
- item['date'] = Time.parse(date)
983
+ item['date'] = Time.parse(date) || selected[i]['date']
884
984
  update_item(selected[i], item)
885
985
  end
886
986
  end
887
987
 
888
988
  write(@doing_file)
889
989
  end
990
+
991
+ if opt[:output]
992
+ selected.map! do |item|
993
+ item['title'] = "#{item['title']} @project(#{item['section']})"
994
+ item
995
+ end
996
+
997
+ @content = {'Export' => {'original' => 'Export:', 'items' => selected}}
998
+ options = {section: 'Export'}
999
+
1000
+ if opt[:output] !~ /(doing|taskpaper)/
1001
+ options[:output] = opt[:output]
1002
+ else
1003
+ options[:template] = '- %date | %title%note'
1004
+ end
1005
+
1006
+ output = list_section(options)
1007
+
1008
+ if opt[:save_to]
1009
+ file = File.expand_path(opt[:save_to])
1010
+ if File.exist?(file)
1011
+ # Create a backup copy for the undo command
1012
+ FileUtils.cp(file, "#{file}~")
1013
+ end
1014
+
1015
+ File.open(file, 'w+') do |f|
1016
+ f.puts output
1017
+ end
1018
+
1019
+ @results.push("Export saved to #{file}")
1020
+ else
1021
+ puts output
1022
+ end
1023
+ end
890
1024
  end
891
1025
 
892
1026
  ##
@@ -1068,6 +1202,33 @@ class WWID
1068
1202
  @content[section]['items'] = section_items
1069
1203
  end
1070
1204
 
1205
+ ##
1206
+ ## @brief Remove a tag on an item from the index
1207
+ ##
1208
+ ## @param old_item (Item) The item to tag
1209
+ ## @param tag (string) The tag to remove
1210
+ ##
1211
+ def untag_item(old_item, tags)
1212
+ title = old_item['title'].dup
1213
+ if tags.is_a? ::String
1214
+ tags = tags.split(/ *, */).map {|t| t.strip.gsub(/\*/,'[^ (]*') }
1215
+ end
1216
+
1217
+ tags.each do |tag|
1218
+ if title =~ /@#{tag}/
1219
+ title.chomp!
1220
+ title.gsub!(/ +@#{tag}(\(.*?\))?/, '')
1221
+ new_item = old_item.dup
1222
+ new_item['title'] = title
1223
+ update_item(old_item, new_item)
1224
+ return new_item
1225
+ else
1226
+ @results.push(%(Item isn't tagged @#{tag}: "#{title}" in #{old_item['section']}))
1227
+ return old_item
1228
+ end
1229
+ end
1230
+ end
1231
+
1071
1232
  ##
1072
1233
  ## @brief Tag an item from the index
1073
1234
  ##
@@ -1075,23 +1236,29 @@ class WWID
1075
1236
  ## @param tag (string) The tag to apply
1076
1237
  ## @param date (Boolean) Include timestamp?
1077
1238
  ##
1078
- def tag_item(old_item, tag, date: false)
1239
+ def tag_item(old_item, tags, remove: false, date: false)
1079
1240
  title = old_item['title'].dup
1241
+ if tags.is_a? ::String
1242
+ tags = tags.split(/ *, */).map(&:strip)
1243
+ end
1244
+
1080
1245
  done_date = Time.now
1081
- if title !~ /@#{tag}/
1082
- title.chomp!
1083
- if date
1084
- title += " @#{tag}(#{done_date.strftime('%F %R')})"
1246
+ tags.each do |tag|
1247
+ if title !~ /@#{tag}/
1248
+ title.chomp!
1249
+ if date
1250
+ title += " @#{tag}(#{done_date.strftime('%F %R')})"
1251
+ else
1252
+ title += " @#{tag}"
1253
+ end
1254
+ new_item = old_item.dup
1255
+ new_item['title'] = title
1256
+ update_item(old_item, new_item)
1257
+ return new_item
1085
1258
  else
1086
- title += " @#{tag}"
1259
+ @results.push(%(Item already @#{tag}: "#{title}" in #{old_item['section']}))
1260
+ return old_item
1087
1261
  end
1088
- new_item = old_item.dup
1089
- new_item['title'] = title
1090
- update_item(old_item, new_item)
1091
- return new_item
1092
- else
1093
- @results.push(%(Item already @#{tag}: "#{title}" in #{old_item['section']}))
1094
- return old_item
1095
1262
  end
1096
1263
  end
1097
1264
 
@@ -1305,10 +1472,10 @@ class WWID
1305
1472
  if File.exist?(file)
1306
1473
  # Create a backup copy for the undo command
1307
1474
  FileUtils.cp(file, "#{file}~")
1475
+ end
1308
1476
 
1309
- File.open(file, 'w+') do |f|
1310
- f.puts output
1311
- end
1477
+ File.open(file, 'w+') do |f|
1478
+ f.puts output
1312
1479
  end
1313
1480
 
1314
1481
  if @config.key?('run_after')
@@ -1522,13 +1689,16 @@ class WWID
1522
1689
  note ||= ''
1523
1690
 
1524
1691
  tags = []
1692
+ attributes = {}
1525
1693
  skip_tags = %w[meanwhile done cancelled flagged]
1526
1694
  i['title'].scan(/@([^(\s]+)(?:\((.*?)\))?/).each do |tag|
1527
1695
  tags.push(tag[0]) unless skip_tags.include?(tag[0])
1696
+ attributes[tag[0]] = tag[1] if tag[1]
1528
1697
  end
1698
+
1529
1699
  if opt[:output] == 'json'
1530
1700
 
1531
- items_out << {
1701
+ i = {
1532
1702
  date: i['date'],
1533
1703
  end_date: end_date,
1534
1704
  title: title.strip, #+ " #{note}"
@@ -1537,6 +1707,10 @@ class WWID
1537
1707
  tags: tags
1538
1708
  }
1539
1709
 
1710
+ attributes.each { |attr, val| i[attr.to_sym] = val }
1711
+
1712
+ items_out << i
1713
+
1540
1714
  elsif opt[:output] == 'timeline'
1541
1715
  new_item = {
1542
1716
  'id' => index + 1,
@@ -1640,7 +1814,7 @@ class WWID
1640
1814
 
1641
1815
  totals = opt[:totals] ? tag_times('html', opt[:sort_tags]) : ''
1642
1816
  engine = Haml::Engine.new(template)
1643
- puts engine.render(Object.new,
1817
+ out = engine.render(Object.new,
1644
1818
  { :@items => items_out, :@page_title => page_title, :@style => style, :@totals => totals })
1645
1819
  else
1646
1820
  items.each do |item|
@@ -1652,11 +1826,12 @@ class WWID
1652
1826
  reset = ''
1653
1827
  end
1654
1828
 
1655
- if (item.has_key?('note') && !item['note'].empty?) && @config[:include_notes]
1829
+ if (item.key?('note') && !item['note'].empty?) && @config[:include_notes]
1656
1830
  note_lines = item['note'].delete_if do |line|
1657
- line =~ /^\s*$/
1658
- end.map { |line| "\t\t" + line.sub(/^\t*/, '').sub(/^-/, '—') + ' ' }
1659
- if opt[:wrap_width] && opt[:wrap_width] > 0
1831
+ line =~ /^\s*$/
1832
+ end
1833
+ note_lines.map! { |line| "\t\t#{line.sub(/^\t*/, '').sub(/^-/, '—')} " }
1834
+ if opt[:wrap_width]&.positive?
1660
1835
  width = opt[:wrap_width]
1661
1836
  note_lines.map! do |line|
1662
1837
  line.strip.gsub(/(.{1,#{width}})(\s+|\Z)/, "\t\\1\n")
@@ -1669,7 +1844,7 @@ class WWID
1669
1844
  output = opt[:template].dup
1670
1845
 
1671
1846
  output.gsub!(/%[a-z]+/) do |m|
1672
- if colors.has_key?(m.sub(/^%/, ''))
1847
+ if colors.key?(m.sub(/^%/, ''))
1673
1848
  colors[m.sub(/^%/, '')]
1674
1849
  else
1675
1850
  m
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doing
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.74
4
+ version: 1.0.79
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Terpstra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-16 00:00:00.000000000 Z
11
+ date: 2021-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -168,6 +168,7 @@ files:
168
168
  - lib/doing/helpers.rb
169
169
  - lib/doing/version.rb
170
170
  - lib/doing/wwid.rb
171
+ - lib/helpers/fuzzyfilefinder
171
172
  - lib/templates/doing.css
172
173
  - lib/templates/doing.haml
173
174
  homepage: http://brettterpstra.com/project/doing/