doing 1.0.58 → 1.0.62
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/bin/doing +38 -11
- data/lib/doing/version.rb +1 -1
- data/lib/doing/wwid.rb +70 -98
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e2384e06e56e40f7f6c2b26121d16e0caa2cf40639158fc0f079f8ae26738da
|
4
|
+
data.tar.gz: 9e62f0ac38c0f19082094b88382e9779b743a4885403d796dddfb21a68ea1de2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8cdb34a404ae818f10ee9facaba83fd44c584d06950fd2908b6fbb25b04e6a117a74a20836b765a2dca1cde480928398a42b5999e1678499013cbb1e88e5ccac
|
7
|
+
data.tar.gz: 5a771f4ba236518f54cd11bc99f1258b90026afe4face70db83e98f5f5ee97124eab732c7c65ccd61f1b98e18129c4034ea6c036c145e45abe298f058e25bc3e
|
data/README.md
CHANGED
@@ -29,7 +29,7 @@ _Side note:_ I actually use the library behind this utility as part of another s
|
|
29
29
|
|
30
30
|
## Installation
|
31
31
|
|
32
|
-
The current version of `doing` is <!--VER-->1.0.
|
32
|
+
The current version of `doing` is <!--VER-->1.0.61<!--END VER-->.
|
33
33
|
|
34
34
|
$ [sudo] gem install doing
|
35
35
|
|
@@ -167,7 +167,7 @@ The config also contains templates for various command outputs. Include placehol
|
|
167
167
|
- there are some random special combo colors. Use `doing colors` to see the list
|
168
168
|
- `%interval`: when used with the `-t` switch on the `show` command, it will display the time between a timestamp or _@start(date)_ tag and the _@done(date)_ tag, if it exists. Otherwise, it will remain empty.
|
169
169
|
|
170
|
-
Date formats are based on Ruby [`strftime`](http://www.ruby-doc.org/stdlib-2.1.1/libdoc/date/rdoc/Date.html#method-i-strftime) formatting.
|
170
|
+
Date formats are based on Ruby [`strftime`](http://www.ruby-doc.org/stdlib-2.1.1/libdoc/date/rdoc/Date.html#method-i-strftime) formatting. You can try it out [here](http://strftime.net).
|
171
171
|
|
172
172
|
My normal template for the `recent` command looks like this:
|
173
173
|
|
data/bin/doing
CHANGED
@@ -310,7 +310,7 @@ end
|
|
310
310
|
|
311
311
|
desc 'Add a completed item with @done(date). No argument finishes last entry.'
|
312
312
|
arg_name 'ENTRY'
|
313
|
-
command [
|
313
|
+
command %i[done did] do |c|
|
314
314
|
c.desc 'Remove @done tag'
|
315
315
|
c.switch %i[r remove], negatable: false, default_value: false
|
316
316
|
|
@@ -367,7 +367,7 @@ command [:done, :did] do |c|
|
|
367
367
|
|
368
368
|
date = options[:took] ? finish_date - took : finish_date
|
369
369
|
elsif options[:took]
|
370
|
-
finish_date = date + took
|
370
|
+
finish_date = options[:back] ? date + took : nil
|
371
371
|
elsif options[:back]
|
372
372
|
finish_date = date
|
373
373
|
else
|
@@ -375,7 +375,9 @@ command [:done, :did] do |c|
|
|
375
375
|
end
|
376
376
|
|
377
377
|
section = wwid.guess_section(options[:s]) || options[:s].cap_first
|
378
|
-
|
378
|
+
if finish_date
|
379
|
+
donedate = options[:date] ? "(#{finish_date.strftime('%F %R')})" : ''
|
380
|
+
end
|
379
381
|
|
380
382
|
if options[:e]
|
381
383
|
raise 'No EDITOR variable defined in environment' if ENV['EDITOR'].nil?
|
@@ -394,8 +396,15 @@ command [:done, :did] do |c|
|
|
394
396
|
if options[:r]
|
395
397
|
wwid.tag_last({ tags: ['done'], count: 1, section: section, remove: true })
|
396
398
|
else
|
397
|
-
|
398
|
-
|
399
|
+
options = { tags: ['done'],
|
400
|
+
archive: options[:a],
|
401
|
+
back: finish_date,
|
402
|
+
count: 1,
|
403
|
+
date: options[:date],
|
404
|
+
section: section,
|
405
|
+
took: took == 0 ? nil : took
|
406
|
+
}
|
407
|
+
wwid.tag_last(options)
|
399
408
|
end
|
400
409
|
elsif !args.empty?
|
401
410
|
title, note = wwid.format_input(args.join(' '))
|
@@ -572,7 +581,7 @@ command [:again, :resume] do |c|
|
|
572
581
|
|
573
582
|
c.desc 'Boolean used to combine multiple tags'
|
574
583
|
c.arg_name 'BOOLEAN'
|
575
|
-
c.flag [:bool], must_match: /^(and|or|not)$/i, default_value: '
|
584
|
+
c.flag [:bool], must_match: /^(and|or|not)$/i, default_value: 'AND'
|
576
585
|
|
577
586
|
c.desc 'Note'
|
578
587
|
c.arg_name 'TEXT'
|
@@ -1230,14 +1239,17 @@ desc 'Move entries between sections'
|
|
1230
1239
|
arg_name 'SECTION_NAME'
|
1231
1240
|
default_value wwid.current_section
|
1232
1241
|
command :archive do |c|
|
1233
|
-
c.desc '
|
1234
|
-
c.arg_name '
|
1235
|
-
c.flag %i[k keep],
|
1242
|
+
c.desc 'How many items to keep (ignored if archiving by tag or search)'
|
1243
|
+
c.arg_name 'X'
|
1244
|
+
c.flag %i[k keep], must_match: /^\d+$/, type: Integer
|
1236
1245
|
|
1237
1246
|
c.desc 'Move entries to'
|
1238
1247
|
c.arg_name 'SECTION_NAME'
|
1239
1248
|
c.flag %i[t to], default_value: 'Archive'
|
1240
1249
|
|
1250
|
+
c.desc 'Label moved items with @from(SECTION_NAME)'
|
1251
|
+
c.switch [:label], default_value: true, negatable: true
|
1252
|
+
|
1241
1253
|
c.desc 'Tag filter, combine multiple tags with a comma. Added for compatibility with other commands.'
|
1242
1254
|
c.arg_name 'TAG'
|
1243
1255
|
c.flag [:tag]
|
@@ -1246,21 +1258,36 @@ command :archive do |c|
|
|
1246
1258
|
c.arg_name 'BOOLEAN'
|
1247
1259
|
c.flag [:bool], must_match: /(and|or|not)/i, default_value: 'AND'
|
1248
1260
|
|
1261
|
+
c.desc 'Search filter'
|
1262
|
+
c.arg_name 'QUERY'
|
1263
|
+
c.flag [:search]
|
1264
|
+
|
1249
1265
|
c.action do |_global_options, options, args|
|
1250
1266
|
if args.empty?
|
1251
1267
|
section = wwid.current_section
|
1252
1268
|
tags = []
|
1269
|
+
elsif args[0] =~ /^all/i
|
1270
|
+
section = 'all'
|
1253
1271
|
elsif args[0] =~ /^@\S+/
|
1254
1272
|
section = 'all'
|
1255
1273
|
tags = args.map { |t| t.sub(/^@/, '').strip }
|
1256
1274
|
else
|
1257
1275
|
section = args[0].cap_first
|
1258
|
-
tags = args.length > 1 ? args[1..].map { |t| t.sub(/^@/, '').strip } :
|
1276
|
+
tags = args.length > 1 ? args[1..].map { |t| t.sub(/^@/, '').strip } : []
|
1259
1277
|
end
|
1260
1278
|
|
1279
|
+
raise '--keep and --count can\'t be used together' if options[:keep] && options[:count]
|
1280
|
+
|
1261
1281
|
tags.concat(options[:tag].split(/ *, */).map { |t| t.sub(/^@/, '').strip }) if options[:tag]
|
1262
1282
|
|
1263
|
-
|
1283
|
+
opts = {
|
1284
|
+
bool: options[:bool],
|
1285
|
+
destination: options[:to],
|
1286
|
+
keep: options[:keep],
|
1287
|
+
search: options[:search],
|
1288
|
+
tags: tags
|
1289
|
+
}
|
1290
|
+
wwid.archive(section, opts)
|
1264
1291
|
end
|
1265
1292
|
end
|
1266
1293
|
|
data/lib/doing/version.rb
CHANGED
data/lib/doing/wwid.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'deep_merge'
|
4
4
|
require 'open3'
|
5
|
+
require 'pp'
|
5
6
|
|
6
7
|
##
|
7
8
|
## @brief Hash helpers
|
@@ -775,6 +776,7 @@ class WWID
|
|
775
776
|
opt[:remove] ||= false
|
776
777
|
opt[:autotag] ||= false
|
777
778
|
opt[:back] ||= false
|
779
|
+
opt[:took] ||= nil
|
778
780
|
|
779
781
|
sec_arr = []
|
780
782
|
|
@@ -832,6 +834,8 @@ class WWID
|
|
832
834
|
else
|
833
835
|
done_date = item['date'] + (opt[:back] - item['date'])
|
834
836
|
end
|
837
|
+
elsif opt[:took]
|
838
|
+
done_date = item['date'] + opt[:took]
|
835
839
|
else
|
836
840
|
done_date = Time.now
|
837
841
|
end
|
@@ -890,26 +894,7 @@ class WWID
|
|
890
894
|
end
|
891
895
|
|
892
896
|
def update_item(old_item, new_item)
|
893
|
-
|
894
|
-
@content.each do |_k, v|
|
895
|
-
items.concat(v['items'])
|
896
|
-
end
|
897
|
-
|
898
|
-
idx = nil
|
899
|
-
|
900
|
-
items.each_with_index do |item, i|
|
901
|
-
if old_item == item
|
902
|
-
idx = i
|
903
|
-
break
|
904
|
-
end
|
905
|
-
end
|
906
|
-
|
907
|
-
if idx.nil?
|
908
|
-
@results.push('No entries found')
|
909
|
-
return
|
910
|
-
end
|
911
|
-
|
912
|
-
section = items[idx]['section']
|
897
|
+
section = old_item['section']
|
913
898
|
|
914
899
|
section_items = @content[section]['items']
|
915
900
|
s_idx = section_items.index(old_item)
|
@@ -917,7 +902,6 @@ class WWID
|
|
917
902
|
section_items[s_idx] = new_item
|
918
903
|
@results.push("Entry updated: #{section_items[s_idx]['title']}")
|
919
904
|
@content[section]['items'] = section_items
|
920
|
-
write(@doing_file)
|
921
905
|
end
|
922
906
|
|
923
907
|
##
|
@@ -1570,31 +1554,24 @@ class WWID
|
|
1570
1554
|
## section
|
1571
1555
|
##
|
1572
1556
|
## @param section (String) The source section
|
1573
|
-
## @param
|
1574
|
-
## @param destination (String) The destination section
|
1575
|
-
## @param tags (Array) Tags to archive
|
1576
|
-
## @param bool (String) Tag boolean combinator
|
1557
|
+
## @param options (Hash) Options
|
1577
1558
|
##
|
1578
|
-
def archive(section = 'Currently',
|
1559
|
+
def archive(section = 'Currently', options = {})
|
1560
|
+
count = options[:keep] || 0
|
1561
|
+
destination = options[:destination] || 'Archive'
|
1562
|
+
tags = options[:tags] || []
|
1563
|
+
bool = options[:bool] || 'AND'
|
1564
|
+
|
1579
1565
|
section = choose_section if section.nil? || section =~ /choose/i
|
1580
|
-
archive_all = section =~
|
1566
|
+
archive_all = section =~ /^all$/i # && !(tags.nil? || tags.empty?)
|
1581
1567
|
section = guess_section(section) unless archive_all
|
1582
1568
|
|
1583
|
-
add_section('Archive') if destination =~
|
1569
|
+
add_section('Archive') if destination =~ /^archive$/i && !sections.include?('Archive')
|
1584
1570
|
|
1585
1571
|
destination = guess_section(destination)
|
1586
1572
|
|
1587
1573
|
if sections.include?(destination) && (sections.include?(section) || archive_all)
|
1588
|
-
|
1589
|
-
to_archive = sections.dup
|
1590
|
-
to_archive.delete(destination)
|
1591
|
-
to_archive.each do |source, _v|
|
1592
|
-
do_archive(source, destination, { count: count, tags: tags, bool: bool, label: true })
|
1593
|
-
end
|
1594
|
-
else
|
1595
|
-
do_archive(section, destination, { count: count, tags: tags, bool: bool, label: true })
|
1596
|
-
end
|
1597
|
-
|
1574
|
+
do_archive(section, destination, { count: count, tags: tags, bool: bool, search: options[:search], label: options[:label] })
|
1598
1575
|
write(doing_file)
|
1599
1576
|
else
|
1600
1577
|
raise 'Either source or destination does not exist'
|
@@ -1608,74 +1585,69 @@ class WWID
|
|
1608
1585
|
## @param destination (String) The destination section
|
1609
1586
|
## @param opt (Hash) Additional Options
|
1610
1587
|
##
|
1611
|
-
def do_archive(
|
1612
|
-
count = opt[:count] ||
|
1613
|
-
tags
|
1614
|
-
bool
|
1615
|
-
label = opt[:label] ||
|
1588
|
+
def do_archive(sect, destination, opt = {})
|
1589
|
+
count = opt[:count] || 0
|
1590
|
+
tags = opt[:tags] || []
|
1591
|
+
bool = opt[:bool] || 'AND'
|
1592
|
+
label = opt[:label] || true
|
1616
1593
|
|
1617
|
-
|
1618
|
-
|
1594
|
+
if sect =~ /^all$/i
|
1595
|
+
all_sections = sections.dup
|
1596
|
+
all_sections.delete(destination)
|
1597
|
+
else
|
1598
|
+
all_sections = [sect]
|
1599
|
+
end
|
1619
1600
|
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
del = true if item['title'] =~ /@#{tag}/i
|
1601
|
+
counter = 0
|
1602
|
+
|
1603
|
+
all_sections.each do |section|
|
1604
|
+
items = @content[section]['items']
|
1605
|
+
|
1606
|
+
moved_items = []
|
1607
|
+
if !tags.empty? || opt[:search]
|
1608
|
+
items.delete_if do |item|
|
1609
|
+
if (!tags.empty? && item.has_tags?(tags, bool) || (opt[:search] && item.matches_search?(opt[:search].to_s)))
|
1610
|
+
moved_items.push(item)
|
1611
|
+
counter += 1
|
1612
|
+
true
|
1613
|
+
else
|
1614
|
+
false
|
1635
1615
|
end
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
del = false if item['title'] =~ /@#{tag}/i
|
1616
|
+
end
|
1617
|
+
moved_items.each do |item|
|
1618
|
+
if label && section != 'Currently'
|
1619
|
+
item['title'] =
|
1620
|
+
item['title'].sub(/(?:@from\(.*?\))?(.*)$/, "\\1 @from(#{section})")
|
1642
1621
|
end
|
1643
|
-
moved_items.push(item) if del
|
1644
|
-
del
|
1645
1622
|
end
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1623
|
+
|
1624
|
+
@content[section]['items'] = items
|
1625
|
+
@content[destination]['items'].concat(moved_items)
|
1626
|
+
@results.push("Archived #{moved_items.length} items from #{section} to #{destination}")
|
1627
|
+
else
|
1628
|
+
count = items.length if count == 0 || items.length < count
|
1629
|
+
|
1630
|
+
@content[section]['items'] = if count.zero?
|
1631
|
+
[]
|
1632
|
+
else
|
1633
|
+
items[0..count - 1]
|
1634
|
+
end
|
1635
|
+
|
1636
|
+
items.map! do |item|
|
1637
|
+
if label && section != 'Currently'
|
1638
|
+
item['title'] =
|
1639
|
+
item['title'].sub(/(?:@from\(.*?\))?(.*)$/, "\\1 @from(#{section})")
|
1640
|
+
end
|
1641
|
+
item
|
1651
1642
|
end
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
else
|
1657
|
-
count = items.length if items.length < count
|
1658
|
-
|
1659
|
-
@content[section]['items'] = if count.zero?
|
1660
|
-
[]
|
1661
|
-
else
|
1662
|
-
items[0..count - 1]
|
1663
|
-
end
|
1664
|
-
|
1665
|
-
items.map! do |item|
|
1666
|
-
if label && section != 'Currently'
|
1667
|
-
item['title'] =
|
1668
|
-
item['title'].sub(/(?:@from\(.*?\))?(.*)$/, "\\1 @from(#{section})")
|
1643
|
+
if items.count > count
|
1644
|
+
@content[destination]['items'].concat(items[count..-1])
|
1645
|
+
else
|
1646
|
+
@content[destination]['items'].concat(items)
|
1669
1647
|
end
|
1670
|
-
item
|
1671
|
-
end
|
1672
|
-
if items.count > count
|
1673
|
-
@content[destination]['items'].concat(items[count..-1])
|
1674
|
-
else
|
1675
|
-
@content[destination]['items'].concat(items)
|
1676
|
-
end
|
1677
1648
|
|
1678
|
-
|
1649
|
+
@results.push("Archived #{items.length - count} items from #{section} to #{destination}")
|
1650
|
+
end
|
1679
1651
|
end
|
1680
1652
|
end
|
1681
1653
|
|
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: 1.0.
|
4
|
+
version: 1.0.62
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-07-
|
11
|
+
date: 2021-07-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|