doing 2.1.24 → 2.1.25

Sign up to get free protection for your applications and to get access to all the features.
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