doing 2.1.4pre → 2.1.5pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardoc/checksums +14 -13
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/CHANGELOG.md +21 -0
- data/Gemfile.lock +3 -1
- data/README.md +1 -1
- data/bin/doing +149 -91
- data/doc/Array.html +63 -1
- data/doc/BooleanTermParser/Clause.html +293 -0
- data/doc/BooleanTermParser/Operator.html +172 -0
- data/doc/BooleanTermParser/Query.html +417 -0
- data/doc/BooleanTermParser/QueryParser.html +135 -0
- data/doc/BooleanTermParser/QueryTransformer.html +124 -0
- data/doc/BooleanTermParser.html +115 -0
- data/doc/Doing/CLIFormat.html +131 -0
- data/doc/Doing/Color.html +2 -2
- data/doc/Doing/Completion.html +1 -1
- data/doc/Doing/Configuration.html +116 -12
- data/doc/Doing/Errors/DoingNoTraceError.html +1 -1
- data/doc/Doing/Errors/DoingRuntimeError.html +1 -1
- data/doc/Doing/Errors/DoingStandardError.html +1 -1
- data/doc/Doing/Errors/EmptyInput.html +1 -1
- data/doc/Doing/Errors/NoResults.html +1 -1
- data/doc/Doing/Errors/PluginException.html +1 -1
- data/doc/Doing/Errors/UserCancelled.html +1 -1
- data/doc/Doing/Errors/WrongCommand.html +1 -1
- data/doc/Doing/Errors.html +1 -1
- data/doc/Doing/Hooks.html +1 -1
- data/doc/Doing/Item.html +100 -73
- data/doc/Doing/Items.html +2 -2
- data/doc/Doing/LogAdapter.html +70 -1
- data/doc/Doing/Note.html +5 -134
- data/doc/Doing/Pager.html +1 -1
- data/doc/Doing/Plugins.html +380 -40
- data/doc/Doing/Prompt.html +1 -1
- data/doc/Doing/Section.html +1 -1
- data/doc/Doing/TemplateString.html +713 -0
- data/doc/Doing/Util/Backup.html +686 -0
- data/doc/Doing/Util.html +1 -1
- data/doc/Doing/WWID.html +5 -5
- data/doc/Doing.html +4 -4
- data/doc/GLI/Commands/MarkdownDocumentListener.html +1 -1
- data/doc/GLI/Commands.html +1 -1
- data/doc/GLI.html +1 -1
- data/doc/Hash.html +1 -1
- data/doc/PhraseParser/Operator.html +172 -0
- data/doc/PhraseParser/PhraseClause.html +303 -0
- data/doc/PhraseParser/Query.html +495 -0
- data/doc/PhraseParser/QueryParser.html +136 -0
- data/doc/PhraseParser/QueryTransformer.html +124 -0
- data/doc/PhraseParser/TermClause.html +293 -0
- data/doc/PhraseParser.html +115 -0
- data/doc/Status.html +1 -1
- data/doc/String.html +182 -12
- data/doc/Symbol.html +35 -1
- data/doc/Time.html +1 -1
- data/doc/_index.html +21 -14
- data/doc/class_list.html +1 -1
- data/doc/file.README.html +2 -2
- data/doc/index.html +2 -2
- data/doc/method_list.html +319 -175
- data/doc/top-level-namespace.html +1 -1
- data/doing.gemspec +1 -0
- data/doing.rdoc +56 -9
- data/lib/doing/array.rb +9 -0
- data/lib/doing/configuration.rb +30 -8
- data/lib/doing/item.rb +12 -3
- data/lib/doing/log_adapter.rb +28 -0
- data/lib/doing/note.rb +31 -30
- data/lib/doing/plugin_manager.rb +57 -13
- data/lib/doing/plugins/export/dayone_export.rb +209 -0
- data/lib/doing/plugins/export/template_export.rb +90 -85
- data/lib/doing/prompt.rb +9 -6
- data/lib/doing/string.rb +68 -27
- data/lib/doing/symbol.rb +4 -0
- data/lib/doing/template_string.rb +197 -0
- data/lib/doing/util.rb +4 -2
- data/lib/doing/util_backup.rb +55 -3
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +27 -18
- data/lib/doing.rb +3 -0
- data/lib/templates/doing-dayone-entry.erb +6 -0
- data/lib/templates/doing-dayone.erb +5 -0
- metadata +42 -2
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
</div>
|
|
103
103
|
|
|
104
104
|
<div id="footer">
|
|
105
|
-
Generated on
|
|
105
|
+
Generated on Sun Dec 19 12:35:32 2021 by
|
|
106
106
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
107
107
|
0.9.26 (ruby-3.0.1).
|
|
108
108
|
</div>
|
data/doing.gemspec
CHANGED
|
@@ -41,5 +41,6 @@ spec = Gem::Specification.new do |s|
|
|
|
41
41
|
s.add_runtime_dependency('tty-which', '~> 0.5', '>= 0.5.0')
|
|
42
42
|
s.add_runtime_dependency('tty-markdown', '~> 0.7', '>= 0.7.0')
|
|
43
43
|
s.add_runtime_dependency('parslet', '~> 2.0', '>= 2.0.0')
|
|
44
|
+
s.add_runtime_dependency('plist', '~> 3.6', '>= 3.6.0')
|
|
44
45
|
# s.add_runtime_dependency('amatch', '~> 0.4', '>= 0.4.0')
|
|
45
46
|
end
|
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.
|
|
8
|
+
v2.1.5pre
|
|
9
9
|
|
|
10
10
|
=== Global Options
|
|
11
11
|
=== --config_file arg
|
|
@@ -711,7 +711,7 @@ Date range to show, or a single day to filter date on.
|
|
|
711
711
|
|
|
712
712
|
===== -o|--output FORMAT
|
|
713
713
|
|
|
714
|
-
Output to export format (csv|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
714
|
+
Output to export format (csv|dayone|dayone-days|dayone-entries|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
715
715
|
|
|
716
716
|
[Default Value] None
|
|
717
717
|
|
|
@@ -1204,7 +1204,7 @@ it will create a range.
|
|
|
1204
1204
|
===== Options
|
|
1205
1205
|
===== -o|--output FORMAT
|
|
1206
1206
|
|
|
1207
|
-
Output to export format (csv|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
1207
|
+
Output to export format (csv|dayone|dayone-days|dayone-entries|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
1208
1208
|
|
|
1209
1209
|
[Default Value] None
|
|
1210
1210
|
|
|
@@ -1532,7 +1532,7 @@ Move selected items to section
|
|
|
1532
1532
|
|
|
1533
1533
|
===== -o|--output FORMAT
|
|
1534
1534
|
|
|
1535
|
-
Output entries to format (csv|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
1535
|
+
Output entries to format (csv|dayone|dayone-days|dayone-entries|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
1536
1536
|
|
|
1537
1537
|
[Default Value] None
|
|
1538
1538
|
|
|
@@ -1669,6 +1669,7 @@ Show entries older than date. If this is only a time (8am, 1:30pm, 15:00), all d
|
|
|
1669
1669
|
Max count to show
|
|
1670
1670
|
|
|
1671
1671
|
[Default Value] 0
|
|
1672
|
+
[Must Match] (?-mix:^\d+$)
|
|
1672
1673
|
|
|
1673
1674
|
|
|
1674
1675
|
===== --case TYPE
|
|
@@ -1693,7 +1694,7 @@ Date range to show, or a single day to filter date on.
|
|
|
1693
1694
|
|
|
1694
1695
|
===== -o|--output FORMAT
|
|
1695
1696
|
|
|
1696
|
-
Output to export format (csv|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
1697
|
+
Output to export format (csv|dayone|dayone-days|dayone-entries|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
1697
1698
|
|
|
1698
1699
|
[Default Value] None
|
|
1699
1700
|
|
|
@@ -1784,7 +1785,7 @@ and "2d" would be interpreted as "two days ago."
|
|
|
1784
1785
|
===== Options
|
|
1785
1786
|
===== -o|--output FORMAT
|
|
1786
1787
|
|
|
1787
|
-
Output to export format (csv|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
1788
|
+
Output to export format (csv|dayone|dayone-days|dayone-entries|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
1788
1789
|
|
|
1789
1790
|
[Default Value] None
|
|
1790
1791
|
|
|
@@ -1939,6 +1940,22 @@ List all tags in the current Doing file
|
|
|
1939
1940
|
|
|
1940
1941
|
|
|
1941
1942
|
===== Options
|
|
1943
|
+
===== --bool BOOLEAN
|
|
1944
|
+
|
|
1945
|
+
Boolean used to combine multiple tags. Use PATTERN to parse + and - as booleans.
|
|
1946
|
+
|
|
1947
|
+
[Default Value] PATTERN
|
|
1948
|
+
[Must Match] (?i-mx:^(?:and|all|any|or|not|none|p(?:at(?:tern)?)?)$)
|
|
1949
|
+
|
|
1950
|
+
|
|
1951
|
+
===== --case TYPE
|
|
1952
|
+
|
|
1953
|
+
Case sensitivity for search string matching [(c)ase-sensitive, (i)gnore, (s)mart]
|
|
1954
|
+
|
|
1955
|
+
[Default Value] smart
|
|
1956
|
+
[Must Match] (?-mix:^[csi])
|
|
1957
|
+
|
|
1958
|
+
|
|
1942
1959
|
===== -o|--order ORDER
|
|
1943
1960
|
|
|
1944
1961
|
Sort order (asc/desc)
|
|
@@ -1954,6 +1971,14 @@ Section
|
|
|
1954
1971
|
[Default Value] All
|
|
1955
1972
|
|
|
1956
1973
|
|
|
1974
|
+
===== --search QUERY
|
|
1975
|
+
|
|
1976
|
+
Get tags for items matching search. Surround with
|
|
1977
|
+
slashes for regex (e.g. "/query/"), start with a single quote for exact match ("'query").
|
|
1978
|
+
|
|
1979
|
+
[Default Value] None
|
|
1980
|
+
|
|
1981
|
+
|
|
1957
1982
|
===== --sort SORT_ORDER
|
|
1958
1983
|
|
|
1959
1984
|
Sort by name or count
|
|
@@ -1962,11 +1987,33 @@ Sort by name or count
|
|
|
1962
1987
|
[Must Match] (?-mix:^(?:n(?:ame)?|c(?:ount)?)$)
|
|
1963
1988
|
|
|
1964
1989
|
|
|
1990
|
+
===== --tag TAG
|
|
1991
|
+
|
|
1992
|
+
Get tags for entries matching tags. Combine multiple tags with a comma. Wildcards allowed (*, ?).
|
|
1993
|
+
|
|
1994
|
+
[Default Value] None
|
|
1995
|
+
|
|
1996
|
+
|
|
1965
1997
|
===== -c|--[no-]counts
|
|
1966
1998
|
Show count of occurrences
|
|
1967
1999
|
|
|
1968
2000
|
|
|
1969
2001
|
|
|
2002
|
+
===== -i|--interactive
|
|
2003
|
+
Select items to scan from a menu of matching entries
|
|
2004
|
+
|
|
2005
|
+
|
|
2006
|
+
|
|
2007
|
+
===== --not
|
|
2008
|
+
Get tags from items that *don't* match search/tag filters
|
|
2009
|
+
|
|
2010
|
+
|
|
2011
|
+
|
|
2012
|
+
===== -x|--exact
|
|
2013
|
+
Force exact search string matching (case sensitive)
|
|
2014
|
+
|
|
2015
|
+
|
|
2016
|
+
|
|
1970
2017
|
==== Command: <tt>template TYPE</tt>
|
|
1971
2018
|
Output HTML, CSS, and Markdown (ERB) templates for customization
|
|
1972
2019
|
|
|
@@ -2016,7 +2063,7 @@ Time range to show `doing today --from "12pm to 4pm"`
|
|
|
2016
2063
|
|
|
2017
2064
|
===== -o|--output FORMAT
|
|
2018
2065
|
|
|
2019
|
-
Output to export format (csv|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
2066
|
+
Output to export format (csv|dayone|dayone-days|dayone-entries|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
2020
2067
|
|
|
2021
2068
|
[Default Value] None
|
|
2022
2069
|
|
|
@@ -2141,7 +2188,7 @@ Date range to show, or a single day to filter date on.
|
|
|
2141
2188
|
|
|
2142
2189
|
===== -o|--output FORMAT
|
|
2143
2190
|
|
|
2144
|
-
Output to export format (csv|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
2191
|
+
Output to export format (csv|dayone|dayone-days|dayone-entries|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
2145
2192
|
|
|
2146
2193
|
[Default Value] None
|
|
2147
2194
|
|
|
@@ -2324,7 +2371,7 @@ Time range to show, e.g. `doing yesterday --from "1am to 8am"`
|
|
|
2324
2371
|
|
|
2325
2372
|
===== -o|--output FORMAT
|
|
2326
2373
|
|
|
2327
|
-
Output to export format (csv|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
2374
|
+
Output to export format (csv|dayone|dayone-days|dayone-entries|doing|html|markdown|say|taskpaper|template|timeline|wiki)
|
|
2328
2375
|
|
|
2329
2376
|
[Default Value] None
|
|
2330
2377
|
|
data/lib/doing/array.rb
CHANGED
|
@@ -5,6 +5,15 @@ module Doing
|
|
|
5
5
|
## Array helpers
|
|
6
6
|
##
|
|
7
7
|
class ::Array
|
|
8
|
+
##
|
|
9
|
+
## Convert an @tags to plain strings
|
|
10
|
+
##
|
|
11
|
+
## @return [Array] array of strings
|
|
12
|
+
##
|
|
13
|
+
def tags_to_array
|
|
14
|
+
map { |t| t.sub(/^@/, '') }
|
|
15
|
+
end
|
|
16
|
+
|
|
8
17
|
# Convert strings to @tags
|
|
9
18
|
#
|
|
10
19
|
# @example `['one', '@two', 'three'].to_tags`
|
data/lib/doing/configuration.rb
CHANGED
|
@@ -29,8 +29,8 @@ module Doing
|
|
|
29
29
|
'plugin_path' => File.join(Util.user_home, '.config', 'doing', 'plugins'),
|
|
30
30
|
'command_path' => File.join(Util.user_home, '.config', 'doing', 'commands')
|
|
31
31
|
},
|
|
32
|
-
'doing_file' => '
|
|
33
|
-
'backup_dir' => '~/.doing_backup',
|
|
32
|
+
'doing_file' => '~/.local/share/doing/what_was_i_doing.md',
|
|
33
|
+
'backup_dir' => '~/.local/share/doing/doing_backup',
|
|
34
34
|
'current_section' => 'Currently',
|
|
35
35
|
'paginate' => false,
|
|
36
36
|
'never_time' => [],
|
|
@@ -43,7 +43,8 @@ module Doing
|
|
|
43
43
|
'templates' => {
|
|
44
44
|
'default' => {
|
|
45
45
|
'date_format' => '%Y-%m-%d %H:%M',
|
|
46
|
-
'template' => '%
|
|
46
|
+
'template' => '%reset%cyan%shortdate %boldwhite%80║ title %dark%boldmagenta[%boldwhite%-10section%boldmagenta]%reset
|
|
47
|
+
%yellow%interval%boldred%duration%dark%white%80_14┃ note',
|
|
47
48
|
'wrap_width' => 0,
|
|
48
49
|
'order' => 'asc'
|
|
49
50
|
},
|
|
@@ -60,7 +61,8 @@ module Doing
|
|
|
60
61
|
},
|
|
61
62
|
'recent' => {
|
|
62
63
|
'date_format' => '%_I:%M%P',
|
|
63
|
-
'template' => '%shortdate
|
|
64
|
+
'template' => '%reset%cyan%shortdate %boldwhite%80║ title %dark%boldmagenta[%boldwhite%-10section%boldmagenta]%reset
|
|
65
|
+
%yellow%interval%boldred%duration%dark%white%80_14┃ note',
|
|
64
66
|
'wrap_width' => 88,
|
|
65
67
|
'count' => 10,
|
|
66
68
|
'order' => 'asc'
|
|
@@ -72,7 +74,7 @@ module Doing
|
|
|
72
74
|
'views' => {
|
|
73
75
|
'done' => {
|
|
74
76
|
'date_format' => '%_I:%M%P',
|
|
75
|
-
'template' => '%date | %title%note',
|
|
77
|
+
'template' => '%date | %title (%section)% 18: note',
|
|
76
78
|
'wrap_width' => 0,
|
|
77
79
|
'section' => 'All',
|
|
78
80
|
'count' => 0,
|
|
@@ -93,6 +95,11 @@ module Doing
|
|
|
93
95
|
'marker_color' => 'red',
|
|
94
96
|
'default_tags' => [],
|
|
95
97
|
'tag_sort' => 'name',
|
|
98
|
+
'search' => {
|
|
99
|
+
'matching' => 'pattern', # fuzzy, pattern, exact
|
|
100
|
+
'distance' => 3,
|
|
101
|
+
'case' => 'smart' # sensitive, ignore, smart
|
|
102
|
+
},
|
|
96
103
|
'include_notes' => true
|
|
97
104
|
}
|
|
98
105
|
|
|
@@ -110,6 +117,17 @@ module Doing
|
|
|
110
117
|
@config_dir ||= File.join(Util.user_home, '.config', 'doing')
|
|
111
118
|
end
|
|
112
119
|
|
|
120
|
+
##
|
|
121
|
+
## Check if configuration enforces exact string matching
|
|
122
|
+
##
|
|
123
|
+
## @return [Boolean] exact matching enabled
|
|
124
|
+
##
|
|
125
|
+
def exact_match?
|
|
126
|
+
search_settings = @settings['search']
|
|
127
|
+
matching = search_settings.fetch('matching', 'pattern').normalize_matching
|
|
128
|
+
matching == :exact
|
|
129
|
+
end
|
|
130
|
+
|
|
113
131
|
def default_config_file
|
|
114
132
|
if File.exist?(config_dir) && !File.directory?(config_dir)
|
|
115
133
|
raise DoingRuntimeError, "#{config_dir} exists but is not a directory"
|
|
@@ -220,11 +238,15 @@ module Doing
|
|
|
220
238
|
cfg.nil? ? nil : { real_path[-1] => cfg }
|
|
221
239
|
end
|
|
222
240
|
|
|
223
|
-
# It takes the input, fills in the defaults where values
|
|
241
|
+
# It takes the input, fills in the defaults where values
|
|
242
|
+
# do not exist.
|
|
243
|
+
#
|
|
244
|
+
# @param user_config a Hash or Configuration of
|
|
245
|
+
# overrides.
|
|
224
246
|
#
|
|
225
|
-
#
|
|
247
|
+
# @return [Hash] a Configuration filled with
|
|
248
|
+
# defaults.
|
|
226
249
|
#
|
|
227
|
-
# Returns a Configuration filled with defaults.
|
|
228
250
|
def from(user_config)
|
|
229
251
|
Util.deep_merge_hashes(DEFAULTS, Configuration[user_config].stringify_keys)
|
|
230
252
|
end
|
data/lib/doing/item.rb
CHANGED
|
@@ -7,7 +7,7 @@ module Doing
|
|
|
7
7
|
class Item
|
|
8
8
|
attr_accessor :date, :title, :section, :note
|
|
9
9
|
|
|
10
|
-
attr_reader :id
|
|
10
|
+
# attr_reader :id
|
|
11
11
|
|
|
12
12
|
##
|
|
13
13
|
## Initialize an item with date, title, section, and
|
|
@@ -162,6 +162,10 @@ module Doing
|
|
|
162
162
|
@title.scan(/(?<= |\A)@([^\s(]+)/).map { |tag| tag[0] }.sort.uniq
|
|
163
163
|
end
|
|
164
164
|
|
|
165
|
+
def tag_array
|
|
166
|
+
tags.tags_to_array
|
|
167
|
+
end
|
|
168
|
+
|
|
165
169
|
##
|
|
166
170
|
## Test if item contains tag(s)
|
|
167
171
|
##
|
|
@@ -208,8 +212,13 @@ module Doing
|
|
|
208
212
|
##
|
|
209
213
|
## @return [Boolean] matches search criteria
|
|
210
214
|
##
|
|
211
|
-
def search(search, distance:
|
|
212
|
-
|
|
215
|
+
def search(search, distance: nil, negate: false, case_type: nil)
|
|
216
|
+
prefs = Doing.config.settings['search'] || {}
|
|
217
|
+
matching = prefs.fetch('matching', 'pattern').normalize_matching
|
|
218
|
+
distance ||= prefs.fetch('distance', 3).to_i
|
|
219
|
+
case_type ||= prefs.fetch('case', 'smart').normalize_case
|
|
220
|
+
|
|
221
|
+
if search.is_rx? || matching == :fuzzy
|
|
213
222
|
matches = @title + @note.to_s =~ search.to_rx(distance: distance, case_type: case_type)
|
|
214
223
|
else
|
|
215
224
|
query = to_phrase_query(search.strip)
|
data/lib/doing/log_adapter.rb
CHANGED
|
@@ -38,6 +38,7 @@ module Doing
|
|
|
38
38
|
rotated
|
|
39
39
|
skipped
|
|
40
40
|
updated
|
|
41
|
+
exported
|
|
41
42
|
].freeze
|
|
42
43
|
|
|
43
44
|
#
|
|
@@ -265,6 +266,31 @@ module Doing
|
|
|
265
266
|
end
|
|
266
267
|
end
|
|
267
268
|
|
|
269
|
+
def benchmark(key, state)
|
|
270
|
+
return unless ENV['DOING_BENCHMARK']
|
|
271
|
+
|
|
272
|
+
@benchmarks ||= {}
|
|
273
|
+
@benchmarks[key] ||= { start: nil, finish: nil }
|
|
274
|
+
@benchmarks[key][state] = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def log_benchmarks
|
|
278
|
+
if ENV['DOING_BENCHMARK']
|
|
279
|
+
output = []
|
|
280
|
+
@benchmarks.each do |k, timers|
|
|
281
|
+
if timers[:finish] && timers[:start]
|
|
282
|
+
output << "#{k}: #{timers[:finish] - timers[:start]}"
|
|
283
|
+
else
|
|
284
|
+
output << "#{k}: error"
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
output.each do |msg|
|
|
288
|
+
$stdout.puts color_message(:debug, 'Benchmark:', msg)
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
|
|
268
294
|
def log_change(tags_added: [], tags_removed: [], count: 1, item: nil, single: false)
|
|
269
295
|
if tags_added.empty? && tags_removed.empty?
|
|
270
296
|
count(:skipped, level: :debug, message: '%count %items with no change', count: count)
|
|
@@ -319,6 +345,8 @@ module Doing
|
|
|
319
345
|
['Archived:', data[:message] || 'completed and archived %count %items']
|
|
320
346
|
when :skipped
|
|
321
347
|
['Skipped:', data[:message] || '%count %items were unchanged']
|
|
348
|
+
when :exported
|
|
349
|
+
['Exported:', data[:message] || '%count %items were exported']
|
|
322
350
|
end
|
|
323
351
|
end
|
|
324
352
|
|
data/lib/doing/note.rb
CHANGED
|
@@ -22,7 +22,7 @@ module Doing
|
|
|
22
22
|
## Add note contents, optionally replacing existing note
|
|
23
23
|
##
|
|
24
24
|
## @param note [Array] The note to add, can be
|
|
25
|
-
##
|
|
25
|
+
## String, Array, or Note
|
|
26
26
|
## @param replace [Boolean] replace existing
|
|
27
27
|
## content
|
|
28
28
|
##
|
|
@@ -36,32 +36,7 @@ module Doing
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
##
|
|
39
|
-
##
|
|
40
|
-
##
|
|
41
|
-
## @param lines [Array] Array of strings
|
|
42
|
-
##
|
|
43
|
-
def append(lines)
|
|
44
|
-
concat(lines)
|
|
45
|
-
replace compress
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
##
|
|
49
|
-
## Append a string to the note content
|
|
50
|
-
##
|
|
51
|
-
## @param input [String] The input string,
|
|
52
|
-
## newlines will be split
|
|
53
|
-
##
|
|
54
|
-
def append_string(input)
|
|
55
|
-
concat(input.split(/\n/).map(&:strip))
|
|
56
|
-
replace compress
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def compress!
|
|
60
|
-
replace compress
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
##
|
|
64
|
-
## Remove blank lines and comment lines (#)
|
|
39
|
+
## Remove blank lines and comments (#)
|
|
65
40
|
##
|
|
66
41
|
## @return [Array] compressed array
|
|
67
42
|
##
|
|
@@ -69,8 +44,8 @@ module Doing
|
|
|
69
44
|
delete_if { |l| l =~ /^\s*$/ || l =~ /^#/ }
|
|
70
45
|
end
|
|
71
46
|
|
|
72
|
-
def
|
|
73
|
-
replace
|
|
47
|
+
def compress!
|
|
48
|
+
replace compress
|
|
74
49
|
end
|
|
75
50
|
|
|
76
51
|
##
|
|
@@ -83,6 +58,10 @@ module Doing
|
|
|
83
58
|
map(&:strip)
|
|
84
59
|
end
|
|
85
60
|
|
|
61
|
+
def strip_lines!
|
|
62
|
+
replace strip_lines
|
|
63
|
+
end
|
|
64
|
+
|
|
86
65
|
##
|
|
87
66
|
## Note as multi-line string
|
|
88
67
|
def to_s
|
|
@@ -101,11 +80,33 @@ module Doing
|
|
|
101
80
|
## @param other [Note] The other Note
|
|
102
81
|
##
|
|
103
82
|
## @return [Boolean] true if equal
|
|
104
|
-
##
|
|
105
83
|
def equal?(other)
|
|
106
84
|
return false unless other.is_a?(Note)
|
|
107
85
|
|
|
108
86
|
to_s == other.to_s
|
|
109
87
|
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
##
|
|
92
|
+
## Append an array of strings to note
|
|
93
|
+
##
|
|
94
|
+
## @param lines [Array] Array of strings
|
|
95
|
+
##
|
|
96
|
+
def append(lines)
|
|
97
|
+
concat(lines)
|
|
98
|
+
replace compress
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
##
|
|
102
|
+
## Append a string to the note content
|
|
103
|
+
##
|
|
104
|
+
## @param input [String] The input string,
|
|
105
|
+
## newlines will be split
|
|
106
|
+
##
|
|
107
|
+
def append_string(input)
|
|
108
|
+
concat(input.split(/\n/).map(&:strip))
|
|
109
|
+
replace compress
|
|
110
|
+
end
|
|
110
111
|
end
|
|
111
112
|
end
|
data/lib/doing/plugin_manager.rb
CHANGED
|
@@ -28,26 +28,30 @@ module Doing
|
|
|
28
28
|
plugins
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
#
|
|
31
|
+
# Setup the plugin search path
|
|
32
|
+
#
|
|
33
|
+
# @param add_dir [String] optional additional
|
|
34
|
+
# path to include
|
|
35
|
+
#
|
|
36
|
+
# @return [Array] Returns an Array of plugin search paths
|
|
32
37
|
#
|
|
33
|
-
# Returns an Array of plugin search paths
|
|
34
38
|
def plugins_path(add_dir = nil)
|
|
35
39
|
paths = Array(File.join(File.dirname(__FILE__), 'plugins'))
|
|
36
40
|
paths << File.join(add_dir) if add_dir
|
|
37
41
|
paths.map { |d| File.expand_path(d) }
|
|
38
42
|
end
|
|
39
43
|
|
|
40
|
-
|
|
44
|
+
|
|
41
45
|
# Register a plugin
|
|
42
46
|
#
|
|
43
|
-
# param
|
|
44
|
-
#
|
|
45
|
-
# param
|
|
46
|
-
#
|
|
47
|
-
# param
|
|
47
|
+
# @param title [String|Array] The name of the
|
|
48
|
+
# plugin (can be an array of names)
|
|
49
|
+
# @param type [Symbol] The plugin type
|
|
50
|
+
# (:import, :export)
|
|
51
|
+
# @param klass [Class] The class responding to
|
|
52
|
+
# :render or :import
|
|
48
53
|
#
|
|
49
|
-
#
|
|
50
|
-
# returns: Success boolean
|
|
54
|
+
# @return [Boolean] Success boolean
|
|
51
55
|
#
|
|
52
56
|
def register(title, type, klass)
|
|
53
57
|
type = validate_plugin(title, type, klass)
|
|
@@ -90,6 +94,15 @@ module Doing
|
|
|
90
94
|
type
|
|
91
95
|
end
|
|
92
96
|
|
|
97
|
+
##
|
|
98
|
+
## Converts a partial symbol to a valid plugin type,
|
|
99
|
+
## e.g. :imp => :import
|
|
100
|
+
##
|
|
101
|
+
## @param type [Symbol] the symbol to test
|
|
102
|
+
## @param default [Symbol] fallback value
|
|
103
|
+
##
|
|
104
|
+
## @return [Symbol] :import or :export
|
|
105
|
+
##
|
|
93
106
|
def valid_type(type, default: nil)
|
|
94
107
|
type ||= default
|
|
95
108
|
|
|
@@ -154,10 +167,13 @@ module Doing
|
|
|
154
167
|
end
|
|
155
168
|
|
|
156
169
|
##
|
|
157
|
-
## Return a regular expression of all
|
|
158
|
-
##
|
|
170
|
+
## Return a regular expression of all plugin triggers
|
|
171
|
+
## for type
|
|
172
|
+
##
|
|
173
|
+
## @param type [Symbol] The type :import or
|
|
174
|
+
## :export
|
|
159
175
|
##
|
|
160
|
-
## @
|
|
176
|
+
## @return [Regexp] regular expression
|
|
161
177
|
##
|
|
162
178
|
def plugin_regex(type: :export)
|
|
163
179
|
type = valid_type(type)
|
|
@@ -168,6 +184,14 @@ module Doing
|
|
|
168
184
|
Regexp.new("^(?:#{pattern.join('|')})$", true)
|
|
169
185
|
end
|
|
170
186
|
|
|
187
|
+
##
|
|
188
|
+
## Return array of available template names
|
|
189
|
+
##
|
|
190
|
+
## @param type [Symbol] Plugin type (:import,
|
|
191
|
+
## :export)
|
|
192
|
+
##
|
|
193
|
+
## @return [Array<String>] template names
|
|
194
|
+
##
|
|
171
195
|
def plugin_templates(type: :export)
|
|
172
196
|
type = valid_type(type)
|
|
173
197
|
templates = []
|
|
@@ -181,6 +205,15 @@ module Doing
|
|
|
181
205
|
templates
|
|
182
206
|
end
|
|
183
207
|
|
|
208
|
+
##
|
|
209
|
+
## Return a regular expression of all template
|
|
210
|
+
## triggers for type
|
|
211
|
+
##
|
|
212
|
+
## @param type [Symbol] The type :import or
|
|
213
|
+
## :export
|
|
214
|
+
##
|
|
215
|
+
## @return [Regexp] regular expression
|
|
216
|
+
##
|
|
184
217
|
def template_regex(type: :export)
|
|
185
218
|
type = valid_type(type)
|
|
186
219
|
pattern = []
|
|
@@ -193,6 +226,17 @@ module Doing
|
|
|
193
226
|
Regexp.new("^(?:#{pattern.join('|')})$", true)
|
|
194
227
|
end
|
|
195
228
|
|
|
229
|
+
##
|
|
230
|
+
## Find and return the appropriate template for a
|
|
231
|
+
## trigger string. Outputs a string that can be
|
|
232
|
+
## written out to the terminal for redirection
|
|
233
|
+
##
|
|
234
|
+
## @param trigger [String] The trigger to test
|
|
235
|
+
## @param type [Symbol] the plugin type
|
|
236
|
+
## (:import, :export)
|
|
237
|
+
##
|
|
238
|
+
## @return [String] string content of template for trigger
|
|
239
|
+
##
|
|
196
240
|
def template_for_trigger(trigger, type: :export)
|
|
197
241
|
type = valid_type(type)
|
|
198
242
|
plugs = plugins[type].clone
|