doing 0.2.5pre → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8806f026f8106baa4c033a2d30675e0f3c30afea
4
- data.tar.gz: 77139cb8ae62cc18311d5fcd7c27a725806375c9
3
+ metadata.gz: a4645c47a272a4fdf45174b2adff019820ed1537
4
+ data.tar.gz: 444fa7c255629e9f9e5f1b357c28b0fd2ac3e8c3
5
5
  SHA512:
6
- metadata.gz: 6fb8b55cc46ceefe4c139af635417b2c318e90705ef7da3fb3aa2e2050bd7e7de89d4d9633e538ec0ca26e6d3582a81e3fa394ac3bf032684d463a36573f5cca
7
- data.tar.gz: 659c26db54235f3ca7d13cc34bdc2f4cdd3e028cc6514c2c5f01c0c9216c7c0fcc693de629f3b965dd5b533e91b8390e09fdd29aebd010d5109ba947394ef16a
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 - List all entries
289
- recent - List recent entries
290
- today - List entries from today
291
- last - Show the last entry
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
- wwid.tag_last({:tags => ["done"], :count => 1, :section => section, :archive => options[:a], :back => date, :date => options[:d]})
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[:a] || options[:b]
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
@@ -1,3 +1,3 @@
1
1
  module Doing
2
- VERSION = '0.2.5pre'
2
+ VERSION = '0.2.5'
3
3
  end
@@ -12,7 +12,7 @@ class WWID
12
12
  attr_accessor :content, :sections, :current_section, :doing_file, :config
13
13
 
14
14
 
15
- def initialize(input=nil)
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 = @doing_file
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 => i['title'].gsub(/(@[^ \(]+(\(.*?\))?)/is,'<span class="tag">\1</span>').strip, #+ " #{note}"
492
- :note => i['note']
547
+ :title => title.gsub(/(@[^ \(]+(\(.*?\))?)/im,'<span class="tag">\1</span>').strip, #+ " #{note}"
548
+ :note => note
493
549
  }
494
550
  }
495
- style = "body{background:#faf9f5;color:#333;font-family:Palatino,Georgia,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:1.75}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}"
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(/\t\t/,"\t"))
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.5pre
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-03-22 00:00:00.000000000 Z
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: 1.3.1
149
+ version: '0'
150
150
  requirements: []
151
151
  rubyforge_project:
152
152
  rubygems_version: 2.2.2