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