nin 0.7.0 → 1.0.0

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
  SHA256:
3
- metadata.gz: e69e3a795983376ba5be5fd6bd9b639dcb8856cf11585e52cb2493b701e98ab4
4
- data.tar.gz: 4e3662bb0d5e87243eb78d20619e5a33904c586e158a3e4fa067ebd098e6e0d1
3
+ metadata.gz: 3861707860a4a5fabaf36726dee7e0e96d806bcfb3186f8d89e20fb31ace4e8e
4
+ data.tar.gz: e4a55a32155286f7e06064795d77b2611a17e6c4a6534f850ea1e1798f5002d1
5
5
  SHA512:
6
- metadata.gz: 72afcf6252cd03732ebd9b1e03d9eb0fc209aaf22edc1de4760be1a0d5e89ee2cf01210dd915cd0cb01d3d23700552e45e7de9738ebcd76b86b196d432a416e7
7
- data.tar.gz: f6850697bc332effae708dcee96ef0b1f0812e8e254c8a9f7ad5bb3da57f35db6188c0d739dfb386be4dc03e1529d5ff7538051f69044210f9bf09cf0f311c8a
6
+ metadata.gz: 754a8cc8c7a0a503f1feec3a46d725fefc793cbc41514f592e4c8bdcccec14d87926d11b0833abb44e5afe69ab141f30681b6d653008dfaca28f12bef70d2ac7
7
+ data.tar.gz: 3923c3a626568dc5f20478c6235c98305dda0ac7536618f65337d7a9123c7ec8148d70dedc58e393638e651bbfee0e05ff66edef2f495d9657df9933ecdb1788
data/.gitignore CHANGED
@@ -1,2 +1,4 @@
1
1
  *.gem
2
2
  .byebug_history
3
+ .bundle/
4
+ Gemfile.lock
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2
4
+ - 2.5
5
+ - jruby
data/Gemfile CHANGED
@@ -3,3 +3,7 @@ source "https://rubygems.org"
3
3
  git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  gemspec
6
+
7
+ group :development, :test do
8
+ gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
9
+ end
data/README.md CHANGED
@@ -1,9 +1,14 @@
1
- nin
2
- ---
1
+ <div align="center">
2
+ <h1>
3
+ nin
4
+ </h1>
3
5
 
4
- A simple, full-featured command line todo app
6
+ A simple, full-featured command line todo app
5
7
 
6
- ![nin demo GIF](/demo.gif)
8
+ ![nin demo GIF](/demo.gif)
9
+ </div>
10
+
11
+ [![Build Status](https://travis-ci.com/aonemd/nin.svg?branch=master)](https://travis-ci.com/aonemd/nin)
7
12
 
8
13
  ## Features
9
14
 
@@ -11,8 +16,8 @@ A simple, full-featured command line todo app
11
16
  - Currently supports: listing, adding, editing, deleting, completing,
12
17
  archiving, and deleting archived todo items
13
18
  - Smart colored output
19
+ - Uses YAML for storage by default (There's an option to use TOML but no configuration for it, yet)
14
20
  - Modular code covered by unit tests
15
- - Uses YAML for storage by default
16
21
 
17
22
  ## Installation
18
23
 
@@ -36,14 +41,17 @@ USAGE:
36
41
  nin COMMAND [arguments...]
37
42
 
38
43
  COMMANDS:
39
- l [a] List all unarchived todos. Pass optional argument `a` to list all todos
40
- a desc Add a todo. Prepend due date by an @. Prepend tag by a \#
41
- e id desc Edit a todo. Prepend due date by an @. Prepend tag by a \#
42
- c id(s) Un/complete todo(s)
43
- ac id(s) Un/archive todo(s)
44
- d id(s) Delete todo(s)
45
- gc Delete all archived todos. Resets item ids as a side effect
46
- o Open todo file in $EDITOR
44
+ l | list [a] List all unarchived todos. Pass optional argument `a` to list all todos
45
+ a | add desc Add a todo. Prepend due date by a @. Prepend each tag by a \#
46
+ e | edit id desc Edit a todo. Prepend due date by a @. Prepend each tag by a \#
47
+ p | prioritize id step Prioritize a todo by either a positive or negative step within its date group
48
+ c | complete id(s) Un/complete todo(s)
49
+ ac | archive id(s) Un/archive todo(s)
50
+ d | delete id(s) Delete todo(s)
51
+ gc | garbage Delete all archived todos. Resets item ids as a side effect
52
+ s | analyze Analyze tasks and print statistics
53
+ i | repl Open nin in REPL mode
54
+ o | open Open todo file in $EDITOR
47
55
  ```
48
56
 
49
57
  ## Why
data/lib/nin.rb CHANGED
@@ -1,16 +1,20 @@
1
1
  require 'psych'
2
- require 'toml-rb'
3
2
  require 'chronic'
4
3
  require 'colored2'
5
4
  require 'date'
5
+ require 'delegate'
6
6
  require 'readline'
7
7
 
8
8
  require_relative 'nin/version'
9
+ require_relative 'nin/extensions/array_extensions'
10
+ require_relative 'nin/extensions/string_extensions'
11
+ require_relative 'nin/extensions/integer_extensions'
12
+ require_relative 'nin/extensions/date_extensions'
9
13
  require_relative 'nin/error'
10
14
  require_relative 'nin/yaml_store'
11
- require_relative 'nin/toml_store'
12
15
  require_relative 'nin/parser'
13
- require_relative 'nin/item_presenter'
14
16
  require_relative 'nin/item'
15
17
  require_relative 'nin/todo'
18
+ require_relative 'nin/presenters/item_presenter'
19
+ require_relative 'nin/presenters/todo_presenter'
16
20
  require_relative 'nin/command'
@@ -12,38 +12,45 @@ module Nin
12
12
 
13
13
  def call
14
14
  case @command
15
- when 'l'
15
+ when 'l', 'list'
16
16
  @todo.list
17
- when 'a'
17
+ when 'a', 'add'
18
18
  desc, date, tags = Parser.new(@args.join(' ')).call
19
19
  @todo.add(desc, date, tags)
20
- when 'e'
20
+ when 'e', 'edit'
21
21
  desc, date, tags = Parser.new(@args[1..-1].join(' ')).call
22
22
  @todo.edit(@args[0].to_i, desc, date, tags)
23
- when 'c'
23
+ when 'p', 'prioritize'
24
+ @todo.prioritize(@args[0].to_i, @args[1].to_i)
25
+ when 'c', 'complete'
24
26
  @todo.complete(*@args)
25
- when 'ac'
27
+ when 'ac', 'archive'
26
28
  @todo.archive(*@args)
27
- when 'd'
29
+ when 'd', 'delete'
28
30
  @todo.delete(*@args)
29
- when 'gc'
31
+ when 'gc', 'garbage'
30
32
  @todo.delete_archived
31
- when 'o'
32
- system("`echo $EDITOR` #{@todo.store.file}")
33
- when 'i'
33
+ when 's', 'analyze'
34
+ @todo.analyze
35
+ when 'i', 'repl'
34
36
  run_interactive_mode
37
+ when 'o', 'open'
38
+ system("`echo $EDITOR` #{@todo.store.file}")
35
39
  else
36
40
  puts "NAME:\n\tnin - a simple, full-featured command line todo app"
37
41
  puts "\nUSAGE:\n\tnin COMMAND [arguments...]"
38
42
  puts "\nCOMMANDS:"
39
- puts "\tl [a] List all unarchived todos. Pass optional argument `a` to list all todos"
40
- puts "\ta desc Add a todo. Prepend due date by a @. Prepend each tag by a \\#"
41
- puts "\te id desc Edit a todo. Prepend due date by a @. Prepend each tag by a \\#"
42
- puts "\tc id(s) Un/complete todo(s)"
43
- puts "\tac id(s) Un/archive todo(s)"
44
- puts "\td id(s) Delete todo(s)"
45
- puts "\tgc Delete all archived todos. Resets item ids as a side effect"
46
- puts "\to Open todo file in $EDITOR"
43
+ puts "\tl | list [a] List all unarchived todos. Pass optional argument `a` to list all todos"
44
+ puts "\ta | add desc Add a todo. Prepend due date by a @. Prepend each tag by a \\#"
45
+ puts "\te | edit id desc Edit a todo. Prepend due date by a @. Prepend each tag by a \\#"
46
+ puts "\tp | prioritize id step Prioritize a todo by either a positive or negative step within its date group"
47
+ puts "\tc | complete id(s) Un/complete todo(s)"
48
+ puts "\tac | archive id(s) Un/archive todo(s)"
49
+ puts "\td | delete id(s) Delete todo(s)"
50
+ puts "\tgc | garbage Delete all archived todos. Resets item ids as a side effect"
51
+ puts "\ts | analyze Analyze tasks and print statistics"
52
+ puts "\ti | repl Open nin in REPL mode"
53
+ puts "\to | open Open todo file in $EDITOR"
47
54
  end
48
55
  end
49
56
 
@@ -0,0 +1,37 @@
1
+ class Array
2
+ def sorted_by?
3
+ each_cons(2).all? { |a, b| ((yield a) <=> (yield b)) <= 0 }
4
+ end
5
+
6
+ def limit(offset)
7
+ offset > 0 ? self.last(offset) : self.first(offset.abs)
8
+ end
9
+
10
+ def round_shift(element, step)
11
+ new_element = [self.min, (element - step), self.max].median
12
+ actual_step = element - new_element
13
+
14
+ [new_element, actual_step]
15
+ end
16
+
17
+ def median
18
+ return nil if self.empty?
19
+
20
+ sorted = self.sort
21
+ len = self.length
22
+
23
+ (sorted[(len - 1) / 2] + sorted[len / 2]) / 2
24
+ end
25
+
26
+ def find_by(key, val)
27
+ self.where(key, val).first
28
+ end
29
+
30
+ def where(key, val = nil, &block)
31
+ self.select do |element|
32
+ key_eval = element.send(key)
33
+
34
+ block_given? ? block.call(key_eval) : (key_eval == val)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,20 @@
1
+ class Date
2
+ def self.parse_or_return(unparsed_date)
3
+ return unparsed_date unless unparsed_date.is_a?(String)
4
+
5
+ Date.parse(unparsed_date)
6
+ end
7
+
8
+ def humanize
9
+ case self
10
+ when Date.today.prev_day
11
+ 'yesterday'
12
+ when Date.today
13
+ 'today'
14
+ when Date.today.succ
15
+ 'tomorrow'
16
+ else
17
+ self.to_s
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ class Integer
2
+ def length
3
+ Math.log10(self).to_i + 1
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class String
2
+ def remove_color
3
+ self.gsub(/\e\[([;\d]+)?m/, '')
4
+ end
5
+ end
@@ -4,23 +4,25 @@ module Nin
4
4
 
5
5
  def initialize(id,
6
6
  desc,
7
- date = nil,
7
+ date = Date.today,
8
8
  tags = [],
9
9
  completed = false,
10
10
  archived = false,
11
- formatter = ItemPresenter)
11
+ formatter = Presenter::ItemPresenter)
12
12
 
13
13
  @id = id
14
14
  @desc = desc
15
- self.date = date # this looks ugly
15
+ @date = Date.parse_or_return(date) || Date.today
16
16
  @tags = tags
17
17
  @completed = completed
18
18
  @archived = archived
19
19
  @formatter = formatter.new(self)
20
20
  end
21
21
 
22
- def date=(date = nil)
23
- @date = date || Date.today.to_s
22
+ def edit(desc, date = nil, tags = [])
23
+ self.desc = desc
24
+ self.date = date unless date.nil?
25
+ self.tags.concat(tags)
24
26
  end
25
27
 
26
28
  def toggle_completed!
@@ -31,6 +33,22 @@ module Nin
31
33
  @archived = !@archived
32
34
  end
33
35
 
36
+ def completed?
37
+ @completed
38
+ end
39
+
40
+ def archived?
41
+ @archived
42
+ end
43
+
44
+ def past?
45
+ @date < Date.today
46
+ end
47
+
48
+ def today?
49
+ @date == Date.today
50
+ end
51
+
34
52
  def to_s
35
53
  @formatter.call
36
54
  end
@@ -41,20 +59,8 @@ module Nin
41
59
  'desc' => desc,
42
60
  'tags' => tags,
43
61
  'completed' => completed,
44
- 'archived' => archived
62
+ 'archived' => archived
45
63
  }
46
64
  end
47
-
48
- def completed?
49
- @completed
50
- end
51
-
52
- def archived?
53
- @archived
54
- end
55
-
56
- def due?
57
- @date < Date.today.to_s
58
- end
59
65
  end
60
66
  end
@@ -0,0 +1,53 @@
1
+ module Nin
2
+ module Presenter
3
+ class ItemPresenter < ::SimpleDelegator
4
+ def call(options = {})
5
+ _id, _completed, _date, _desc, _tags = id, completed, date, desc, tags
6
+
7
+ separating_spaces = options.fetch(:separating_spaces, 2)
8
+ id_spaces = options.fetch(:longest_id, 1) + separating_spaces
9
+ completed_spaces = _completed.length + separating_spaces
10
+ date_spaces = _date.length + (options.fetch(:longest_date, 11) - _date.remove_color.length) + separating_spaces
11
+
12
+ sprintf("%-#{id_spaces}d %-#{completed_spaces}s %-#{date_spaces}s %s %s",
13
+ _id, _completed, _date, _desc, _tags)
14
+ end
15
+
16
+ private
17
+
18
+ def desc
19
+ if self.archived?
20
+ self.desc.yellow
21
+ elsif self.completed?
22
+ self.desc.white
23
+ else
24
+ self.desc
25
+ end
26
+ end
27
+
28
+ def completed
29
+ if self.completed?
30
+ '[x]'.green
31
+ else
32
+ '[ ]'
33
+ end
34
+ end
35
+
36
+ def date
37
+ date_in_words = '@' << self.date.humanize
38
+
39
+ if self.past?
40
+ date_in_words.magenta
41
+ elsif self.today?
42
+ date_in_words.bold.cyan
43
+ else
44
+ date_in_words.cyan
45
+ end
46
+ end
47
+
48
+ def tags
49
+ self.tags.map { |tag| tag.dup.prepend('#') }.join(' ').blue
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,15 @@
1
+ module Nin
2
+ module Presenter
3
+ class TodoPresenter < ::SimpleDelegator
4
+ def call
5
+ formatting_options = { separating_spaces: 4,
6
+ longest_id: self.map(&:id).max.length,
7
+ longest_date: 11 }
8
+
9
+ self.map do |item|
10
+ Presenter::ItemPresenter.new(item).call(formatting_options)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -6,29 +6,47 @@ module Nin
6
6
  def initialize(store = YamlStore.new, options = {})
7
7
  @store = store
8
8
  @options = options
9
- @items = load_items.sort_by(&:date)
9
+ @items = load_items_sorted
10
10
  end
11
11
 
12
12
  def list
13
- if @options[:archived]
14
- @items
15
- else
16
- unarchived_items
17
- end.each do |item|
18
- puts item
19
- end
13
+ items_to_list = if @options[:archived]
14
+ @items
15
+ else
16
+ unarchived_items
17
+ end
18
+
19
+ puts Presenter::TodoPresenter.new(items_to_list).call
20
20
  end
21
21
 
22
22
  def add(desc, date, tags)
23
23
  @items << Item.new(next_id, desc, date, tags)
24
+
24
25
  @store.write(to_hash)
25
26
  end
26
27
 
27
28
  def edit(id, desc, date, tags)
28
- item = find_by_id(id)
29
- item.desc = desc
30
- item.date = date
31
- item.tags = tags
29
+ item = find_by_id(id)
30
+
31
+ item.edit(desc, date, tags)
32
+
33
+ @store.write(to_hash)
34
+ end
35
+
36
+ def prioritize(id, step = 1)
37
+ item_to_prioritize = find_by_id(id)
38
+ item_group = @items.group_by(&:date)[item_to_prioritize.date]
39
+
40
+ new_id, actual_step = item_group.map(&:id).round_shift(id, step)
41
+ step_sign = actual_step > 0 ? +1 : -1
42
+
43
+ items_to_reprioritize = item_group.where(:id) do |item_id|
44
+ step_sign * item_id < step_sign * id
45
+ end.limit(actual_step)
46
+
47
+ item_to_prioritize.id = new_id
48
+ items_to_reprioritize.each { |item| item.id += step_sign }
49
+
32
50
  @store.write(to_hash)
33
51
  end
34
52
 
@@ -52,6 +70,7 @@ module Nin
52
70
 
53
71
  def delete_archived
54
72
  delete(*archived_items.map(&:id))
73
+
55
74
  reset_item_indices!
56
75
  end
57
76
 
@@ -64,8 +83,21 @@ module Nin
64
83
  reset_item_indices!
65
84
  end
66
85
 
86
+ def analyze
87
+ items_to_analyze = @items.where(:completed, true)
88
+
89
+ histogram = items_to_analyze.group_by(&:date).map { |k, v| [k, v.size] }
90
+ histogram.each do |date, size|
91
+ puts "#{date} : #{'*' * size}"
92
+ end
93
+ end
94
+
67
95
  private
68
96
 
97
+ def load_items_sorted
98
+ load_items.sort_by { |item| [item.date, item.id] }
99
+ end
100
+
69
101
  def load_items
70
102
  items = []
71
103
  @store.read.map do |key, values|
@@ -76,21 +108,39 @@ module Nin
76
108
  date,
77
109
  item.fetch('tags'),
78
110
  item.fetch('completed'),
79
- item.fetch('archived')
80
- )
111
+ item.fetch('archived'))
81
112
  end
82
113
  end
83
114
 
84
115
  items
85
116
  end
86
117
 
118
+ def archived_items
119
+ @items.where(:archived?, true)
120
+ end
121
+
122
+ def unarchived_items
123
+ @items.where(:archived?, false)
124
+ end
125
+
126
+ def find_by_id(id)
127
+ found_item = @items.find_by(:id, id)
128
+
129
+ raise ItemNotFoundError unless found_item
130
+
131
+ found_item
132
+ end
133
+
87
134
  def to_hash
88
- @items.group_by(&:date).reduce({}) do |hash, (key, values)|
89
- hash[key] = values.map(&:to_h)
90
- hash
135
+ groupped_items.reduce({}) do |hash, (date, items)|
136
+ hash.update(date => items.map(&:to_h))
91
137
  end
92
138
  end
93
139
 
140
+ def groupped_items
141
+ @items.group_by { |item| item.date.to_s }
142
+ end
143
+
94
144
  def next_id
95
145
  last_id + 1
96
146
  end
@@ -103,22 +153,6 @@ module Nin
103
153
  end
104
154
  end
105
155
 
106
- def find_by_id(id)
107
- found_item = @items.find { |item| item.id == id }
108
-
109
- raise ItemNotFoundError unless found_item
110
-
111
- found_item
112
- end
113
-
114
- def archived_items
115
- @items.select { |item| item.archived? }
116
- end
117
-
118
- def unarchived_items
119
- @items.select { |item| !item.archived? }
120
- end
121
-
122
156
  def reset_item_indices!
123
157
  @items.each.with_index(1) do |item, index|
124
158
  item.id = index
@@ -1,3 +1,3 @@
1
1
  module Nin
2
- VERSION='0.7.0'
2
+ VERSION='1.0.0'
3
3
  end
@@ -18,10 +18,9 @@ Gem::Specification.new do |gem|
18
18
  gem.version = Nin::VERSION
19
19
  gem.license = 'MIT'
20
20
 
21
- gem.add_dependency 'toml-rb'
22
21
  gem.add_dependency 'chronic'
23
22
  gem.add_dependency 'colored2'
24
23
 
25
- gem.add_development_dependency 'byebug'
24
+ gem.add_development_dependency 'rake'
26
25
  gem.add_development_dependency 'minitest'
27
26
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ahmed Saleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-24 00:00:00.000000000 Z
11
+ date: 2019-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: toml-rb
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: chronic
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -53,7 +39,7 @@ dependencies:
53
39
  - !ruby/object:Gem::Version
54
40
  version: '0'
55
41
  - !ruby/object:Gem::Dependency
56
- name: byebug
42
+ name: rake
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
45
  - - ">="
@@ -88,8 +74,8 @@ extensions: []
88
74
  extra_rdoc_files: []
89
75
  files:
90
76
  - ".gitignore"
77
+ - ".travis.yml"
91
78
  - Gemfile
92
- - Gemfile.lock
93
79
  - LICENSE
94
80
  - README.md
95
81
  - Rakefile
@@ -98,11 +84,15 @@ files:
98
84
  - lib/nin.rb
99
85
  - lib/nin/command.rb
100
86
  - lib/nin/error.rb
87
+ - lib/nin/extensions/array_extensions.rb
88
+ - lib/nin/extensions/date_extensions.rb
89
+ - lib/nin/extensions/integer_extensions.rb
90
+ - lib/nin/extensions/string_extensions.rb
101
91
  - lib/nin/item.rb
102
- - lib/nin/item_presenter.rb
103
92
  - lib/nin/parser.rb
93
+ - lib/nin/presenters/item_presenter.rb
94
+ - lib/nin/presenters/todo_presenter.rb
104
95
  - lib/nin/todo.rb
105
- - lib/nin/toml_store.rb
106
96
  - lib/nin/version.rb
107
97
  - lib/nin/yaml_store.rb
108
98
  - nin.gemspec
@@ -125,8 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
115
  - !ruby/object:Gem::Version
126
116
  version: '0'
127
117
  requirements: []
128
- rubyforge_project:
129
- rubygems_version: 2.7.6
118
+ rubygems_version: 3.0.3
130
119
  signing_key:
131
120
  specification_version: 4
132
121
  summary: A command line todo app that provides an easy to use CLI for everyday todo
@@ -1,29 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- nin (0.6.0)
5
- chronic
6
- colored2
7
- toml-rb
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- byebug (10.0.2)
13
- chronic (0.10.2)
14
- citrus (3.0.2)
15
- colored2 (3.1.2)
16
- minitest (5.11.3)
17
- toml-rb (1.1.2)
18
- citrus (~> 3.0, > 3.0)
19
-
20
- PLATFORMS
21
- ruby
22
-
23
- DEPENDENCIES
24
- byebug
25
- minitest
26
- nin!
27
-
28
- BUNDLED WITH
29
- 1.17.1
@@ -1,49 +0,0 @@
1
- module Nin
2
- class ItemPresenter < SimpleDelegator
3
- def call
4
- sprintf("%d\t%s\t%s \t%s %s",
5
- id, completed, date, desc, tags).gsub(' ', ' ')
6
- end
7
-
8
- private
9
-
10
- def desc
11
- if self.archived?
12
- self.desc.yellow
13
- elsif self.completed?
14
- self.desc.white
15
- else
16
- self.desc
17
- end
18
- end
19
-
20
- def completed
21
- if self.completed?
22
- '[x]'.green
23
- else
24
- '[ ]'
25
- end
26
- end
27
-
28
- def date
29
- case self.date
30
- when Date.today.to_s
31
- '@today'.bold
32
- when Date.today.succ.to_s
33
- '@tomorrow'
34
- when Date.today.prev_day.to_s
35
- '@yesterday'.magenta
36
- else
37
- if self.due?
38
- ('@' << self.date).magenta
39
- else
40
- '@' << self.date
41
- end
42
- end.cyan
43
- end
44
-
45
- def tags
46
- self.tags.map { |tag| tag.dup.prepend('#') }.join(' ').blue
47
- end
48
- end
49
- end
@@ -1,31 +0,0 @@
1
- module Nin
2
- class TomlStore
3
- DEFAULT_FILE = "#{ENV['HOME']}/.todos.toml"
4
-
5
- attr_reader :file
6
-
7
- def initialize(file = DEFAULT_FILE)
8
- @file = file
9
-
10
- init_store
11
- end
12
-
13
- def read
14
- TomlRB.load_file(@file)
15
- end
16
-
17
- def write(hash)
18
- File.open(@file, 'w') do |file|
19
- file.write(TomlRB.dump(hash))
20
- end
21
- end
22
-
23
- private
24
-
25
- def init_store
26
- return if File.exist?(@file)
27
-
28
- File.open(@file, "w")
29
- end
30
- end
31
- end