quirk 0.0.4 → 0.0.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.
- data/README.md +50 -14
- data/quirk +3 -3
- data/quirk.rb +30 -4
- data/quirk_test.rb +68 -3
- metadata +3 -3
data/README.md
CHANGED
@@ -6,32 +6,32 @@ Quirk is a command line utility for tracking good and bad habits.
|
|
6
6
|
Installation
|
7
7
|
============
|
8
8
|
|
9
|
-
|
9
|
+
$ gem install quirk
|
10
10
|
|
11
11
|
Then configure your habits in a plaintext file:
|
12
12
|
|
13
|
-
|
13
|
+
$ quirk -e
|
14
14
|
mile-run: monday, wednesday, thursday
|
15
15
|
walk-dog: everyday
|
16
|
-
; comments start with semi-colons
|
17
|
-
|
16
|
+
^quit-tv: friday ; comments start with semi-colons
|
17
|
+
|
18
|
+
By default, all this does is edit the `~/.quirk` file. You can configure
|
19
|
+
which file to use by setting the environment variable `QUIRKFILE`.
|
18
20
|
|
19
21
|
If a habit is prefixed with `^`, it means you're trying to break that habit.
|
20
22
|
In this case you're trying to quit TV on Fridays.
|
21
23
|
|
22
|
-
By default, all this does is edit the `~/.quirk` file. You can configure
|
23
|
-
which file to use by setting the environment variable `QUIRKFILE`.
|
24
24
|
|
25
25
|
Usage
|
26
26
|
=====
|
27
27
|
|
28
28
|
When you've done something, mark it with:
|
29
29
|
|
30
|
-
|
30
|
+
$ quirk -m mile-run
|
31
31
|
|
32
32
|
To see a single habit (green days are good, red is bad):
|
33
33
|
|
34
|
-
|
34
|
+
$ quirk -c mile-run
|
35
35
|
Jan 2012
|
36
36
|
Su Mo Tu We Th Fr Sa
|
37
37
|
1 2 3 4 5 6 7
|
@@ -42,15 +42,21 @@ To see a single habit (green days are good, red is bad):
|
|
42
42
|
|
43
43
|
Looking for a specific year?
|
44
44
|
|
45
|
-
|
45
|
+
$ quirk mile-run -y 2011
|
46
46
|
|
47
47
|
See all of your current streaks:
|
48
48
|
|
49
|
-
|
49
|
+
$ quirk
|
50
50
|
17 mile-run
|
51
51
|
3 walk-dog
|
52
52
|
-3 quit-tv
|
53
53
|
|
54
|
+
See which habits are pending for today:
|
55
|
+
|
56
|
+
$ quirk -t
|
57
|
+
mile-run
|
58
|
+
walk-dog
|
59
|
+
|
54
60
|
Habits are stored in plaintext in `~/.quirk`. You can use `quirk -e` to
|
55
61
|
add/remove entries. Note that habits start on the day of the first mark
|
56
62
|
by default. You can also specify the first day using `^`:
|
@@ -59,9 +65,20 @@ by default. You can also specify the first day using `^`:
|
|
59
65
|
2012/01/01 ^quit-tv
|
60
66
|
|
61
67
|
The first line means you walked the dog on `1/1`. The second line means you
|
62
|
-
started the habit of quitting TV. This is
|
68
|
+
started the habit of quitting TV. This is especially handy for starting
|
63
69
|
quitting habits on a green day.
|
64
70
|
|
71
|
+
You can specify the last day for a habit using `$`:
|
72
|
+
|
73
|
+
2012/01/01 ^quit-tv
|
74
|
+
2012/01/30 $quit-tv
|
75
|
+
2012/01/15 quit-tv
|
76
|
+
2012/01/16 quit-tv
|
77
|
+
|
78
|
+
The first line means on `1/1`, I'm going to start quitting TV. The second line
|
79
|
+
means I'll stop the habit on `1/30`, it's just a temporary goal for 1 month.
|
80
|
+
The last two lines means I watched TV on `1/15` and `1/16` (two red days).
|
81
|
+
|
65
82
|
Zsh Tab Completion
|
66
83
|
==================
|
67
84
|
|
@@ -72,12 +89,31 @@ Here's an example zsh completion function:
|
|
72
89
|
|
73
90
|
Put this into your `site-functions` directory (wherever `$fpath` points to):
|
74
91
|
|
75
|
-
|
92
|
+
$ echo $fpath
|
76
93
|
/usr/share/zsh/site-functions /usr/share/zsh/4.3.11/functions
|
77
|
-
|
94
|
+
$ vim /usr/share/zsh/site-functions/_quirk
|
95
|
+
|
96
|
+
Tmux and Other Notifications Integration
|
97
|
+
========================================
|
98
|
+
|
99
|
+
Use `quirk -t` to see which habits are pending for today. Habits are separated
|
100
|
+
by a newline. Use `xargs` and/or `tr` to format as you see fit:
|
101
|
+
|
102
|
+
$ quirk -t
|
103
|
+
mile-run
|
104
|
+
wlak-dog
|
105
|
+
$ quirk -t | xargs
|
106
|
+
mile-run walk-dog
|
107
|
+
$ quirk -t | xargs | tr " " ,
|
108
|
+
mile-run,walk-dog
|
109
|
+
|
110
|
+
This is useful for `tmux`'s status as a reminder of which habits are pending.
|
111
|
+
Put this in your `.tmux.conf` file:
|
112
|
+
|
113
|
+
set -g status-right '#[fg=yellow]#(quirk -t | xargs | tr " " ,)'
|
78
114
|
|
79
115
|
License
|
80
116
|
=======
|
81
117
|
|
82
|
-
Copyright
|
118
|
+
Copyright Hugh Bien - http://hughbien.com.
|
83
119
|
Released under BSD License, see LICENSE.md for more info.
|
data/quirk
CHANGED
@@ -5,7 +5,7 @@ require File.expand_path('quirk', File.dirname(__FILE__))
|
|
5
5
|
ARGV.options do |o|
|
6
6
|
begin
|
7
7
|
app = Quirk::App.new
|
8
|
-
action =
|
8
|
+
action = 'streaks'
|
9
9
|
o.set_summary_indent(' ')
|
10
10
|
o.banner = "Usage: #{File.basename($0)} [OPTION]"
|
11
11
|
o.define_head "Track good and bad habits (v#{Quirk::VERSION})"
|
@@ -13,11 +13,11 @@ ARGV.options do |o|
|
|
13
13
|
o.on('-e', '--edit', 'edit habits') { action = [:edit] }
|
14
14
|
o.on('-l', '--list', 'list habits') { action = [:list] }
|
15
15
|
o.on('-m', '--mark habit', 'mark for today') { |h| action = [:mark, h] }
|
16
|
-
o.on('-
|
16
|
+
o.on('-t', '--today', 'unfinished habits for today') { action = [:today] }
|
17
17
|
o.on('-y', '--year year', 'set calendar year') { |y| app.year = y }
|
18
18
|
o.on('-h', '--help', 'show this help message') { puts o; exit }
|
19
19
|
o.parse!
|
20
|
-
|
20
|
+
app.send(*action)
|
21
21
|
rescue RuntimeError => e
|
22
22
|
puts e.to_s
|
23
23
|
end
|
data/quirk.rb
CHANGED
@@ -2,7 +2,7 @@ require 'date'
|
|
2
2
|
require 'colorize'
|
3
3
|
|
4
4
|
module Quirk
|
5
|
-
VERSION = '0.0.
|
5
|
+
VERSION = '0.0.5'
|
6
6
|
QUIRKFILE = ENV['QUIRKFILE'] || "#{ENV['HOME']}/.quirk"
|
7
7
|
EDITOR = ENV['EDITOR'] || 'vi'
|
8
8
|
|
@@ -39,6 +39,10 @@ module Quirk
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
def today
|
43
|
+
puts cal.today if cal.today !~ /^\s*$/
|
44
|
+
end
|
45
|
+
|
42
46
|
def streaks
|
43
47
|
puts cal.streaks
|
44
48
|
end
|
@@ -75,14 +79,23 @@ module Quirk
|
|
75
79
|
@first_date = date
|
76
80
|
end
|
77
81
|
|
82
|
+
def mark_last!(date)
|
83
|
+
@last_date = date
|
84
|
+
end
|
85
|
+
|
78
86
|
def first_date
|
79
87
|
@first_date || @marks.first
|
80
88
|
end
|
81
89
|
|
90
|
+
def pending?(date)
|
91
|
+
weekday = date.strftime("%w").to_i
|
92
|
+
!quitting? && days.include?(weekday) && color_on(date) != :light_green
|
93
|
+
end
|
94
|
+
|
82
95
|
def color_on(date)
|
83
96
|
hit_color = quitting? ? :light_red : :light_green
|
84
97
|
miss_color = quitting? ? :light_green : :light_red
|
85
|
-
last_date = Quirk.today
|
98
|
+
last_date = [@last_date, Quirk.today].compact.min
|
86
99
|
if first_date.nil? ||
|
87
100
|
date < first_date ||
|
88
101
|
date > last_date ||
|
@@ -96,7 +109,7 @@ module Quirk
|
|
96
109
|
end
|
97
110
|
|
98
111
|
def streak
|
99
|
-
return 0 if
|
112
|
+
return 0 if first_date.nil?
|
100
113
|
|
101
114
|
count = 0
|
102
115
|
deltas = {:light_red => -1, :light_green => 1, :white => 0}
|
@@ -208,12 +221,24 @@ module Quirk
|
|
208
221
|
original = original.sub(/^\^\s*/, '')
|
209
222
|
habit = @habits[original] if has_habit?(original)
|
210
223
|
habit.mark_first!(date)
|
224
|
+
elsif original =~ /^\$\s*/
|
225
|
+
original = original.sub(/^\$\s*/, '')
|
226
|
+
habit = @habits[original] if has_habit?(original)
|
227
|
+
habit.mark_last!(date)
|
211
228
|
elsif has_habit?(original)
|
212
229
|
@habits[original].mark!(date)
|
213
230
|
end
|
214
231
|
end
|
215
232
|
end
|
216
233
|
|
234
|
+
def today
|
235
|
+
@habits.values.
|
236
|
+
select {|h| h.pending?(Quirk.today)}.
|
237
|
+
map(&:id).
|
238
|
+
sort.
|
239
|
+
join("\n")
|
240
|
+
end
|
241
|
+
|
217
242
|
def streaks
|
218
243
|
pairs = @habits.values.map do |habit|
|
219
244
|
[habit.streak, habit.id]
|
@@ -227,9 +252,10 @@ module Quirk
|
|
227
252
|
def self.parse(text)
|
228
253
|
marks, habits = [], []
|
229
254
|
text.strip.each_line do |line|
|
255
|
+
line = line.split(';')[0].to_s.strip # remove comments
|
230
256
|
if line =~ /^\d\d\d\d\/\d\d?\/\d\d?\s+/
|
231
257
|
marks << line
|
232
|
-
elsif line !~ /^\s*$/
|
258
|
+
elsif line !~ /^\s*$/
|
233
259
|
habits << Habit.parse(line)
|
234
260
|
end
|
235
261
|
end
|
data/quirk_test.rb
CHANGED
@@ -28,6 +28,19 @@ class QuirkHabitTest < MiniTest::Unit::TestCase
|
|
28
28
|
assert(habit3.quitting?)
|
29
29
|
end
|
30
30
|
|
31
|
+
def test_pending
|
32
|
+
habit = Quirk::Habit.parse('running: monday')
|
33
|
+
refute(habit.pending?(Date.new(2012, 1, 1)))
|
34
|
+
assert(habit.pending?(Date.new(2012, 1, 2)))
|
35
|
+
habit.mark!(Date.new(2012, 1, 2))
|
36
|
+
refute(habit.pending?(Date.new(2012, 1, 2)))
|
37
|
+
|
38
|
+
habit2 = Quirk::Habit.parse('^quit-tv: everyday')
|
39
|
+
refute(habit.pending?(Date.new(2012, 1, 1)))
|
40
|
+
habit.mark!(Date.new(2012, 1, 1))
|
41
|
+
refute(habit.pending?(Date.new(2012, 1, 1)))
|
42
|
+
end
|
43
|
+
|
31
44
|
def test_color_on
|
32
45
|
habit = Quirk::Habit.parse('running: sunday, monday, wednesday, thursday')
|
33
46
|
habit.mark!(Date.new(2012, 1, 2))
|
@@ -65,6 +78,51 @@ class QuirkHabitTest < MiniTest::Unit::TestCase
|
|
65
78
|
assert_equal(:white, quit.color_on(Date.new(2012, 1, 6)))
|
66
79
|
end
|
67
80
|
|
81
|
+
def test_color_on_last_date
|
82
|
+
habit = Quirk::Habit.parse('running: everyday')
|
83
|
+
habit.mark!(Date.new(2012, 1, 2))
|
84
|
+
habit.mark!(Date.new(2012, 1, 3))
|
85
|
+
habit.mark_last!(Date.new(2012, 1, 4))
|
86
|
+
assert_equal(:white, habit.color_on(Date.new(2012, 1, 1)))
|
87
|
+
assert_equal(:light_green, habit.color_on(Date.new(2012, 1, 2)))
|
88
|
+
assert_equal(:light_green, habit.color_on(Date.new(2012, 1, 3)))
|
89
|
+
assert_equal(:white, habit.color_on(Date.new(2012, 1, 4)))
|
90
|
+
assert_equal(:white, habit.color_on(Date.new(2012, 1, 5)))
|
91
|
+
|
92
|
+
habit.mark!(Date.new(2012, 1, 4))
|
93
|
+
habit.mark!(Date.new(2012, 1, 5))
|
94
|
+
assert_equal(:light_green, habit.color_on(Date.new(2012, 1, 4)))
|
95
|
+
assert_equal(:white, habit.color_on(Date.new(2012, 1, 5)))
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_color_on_future_last_date
|
99
|
+
habit = Quirk::Habit.parse('running: everyday')
|
100
|
+
habit.mark!(Date.new(2012, 1, 2))
|
101
|
+
habit.mark!(Date.new(2012, 1, 4))
|
102
|
+
habit.mark_last!(Date.new(2012, 1, 29))
|
103
|
+
assert_equal(:white, habit.color_on(Date.new(2012, 1, 1)))
|
104
|
+
assert_equal(:light_green, habit.color_on(Date.new(2012, 1, 2)))
|
105
|
+
assert_equal(:light_red, habit.color_on(Date.new(2012, 1, 3)))
|
106
|
+
assert_equal(:light_green, habit.color_on(Date.new(2012, 1, 4)))
|
107
|
+
assert_equal(:white, habit.color_on(Date.new(2012, 1, 5)))
|
108
|
+
assert_equal(:white, habit.color_on(Date.new(2012, 1, 6)))
|
109
|
+
assert_equal(:white, habit.color_on(Date.new(2012, 1, 28)))
|
110
|
+
assert_equal(:white, habit.color_on(Date.new(2012, 1, 29)))
|
111
|
+
assert_equal(:white, habit.color_on(Date.new(2012, 1, 30)))
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_color_on_quit_last_date
|
115
|
+
quit = Quirk::Habit.parse('^quit-tv: everyday')
|
116
|
+
quit.mark_first!(Date.new(2012, 1, 1))
|
117
|
+
quit.mark_last!(Date.new(2012, 1, 4))
|
118
|
+
quit.mark!(Date.new(2012, 1, 5))
|
119
|
+
assert_equal(:light_green, quit.color_on(Date.new(2012, 1, 1)))
|
120
|
+
assert_equal(:light_green, quit.color_on(Date.new(2012, 1, 2)))
|
121
|
+
assert_equal(:light_green, quit.color_on(Date.new(2012, 1, 3)))
|
122
|
+
assert_equal(:light_green, quit.color_on(Date.new(2012, 1, 4)))
|
123
|
+
assert_equal(:white, quit.color_on(Date.new(2012, 1, 5)))
|
124
|
+
end
|
125
|
+
|
68
126
|
def test_streak
|
69
127
|
missing = Quirk::Habit.parse('running: everyday')
|
70
128
|
assert_equal(0, missing.streak)
|
@@ -103,6 +161,7 @@ class QuirkCalendarTest < MiniTest::Unit::TestCase
|
|
103
161
|
@smoking = Quirk::Habit.parse('^smoking: everyday')
|
104
162
|
@cal = Quirk::Calendar.new([@running, @walking, @smoking])
|
105
163
|
@cal.mark!('2012/01/01 ^smoking')
|
164
|
+
@cal.mark!('2012/01/04 $smoking')
|
106
165
|
@cal.mark!('2012/01/01 running, walk-dog')
|
107
166
|
@cal.mark!('2012/01/02 running, walk-dog')
|
108
167
|
end
|
@@ -110,10 +169,10 @@ class QuirkCalendarTest < MiniTest::Unit::TestCase
|
|
110
169
|
def test_parse
|
111
170
|
calendar = Quirk::Calendar.parse(
|
112
171
|
"; ignore comment line\n" +
|
113
|
-
"running: everyday\n" +
|
172
|
+
"running: everyday ; ignore comment\n" +
|
114
173
|
"^smoking: everyday\n\n" +
|
115
174
|
"; ignore comment line\n" +
|
116
|
-
"2012/01/01 ^smoking\n" +
|
175
|
+
"2012/01/01 ^smoking ; ignore comment\n" +
|
117
176
|
"2012/01/01 running\n\n")
|
118
177
|
|
119
178
|
assert(calendar.has_habit?('running'))
|
@@ -135,7 +194,13 @@ class QuirkCalendarTest < MiniTest::Unit::TestCase
|
|
135
194
|
assert_equal(Date.new(2012, 1, 1), @smoking.first_date)
|
136
195
|
end
|
137
196
|
|
197
|
+
def test_today
|
198
|
+
assert_equal("running", @cal.today)
|
199
|
+
@cal.mark!('2012/01/05 running')
|
200
|
+
assert_equal("", @cal.today)
|
201
|
+
end
|
202
|
+
|
138
203
|
def test_streaks
|
139
|
-
assert_equal("-2 running\n
|
204
|
+
assert_equal("-2 running\n 1 walk-dog\n 4 smoking", @cal.streaks)
|
140
205
|
end
|
141
206
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quirk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: .
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-02-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
@@ -53,8 +53,8 @@ extra_rdoc_files: []
|
|
53
53
|
files:
|
54
54
|
- quirk.rb
|
55
55
|
- quirk_test.rb
|
56
|
-
- README.md
|
57
56
|
- LICENSE.md
|
57
|
+
- README.md
|
58
58
|
- quirk
|
59
59
|
- ./quirk
|
60
60
|
homepage: https://github.com/hughbien/quirk
|