nin 0.7.0 → 1.0.0

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 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