doing 2.1.24 → 2.1.25

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.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/.yardoc/checksums +11 -10
  3. data/.yardoc/object_types +0 -0
  4. data/.yardoc/objects/root.dat +0 -0
  5. data/CHANGELOG.md +17 -0
  6. data/Gemfile.lock +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +2 -1
  9. data/bin/doing +81 -37
  10. data/docs/doc/Array.html +70 -7
  11. data/docs/doc/BooleanTermParser/Clause.html +5 -5
  12. data/docs/doc/BooleanTermParser/Operator.html +4 -4
  13. data/docs/doc/BooleanTermParser/Query.html +8 -8
  14. data/docs/doc/BooleanTermParser/QueryParser.html +2 -2
  15. data/docs/doc/BooleanTermParser/QueryTransformer.html +2 -2
  16. data/docs/doc/BooleanTermParser.html +1 -1
  17. data/docs/doc/Doing/Color.html +4 -4
  18. data/docs/doc/Doing/Completion.html +2 -2
  19. data/docs/doc/Doing/Configuration.html +14 -16
  20. data/docs/doc/Doing/Errors/DoingNoTraceError.html +2 -2
  21. data/docs/doc/Doing/Errors/DoingRuntimeError.html +2 -2
  22. data/docs/doc/Doing/Errors/DoingStandardError.html +2 -2
  23. data/docs/doc/Doing/Errors/EmptyInput.html +2 -2
  24. data/docs/doc/Doing/Errors/NoResults.html +2 -2
  25. data/docs/doc/Doing/Errors/PluginException.html +3 -3
  26. data/docs/doc/Doing/Errors/UserCancelled.html +2 -2
  27. data/docs/doc/Doing/Errors/WrongCommand.html +2 -2
  28. data/docs/doc/Doing/Errors.html +1 -1
  29. data/docs/doc/Doing/Hooks.html +6 -6
  30. data/docs/doc/Doing/Item.html +50 -16
  31. data/docs/doc/Doing/Items.html +10 -10
  32. data/docs/doc/Doing/LogAdapter.html +24 -24
  33. data/docs/doc/Doing/Note.html +7 -7
  34. data/docs/doc/Doing/Pager.html +4 -4
  35. data/docs/doc/Doing/Plugins.html +7 -7
  36. data/docs/doc/Doing/Prompt.html +14 -14
  37. data/docs/doc/Doing/Section.html +6 -6
  38. data/docs/doc/Doing/TemplateString.html +8 -8
  39. data/docs/doc/Doing/Types.html +6 -1
  40. data/docs/doc/Doing/Util/Backup.html +10 -10
  41. data/docs/doc/Doing/Util.html +15 -15
  42. data/docs/doc/Doing/WWID.html +65 -53
  43. data/docs/doc/Doing.html +3 -3
  44. data/docs/doc/GLI/Commands/Help.html +3 -3
  45. data/docs/doc/GLI/Commands/MarkdownDocumentListener.html +17 -17
  46. data/docs/doc/GLI/Commands.html +1 -1
  47. data/docs/doc/GLI.html +1 -1
  48. data/docs/doc/Hash.html +45 -11
  49. data/docs/doc/Numeric.html +5 -5
  50. data/docs/doc/PhraseParser/Operator.html +4 -4
  51. data/docs/doc/PhraseParser/PhraseClause.html +5 -5
  52. data/docs/doc/PhraseParser/Query.html +10 -10
  53. data/docs/doc/PhraseParser/QueryParser.html +2 -2
  54. data/docs/doc/PhraseParser/QueryTransformer.html +2 -2
  55. data/docs/doc/PhraseParser/TermClause.html +5 -5
  56. data/docs/doc/PhraseParser.html +1 -1
  57. data/docs/doc/Status.html +7 -7
  58. data/docs/doc/String.html +107 -44
  59. data/docs/doc/Symbol.html +8 -8
  60. data/docs/doc/Time.html +6 -6
  61. data/docs/doc/_index.html +41 -18
  62. data/docs/doc/class_list.html +1 -1
  63. data/docs/doc/file.README.html +2 -2
  64. data/docs/doc/index.html +2 -2
  65. data/docs/doc/method_list.html +369 -313
  66. data/docs/doc/top-level-namespace.html +2 -2
  67. data/doing.rdoc +19 -11
  68. data/example_plugin.rb +2 -2
  69. data/lib/completion/_doing.zsh +12 -12
  70. data/lib/completion/doing.bash +2 -2
  71. data/lib/completion/doing.fish +9 -8
  72. data/lib/doing/changelog/changes.rb +1 -1
  73. data/lib/doing/configuration.rb +4 -6
  74. data/lib/doing/good.rb +64 -0
  75. data/lib/doing/hash.rb +4 -0
  76. data/lib/doing/hooks.rb +3 -3
  77. data/lib/doing/item.rb +14 -10
  78. data/lib/doing/plugins/import/calendar_import.rb +1 -1
  79. data/lib/doing/plugins/import/doing_import.rb +1 -1
  80. data/lib/doing/plugins/import/timing_import.rb +1 -1
  81. data/lib/doing/string.rb +1 -1
  82. data/lib/doing/template_string.rb +2 -2
  83. data/lib/doing/types.rb +1 -0
  84. data/lib/doing/util.rb +10 -10
  85. data/lib/doing/version.rb +1 -1
  86. data/lib/doing/wwid.rb +40 -18
  87. data/lib/doing.rb +1 -0
  88. data/lib/helpers/threaded_tests.rb +35 -64
  89. data/lib/helpers/threaded_tests_string.rb +50 -0
  90. metadata +4 -2
@@ -86,7 +86,7 @@
86
86
 
87
87
 
88
88
 
89
- <strong class="classes">Classes:</strong> <span class='object_link'><a href="Array.html" title="Array (class)">Array</a></span>, <span class='object_link'><a href="Hash.html" title="Hash (class)">Hash</a></span>, <span class='object_link'><a href="Numeric.html" title="Numeric (class)">Numeric</a></span>, <span class='object_link'><a href="String.html" title="String (class)">String</a></span>, <span class='object_link'><a href="Symbol.html" title="Symbol (class)">Symbol</a></span>, <span class='object_link'><a href="Time.html" title="Time (class)">Time</a></span>
89
+ <strong class="classes">Classes:</strong> <span class='object_link'><a href="Array.html" title="Array (class)">Array</a></span>, <span class='object_link'><a href="FalseClass.html" title="FalseClass (class)">FalseClass</a></span>, <span class='object_link'><a href="Hash.html" title="Hash (class)">Hash</a></span>, <span class='object_link'><a href="Numeric.html" title="Numeric (class)">Numeric</a></span>, <span class='object_link'><a href="Object.html" title="Object (class)">Object</a></span>, <span class='object_link'><a href="String.html" title="String (class)">String</a></span>, <span class='object_link'><a href="Symbol.html" title="Symbol (class)">Symbol</a></span>, <span class='object_link'><a href="Time.html" title="Time (class)">Time</a></span>, <span class='object_link'><a href="TrueClass.html" title="TrueClass (class)">TrueClass</a></span>
90
90
 
91
91
 
92
92
  </p>
@@ -102,7 +102,7 @@
102
102
  </div>
103
103
 
104
104
  <div id="footer">
105
- Generated on Sat Jan 22 17:30:14 2022 by
105
+ Generated on Sun Jan 23 09:24:04 2022 by
106
106
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
107
107
  0.9.27 (ruby-3.0.1).
108
108
  </div>
data/doing.rdoc CHANGED
@@ -5,7 +5,7 @@ record of what you've been doing, complete with tag-based time tracking. The
5
5
  command line tool allows you to add entries, annotate with tags and notes, and
6
6
  view your entries with myriad options, with a focus on a "natural" language syntax.
7
7
 
8
- v2.1.24
8
+ v2.1.25
9
9
 
10
10
  === Global Options
11
11
  === --config_file arg
@@ -165,7 +165,7 @@ Prompt for note via multi-line input
165
165
 
166
166
 
167
167
  ===== -e|--editor
168
- Edit duplicated entry with vim before adding
168
+ Edit duplicated entry with /opt/homebrew/bin/vim before adding
169
169
 
170
170
 
171
171
 
@@ -625,7 +625,7 @@ Include date
625
625
 
626
626
 
627
627
  ===== -e|--editor
628
- Edit entry with vim (with no arguments, edits the last entry)
628
+ Edit entry with /opt/homebrew/bin/vim (with no arguments, edits the last entry)
629
629
 
630
630
 
631
631
 
@@ -857,7 +857,7 @@ Show elapsed time on entries without @done tag
857
857
 
858
858
 
859
859
  ===== -e|--editor
860
- Edit matching entries with vim
860
+ Edit matching entries with /opt/homebrew/bin/vim
861
861
 
862
862
 
863
863
 
@@ -1078,7 +1078,7 @@ Show elapsed time if entry is not tagged @done
1078
1078
 
1079
1079
 
1080
1080
  ===== -e|--editor
1081
- Edit entry with vim
1081
+ Edit entry with /opt/homebrew/bin/vim
1082
1082
 
1083
1083
 
1084
1084
 
@@ -1122,7 +1122,7 @@ Prompt for note via multi-line input
1122
1122
 
1123
1123
 
1124
1124
  ===== -e|--editor
1125
- Edit entry with vim
1125
+ Edit entry with /opt/homebrew/bin/vim
1126
1126
 
1127
1127
 
1128
1128
 
@@ -1260,7 +1260,7 @@ Prompt for note via multi-line input
1260
1260
 
1261
1261
 
1262
1262
  ===== -e|--editor
1263
- Edit entry with vim
1263
+ Edit entry with /opt/homebrew/bin/vim
1264
1264
 
1265
1265
 
1266
1266
 
@@ -1324,7 +1324,7 @@ Prompt for note via multi-line input
1324
1324
 
1325
1325
 
1326
1326
  ===== -e|--editor
1327
- Edit entry with vim
1327
+ Edit entry with /opt/homebrew/bin/vim
1328
1328
 
1329
1329
 
1330
1330
 
@@ -1357,7 +1357,7 @@ A parenthetical at the end of the entry will be converted to a note.
1357
1357
 
1358
1358
  Run without arguments to create a new entry interactively.
1359
1359
 
1360
- Run with --editor to create a new entry using vim.
1360
+ Run with --editor to create a new entry using /opt/homebrew/bin/vim.
1361
1361
  ===== Options
1362
1362
  ===== -b|--back|--started DATE_STRING
1363
1363
 
@@ -1366,6 +1366,14 @@ Backdate start time [4pm|20m|2h|"yesterday noon"]
1366
1366
  [Default Value] None
1367
1367
 
1368
1368
 
1369
+ ===== --from TIME_RANGE
1370
+
1371
+ Set a start and optionally end time as a date range ("from 1pm to 2:30pm").
1372
+ If an end time is provided, a dated @done tag will be added
1373
+
1374
+ [Default Value] None
1375
+
1376
+
1369
1377
  ===== -n|--note TEXT
1370
1378
 
1371
1379
  Include a note
@@ -1386,7 +1394,7 @@ Prompt for note via multi-line input
1386
1394
 
1387
1395
 
1388
1396
  ===== -e|--editor
1389
- Edit entry with vim
1397
+ Edit entry with /opt/homebrew/bin/vim
1390
1398
 
1391
1399
 
1392
1400
 
@@ -1457,7 +1465,7 @@ Show time totals at the end of output
1457
1465
  Open the "doing" file in an editor
1458
1466
 
1459
1467
  `doing open` defaults to using the editors->doing_file setting
1460
- in /Users/ttscoff/.config/doing/config.yml (TaskPaper).
1468
+ in /Users/ttscoff/.config/doing/config.yml (/opt/homebrew/bin/vim).
1461
1469
  ===== Options
1462
1470
  ===== -a|--app APP_NAME
1463
1471
 
data/example_plugin.rb CHANGED
@@ -123,7 +123,7 @@ module Doing
123
123
  ## @return [String] Rendered output
124
124
  ##
125
125
  def self.render(wwid, items, variables: {})
126
- return if items.nil? || items.empty?
126
+ return unless items.good?
127
127
 
128
128
  # the :options key includes the flags passed to the
129
129
  # command that called the plugin use `puts
@@ -164,7 +164,7 @@ module Doing
164
164
 
165
165
  if wwid.config['export_templates'].key?('say')
166
166
  cfg_tpl = wwid.config['export_templates']['say']
167
- tpl = cfg_tpl unless cfg_tpl.nil? || cfg_tpl.empty?
167
+ tpl = cfg_tpl if cfg_tpl.good?
168
168
  end
169
169
  output = tpl.dup
170
170
  output.gsub!(/%date/, date)
@@ -70,10 +70,10 @@ function _doing() {
70
70
  args=( )
71
71
  ;;
72
72
  again)
73
- args=( "(--ask)--ask}[Prompt for note via multi-line input]" "(--started=)--started=}[Backdate start date by interval or set to time [4pm|20m|2h|"yesterday noon"]]" "(--bool=)--bool=}[Boolean used to combine multiple tags]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" {-e,--editor}"[Edit duplicated entry with vim before adding]" {-i,--interactive}"[Select item to resume from a menu of matching entries]" "(--in=)--in=}[Add new entry to section]" {-n,--note=}"[Add a note]" "(--not)--not}[Resume items that *dont* match search/tag filterst* match search/tag filters]" {-s,--section=}"[Get last entry from a specific section]" "(--search=)--search=}[Repeat last entry matching search]" "(--tag=)--tag=}[Repeat last entry matching tags]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact search string matching]" )
73
+ args=( "(--ask)--ask}[Prompt for note via multi-line input]" "(--started=)--started=}[Backdate start date by interval or set to time [4pm|20m|2h|"yesterday noon"]]" "(--bool=)--bool=}[Boolean used to combine multiple tags]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" {-e,--editor}"[Edit duplicated entry with /opt/homebrew/bin/vim before adding]" {-i,--interactive}"[Select item to resume from a menu of matching entries]" "(--in=)--in=}[Add new entry to section]" {-n,--note=}"[Add a note]" "(--not)--not}[Resume items that *dont* match search/tag filterst* match search/tag filters]" {-s,--section=}"[Get last entry from a specific section]" "(--search=)--search=}[Repeat last entry matching search]" "(--tag=)--tag=}[Repeat last entry matching tags]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact search string matching]" )
74
74
  ;;
75
75
  resume)
76
- args=( "(--ask)--ask}[Prompt for note via multi-line input]" "(--started=)--started=}[Backdate start date by interval or set to time [4pm|20m|2h|"yesterday noon"]]" "(--bool=)--bool=}[Boolean used to combine multiple tags]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" {-e,--editor}"[Edit duplicated entry with vim before adding]" {-i,--interactive}"[Select item to resume from a menu of matching entries]" "(--in=)--in=}[Add new entry to section]" {-n,--note=}"[Add a note]" "(--not)--not}[Resume items that *dont* match search/tag filterst* match search/tag filters]" {-s,--section=}"[Get last entry from a specific section]" "(--search=)--search=}[Repeat last entry matching search]" "(--tag=)--tag=}[Repeat last entry matching tags]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact search string matching]" )
76
+ args=( "(--ask)--ask}[Prompt for note via multi-line input]" "(--started=)--started=}[Backdate start date by interval or set to time [4pm|20m|2h|"yesterday noon"]]" "(--bool=)--bool=}[Boolean used to combine multiple tags]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" {-e,--editor}"[Edit duplicated entry with /opt/homebrew/bin/vim before adding]" {-i,--interactive}"[Select item to resume from a menu of matching entries]" "(--in=)--in=}[Add new entry to section]" {-n,--note=}"[Add a note]" "(--not)--not}[Resume items that *dont* match search/tag filterst* match search/tag filters]" {-s,--section=}"[Get last entry from a specific section]" "(--search=)--search=}[Repeat last entry matching search]" "(--tag=)--tag=}[Repeat last entry matching tags]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact search string matching]" )
77
77
  ;;
78
78
  archive)
79
79
  args=( "(--before=)--before=}[Archive entries older than date]" "(--bool=)--bool=}[Tag boolean]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" {-k,--keep=}"[How many items to keep]" "(--label)--label}[Label moved items with @from(SECTION_NAME)]" "(--not)--not}[Show items that *dont* match search stringt* match search string]" "(--search=)--search=}[Search filter]" {-t,--to=}"[Move entries to]" "(--tag=)--tag=}[Tag filter]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact search string matching]" )
@@ -106,19 +106,19 @@ function _doing() {
106
106
  args=( {-d,--dump}"[DEPRECATED]" {-u,--update}"[DEPRECATED]" )
107
107
  ;;
108
108
  done)
109
- args=( {-a,--archive}"[Immediately archive the entry]" "(--ask)--ask}[Prompt for note via multi-line input]" "(--finished=)--finished=}[Set finish date to specific date/time]" "(--started=)--started=}[Backdate start date by interval or set to time [4pm|20m|2h|"yesterday noon"]]" "(--date)--date}[Include date]" {-e,--editor}"[Edit entry with vim]" "(--from=)--from=}[Start and end times as a date/time range `doing done --from "1am to 8am"`]" {-n,--note=}"[Include a note]" {-r,--remove}"[Remove @done tag]" {-s,--section=}"[Section]" "(--for=)--for=}[Set completion date to start date plus interval]" {-u,--unfinished}"[Finish last entry not already marked @done]" )
109
+ args=( {-a,--archive}"[Immediately archive the entry]" "(--ask)--ask}[Prompt for note via multi-line input]" "(--finished=)--finished=}[Set finish date to specific date/time]" "(--started=)--started=}[Backdate start date by interval or set to time [4pm|20m|2h|"yesterday noon"]]" "(--date)--date}[Include date]" {-e,--editor}"[Edit entry with /opt/homebrew/bin/vim]" "(--from=)--from=}[Start and end times as a date/time range `doing done --from "1am to 8am"`]" {-n,--note=}"[Include a note]" {-r,--remove}"[Remove @done tag]" {-s,--section=}"[Section]" "(--for=)--for=}[Set completion date to start date plus interval]" {-u,--unfinished}"[Finish last entry not already marked @done]" )
110
110
  ;;
111
111
  did)
112
- args=( {-a,--archive}"[Immediately archive the entry]" "(--ask)--ask}[Prompt for note via multi-line input]" "(--finished=)--finished=}[Set finish date to specific date/time]" "(--started=)--started=}[Backdate start date by interval or set to time [4pm|20m|2h|"yesterday noon"]]" "(--date)--date}[Include date]" {-e,--editor}"[Edit entry with vim]" "(--from=)--from=}[Start and end times as a date/time range `doing done --from "1am to 8am"`]" {-n,--note=}"[Include a note]" {-r,--remove}"[Remove @done tag]" {-s,--section=}"[Section]" "(--for=)--for=}[Set completion date to start date plus interval]" {-u,--unfinished}"[Finish last entry not already marked @done]" )
112
+ args=( {-a,--archive}"[Immediately archive the entry]" "(--ask)--ask}[Prompt for note via multi-line input]" "(--finished=)--finished=}[Set finish date to specific date/time]" "(--started=)--started=}[Backdate start date by interval or set to time [4pm|20m|2h|"yesterday noon"]]" "(--date)--date}[Include date]" {-e,--editor}"[Edit entry with /opt/homebrew/bin/vim]" "(--from=)--from=}[Start and end times as a date/time range `doing done --from "1am to 8am"`]" {-n,--note=}"[Include a note]" {-r,--remove}"[Remove @done tag]" {-s,--section=}"[Section]" "(--for=)--for=}[Set completion date to start date plus interval]" {-u,--unfinished}"[Finish last entry not already marked @done]" )
113
113
  ;;
114
114
  finish)
115
115
  args=( {-a,--archive}"[Archive entries]" "(--finished=)--finished=}[Set finish date to specific date/time]" "(--auto)--auto}[Auto-generate finish dates from next entrys start times start time]" "(--started=)--started=}[Backdate completed date to date string [4pm|20m|2h|yesterday noon]]" "(--bool=)--bool=}[Boolean]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" "(--date)--date}[Include date]" {-i,--interactive}"[Select item(s) to finish from a menu of matching entries]" "(--not)--not}[Finish items that *dont* match search/tag filterst* match search/tag filters]" {-r,--remove}"[Remove done tag]" {-s,--section=}"[Section]" "(--search=)--search=}[Finish the last X entries matching search filter]" "(--for=)--for=}[Set the completed date to the start date plus XX[hmd]]" "(--tag=)--tag=}[Finish the last X entries containing TAG]" {-u,--unfinished}"[Finish last entry]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact search string matching]" )
116
116
  ;;
117
117
  grep)
118
- args=( "(--after=)--after=}[Search entries newer than date]" "(--before=)--before=}[Search entries older than date]" "(--bool=)--bool=}[Combine multiple tags or value queries using AND]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" "(--config_template=)--config_template=}[Output using a template from configuration]" {-d,--delete}"[Delete matching entries]" "(--duration)--duration}[Show elapsed time on entries without @done tag]" {-e,--editor}"[Edit matching entries with vim]" "(--from=)--from=}[Date range to show]" {-h,--hilite}"[Highlight search matches in output]" {-i,--interactive}"[Display an interactive menu of results to perform further operations]" "(--not)--not}[Show items that *dont* match search stringt* match search string]" {-o,--output=}"[Output to export format]" "(--only_timed)--only_timed}[Only show items with recorded time intervals]" {-s,--section=}"[Section]" {-t,--times}"[Show time intervals on @done tasks]" "(--tag_sort=)--tag_sort=}[Sort tags by]" "(--template=)--template=}[Override output format with a template string containing %placeholders]" "(--totals)--totals}[Show intervals with totals at the end of output]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact string matching]" )
118
+ args=( "(--after=)--after=}[Search entries newer than date]" "(--before=)--before=}[Search entries older than date]" "(--bool=)--bool=}[Combine multiple tags or value queries using AND]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" "(--config_template=)--config_template=}[Output using a template from configuration]" {-d,--delete}"[Delete matching entries]" "(--duration)--duration}[Show elapsed time on entries without @done tag]" {-e,--editor}"[Edit matching entries with /opt/homebrew/bin/vim]" "(--from=)--from=}[Date range to show]" {-h,--hilite}"[Highlight search matches in output]" {-i,--interactive}"[Display an interactive menu of results to perform further operations]" "(--not)--not}[Show items that *dont* match search stringt* match search string]" {-o,--output=}"[Output to export format]" "(--only_timed)--only_timed}[Only show items with recorded time intervals]" {-s,--section=}"[Section]" {-t,--times}"[Show time intervals on @done tasks]" "(--tag_sort=)--tag_sort=}[Sort tags by]" "(--template=)--template=}[Override output format with a template string containing %placeholders]" "(--totals)--totals}[Show intervals with totals at the end of output]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact string matching]" )
119
119
  ;;
120
120
  search)
121
- args=( "(--after=)--after=}[Search entries newer than date]" "(--before=)--before=}[Search entries older than date]" "(--bool=)--bool=}[Combine multiple tags or value queries using AND]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" "(--config_template=)--config_template=}[Output using a template from configuration]" {-d,--delete}"[Delete matching entries]" "(--duration)--duration}[Show elapsed time on entries without @done tag]" {-e,--editor}"[Edit matching entries with vim]" "(--from=)--from=}[Date range to show]" {-h,--hilite}"[Highlight search matches in output]" {-i,--interactive}"[Display an interactive menu of results to perform further operations]" "(--not)--not}[Show items that *dont* match search stringt* match search string]" {-o,--output=}"[Output to export format]" "(--only_timed)--only_timed}[Only show items with recorded time intervals]" {-s,--section=}"[Section]" {-t,--times}"[Show time intervals on @done tasks]" "(--tag_sort=)--tag_sort=}[Sort tags by]" "(--template=)--template=}[Override output format with a template string containing %placeholders]" "(--totals)--totals}[Show intervals with totals at the end of output]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact string matching]" )
121
+ args=( "(--after=)--after=}[Search entries newer than date]" "(--before=)--before=}[Search entries older than date]" "(--bool=)--bool=}[Combine multiple tags or value queries using AND]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" "(--config_template=)--config_template=}[Output using a template from configuration]" {-d,--delete}"[Delete matching entries]" "(--duration)--duration}[Show elapsed time on entries without @done tag]" {-e,--editor}"[Edit matching entries with /opt/homebrew/bin/vim]" "(--from=)--from=}[Date range to show]" {-h,--hilite}"[Highlight search matches in output]" {-i,--interactive}"[Display an interactive menu of results to perform further operations]" "(--not)--not}[Show items that *dont* match search stringt* match search string]" {-o,--output=}"[Output to export format]" "(--only_timed)--only_timed}[Only show items with recorded time intervals]" {-s,--section=}"[Section]" {-t,--times}"[Show time intervals on @done tasks]" "(--tag_sort=)--tag_sort=}[Sort tags by]" "(--template=)--template=}[Override output format with a template string containing %placeholders]" "(--totals)--totals}[Show intervals with totals at the end of output]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact string matching]" )
122
122
  ;;
123
123
  help)
124
124
  args=( )
@@ -127,10 +127,10 @@ function _doing() {
127
127
  args=( "(--after=)--after=}[Import entries newer than date]" "(--autotag)--autotag}[Autotag entries]" "(--before=)--before=}[Import entries older than date]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" {-f,--from=}"[Date range to import]" "(--not)--not}[Import items that *dont* match search/tag/date filterst* match search/tag/date filters]" "(--only_timed)--only_timed}[Only import items with recorded time intervals]" "(--overlap)--overlap}[Allow entries that overlap existing times]" "(--prefix=)--prefix=}[Prefix entries with]" {-s,--section=}"[Target section]" "(--search=)--search=}[Only import items matching search]" {-t,--tag=}"[Tag all imported entries]" "(--type=)--type=}[Import type]" {-x,--exact}"[Force exact search string matching]" )
128
128
  ;;
129
129
  last)
130
- args=( "(--bool=)--bool=}[Tag boolean]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" "(--config_template=)--config_template=}[Output using a template from configuration]" {-d,--delete}"[Delete the last entry]" "(--duration)--duration}[Show elapsed time if entry is not tagged @done]" {-e,--editor}"[Edit entry with vim]" {-h,--hilite}"[Highlight search matches in output]" "(--not)--not}[Show items that *dont* match search string or tag filtert* match search string or tag filter]" {-s,--section=}"[Specify a section]" "(--search=)--search=}[Search filter]" "(--tag=)--tag=}[Tag filter]" "(--template=)--template=}[Override output format with a template string containing %placeholders]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact search string matching]" )
130
+ args=( "(--bool=)--bool=}[Tag boolean]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" "(--config_template=)--config_template=}[Output using a template from configuration]" {-d,--delete}"[Delete the last entry]" "(--duration)--duration}[Show elapsed time if entry is not tagged @done]" {-e,--editor}"[Edit entry with /opt/homebrew/bin/vim]" {-h,--hilite}"[Highlight search matches in output]" "(--not)--not}[Show items that *dont* match search string or tag filtert* match search string or tag filter]" {-s,--section=}"[Specify a section]" "(--search=)--search=}[Search filter]" "(--tag=)--tag=}[Tag filter]" "(--template=)--template=}[Override output format with a template string containing %placeholders]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact search string matching]" )
131
131
  ;;
132
132
  later)
133
- args=( "(--ask)--ask}[Prompt for note via multi-line input]" "(--started=)--started=}[Backdate start time to date string [4pm|20m|2h|yesterday noon]]" {-e,--editor}"[Edit entry with vim]" {-n,--note=}"[Note]" )
133
+ args=( "(--ask)--ask}[Prompt for note via multi-line input]" "(--started=)--started=}[Backdate start time to date string [4pm|20m|2h|yesterday noon]]" {-e,--editor}"[Edit entry with /opt/homebrew/bin/vim]" {-n,--note=}"[Note]" )
134
134
  ;;
135
135
  mark)
136
136
  args=( "(--bool=)--bool=}[Boolean]" {-c,--count=}"[How many recent entries to tag]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" {-d,--date}"[Include current date/time with tag]" "(--force)--force}[Dont ask permission to flag all entries when count is 0t ask permission to flag all entries when count is 0]" {-i,--interactive}"[Select item(s) to flag from a menu of matching entries]" "(--not)--not}[Flag items that *dont* match search/tag/date filterst* match search/tag/date filters]" {-r,--remove}"[Remove flag]" {-s,--section=}"[Section]" "(--search=)--search=}[Flag the last entry matching search filter]" "(--tag=)--tag=}[Flag the last entry containing TAG]" {-u,--unfinished}"[Flag last entry]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact search string matching]" )
@@ -139,16 +139,16 @@ function _doing() {
139
139
  args=( "(--bool=)--bool=}[Boolean]" {-c,--count=}"[How many recent entries to tag]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" {-d,--date}"[Include current date/time with tag]" "(--force)--force}[Dont ask permission to flag all entries when count is 0t ask permission to flag all entries when count is 0]" {-i,--interactive}"[Select item(s) to flag from a menu of matching entries]" "(--not)--not}[Flag items that *dont* match search/tag/date filterst* match search/tag/date filters]" {-r,--remove}"[Remove flag]" {-s,--section=}"[Section]" "(--search=)--search=}[Flag the last entry matching search filter]" "(--tag=)--tag=}[Flag the last entry containing TAG]" {-u,--unfinished}"[Flag last entry]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact search string matching]" )
140
140
  ;;
141
141
  meanwhile)
142
- args=( {-a,--archive}"[Archive previous @meanwhile entry]" "(--ask)--ask}[Prompt for note via multi-line input]" "(--started=)--started=}[Backdate start date for new entry to date string [4pm|20m|2h|yesterday noon]]" {-e,--editor}"[Edit entry with vim]" {-n,--note=}"[Note]" {-s,--section=}"[Section]" )
142
+ args=( {-a,--archive}"[Archive previous @meanwhile entry]" "(--ask)--ask}[Prompt for note via multi-line input]" "(--started=)--started=}[Backdate start date for new entry to date string [4pm|20m|2h|yesterday noon]]" {-e,--editor}"[Edit entry with /opt/homebrew/bin/vim]" {-n,--note=}"[Note]" {-s,--section=}"[Section]" )
143
143
  ;;
144
144
  note)
145
- args=( "(--ask)--ask}[Prompt for note via multi-line input]" "(--bool=)--bool=}[Boolean]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" {-e,--editor}"[Edit entry with vim]" {-i,--interactive}"[Select item for new note from a menu of matching entries]" "(--not)--not}[Add note to item that *doesnt* match search/tag filterst* match search/tag filters]" {-r,--remove}"[Replace/Remove last entrys notes note]" {-s,--section=}"[Section]" "(--search=)--search=}[Add/remove note from last entry matching search filter]" "(--tag=)--tag=}[Add/remove note from last entry matching tag]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact search string matching]" )
145
+ args=( "(--ask)--ask}[Prompt for note via multi-line input]" "(--bool=)--bool=}[Boolean]" "(--case=)--case=}[Case sensitivity for search string matching [(c)ase-sensitive]" {-e,--editor}"[Edit entry with /opt/homebrew/bin/vim]" {-i,--interactive}"[Select item for new note from a menu of matching entries]" "(--not)--not}[Add note to item that *doesnt* match search/tag filterst* match search/tag filters]" {-r,--remove}"[Replace/Remove last entrys notes note]" {-s,--section=}"[Section]" "(--search=)--search=}[Add/remove note from last entry matching search filter]" "(--tag=)--tag=}[Add/remove note from last entry matching tag]" "(--val=)--val=}[Perform a tag value query]" {-x,--exact}"[Force exact search string matching]" )
146
146
  ;;
147
147
  now)
148
- args=( "(--ask)--ask}[Prompt for note via multi-line input]" "(--started=)--started=}[Backdate start time [4pm|20m|2h|"yesterday noon"]]" {-e,--editor}"[Edit entry with vim]" {-f,--finish_last}"[Timed entry]" {-n,--note=}"[Include a note]" {-s,--section=}"[Section]" )
148
+ args=( "(--ask)--ask}[Prompt for note via multi-line input]" "(--started=)--started=}[Backdate start time [4pm|20m|2h|"yesterday noon"]]" {-e,--editor}"[Edit entry with /opt/homebrew/bin/vim]" {-f,--finish_last}"[Timed entry]" "(--from=)--from=}[Set a start and optionally end time as a date range]" {-n,--note=}"[Include a note]" {-s,--section=}"[Section]" )
149
149
  ;;
150
150
  next)
151
- args=( "(--ask)--ask}[Prompt for note via multi-line input]" "(--started=)--started=}[Backdate start time [4pm|20m|2h|"yesterday noon"]]" {-e,--editor}"[Edit entry with vim]" {-f,--finish_last}"[Timed entry]" {-n,--note=}"[Include a note]" {-s,--section=}"[Section]" )
151
+ args=( "(--ask)--ask}[Prompt for note via multi-line input]" "(--started=)--started=}[Backdate start time [4pm|20m|2h|"yesterday noon"]]" {-e,--editor}"[Edit entry with /opt/homebrew/bin/vim]" {-f,--finish_last}"[Timed entry]" "(--from=)--from=}[Set a start and optionally end time as a date range]" {-n,--note=}"[Include a note]" {-s,--section=}"[Section]" )
152
152
  ;;
153
153
  on)
154
154
  args=( "(--config_template=)--config_template=}[Output using a template from configuration]" "(--duration)--duration}[Show elapsed time on entries without @done tag]" {-o,--output=}"[Output to export format]" {-s,--section=}"[Section]" {-t,--times}"[Show time intervals on @done tasks]" "(--tag_sort=)--tag_sort=}[Sort tags by]" "(--template=)--template=}[Override output format with a template string containing %placeholders]" "(--totals)--totals}[Show time totals at the end of output]" )
@@ -191,9 +191,9 @@ _doing_note() {
191
191
  _doing_now() {
192
192
 
193
193
  if [[ "$token" == --* ]]; then
194
- COMPREPLY=( $( compgen -W '--ask --started --editor --finish_last --note --section' -- $token ) )
194
+ COMPREPLY=( $( compgen -W '--ask --started --editor --finish_last --from --note --section' -- $token ) )
195
195
  elif [[ "$token" == -* ]]; then
196
- COMPREPLY=( $( compgen -W '-e -f -n -s --ask --started --editor --finish_last --note --section' -- $token ) )
196
+ COMPREPLY=( $( compgen -W '-e -f -n -s --ask --started --editor --finish_last --from --note --section' -- $token ) )
197
197
 
198
198
  fi
199
199
  }
@@ -181,7 +181,7 @@ complete -c doing -l ask -f -n '__fish_doing_using_command again resume' -d Pr
181
181
  complete -c doing -l started -f -r -n '__fish_doing_using_command again resume' -d Backdate\ start\ date\ by\ interval\ or\ set\ to\ time\ \[4pm\|20m\|2h\|\"yesterday\ noon\"\]
182
182
  complete -c doing -l bool -f -r -n '__fish_doing_using_command again resume' -d Boolean\ used\ to\ combine\ multiple\ tags
183
183
  complete -c doing -l case -f -r -n '__fish_doing_using_command again resume' -d Case\ sensitivity\ for\ search\ string\ matching\ \[\(c\)ase-sensitive
184
- complete -c doing -l editor -s e -f -n '__fish_doing_using_command again resume' -d Edit\ duplicated\ entry\ with\ vim\ before\ adding
184
+ complete -c doing -l editor -s e -f -n '__fish_doing_using_command again resume' -d Edit\ duplicated\ entry\ with\ /opt/homebrew/bin/vim\ before\ adding
185
185
  complete -c doing -l interactive -s i -f -n '__fish_doing_using_command again resume' -d Select\ item\ to\ resume\ from\ a\ menu\ of\ matching\ entries
186
186
  complete -c doing -l in -f -r -n '__fish_doing_using_command again resume' -d Add\ new\ entry\ to\ section
187
187
  complete -c doing -l note -s n -f -r -n '__fish_doing_using_command again resume' -d Add\ a\ note
@@ -233,7 +233,7 @@ complete -c doing -l ask -f -n '__fish_doing_using_command done did' -d Prompt
233
233
  complete -c doing -l finished -f -r -n '__fish_doing_using_command done did' -d Set\ finish\ date\ to\ specific\ date/time
234
234
  complete -c doing -l started -f -r -n '__fish_doing_using_command done did' -d Backdate\ start\ date\ by\ interval\ or\ set\ to\ time\ \[4pm\|20m\|2h\|\"yesterday\ noon\"\]
235
235
  complete -c doing -l date -f -n '__fish_doing_using_command done did' -d Include\ date
236
- complete -c doing -l editor -s e -f -n '__fish_doing_using_command done did' -d Edit\ entry\ with\ vim
236
+ complete -c doing -l editor -s e -f -n '__fish_doing_using_command done did' -d Edit\ entry\ with\ /opt/homebrew/bin/vim
237
237
  complete -c doing -l from -f -r -n '__fish_doing_using_command done did' -d Start\ and\ end\ times\ as\ a\ date/time\ range\ \`doing\ done\ --from\ \"1am\ to\ 8am\"\`
238
238
  complete -c doing -l note -s n -f -r -n '__fish_doing_using_command done did' -d Include\ a\ note
239
239
  complete -c doing -l remove -s r -f -n '__fish_doing_using_command done did' -d Remove\ @done\ tag
@@ -264,7 +264,7 @@ complete -c doing -l case -f -r -n '__fish_doing_using_command grep search' -d
264
264
  complete -c doing -l config_template -f -r -n '__fish_doing_using_command grep search' -d Output\ using\ a\ template\ from\ configuration
265
265
  complete -c doing -l delete -s d -f -n '__fish_doing_using_command grep search' -d Delete\ matching\ entries
266
266
  complete -c doing -l duration -f -n '__fish_doing_using_command grep search' -d Show\ elapsed\ time\ on\ entries\ without\ @done\ tag
267
- complete -c doing -l editor -s e -f -n '__fish_doing_using_command grep search' -d Edit\ matching\ entries\ with\ vim
267
+ complete -c doing -l editor -s e -f -n '__fish_doing_using_command grep search' -d Edit\ matching\ entries\ with\ /opt/homebrew/bin/vim
268
268
  complete -c doing -l from -f -r -n '__fish_doing_using_command grep search' -d Date\ range\ to\ show
269
269
  complete -c doing -l hilite -s h -f -n '__fish_doing_using_command grep search' -d Highlight\ search\ matches\ in\ output
270
270
  complete -c doing -l interactive -s i -f -n '__fish_doing_using_command grep search' -d Display\ an\ interactive\ menu\ of\ results\ to\ perform\ further\ operations
@@ -298,7 +298,7 @@ complete -c doing -l case -f -r -n '__fish_doing_using_command last' -d Case\ s
298
298
  complete -c doing -l config_template -f -r -n '__fish_doing_using_command last' -d Output\ using\ a\ template\ from\ configuration
299
299
  complete -c doing -l delete -s d -f -n '__fish_doing_using_command last' -d Delete\ the\ last\ entry
300
300
  complete -c doing -l duration -f -n '__fish_doing_using_command last' -d Show\ elapsed\ time\ if\ entry\ is\ not\ tagged\ @done
301
- complete -c doing -l editor -s e -f -n '__fish_doing_using_command last' -d Edit\ entry\ with\ vim
301
+ complete -c doing -l editor -s e -f -n '__fish_doing_using_command last' -d Edit\ entry\ with\ /opt/homebrew/bin/vim
302
302
  complete -c doing -l hilite -s h -f -n '__fish_doing_using_command last' -d Highlight\ search\ matches\ in\ output
303
303
  complete -c doing -l not -f -n '__fish_doing_using_command last' -d Show\ items\ that\ \*don\'t\*\ match\ search\ string\ or\ tag\ filter
304
304
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command last' -d Specify\ a\ section
@@ -309,7 +309,7 @@ complete -c doing -l val -f -r -n '__fish_doing_using_command last' -d Perform\
309
309
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command last' -d Force\ exact\ search\ string\ matching
310
310
  complete -c doing -l ask -f -n '__fish_doing_using_command later' -d Prompt\ for\ note\ via\ multi-line\ input
311
311
  complete -c doing -l started -f -r -n '__fish_doing_using_command later' -d Backdate\ start\ time\ to\ date\ string\ \[4pm\|20m\|2h\|yesterday\ noon\]
312
- complete -c doing -l editor -s e -f -n '__fish_doing_using_command later' -d Edit\ entry\ with\ vim
312
+ complete -c doing -l editor -s e -f -n '__fish_doing_using_command later' -d Edit\ entry\ with\ /opt/homebrew/bin/vim
313
313
  complete -c doing -l note -s n -f -r -n '__fish_doing_using_command later' -d Note
314
314
  complete -c doing -l bool -f -r -n '__fish_doing_using_command mark flag' -d Boolean
315
315
  complete -c doing -l count -s c -f -r -n '__fish_doing_using_command mark flag' -d How\ many\ recent\ entries\ to\ tag
@@ -328,13 +328,13 @@ complete -c doing -l exact -s x -f -n '__fish_doing_using_command mark flag' -d
328
328
  complete -c doing -l archive -s a -f -n '__fish_doing_using_command meanwhile' -d Archive\ previous\ @meanwhile\ entry
329
329
  complete -c doing -l ask -f -n '__fish_doing_using_command meanwhile' -d Prompt\ for\ note\ via\ multi-line\ input
330
330
  complete -c doing -l started -f -r -n '__fish_doing_using_command meanwhile' -d Backdate\ start\ date\ for\ new\ entry\ to\ date\ string\ \[4pm\|20m\|2h\|yesterday\ noon\]
331
- complete -c doing -l editor -s e -f -n '__fish_doing_using_command meanwhile' -d Edit\ entry\ with\ vim
331
+ complete -c doing -l editor -s e -f -n '__fish_doing_using_command meanwhile' -d Edit\ entry\ with\ /opt/homebrew/bin/vim
332
332
  complete -c doing -l note -s n -f -r -n '__fish_doing_using_command meanwhile' -d Note
333
333
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command meanwhile' -d Section
334
334
  complete -c doing -l ask -f -n '__fish_doing_using_command note' -d Prompt\ for\ note\ via\ multi-line\ input
335
335
  complete -c doing -l bool -f -r -n '__fish_doing_using_command note' -d Boolean
336
336
  complete -c doing -l case -f -r -n '__fish_doing_using_command note' -d Case\ sensitivity\ for\ search\ string\ matching\ \[\(c\)ase-sensitive
337
- complete -c doing -l editor -s e -f -n '__fish_doing_using_command note' -d Edit\ entry\ with\ vim
337
+ complete -c doing -l editor -s e -f -n '__fish_doing_using_command note' -d Edit\ entry\ with\ /opt/homebrew/bin/vim
338
338
  complete -c doing -l interactive -s i -f -n '__fish_doing_using_command note' -d Select\ item\ for\ new\ note\ from\ a\ menu\ of\ matching\ entries
339
339
  complete -c doing -l not -f -n '__fish_doing_using_command note' -d Add\ note\ to\ item\ that\ \*doesn\'t\*\ match\ search/tag\ filters
340
340
  complete -c doing -l remove -s r -f -n '__fish_doing_using_command note' -d Replace/Remove\ last\ entry\'s\ note
@@ -345,8 +345,9 @@ complete -c doing -l val -f -r -n '__fish_doing_using_command note' -d Perform\
345
345
  complete -c doing -l exact -s x -f -n '__fish_doing_using_command note' -d Force\ exact\ search\ string\ matching
346
346
  complete -c doing -l ask -f -n '__fish_doing_using_command now next' -d Prompt\ for\ note\ via\ multi-line\ input
347
347
  complete -c doing -l started -f -r -n '__fish_doing_using_command now next' -d Backdate\ start\ time\ \[4pm\|20m\|2h\|\"yesterday\ noon\"\]
348
- complete -c doing -l editor -s e -f -n '__fish_doing_using_command now next' -d Edit\ entry\ with\ vim
348
+ complete -c doing -l editor -s e -f -n '__fish_doing_using_command now next' -d Edit\ entry\ with\ /opt/homebrew/bin/vim
349
349
  complete -c doing -l finish_last -s f -f -n '__fish_doing_using_command now next' -d Timed\ entry
350
+ complete -c doing -l from -f -r -n '__fish_doing_using_command now next' -d Set\ a\ start\ and\ optionally\ end\ time\ as\ a\ date\ range
350
351
  complete -c doing -l note -s n -f -r -n '__fish_doing_using_command now next' -d Include\ a\ note
351
352
  complete -c doing -l section -s s -f -r -n '__fish_doing_using_command now next' -d Section
352
353
  complete -c doing -l config_template -f -r -n '__fish_doing_using_command on' -d Output\ using\ a\ template\ from\ configuration
@@ -24,7 +24,7 @@ module Doing
24
24
  private
25
25
 
26
26
  def parse_changes(lookup, search)
27
- change_rx = /(?<=\n|\A)### (\d+\.\d+\.\d+(?:\w+)?)(.*?)(?=\n### |\Z)/m
27
+ change_rx = /(?<=\n|\A)### (\d+\.\d+\.\d+(?:\w*))(.*)(?=\n### |\Z)/m
28
28
  @changes = @content.scan(change_rx).each_with_object([]) do |m, a|
29
29
  next if m[0].nil? || m[1].nil?
30
30
 
@@ -45,8 +45,7 @@ module Doing
45
45
  'templates' => {
46
46
  'default' => {
47
47
  'date_format' => '%Y-%m-%d %H:%M',
48
- 'template' => '%reset%cyan%shortdate %boldwhite%80║ title %dark%boldmagenta[%boldwhite%-10section%boldmagenta]%reset
49
- %yellow%interval%boldred%duration%dark%white%80_14┃ note',
48
+ 'template' => '%reset%cyan%shortdate %boldwhite%80║ title %boldmagenta[%boldwhite%-10section%boldmagenta]%reset %yellow%interval%boldred%duration%white%80_14┃ note',
50
49
  'wrap_width' => 0,
51
50
  'order' => 'asc'
52
51
  },
@@ -63,8 +62,7 @@ module Doing
63
62
  },
64
63
  'recent' => {
65
64
  'date_format' => '%_I:%M%P',
66
- 'template' => '%reset%cyan%shortdate %boldwhite%80║ title %dark%boldmagenta[%boldwhite%-10section%boldmagenta]%reset
67
- %yellow%interval%boldred%duration%dark%white%80_14┃ note',
65
+ 'template' => '%reset%cyan%shortdate %boldwhite%80║ title %boldmagenta[%boldwhite%-10section%boldmagenta]%reset %yellow%interval%boldred%duration%white%80_14┃ note',
68
66
  'wrap_width' => 88,
69
67
  'count' => 10,
70
68
  'order' => 'asc'
@@ -314,7 +312,7 @@ module Doing
314
312
 
315
313
  @ignore_local = opt[:ignore_local] if opt[:ignore_local]
316
314
 
317
- config = read_config.dup
315
+ config = read_config.clone
318
316
 
319
317
  plugin_config = Util.deep_merge_hashes(DEFAULTS['plugins'], config['plugins'] || {})
320
318
 
@@ -322,7 +320,7 @@ module Doing
322
320
 
323
321
  Plugins.plugins.each do |_type, plugins|
324
322
  plugins.each do |title, plugin|
325
- plugin_config[title] = plugin[:config] if plugin[:config] && !plugin[:config].empty?
323
+ plugin_config[title] = plugin[:config] if plugin[:config].good?
326
324
  config['export_templates'][title] ||= nil if plugin[:templates] && !plugin[:templates].empty?
327
325
  end
328
326
  end
data/lib/doing/good.rb ADDED
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doing
4
+ # Object helpers
5
+ class ::Object
6
+ ##
7
+ ## Tests if object is nil or empty
8
+ ##
9
+ ## @return [Boolean] true if object is defined and
10
+ ## has content
11
+ ##
12
+ def good?
13
+ !nil? && !empty?
14
+ end
15
+ end
16
+
17
+ class ::String
18
+ ##
19
+ ## Tests if object is nil or empty
20
+ ##
21
+ ## @return [Boolean] true if object is defined and
22
+ ## has content
23
+ ##
24
+ def good?
25
+ !strip.empty?
26
+ end
27
+ end
28
+
29
+ class ::Array
30
+ ##
31
+ ## Tests if object is nil or empty
32
+ ##
33
+ ## @return [Boolean] true if object is defined and
34
+ ## has content
35
+ ##
36
+ def good?
37
+ !nil? && !empty?
38
+ end
39
+ end
40
+
41
+ class ::FalseClass
42
+ ##
43
+ ## Tests if object is nil or empty
44
+ ##
45
+ ## @return [Boolean] true if object is defined and
46
+ ## has content
47
+ ##
48
+ def good?
49
+ false
50
+ end
51
+ end
52
+
53
+ class ::TrueClass
54
+ ##
55
+ ## Tests if object is nil or empty
56
+ ##
57
+ ## @return [Boolean] true if object is defined and
58
+ ## has content
59
+ ##
60
+ def good?
61
+ true
62
+ end
63
+ end
64
+ end
data/lib/doing/hash.rb CHANGED
@@ -34,6 +34,10 @@ module Doing
34
34
  replace deep_thaw
35
35
  end
36
36
 
37
+ def clone
38
+ Marshal.load(Marshal.dump(self))
39
+ end
40
+
37
41
  # Turn all keys into string
38
42
  #
39
43
  # Return a copy of the hash where all its keys are strings
data/lib/doing/hooks.rb CHANGED
@@ -10,8 +10,8 @@ module Doing
10
10
  post_local_config: [], # wwid
11
11
  post_read: [], # wwid
12
12
  pre_entry_add: [], # wwid, new_entry
13
- post_entry_added: [], # wwid, new_entry.dup
14
- post_entry_updated: [], # wwid, entry
13
+ post_entry_added: [], # wwid, new_entry
14
+ post_entry_updated: [], # wwid, entry, old_entry
15
15
  post_entry_removed: [], # wwid, entry.dup
16
16
  pre_export: [], # wwid, format, entries
17
17
  pre_write: [], # wwid, file
@@ -57,7 +57,7 @@ module Doing
57
57
 
58
58
  def self.trigger(event, *args)
59
59
  hooks = @registry[event]
60
- return if hooks.nil? || hooks.empty?
60
+ return unless hooks.good?
61
61
 
62
62
  # sort and call hooks according to priority and load order
63
63
  hooks.sort_by { |h| @hook_priority[h] }.each do |hook|
data/lib/doing/item.rb CHANGED
@@ -399,7 +399,7 @@ module Doing
399
399
 
400
400
  # outputs item in Doing file format, including leading tab
401
401
  def to_s
402
- "\t- #{@date.strftime('%Y-%m-%d %H:%M')} | #{@title}#{@note.empty? ? '' : "\n#{@note}"}"
402
+ "\t- #{@date.strftime('%Y-%m-%d %H:%M')} | #{@title}#{@note.good? ? "\n#{@note}" : ''}"
403
403
  end
404
404
 
405
405
  ##
@@ -429,6 +429,10 @@ module Doing
429
429
  %(<Doing::Item @date=#{@date}>)
430
430
  end
431
431
 
432
+ def clone
433
+ Marshal.load(Marshal.dump(self))
434
+ end
435
+
432
436
  private
433
437
 
434
438
  def should?(key)
@@ -457,7 +461,7 @@ module Doing
457
461
  end
458
462
 
459
463
  def all_searches?(searches, case_type: :smart)
460
- return true if searches.nil? || searches.empty?
464
+ return true unless searches.good?
461
465
 
462
466
  text = @title + @note.to_s
463
467
  searches.each do |s|
@@ -468,7 +472,7 @@ module Doing
468
472
  end
469
473
 
470
474
  def no_searches?(searches, case_type: :smart)
471
- return true if searches.nil? || searches.empty?
475
+ return true unless searches.good?
472
476
 
473
477
  text = @title + @note.to_s
474
478
  searches.each do |s|
@@ -479,7 +483,7 @@ module Doing
479
483
  end
480
484
 
481
485
  def any_searches?(searches, case_type: :smart)
482
- return true if searches.nil? || searches.empty?
486
+ return true unless searches.good?
483
487
 
484
488
  text = @title + @note.to_s
485
489
  searches.each do |s|
@@ -490,7 +494,7 @@ module Doing
490
494
  end
491
495
 
492
496
  def all_tags?(tags)
493
- return true if tags.nil? || tags.empty?
497
+ return true unless tags.good?
494
498
 
495
499
  tags.each do |tag|
496
500
  return false unless @title =~ /@#{tag.wildcard_to_rx}(?= |\(|\Z)/i
@@ -499,7 +503,7 @@ module Doing
499
503
  end
500
504
 
501
505
  def no_tags?(tags)
502
- return true if tags.nil? || tags.empty?
506
+ return true unless tags.good?
503
507
 
504
508
  tags.each do |tag|
505
509
  return false if @title =~ /@#{tag.wildcard_to_rx}(?= |\(|\Z)/i
@@ -508,7 +512,7 @@ module Doing
508
512
  end
509
513
 
510
514
  def any_tags?(tags)
511
- return true if tags.nil? || tags.empty?
515
+ return true unless tags.good?
512
516
 
513
517
  tags.each do |tag|
514
518
  return true if @title =~ /@#{tag.wildcard_to_rx}(?= |\(|\Z)/i
@@ -537,7 +541,7 @@ module Doing
537
541
  end
538
542
 
539
543
  def any_values?(queries)
540
- return true if queries.nil? || queries.empty?
544
+ return true unless queries.good?
541
545
 
542
546
  queries.each do |q|
543
547
  parts = split_value_query(q)
@@ -547,7 +551,7 @@ module Doing
547
551
  end
548
552
 
549
553
  def all_values?(queries)
550
- return true if queries.nil? || queries.empty?
554
+ return true unless queries.good?
551
555
 
552
556
  queries.each do |q|
553
557
  parts = split_value_query(q)
@@ -557,7 +561,7 @@ module Doing
557
561
  end
558
562
 
559
563
  def no_values?(queries)
560
- return true if queries.nil? || queries.empty?
564
+ return true unless queries.good?
561
565
 
562
566
  queries.each do |q|
563
567
  parts = split_value_query(q)
@@ -89,7 +89,7 @@ module Doing
89
89
 
90
90
  wwid.content.concat(new_items)
91
91
 
92
- new_items.map { |item| Hooks.trigger :post_entry_added, self, item.dup }
92
+ new_items.map { |item| Hooks.trigger :post_entry_added, self, item }
93
93
 
94
94
  Doing.logger.info(%(Imported #{new_items.count} items to #{section}))
95
95
  end
@@ -93,7 +93,7 @@ module Doing
93
93
  wwid.content.add_section(item.section) unless wwid.content.section?(item.section)
94
94
  Hooks.trigger :pre_entry_add, self, item
95
95
  wwid.content.push(item)
96
- Hooks.trigger :post_entry_added, self, item.dup
96
+ Hooks.trigger :post_entry_added, self, item
97
97
  end
98
98
 
99
99
  Doing.logger.info('Imported:', "#{imported.count} items")
@@ -93,7 +93,7 @@ module Doing
93
93
 
94
94
  wwid.content.concat(new_items)
95
95
 
96
- new_items.map { |item| Hooks.trigger :post_entry_added, self, item.dup }
96
+ new_items.map { |item| Hooks.trigger :post_entry_added, self, item }
97
97
 
98
98
  Doing.logger.info('Imported:', %(#{new_items.count} items to #{section}))
99
99
  end
data/lib/doing/string.rb CHANGED
@@ -108,7 +108,7 @@ module Doing
108
108
  escapes = scan(/(\e\[[\d;]+m)[^\e]+@/)
109
109
  color = color.split(' ') unless color.is_a?(Array)
110
110
  tag_color = color.each_with_object([]) { |c, arr| arr << Doing::Color.send(c) }.join('')
111
- last_color = if !escapes.empty?
111
+ last_color = if escapes.good?
112
112
  (escapes.count > 1 ? escapes[-2..-1] : [escapes[-1]]).map { |v| v[0] }.join('')
113
113
  else
114
114
  Doing::Color.default