doing 0.2.5pre → 0.2.5
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/README.md +10 -4
- data/bin/doing +80 -2
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +70 -9
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4645c47a272a4fdf45174b2adff019820ed1537
|
4
|
+
data.tar.gz: 444fa7c255629e9f9e5f1b357c28b0fd2ac3e8c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b8872bc854b897c25737f79f50ab86ec91f48b5b64118cc121c463c0782738070150b06ef8a9e076b5a9bdf5922f94a5d45db35166f80af8cf0fc63f9e51519
|
7
|
+
data.tar.gz: 4ed502a4de7165e67a5cc41d4737f069ececd82e64efa8af092d0c847b32ca1e99151ec7071945dace041277208411c0e0b36bdfc6a468330bb14a60b3660e87
|
data/README.md
CHANGED
@@ -261,6 +261,7 @@ Outputs:
|
|
261
261
|
now - Add an entry
|
262
262
|
later - Add an item to the Later section
|
263
263
|
done - Add a completed item with @done(date). No argument finishes last entry.
|
264
|
+
meanwhile - Finish any @meanwhile tasks and optionally create a new one
|
264
265
|
|
265
266
|
The `doing now` command can accept `-s section_name` to send the new entry straight to a non-default section.
|
266
267
|
|
@@ -270,6 +271,8 @@ You can also backdate entries using natural language with `--back 15m` or `--bac
|
|
270
271
|
|
271
272
|
All of these commands accept a `-e` argument. This opens your command line editor as defined in the environment variable `$EDITOR`. Add your entry, save the temp file and close it, and the new entry will be added. Anything after the first line is included as a note on the entry.
|
272
273
|
|
274
|
+
`doing meanwhile` is a special command for creating and finishing tasks that may have other entries come before they're complete. When you create an entry with `doing meanwhile [entry text]`, it will automatically complete the last @meanwhile item (dated @done tag) and add the @meanwhile tag to the new item. This allows time tracking on a more general basis, and still lets you keep track of the smaller things you do while working on an overarching project. The `meanwhile` command accepts `--back [time]` and will backdate the @done tag and start date of the new task at the same time. Running `meanwhile` with no arguments will simply complete the last @meanwhile task. See `doing help meanwhile` for more options.
|
275
|
+
|
273
276
|
#### Modifying entries:
|
274
277
|
|
275
278
|
finish - Mark last X entries as @done
|
@@ -285,10 +288,11 @@ All of these commands accept a `-e` argument. This opens your command line edito
|
|
285
288
|
|
286
289
|
#### Displaying entries:
|
287
290
|
|
288
|
-
show
|
289
|
-
recent
|
290
|
-
today
|
291
|
-
|
291
|
+
show - List all entries
|
292
|
+
recent - List recent entries
|
293
|
+
today - List entries from today
|
294
|
+
yesterday - List entries from yesterday
|
295
|
+
last - Show the last entry
|
292
296
|
|
293
297
|
`doing show` on its own will list all entries in the "Currently" section. Add a section name as an argument to display that section instead. Use "all" to display all entries from all sections.
|
294
298
|
|
@@ -300,6 +304,8 @@ The `show` command can also show the time spent on a task if it has a `@done(dat
|
|
300
304
|
|
301
305
|
If you have a use for it, you can use `--csv` on the show or view commands to output the results as a comma-separated CSV to STDOUT. Redirect to a file to save it: `doing show all done --csv > ~/Desktop/done.csv`.
|
302
306
|
|
307
|
+
`doing yesterday` is great for stand-ups, thanks to [Sean Collins](https://github.com/sc68cal) for that. Note that you can show yesterday's activity from an alternate section by using the section name as an argument (e.g. `doing yesterday archive`).
|
308
|
+
|
303
309
|
#### Views
|
304
310
|
|
305
311
|
view - Display a user-created view
|
data/bin/doing
CHANGED
@@ -25,6 +25,9 @@ switch [:notes], :default_value => true, :negatable => true
|
|
25
25
|
# desc 'Wrap notes at X chars (0 for no wrap)'
|
26
26
|
# flag [:w,:wrapwidth], :must_match => /^\d+$/, :type => Integer
|
27
27
|
|
28
|
+
desc 'Specify a different doing_file'
|
29
|
+
flag [:f, :doing_file]
|
30
|
+
|
28
31
|
desc 'Add an entry'
|
29
32
|
arg_name 'entry'
|
30
33
|
command :now do |c|
|
@@ -83,6 +86,53 @@ command :now do |c|
|
|
83
86
|
end
|
84
87
|
end
|
85
88
|
|
89
|
+
desc 'Finish any running @meanwhile tasks and optionally create a new one'
|
90
|
+
arg_name 'entry'
|
91
|
+
command :meanwhile do |c|
|
92
|
+
c.desc 'Section'
|
93
|
+
c.arg_name 'section_name'
|
94
|
+
c.default_value wwid.current_section
|
95
|
+
c.flag [:s,:section], :default_value => wwid.current_section
|
96
|
+
|
97
|
+
c.desc "Edit entry with #{ENV['EDITOR']}"
|
98
|
+
c.switch [:e,:editor]
|
99
|
+
|
100
|
+
c.desc "Archive previous @meanwhile entry"
|
101
|
+
c.switch [:a,:archive], :default_value => false
|
102
|
+
|
103
|
+
c.desc 'Backdate to "date_string" (natural language)'
|
104
|
+
c.flag [:back]
|
105
|
+
|
106
|
+
c.action do |global_options,options,args|
|
107
|
+
if options[:back]
|
108
|
+
date = wwid.chronify(options[:back])
|
109
|
+
|
110
|
+
raise "Unable to parse date string" if date.nil?
|
111
|
+
else
|
112
|
+
date = Time.now
|
113
|
+
end
|
114
|
+
|
115
|
+
section = wwid.guess_section(options[:s]) || options[:s].cap_first
|
116
|
+
input = ""
|
117
|
+
|
118
|
+
if options[:e]
|
119
|
+
raise "No EDITOR variable defined in environment" if ENV['EDITOR'].nil?
|
120
|
+
input += args.join(" ") if args.length > 0
|
121
|
+
input = wwid.fork_editor(input)
|
122
|
+
else
|
123
|
+
if args.length > 0
|
124
|
+
input = args.join(" ")
|
125
|
+
elsif STDIN.stat.size > 0
|
126
|
+
input = STDIN.read
|
127
|
+
end
|
128
|
+
end
|
129
|
+
input = false unless input && input.length > 0
|
130
|
+
|
131
|
+
wwid.stop_start("meanwhile",{:new_item => input, :back => date, :section => section, :archive => options[:a]})
|
132
|
+
wwid.write(wwid.doing_file)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
86
136
|
desc 'Add an item to the Later section'
|
87
137
|
arg_name 'entry'
|
88
138
|
command :later do |c|
|
@@ -136,6 +186,10 @@ end
|
|
136
186
|
desc 'Add a completed item with @done(date). No argument finishes last entry.'
|
137
187
|
arg_name 'entry'
|
138
188
|
command :done do |c|
|
189
|
+
c.desc 'Remove @done tag'
|
190
|
+
c.default_value false
|
191
|
+
c.switch [:r,:remove], :negatable => false, :default_value => false
|
192
|
+
|
139
193
|
c.desc 'Include date'
|
140
194
|
c.default_value true
|
141
195
|
c.switch [:d,:date], :default_value => true
|
@@ -185,7 +239,11 @@ command :done do |c|
|
|
185
239
|
raise "No content"
|
186
240
|
end
|
187
241
|
elsif args.length == 0 && STDIN.stat.size == 0
|
188
|
-
|
242
|
+
if options[:r]
|
243
|
+
wwid.tag_last({:tags => ["done"], :count => 1, :section => section, :remove => true })
|
244
|
+
else
|
245
|
+
wwid.tag_last({:tags => ["done"], :count => 1, :section => section, :archive => options[:a], :back => date, :date => options[:d]})
|
246
|
+
end
|
189
247
|
else
|
190
248
|
if args.length > 0
|
191
249
|
title, note = wwid.format_input(args.join(" "))
|
@@ -430,6 +488,16 @@ command :today do |c|
|
|
430
488
|
end
|
431
489
|
end
|
432
490
|
|
491
|
+
desc 'List entries from yesterday'
|
492
|
+
default_value wwid.current_section
|
493
|
+
arg_name 'section'
|
494
|
+
command :yesterday do |c|
|
495
|
+
c.action do |global_options, options,args|
|
496
|
+
section = args.length > 0 ? args.join(" ") : wwid.current_section
|
497
|
+
puts wwid.yesterday(section).strip
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
433
501
|
desc 'Show the last entry'
|
434
502
|
command :last do |c|
|
435
503
|
c.action do |global_options,options,args|
|
@@ -616,11 +684,16 @@ command :config do |c|
|
|
616
684
|
c.desc 'Application to use (OS X only)'
|
617
685
|
c.flag [:a]
|
618
686
|
|
687
|
+
c.desc "Use the editor_app defined in ~/.doingrc (#{wwid.config['editor_app']})"
|
688
|
+
c.switch [:x]
|
689
|
+
|
619
690
|
c.desc 'Application bundle id to use (OS X only)'
|
620
691
|
c.flag [:b]
|
621
692
|
|
622
693
|
c.action do |global_options,options,args|
|
623
|
-
if options[:
|
694
|
+
if options[:x]
|
695
|
+
%x{open -a "#{wwid.config['editor_app']}" "#{File.expand_path(DOING_CONFIG)}"}
|
696
|
+
elsif options[:a] || options[:b]
|
624
697
|
if options[:a]
|
625
698
|
%x{open -a "#{options[:a]}" "#{File.expand_path(DOING_CONFIG)}"}
|
626
699
|
elsif options[:b]
|
@@ -635,6 +708,11 @@ command :config do |c|
|
|
635
708
|
end
|
636
709
|
|
637
710
|
pre do |global,command,options,args|
|
711
|
+
if global[:doing_file]
|
712
|
+
wwid.init_doing_file(input=global[:doing_file])
|
713
|
+
else
|
714
|
+
wwid.init_doing_file
|
715
|
+
end
|
638
716
|
wwid.config[:include_notes] = false unless global[:notes]
|
639
717
|
if global[:version]
|
640
718
|
puts "doing v" + Doing::VERSION
|
data/lib/doing/version.rb
CHANGED
data/lib/doing/wwid.rb
CHANGED
@@ -12,7 +12,7 @@ class WWID
|
|
12
12
|
attr_accessor :content, :sections, :current_section, :doing_file, :config
|
13
13
|
|
14
14
|
|
15
|
-
def initialize
|
15
|
+
def initialize
|
16
16
|
@content = {}
|
17
17
|
@timers = {}
|
18
18
|
@config = read_config
|
@@ -64,7 +64,6 @@ class WWID
|
|
64
64
|
@config['marker_tag'] ||= 'flagged'
|
65
65
|
@config['marker_color'] ||= 'red'
|
66
66
|
|
67
|
-
@doing_file = File.expand_path(config['doing_file'])
|
68
67
|
@current_section = config['current_section']
|
69
68
|
@default_template = config['templates']['default']['template']
|
70
69
|
@default_date_format = config['templates']['default']['date_format']
|
@@ -72,17 +71,24 @@ class WWID
|
|
72
71
|
@config[:include_notes] ||= true
|
73
72
|
|
74
73
|
File.open(File.expand_path(DOING_CONFIG), 'w') { |yf| YAML::dump(config, yf) }
|
74
|
+
end
|
75
|
+
|
76
|
+
def init_doing_file(input=nil)
|
77
|
+
@doing_file = File.expand_path(config['doing_file'])
|
75
78
|
|
76
79
|
if input.nil?
|
77
80
|
create(@doing_file) unless File.exists?(@doing_file)
|
78
81
|
input = IO.read(@doing_file)
|
79
82
|
input = input.force_encoding('utf-8') if input.respond_to? :force_encoding
|
80
83
|
elsif File.exists?(File.expand_path(input)) && File.file?(File.expand_path(input)) && File.stat(File.expand_path(input)).size > 0
|
84
|
+
@doing_file = File.expand_path(input)
|
81
85
|
input = IO.read(File.expand_path(input))
|
82
86
|
input = input.force_encoding('utf-8') if input.respond_to? :force_encoding
|
83
|
-
@doing_file = File.expand_path(input)
|
84
87
|
elsif input.length < 256
|
88
|
+
@doing_file = File.expand_path(input)
|
85
89
|
create(input)
|
90
|
+
input = IO.read(File.expand_path(input))
|
91
|
+
input = input.force_encoding('utf-8') if input.respond_to? :force_encoding
|
86
92
|
end
|
87
93
|
|
88
94
|
@other_content_top = []
|
@@ -125,7 +131,9 @@ class WWID
|
|
125
131
|
end
|
126
132
|
|
127
133
|
def create(filename=nil)
|
128
|
-
filename
|
134
|
+
if filename.nil?
|
135
|
+
filename = @doing_file
|
136
|
+
end
|
129
137
|
unless File.exists?(filename) && File.stat(filename).size > 0
|
130
138
|
File.open(filename,'w+') do |f|
|
131
139
|
f.puts @current_section + ":"
|
@@ -302,7 +310,7 @@ class WWID
|
|
302
310
|
title = item['title']
|
303
311
|
opt[:tags].each {|tag|
|
304
312
|
if opt[:remove]
|
305
|
-
title.gsub!(/(^| )@#{tag}
|
313
|
+
title.gsub!(/(^| )@#{tag.strip}(\([^\)]*\))?/,'')
|
306
314
|
else
|
307
315
|
unless title =~ /@#{tag}/
|
308
316
|
if (tag == "done" && opt[:date]) || opt[:date]
|
@@ -328,6 +336,43 @@ class WWID
|
|
328
336
|
end
|
329
337
|
end
|
330
338
|
|
339
|
+
# accepts one tag and the raw text of a new item
|
340
|
+
# if the passed tag is on any item, it's replaced with @done
|
341
|
+
# if new_item is not nil, it's tagged with the passed tag and inserted
|
342
|
+
# This is for use where only one instance of a given tag should exist (@meanwhile)
|
343
|
+
def stop_start(tag,opt={})
|
344
|
+
opt[:section] ||= @current_section
|
345
|
+
opt[:archive] ||= false
|
346
|
+
opt[:back] ||= Time.now
|
347
|
+
opt[:new_item] ||= false
|
348
|
+
|
349
|
+
opt[:section] = guess_section(opt[:section])
|
350
|
+
|
351
|
+
tag.sub!(/^@/,'')
|
352
|
+
|
353
|
+
@content[opt[:section]]['items'].each_with_index {|item, i|
|
354
|
+
if item['title'] =~ /@#{tag}/
|
355
|
+
title = item['title'].gsub(/(^| )@(#{tag}|done)(\([^\)]*\))?/,'')
|
356
|
+
title += " @done(#{opt[:back].strftime('%F %R')})"
|
357
|
+
|
358
|
+
@content[opt[:section]]['items'][i]['title'] = title
|
359
|
+
|
360
|
+
if opt[:archive] && opt[:section] != "Archive"
|
361
|
+
@content['Archive']['items'].push(@content[opt[:section]]['items'][i])
|
362
|
+
@content[opt[:section]]['items'].delete_at(i)
|
363
|
+
end
|
364
|
+
end
|
365
|
+
}
|
366
|
+
|
367
|
+
if opt[:new_item]
|
368
|
+
title, note = format_input(opt[:new_item])
|
369
|
+
title += " @#{tag}"
|
370
|
+
add_item(title.cap_first, opt[:section], {:note => note, :back => opt[:back]})
|
371
|
+
end
|
372
|
+
|
373
|
+
write(@doing_file)
|
374
|
+
end
|
375
|
+
|
331
376
|
def write(file=nil)
|
332
377
|
if @other_content_top.empty?
|
333
378
|
output = ""
|
@@ -448,6 +493,10 @@ class WWID
|
|
448
493
|
item['date'] < Date.today.to_time
|
449
494
|
}.reverse!
|
450
495
|
section = Time.now.strftime('%A, %B %d')
|
496
|
+
elsif opt[:yesterday]
|
497
|
+
items.delete_if {|item| item['date'] <= Date.today.prev_day.to_time or
|
498
|
+
item['date'] >= Date.today.to_time
|
499
|
+
}.reverse!
|
451
500
|
else
|
452
501
|
if opt[:age] =~ /oldest/i
|
453
502
|
items = items[0..count]
|
@@ -486,13 +535,20 @@ class WWID
|
|
486
535
|
# else
|
487
536
|
# note = ''
|
488
537
|
# end
|
538
|
+
if RUBY_VERSION.to_f > 1.8
|
539
|
+
title = i['title'].force_encoding('utf-8')
|
540
|
+
note = i['note'].map {|line| line.force_encoding('utf-8').strip } if i['note']
|
541
|
+
else
|
542
|
+
title = i['title']
|
543
|
+
note = i['note'].map { |line| line.strip }
|
544
|
+
end
|
489
545
|
items_out << {
|
490
546
|
:date => i['date'].strftime('%a %-I:%M%p'),
|
491
|
-
:title =>
|
492
|
-
:note =>
|
547
|
+
:title => title.gsub(/(@[^ \(]+(\(.*?\))?)/im,'<span class="tag">\1</span>').strip, #+ " #{note}"
|
548
|
+
:note => note
|
493
549
|
}
|
494
550
|
}
|
495
|
-
style = "body{background:#
|
551
|
+
style = "body{background:#fff;color:#333;font-family:Helvetica,arial,freesans,clean,sans-serif;font-size:16px;line-height:120%;text-align:justify;padding:20px}h1{text-align:left;position:relative;left:220px;margin-bottom:1em}ul{list-style-position:outside;position:relative;left:170px;margin-right:170px;text-align:left}ul li{list-style-type:none;border-left:solid 1px #ccc;padding-left:10px;line-height:2}ul li .date{font-size:14px;position:absolute;left:-82px;color:#7d9ca2;text-align:right;width:110px;line-height:2}ul li .tag{color:#999}ul li .note{display:block;color:#666;padding:0 0 0 22px;line-height:1.4;font-size:15px}ul li .note:before{content:'\\25BA';font-weight:300;position:absolute;left:40px;font-size:8px;color:#aaa;line-height:3}ul li:hover .note{display:block}"
|
496
552
|
template =<<EOT
|
497
553
|
!!!
|
498
554
|
%html
|
@@ -580,7 +636,7 @@ EOT
|
|
580
636
|
output.gsub!(/\s(@\S+(?:\(.*?\))?)/," #{colors[opt[:tags_color]]}\\1")
|
581
637
|
end
|
582
638
|
output.sub!(/%note/,note)
|
583
|
-
output.sub!(/%odnote/,note.gsub(
|
639
|
+
output.sub!(/%odnote/,note.gsub(/^\t*/,""))
|
584
640
|
output.gsub!(/%hr(_under)?/) do |m|
|
585
641
|
o = ""
|
586
642
|
`tput cols`.to_i.times do
|
@@ -736,6 +792,11 @@ EOT
|
|
736
792
|
list_section({:section => @current_section, :wrap_width => cfg['wrap_width'], :count => 0, :format => cfg['date_format'], :template => cfg['template'], :order => "asc", :today => true, :times => times, :output => output})
|
737
793
|
end
|
738
794
|
|
795
|
+
def yesterday(section)
|
796
|
+
section = guess_section(section)
|
797
|
+
list_section({:section => section, :count => 0, :order => "asc", :yesterday => true})
|
798
|
+
end
|
799
|
+
|
739
800
|
def recent(count=10,section=nil,opt={})
|
740
801
|
times = opt[:t] || true
|
741
802
|
cfg = @config['templates']['recent']
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: doing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -144,9 +144,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
144
144
|
version: '0'
|
145
145
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
146
|
requirements:
|
147
|
-
- - '
|
147
|
+
- - '>='
|
148
148
|
- !ruby/object:Gem::Version
|
149
|
-
version:
|
149
|
+
version: '0'
|
150
150
|
requirements: []
|
151
151
|
rubyforge_project:
|
152
152
|
rubygems_version: 2.2.2
|