todotxt 0.0.3 → 0.1.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 +15 -0
- data/.gitignore +2 -0
- data/README.md +1 -0
- data/bin/todotxt +3 -3
- data/conf/todotxt.cfg +13 -1
- data/cucumber.yml +3 -0
- data/features/add.feature +24 -0
- data/features/append.feature +28 -0
- data/features/backwards.feature +28 -0
- data/features/colors.feature +51 -0
- data/features/del.feature +52 -0
- data/features/depri.feature +38 -0
- data/features/do.feature +47 -0
- data/features/due.feature +49 -0
- data/features/edit.feature +31 -0
- data/features/generate_config.feature +19 -0
- data/features/generate_txt.feature +20 -0
- data/features/initialize.feature +73 -0
- data/features/list.feature +132 -0
- data/features/move.feature +33 -0
- data/features/prepend.feature +28 -0
- data/features/pri.feature +40 -0
- data/features/replace.feature +28 -0
- data/features/step_definitions/environment_steps.rb +47 -0
- data/features/step_definitions/list_steps.rb +34 -0
- data/features/support/ansi.rb +5 -0
- data/features/support/aruba.rb +9 -0
- data/features/support/debugger.rb +1 -0
- data/features/undo.feature +54 -0
- data/lib/todotxt/cli.rb +131 -45
- data/lib/todotxt/clihelpers.rb +4 -1
- data/lib/todotxt/config.rb +58 -0
- data/lib/todotxt/regex.rb +1 -0
- data/lib/todotxt/todo.rb +5 -0
- data/lib/todotxt/todofile.rb +40 -0
- data/lib/todotxt/todolist.rb +20 -2
- data/lib/todotxt/version.rb +1 -1
- data/lib/todotxt.rb +2 -0
- data/spec/cli_spec.rb +6 -0
- data/spec/config_spec.rb +52 -0
- data/spec/fixtures/config_both.cfg +4 -0
- data/spec/fixtures/config_new.cfg +2 -0
- data/spec/fixtures/config_old.cfg +1 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/todo_spec.rb +12 -0
- data/spec/todofile_spec.rb +31 -0
- data/spec/todolist_spec.rb +20 -2
- data/todotxt.gemspec +4 -0
- metadata +154 -28
@@ -0,0 +1,33 @@
|
|
1
|
+
Feature: move
|
2
|
+
|
3
|
+
So that I can keep items organised
|
4
|
+
As a user
|
5
|
+
I want to move items between files
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given a config exists with the following files:
|
9
|
+
| alias | path |
|
10
|
+
| todo | todo.txt |
|
11
|
+
| wishlist | wishlist.txt |
|
12
|
+
And a todofile with the following items exists:
|
13
|
+
| todo |
|
14
|
+
| Getting Things Done @bookstore |
|
15
|
+
| Label Maker @officesupply |
|
16
|
+
And an empty todofile named "wishlist.txt" exists
|
17
|
+
|
18
|
+
Scenario: Move item from todo.txt to wishlist.txt
|
19
|
+
When I run `todotxt move 1 wishlist`
|
20
|
+
Then it should pass with:
|
21
|
+
"""
|
22
|
+
1. Getting Things Done @bookstore
|
23
|
+
=> Moved to wishlist.txt
|
24
|
+
"""
|
25
|
+
And the file "todo.txt" should not contain "Getting Things Done @bookstore"
|
26
|
+
And the file "wishlist.txt" should contain "Getting Things Done @bookstore"
|
27
|
+
|
28
|
+
Scenario: Move an illegal item
|
29
|
+
When I run `todotxt move 1337 wishlist`
|
30
|
+
Then it should pass with:
|
31
|
+
"""
|
32
|
+
ERROR: No todo found at line 1337
|
33
|
+
"""
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Feature: Prepend
|
2
|
+
|
3
|
+
So that I can change items
|
4
|
+
As a user
|
5
|
+
I want to prepend text to an item
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given a default config exists
|
9
|
+
And a todofile with the following items exists:
|
10
|
+
| todo |
|
11
|
+
| (B) Install todotxt @cli +todotxt |
|
12
|
+
| Drink coffee |
|
13
|
+
|
14
|
+
Scenario: Add text to an item
|
15
|
+
When I run `todotxt prepend 2 Brew and`
|
16
|
+
Then it should pass with:
|
17
|
+
"""
|
18
|
+
2. Brew and Drink coffee
|
19
|
+
"""
|
20
|
+
And the file "todo.txt" should contain "Brew and Drink coffee"
|
21
|
+
|
22
|
+
|
23
|
+
Scenario: Add text to an illegal item:
|
24
|
+
When I run `todotxt prepend 1337 @sofa`
|
25
|
+
Then it should pass with:
|
26
|
+
"""
|
27
|
+
ERROR: No todo found at line 1337
|
28
|
+
"""
|
@@ -0,0 +1,40 @@
|
|
1
|
+
Feature: Prioritise
|
2
|
+
|
3
|
+
So that I can make items more important
|
4
|
+
As a user
|
5
|
+
I want to prioritise items
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given a default config exists
|
9
|
+
And a todofile with the following items exists:
|
10
|
+
| todo |
|
11
|
+
| (B) Install todotxt @cli +todotxt |
|
12
|
+
| Drink coffee |
|
13
|
+
|
14
|
+
Scenario: Set priority of an item should report it and change it in the file
|
15
|
+
When I run `todotxt pri 2 A`
|
16
|
+
Then it should pass with:
|
17
|
+
"""
|
18
|
+
2. (A) Drink coffee
|
19
|
+
"""
|
20
|
+
And the file "todo.txt" should contain "(A) Drink coffee"
|
21
|
+
|
22
|
+
Scenario: Set the priority of an already prioritised item
|
23
|
+
When I run `todotxt pri 1 A`
|
24
|
+
Then the file "todo.txt" should contain "(A) Install todotxt @cli +todotxt"
|
25
|
+
|
26
|
+
#todo: make it throw an error instead.
|
27
|
+
Scenario: Attempt to set priority to an illegal priority
|
28
|
+
When I run `todotxt pri 2 Foo`
|
29
|
+
Then it should pass with:
|
30
|
+
"""
|
31
|
+
2. Drink coffee
|
32
|
+
"""
|
33
|
+
And the file "todo.txt" should not contain "(Foo) Drink coffee"
|
34
|
+
|
35
|
+
Scenario: Attempt to set the priority of an illegal line
|
36
|
+
When I run `todotxt pri 1337 A`
|
37
|
+
Then it should pass with:
|
38
|
+
"""
|
39
|
+
ERROR: No todo found at line 1337
|
40
|
+
"""
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Feature: Replace
|
2
|
+
|
3
|
+
So that I can change items
|
4
|
+
As a user
|
5
|
+
I want to completely replace an item with new text
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given a default config exists
|
9
|
+
And a todofile with the following items exists:
|
10
|
+
| todo |
|
11
|
+
| (B) Install todotxt @cli +todotxt |
|
12
|
+
| Drink coffee |
|
13
|
+
|
14
|
+
Scenario: Add text to an item
|
15
|
+
When I run `todotxt replace 2 sip frappucino @buckstar`
|
16
|
+
Then it should pass with:
|
17
|
+
"""
|
18
|
+
2. sip frappucino @buckstar
|
19
|
+
"""
|
20
|
+
And the file "todo.txt" should contain "sip frappucino @buckstar"
|
21
|
+
And the file "todo.txt" should not contain "Drink coffee"
|
22
|
+
|
23
|
+
Scenario: Add text to an illegal item:
|
24
|
+
When I run `todotxt prepend 1337 @sofa`
|
25
|
+
Then it should pass with:
|
26
|
+
"""
|
27
|
+
ERROR: No todo found at line 1337
|
28
|
+
"""
|
@@ -0,0 +1,47 @@
|
|
1
|
+
Given /^a default config exists$/ do
|
2
|
+
write_file(".todotxt.cfg", "[files]\ntodo = todo.txt")
|
3
|
+
end
|
4
|
+
|
5
|
+
Given /^an old config exists$/ do
|
6
|
+
write_file(".todotxt.cfg", "todo_txt_path = todo.txt")
|
7
|
+
end
|
8
|
+
|
9
|
+
Given /^an empty environment$/ do
|
10
|
+
step %{a file named ".todotxt.cfg" should not exist}
|
11
|
+
step %{a file named "todo.txt" should not exist}
|
12
|
+
end
|
13
|
+
|
14
|
+
Given /^a config exists with the following files:$/ do |files|
|
15
|
+
files_directive = "[files]\n"
|
16
|
+
files_directive += files.hashes.map {|file| "#{file["alias"]}=#{file["path"]}" }.join("\n")
|
17
|
+
write_file(".todotxt.cfg", files_directive)
|
18
|
+
end
|
19
|
+
|
20
|
+
Given /^a default config exists with the editor set to "(.*?)"$/ do |editor|
|
21
|
+
write_file(".todotxt.cfg", "editor=#{editor}\n[files]\ntodo = todo.txt")
|
22
|
+
end
|
23
|
+
|
24
|
+
Given /^a todofile exists$/ do
|
25
|
+
write_file("todo.txt", "Read documentation for todotxt\nWrite cucumber steps for todotxt")
|
26
|
+
end
|
27
|
+
|
28
|
+
Given /^a todofile with done items exists$/ do
|
29
|
+
write_file("todo.txt", "Read documentation for todotxt\nx Install todotxt\nWrite cucumber steps for todotxt")
|
30
|
+
end
|
31
|
+
|
32
|
+
Given /^a todofile with the following items exists:$/ do |todolist|
|
33
|
+
contents = todolist.hashes.map {|row| row["todo"] }.join("\n")
|
34
|
+
write_file("todo.txt", contents)
|
35
|
+
end
|
36
|
+
|
37
|
+
Given /^an empty todofile named "(.*?)" exists$/ do |filename|
|
38
|
+
write_file(filename, "")
|
39
|
+
end
|
40
|
+
|
41
|
+
Given /^the enviromnent variable "(.*?)" is set to "(.*?)"$/ do |name, value|
|
42
|
+
ENV[name] = value
|
43
|
+
end
|
44
|
+
|
45
|
+
Given /^the date is "(.*?)"$/ do |date|
|
46
|
+
step %{the enviromnent variable "date" is set to "#{date}"}
|
47
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
Then /^I should see all entries from the todofile with numbers$/ do
|
2
|
+
contents = ""
|
3
|
+
File.open(File.join(ENV["HOME"], "todo.txt")).each_line do |line|
|
4
|
+
# matching "1. Do Something"
|
5
|
+
contents += "([\\d]\.\\s+)#{Regexp.escape(line.strip)}.*"
|
6
|
+
end
|
7
|
+
step "it should pass with regex:", contents
|
8
|
+
end
|
9
|
+
|
10
|
+
Then /^I should see all entries from the todofile without formatting$/ do
|
11
|
+
contents = ""
|
12
|
+
File.open(File.join(ENV["HOME"], "todo.txt")).each_line do |line|
|
13
|
+
# matching "1 Do something", note the missing dot .
|
14
|
+
contents += "([\\d]\\s+)#{Regexp.escape(line.strip)}.*"
|
15
|
+
end
|
16
|
+
step "it should pass with regex:", contents
|
17
|
+
step "the output should not match /TODO: [\d]+ items/"
|
18
|
+
end
|
19
|
+
|
20
|
+
Then /^it should count (\d+) TODO\-items$/ do |count|
|
21
|
+
step %{the output should match /^TODO: #{count} items$/}
|
22
|
+
end
|
23
|
+
|
24
|
+
Then /^it should output "([^"]*)" brightly in "([^"]*)"$/ do |string, color|
|
25
|
+
assert_partial_output(string.color(color.to_sym).bright, all_output)
|
26
|
+
end
|
27
|
+
Then /^it should output "([^"]*)" in "([^"]*)"$/ do |string, color|
|
28
|
+
assert_partial_output(string.color(color.to_sym), all_output)
|
29
|
+
end
|
30
|
+
|
31
|
+
Then /^it should pass with todays date$/ do
|
32
|
+
today = DateTime.now.strftime("%Y-%m-%d")
|
33
|
+
step "it should pass with regex:", ".*#{today}.*"
|
34
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'aruba/cucumber'
|
2
|
+
|
3
|
+
# Temporarily enforce an isolated, fake, homedir.
|
4
|
+
Around do |scenario, block|
|
5
|
+
@__aruba_original_home = ENV["HOME"]
|
6
|
+
ENV["HOME"] = File.expand_path(File.join("tmp", "aruba"))
|
7
|
+
block.call
|
8
|
+
ENV["HOME"] = @__aruba_original_home
|
9
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require "debugger"
|
@@ -0,0 +1,54 @@
|
|
1
|
+
Feature: Undo
|
2
|
+
|
3
|
+
So that I can fix mistakes
|
4
|
+
As a user
|
5
|
+
I want to mark items as not done
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given a default config exists
|
9
|
+
Given a todofile with the following items exists:
|
10
|
+
| todo |
|
11
|
+
| x 2013-01-01 Install todotxt @cli +todotxt |
|
12
|
+
| x Read documentation +todotxt |
|
13
|
+
| 2012-12-12 Buy GTD book @amazon +wishlist |
|
14
|
+
|
15
|
+
Scenario: Undo a single item reports it back and marks it as not done in the file
|
16
|
+
When I run `todotxt undo 2`
|
17
|
+
Then it should pass with:
|
18
|
+
"""
|
19
|
+
2. Read documentation +todotxt
|
20
|
+
"""
|
21
|
+
And the file "todo.txt" should contain exactly:
|
22
|
+
"""
|
23
|
+
x 2013-01-01 Install todotxt @cli +todotxt
|
24
|
+
Read documentation +todotxt
|
25
|
+
2012-12-12 Buy GTD book @amazon +wishlist
|
26
|
+
"""
|
27
|
+
|
28
|
+
Scenario: Undo multiple items
|
29
|
+
When I run `todotxt undo 1 2`
|
30
|
+
Then it should pass with:
|
31
|
+
"""
|
32
|
+
1. 2013-01-01 Install todotxt @cli +todotxt
|
33
|
+
2. Read documentation +todotxt
|
34
|
+
"""
|
35
|
+
And the file "todo.txt" should contain exactly:
|
36
|
+
"""
|
37
|
+
2013-01-01 Install todotxt @cli +todotxt
|
38
|
+
Read documentation +todotxt
|
39
|
+
2012-12-12 Buy GTD book @amazon +wishlist
|
40
|
+
"""
|
41
|
+
|
42
|
+
Scenario: Undo an item that was not marked as done
|
43
|
+
When I run `todotxt undo 3`
|
44
|
+
Then it should pass with:
|
45
|
+
"""
|
46
|
+
3. 2012-12-12 Buy GTD book @amazon +wishlist
|
47
|
+
"""
|
48
|
+
|
49
|
+
Scenario: Undo invalid items
|
50
|
+
When I run `todotxt undo 1337`
|
51
|
+
Then it should pass with:
|
52
|
+
"""
|
53
|
+
ERROR: No todo found at line 1337
|
54
|
+
"""
|
data/lib/todotxt/cli.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
require "thor"
|
2
2
|
require "rainbow"
|
3
|
+
require "chronic"
|
3
4
|
require "parseconfig"
|
4
5
|
|
5
6
|
module Todotxt
|
6
|
-
CFG_PATH = File.expand_path("~/.todotxt.cfg")
|
7
|
-
|
8
7
|
class CLI < Thor
|
9
8
|
include Thor::Actions
|
10
9
|
include Todotxt::CLIHelpers
|
@@ -15,14 +14,31 @@ module Todotxt
|
|
15
14
|
|
16
15
|
def initialize(*args)
|
17
16
|
super
|
17
|
+
# Allow testing colors, rainbow usually detects whether
|
18
|
+
# the output goes to a TTY, but Aruba/Cucumber is not a
|
19
|
+
# TTY, so we enforce it here, based on an environment var
|
20
|
+
Sickill::Rainbow.enabled = true if ENV["FORCE_COLORS"] == "TRUE"
|
21
|
+
@config = Config.new
|
22
|
+
@list = nil
|
23
|
+
unless ["help", "generate_config", "generate_txt"].include? ARGV[0]
|
24
|
+
ask_and_create @config unless @config.file_exists?
|
25
|
+
if @config.deprecated? and options[:file]
|
26
|
+
error_and_exit "You are using an old config, which has no support for mulitple files. Please update your configuration."
|
27
|
+
end
|
18
28
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
@list = TodoList.new @txt_path
|
29
|
+
parse_conf
|
30
|
+
ask_and_create @file unless @file.exists?
|
31
|
+
@list = TodoList.new @file
|
23
32
|
end
|
33
|
+
|
24
34
|
end
|
25
35
|
|
36
|
+
class_option :file, :type => :string, :desc => "Use a different file than todo.txt
|
37
|
+
E.g. use 'done' to have the action performed on the file you set for 'done' in the todotxt
|
38
|
+
configuration under [files]."
|
39
|
+
|
40
|
+
default_task :list
|
41
|
+
|
26
42
|
#
|
27
43
|
# Listing
|
28
44
|
#
|
@@ -31,12 +47,7 @@ module Todotxt
|
|
31
47
|
method_option :done, :type => :boolean, :aliases => "-d", :desc => "Include todo items that have been marked as done"
|
32
48
|
method_option :simple, :type => :boolean, :desc => "Simple output (for scripts, etc)"
|
33
49
|
def list search=""
|
34
|
-
with_done
|
35
|
-
|
36
|
-
with_done = true if options[:done]
|
37
|
-
|
38
|
-
@list.filter(search, :with_done => with_done)
|
39
|
-
|
50
|
+
@list.filter(search, :with_done => (options[:done] ? true : false))
|
40
51
|
render_list :simple => !!options[:simple]
|
41
52
|
end
|
42
53
|
map "ls" => :list
|
@@ -61,6 +72,24 @@ module Todotxt
|
|
61
72
|
end
|
62
73
|
map "lsc" => :lscon
|
63
74
|
|
75
|
+
desc "due", "List due items"
|
76
|
+
def due
|
77
|
+
if ENV["date"] # Allow testing to "freeze" the date
|
78
|
+
today = DateTime.parse(ENV["date"]).to_date
|
79
|
+
else
|
80
|
+
today = DateTime.now.to_date
|
81
|
+
end
|
82
|
+
|
83
|
+
puts "Due today (#{today.strftime("%Y-%m-%d")})".bright
|
84
|
+
@list.on_date(today).each { |todo| puts format_todo(todo) }
|
85
|
+
puts "\nPast-due items".bright
|
86
|
+
@list.before_date(today).each { |todo| puts format_todo(todo) }
|
87
|
+
puts "\nDue 7 days in advance".bright
|
88
|
+
((today+1)..(today+7)).each do |day|
|
89
|
+
@list.on_date(day).each { |todo| puts format_todo(todo) }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
64
93
|
#
|
65
94
|
# Todo management
|
66
95
|
#
|
@@ -201,21 +230,72 @@ module Todotxt
|
|
201
230
|
end
|
202
231
|
map "rm" => :del
|
203
232
|
|
233
|
+
desc "edit", "Open todo.txt file in your default editor"
|
234
|
+
def edit
|
235
|
+
system "#{@editor} #{@file.path}"
|
236
|
+
end
|
237
|
+
|
238
|
+
desc "move | mv ITEM#[, ITEM#, ITEM#, ...] file", "Move ITEM# to another file"
|
239
|
+
def move line1, *lines, other_list_alias
|
240
|
+
if @files[other_list_alias.to_sym].nil?
|
241
|
+
error_and_exit "File alias #{other_list_alias} not found"
|
242
|
+
else
|
243
|
+
other_list = TodoList.new @files[other_list_alias.to_sym]
|
244
|
+
end
|
245
|
+
|
246
|
+
lines.unshift(line1).each do |line|
|
247
|
+
todo = @list.find_by_line line
|
248
|
+
if todo
|
249
|
+
say format_todo(todo)
|
250
|
+
@list.move line, other_list
|
251
|
+
notice "Moved to #{other_list}"
|
252
|
+
|
253
|
+
other_list.save
|
254
|
+
@list.save
|
255
|
+
else
|
256
|
+
error "No todo found at line #{line}"
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
map "mv" => :move
|
261
|
+
|
262
|
+
desc "move | mv ITEM#[, ITEM#, ITEM#, ...] file", "Move ITEM# to another file"
|
263
|
+
def move line1, *lines, other_list_alias
|
264
|
+
if @files[other_list_alias.to_sym].nil?
|
265
|
+
error_and_exit "File alias #{other_list_alias} not found"
|
266
|
+
else
|
267
|
+
other_list = TodoList.new @files[other_list_alias.to_sym]
|
268
|
+
end
|
269
|
+
|
270
|
+
lines.unshift(line1).each do |line|
|
271
|
+
todo = @list.find_by_line line
|
272
|
+
if todo
|
273
|
+
say format_todo(todo)
|
274
|
+
@list.move line, other_list
|
275
|
+
notice "Moved to #{other_list}"
|
276
|
+
|
277
|
+
other_list.save
|
278
|
+
@list.save
|
279
|
+
else
|
280
|
+
error "No todo found at line #{line}"
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
map "mv" => :move
|
285
|
+
|
204
286
|
#
|
205
287
|
# File generation
|
206
288
|
#
|
207
289
|
|
208
290
|
desc "generate_config", "Create a .todotxt.cfg file in your home folder, containing the path to todo.txt"
|
209
291
|
def generate_config
|
210
|
-
copy_file "todotxt.cfg",
|
292
|
+
copy_file "todotxt.cfg", Config.config_path
|
211
293
|
puts ""
|
212
|
-
|
213
|
-
parse_config
|
214
294
|
end
|
215
295
|
|
216
296
|
desc "generate_txt", "Create a sample todo.txt"
|
217
297
|
def generate_txt
|
218
|
-
copy_file "todo.txt", @
|
298
|
+
copy_file "todo.txt", @file
|
219
299
|
puts ""
|
220
300
|
end
|
221
301
|
|
@@ -229,7 +309,6 @@ module Todotxt
|
|
229
309
|
end
|
230
310
|
|
231
311
|
private
|
232
|
-
|
233
312
|
def render_list opts={}
|
234
313
|
numsize = @list.count + 1
|
235
314
|
numsize = numsize.to_s.length + 0
|
@@ -247,43 +326,50 @@ module Todotxt
|
|
247
326
|
end
|
248
327
|
end
|
249
328
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
329
|
+
# File should respond_to "basename", "path" and "generate!"
|
330
|
+
def ask_and_create file
|
331
|
+
puts "#{file.basename} doesn't exist yet. Would you like to generate a sample file?"
|
332
|
+
confirm_generate = yes? "Create #{file.path}? [y/N]"
|
254
333
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
end
|
334
|
+
if confirm_generate
|
335
|
+
file.generate!
|
336
|
+
else
|
337
|
+
puts ""
|
338
|
+
exit
|
261
339
|
end
|
340
|
+
end
|
262
341
|
|
263
|
-
|
264
|
-
|
265
|
-
txt = cfg["todo_txt_path"]
|
266
|
-
|
267
|
-
if txt
|
268
|
-
@txt_path = File.expand_path(txt)
|
342
|
+
def parse_conf
|
343
|
+
@files = {}
|
269
344
|
|
270
|
-
|
271
|
-
puts "#{txt} doesn't exist yet. Would you like to generate a sample file?"
|
272
|
-
confirm_generate = yes? "Create #{txt}? [y/N]"
|
345
|
+
return if @config.nil?
|
273
346
|
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
347
|
+
# Backwards compatibility with todo_txt_path
|
348
|
+
# when old variable is still set, and no files=>todo
|
349
|
+
# given, fallback to this old version.
|
350
|
+
if @config["todo_txt_path"]
|
351
|
+
@files[:todo] ||= TodoFile.new(@config["todo_txt_path"])
|
352
|
+
else
|
353
|
+
# Fill the @files from settings.
|
354
|
+
@config["files"].each do |name, file_path|
|
355
|
+
unless file_path.empty?
|
356
|
+
@files[name.to_sym] = TodoFile.new(file_path)
|
279
357
|
end
|
280
358
|
end
|
359
|
+
end
|
360
|
+
|
361
|
+
# Determine what file should be activated, set that in @file
|
362
|
+
if options[:file]
|
363
|
+
file_sym = options[:file].to_sym
|
364
|
+
if @files.has_key? file_sym
|
365
|
+
@file = @files[file_sym]
|
366
|
+
end
|
281
367
|
else
|
282
|
-
|
283
|
-
puts "Please run the following to create a new configuration file:"
|
284
|
-
puts " todotxt generate_config"
|
285
|
-
exit
|
368
|
+
@file = @files[:todo]
|
286
369
|
end
|
370
|
+
|
371
|
+
# Determine the editor
|
372
|
+
@editor = @config["editor"] || ENV["EDITOR"]
|
287
373
|
end
|
288
374
|
end
|
289
375
|
end
|
data/lib/todotxt/clihelpers.rb
CHANGED
@@ -3,7 +3,6 @@ module Todotxt
|
|
3
3
|
|
4
4
|
def format_todo(todo, number_padding=nil)
|
5
5
|
line = todo.line.to_s
|
6
|
-
|
7
6
|
if number_padding
|
8
7
|
line = line.rjust number_padding
|
9
8
|
end
|
@@ -50,5 +49,9 @@ module Todotxt
|
|
50
49
|
puts "ERROR: #{message}".color(:red)
|
51
50
|
end
|
52
51
|
|
52
|
+
def error_and_exit message =""
|
53
|
+
error message
|
54
|
+
exit
|
55
|
+
end
|
53
56
|
end
|
54
57
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "parseconfig"
|
2
|
+
require "fileutils"
|
3
|
+
|
4
|
+
module Todotxt
|
5
|
+
class Config < ParseConfig
|
6
|
+
def initialize config_file = ""
|
7
|
+
if config_file.empty?
|
8
|
+
@config_file = Config.config_path
|
9
|
+
else
|
10
|
+
@config_file = config_file
|
11
|
+
end
|
12
|
+
|
13
|
+
if file_exists?
|
14
|
+
super @config_file
|
15
|
+
validate
|
16
|
+
else
|
17
|
+
@params = {}
|
18
|
+
@groups = []
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def file_exists?
|
23
|
+
File.exists? @config_file
|
24
|
+
end
|
25
|
+
|
26
|
+
def files
|
27
|
+
params["files"] || {"todo" => params["todo_txt_path"] }
|
28
|
+
end
|
29
|
+
|
30
|
+
def generate!
|
31
|
+
FileUtils.copy File.join(File.dirname(File.expand_path(__FILE__)), "..", "..", "conf", "todotxt.cfg"), @config_file
|
32
|
+
import_config
|
33
|
+
end
|
34
|
+
|
35
|
+
def path
|
36
|
+
@config_file
|
37
|
+
end
|
38
|
+
|
39
|
+
def basename
|
40
|
+
File.basename @config_file
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.config_path
|
44
|
+
File.join ENV["HOME"], ".todotxt.cfg"
|
45
|
+
end
|
46
|
+
|
47
|
+
def deprecated?
|
48
|
+
params["files"].nil?
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def validate
|
53
|
+
if params["files"] && params["todo_txt_path"]
|
54
|
+
raise "Bad configuration file: use either files or todo_txt_path"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/todotxt/regex.rb
CHANGED
data/lib/todotxt/todo.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Todotxt
|
2
|
+
class TodoFile
|
3
|
+
|
4
|
+
def initialize path
|
5
|
+
@path = File.expand_path(path)
|
6
|
+
end
|
7
|
+
|
8
|
+
# Generate a file from template
|
9
|
+
def generate!
|
10
|
+
FileUtils.copy File.join(File.dirname(File.expand_path(__FILE__)), "..", "..", "conf", "todo.txt"), @path
|
11
|
+
end
|
12
|
+
|
13
|
+
def path
|
14
|
+
@path
|
15
|
+
end
|
16
|
+
|
17
|
+
def basename
|
18
|
+
File.basename @path
|
19
|
+
end
|
20
|
+
|
21
|
+
def exists?
|
22
|
+
File.exists? File.expand_path(@path)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.from_key(key)
|
26
|
+
config = Todotxt::Config.new
|
27
|
+
if config.files.has_key? key
|
28
|
+
path = config.files[key]
|
29
|
+
self.new path
|
30
|
+
else
|
31
|
+
raise "Key not found in config"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
@path
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|