forget_me_not 0.0.1
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 +7 -0
- data/.gitignore +8 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +104 -0
- data/Rakefile +1 -0
- data/bin/fmn +135 -0
- data/forget-me-not.rb +30 -0
- data/forget_me_not.gemspec +21 -0
- data/lib/fmn/version.rb +3 -0
- data/lib/fmn.rb +4 -0
- metadata +86 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 22544794f3ea49b825752e6184c69b7a6a85b4ec
|
4
|
+
data.tar.gz: 18d2750b71f7fb0e1a92389f15cf7523af80c250
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fb2441285e7174723d3a0ef954c070fb46b01435a4a3fc82b6264a16e97b92f63e30a38ec790a95b1a61c76fc8248752944af91793f2e769a34c721377e004ee
|
7
|
+
data.tar.gz: 8dab65f8e483df38006f9134d145e5a14bde217703a6c775336ee8d50d16f08c48179305d10e06ace53d6402bd3c2f0945ef707d0c574c44b4b9ef5323549fd7
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
forget_me_not (0.0.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
commander (4.3.4)
|
10
|
+
highline (~> 1.7.2)
|
11
|
+
highline (1.7.3)
|
12
|
+
rake (10.4.2)
|
13
|
+
|
14
|
+
PLATFORMS
|
15
|
+
ruby
|
16
|
+
|
17
|
+
DEPENDENCIES
|
18
|
+
bundler (~> 1.9)
|
19
|
+
commander (~> 4.3.4)
|
20
|
+
forget_me_not!
|
21
|
+
rake (~> 10.0)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Giovanni Lodi
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# Forget-Me-Not 🌸
|
2
|
+
|
3
|
+
A smart, contextualised todo list. Designed to live in your terminal, and to be in your face.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
```
|
8
|
+
$ fmn list
|
9
|
+
(1) - Buy tomato sauce and basil for pasta
|
10
|
+
(2) - Tweet about how cool fmn is
|
11
|
+
(3) - Follow @mokagio
|
12
|
+
|
13
|
+
$ fmn add Another thing to remember
|
14
|
+
|
15
|
+
$ fmn list
|
16
|
+
(1) - Buy tomato sauce and basil for pasta
|
17
|
+
(2) - Tweet about how cool fmn is
|
18
|
+
(3) - Follow @mokagio
|
19
|
+
(4) - Another thing to remember
|
20
|
+
|
21
|
+
$ fmn done 4
|
22
|
+
|
23
|
+
$ fmn list
|
24
|
+
(1) - Buy tomato sauce and basil for pasta
|
25
|
+
(2) - Tweet about how cool fmn is
|
26
|
+
(3) - Follow @mokagio
|
27
|
+
```
|
28
|
+
|
29
|
+
That's all right isn't it? But there's more. Forget-Me-Not is *contextual*:
|
30
|
+
|
31
|
+
```
|
32
|
+
$ fmn list
|
33
|
+
(1) - Buy tomato sauce and basil for pasta
|
34
|
+
(2) - Tweet about how cool fmn is
|
35
|
+
(3) - Follow @mokagio
|
36
|
+
|
37
|
+
$ cd my-project-folder
|
38
|
+
$ fmn list
|
39
|
+
(1) - Buy tomato sauce and basil for pasta
|
40
|
+
(2) - Tweet about how cool fmn is
|
41
|
+
(3) - Follow @mokagio
|
42
|
+
(4) - Update README with new features
|
43
|
+
(5) - Look into bug report 42
|
44
|
+
```
|
45
|
+
|
46
|
+
`fmn` tasks list is build by inspecting the current folder and all its ancestors. This means that if you add tasks while into a project folder, you'll won't see them when doing `fmn list` on its paraent.
|
47
|
+
|
48
|
+
And one more thing. Forget-Me-Not has a *global* list, too. The tasks added to the global list will always be listed.
|
49
|
+
|
50
|
+
```
|
51
|
+
$ fmn add -g A global task
|
52
|
+
```
|
53
|
+
|
54
|
+
This is ideal if you want to share tasks across machines.
|
55
|
+
|
56
|
+
_TODO: show how to set the global list location._
|
57
|
+
|
58
|
+
## Motivation
|
59
|
+
|
60
|
+
Forget-Me-Not is a task manager for the terminal junkies, like me. I do most of my work inside the terminal, and I'd like to manage my TODO list from there too.
|
61
|
+
|
62
|
+
Juggling multiple clients and side projects it's important to keep the scope relevant. One TODO list to rule them all would be too messy, but switching between multiple ones adds _too much friction_. Forget-Me-Not location awarness does the job pretty all right, I can add tasks to the each project, and see them only when in there. And with the global list I can track important things too.
|
63
|
+
|
64
|
+
On top of that I'm quite a forgetful person, and I tend to get sidetracked. That is why I want my task manager to be **in my face**, and that's where Forget-Me-Not comes in handy.
|
65
|
+
|
66
|
+
## Shell Integration
|
67
|
+
|
68
|
+
### zsh
|
69
|
+
|
70
|
+
Add this to your `.zshrc`, or `.zshprompt`:
|
71
|
+
|
72
|
+
```
|
73
|
+
precmd() { fmn list --prompt }
|
74
|
+
```
|
75
|
+
|
76
|
+
## Tips
|
77
|
+
|
78
|
+
You might want to add `.fmn.yml` to your global `.gitignore`.
|
79
|
+
|
80
|
+
You might also want to speed up your workflow using aliases, for [example](https://github.com/mokagio/dotfiles/blob/master/aliases):
|
81
|
+
|
82
|
+
```
|
83
|
+
alias t='fmn list'
|
84
|
+
alias ta='fmn add'
|
85
|
+
alias td='fmn done'
|
86
|
+
```
|
87
|
+
|
88
|
+
## Install
|
89
|
+
|
90
|
+
_TODO_
|
91
|
+
|
92
|
+
## About
|
93
|
+
|
94
|
+
_TODO_
|
95
|
+
|
96
|
+
## Alternatives
|
97
|
+
|
98
|
+
Similar softwares are:
|
99
|
+
|
100
|
+
* _TODO_
|
101
|
+
|
102
|
+
---
|
103
|
+
|
104
|
+
(c) 2015 - Giovanni Lodi ([@mokagio](https://twitter.com/mokagio))
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/bin/fmn
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'commander/import'
|
5
|
+
require 'psych'
|
6
|
+
|
7
|
+
@gloable_folder = "#{Dir.home}/Dropbox"
|
8
|
+
@task_file_name = '.fmn.yml'
|
9
|
+
@tasks_key = 'tasks'
|
10
|
+
|
11
|
+
def add_task(task, path)
|
12
|
+
yaml = Psych.load_file(path)
|
13
|
+
end
|
14
|
+
|
15
|
+
def directories_list(current_dir)
|
16
|
+
dirs = [current_dir]
|
17
|
+
parent_dir = File.expand_path('..', current_dir)
|
18
|
+
while parent_dir != current_dir do
|
19
|
+
dirs.push parent_dir
|
20
|
+
current_dir = parent_dir
|
21
|
+
parent_dir = File.expand_path('..', current_dir)
|
22
|
+
end
|
23
|
+
return dirs.reverse
|
24
|
+
end
|
25
|
+
|
26
|
+
def task_yaml_at_path(path)
|
27
|
+
if File.exists?(path) then
|
28
|
+
return Psych.load_file(path)
|
29
|
+
end
|
30
|
+
return nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def tasks_at_path(path)
|
34
|
+
yaml = task_yaml_at_path(path)
|
35
|
+
return nil unless yaml
|
36
|
+
return yaml[@tasks_key].map do |t|
|
37
|
+
{ task: t, path: path }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def tasks_for_dir_list(current_dir)
|
42
|
+
tasks = []
|
43
|
+
dirs = directories_list(Dir.pwd)
|
44
|
+
dirs.each do |dir|
|
45
|
+
path = "#{dir}/#{@task_file_name}"
|
46
|
+
sub_tasks = tasks_at_path(path)
|
47
|
+
tasks.push(sub_tasks) if sub_tasks
|
48
|
+
end
|
49
|
+
tasks = tasks.flatten
|
50
|
+
end
|
51
|
+
|
52
|
+
def all_tasks(current_dir)
|
53
|
+
global_tasks = tasks_at_path("#{@gloable_folder}/#{@task_file_name}")
|
54
|
+
other_tasks = tasks_for_dir_list(current_dir)
|
55
|
+
return [global_tasks, other_tasks].flatten.reject { |e| e.nil? }
|
56
|
+
end
|
57
|
+
|
58
|
+
def write_tasks_to_path(tasks, path)
|
59
|
+
yaml = task_yaml_at_path(path)
|
60
|
+
yaml = {} unless yaml
|
61
|
+
yaml[@tasks_key] = tasks
|
62
|
+
|
63
|
+
File.open(path, 'w') do |file|
|
64
|
+
file.write(Psych.dump(yaml))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
program :name, 'Forget Me Not'
|
69
|
+
program :version, '0.0.1'
|
70
|
+
program :description, 'A smart, contextualized todo list. Designed to live in your terminal, and to be in your face.'
|
71
|
+
|
72
|
+
command :list do |c|
|
73
|
+
c.syntax = 'fmn list, [options]'
|
74
|
+
c.summary = ''
|
75
|
+
c.description = ''
|
76
|
+
c.example 'description', 'command example'
|
77
|
+
c.option '--prompt', 'Use this option when integrating with the shell prompt.'
|
78
|
+
c.action do |args, options|
|
79
|
+
tasks = all_tasks(Dir.pwd)
|
80
|
+
if tasks.empty?
|
81
|
+
puts 'All tasks done. Good on ya :)' unless options.prompt
|
82
|
+
else
|
83
|
+
tasks.each_with_index do |t, index|
|
84
|
+
puts "(#{index + 1}) - #{t[:task]}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
command :add do |c|
|
91
|
+
c.syntax = 'fmn add, [options]'
|
92
|
+
c.summary = 'Add a task to the forget me not list.'
|
93
|
+
c.description = 'Add a task to the forget me not list.'
|
94
|
+
c.example 'Add a task to the forget me not list. You don\'t need quotes.', 'fmn add Buy the milk'
|
95
|
+
c.option '-g', '--global', 'Add to the global list'
|
96
|
+
c.action do |args, options|
|
97
|
+
task = args.join(' ')
|
98
|
+
path = ""
|
99
|
+
if options.global
|
100
|
+
path = "#{@gloable_folder}/#{@task_file_name}"
|
101
|
+
else
|
102
|
+
path = "#{Dir.pwd}/#{@task_file_name}"
|
103
|
+
end
|
104
|
+
|
105
|
+
tasks = tasks_at_path(path) || []
|
106
|
+
tasks = tasks.map { |t| t[:task] }
|
107
|
+
tasks.push(task)
|
108
|
+
|
109
|
+
write_tasks_to_path(tasks, path)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
command :done do |c|
|
114
|
+
c.syntax = 'fmn done [options]'
|
115
|
+
c.summary = 'Mark a task as done.'
|
116
|
+
c.description = 'Mark a task as done, removing it from the list.'
|
117
|
+
c.example 'Mark a task as done.', 'fmn done 1'
|
118
|
+
c.action do |args, options|
|
119
|
+
return unless args.length >= 1
|
120
|
+
|
121
|
+
# TODO: check for non numeric arg
|
122
|
+
index = args[0].to_i - 1
|
123
|
+
|
124
|
+
# TODO: check for unexisting index
|
125
|
+
task_to_remove = all_tasks(Dir.pwd)[index]
|
126
|
+
tasks = tasks_at_path(task_to_remove[:path])
|
127
|
+
|
128
|
+
# TODO: this is quite silly, how can we make it better?
|
129
|
+
# TODO: what about tasks with the same name. Does it even make sense?
|
130
|
+
tasks.delete_if { |t| t[:task] == task_to_remove[:task] }
|
131
|
+
|
132
|
+
write_tasks_to_path(tasks.map { |t| t[:task] }, task_to_remove[:path])
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
data/forget-me-not.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Forget Me Not 🌺 - A smart, contextualized todo list. Designed to live in your terminal, and to be in your face.
|
2
|
+
|
3
|
+
require 'psych'
|
4
|
+
|
5
|
+
puts 'Forget Me Not 🌺\n'
|
6
|
+
|
7
|
+
task_file_name = 'tasks.yml'
|
8
|
+
|
9
|
+
current_dir = Dir.pwd
|
10
|
+
dirs = [current_dir]
|
11
|
+
while File.expand_path('..', current_dir) != current_dir do
|
12
|
+
dir = File.expand_path('..', current_dir)
|
13
|
+
dirs.push dir
|
14
|
+
current_dir = dir
|
15
|
+
end
|
16
|
+
|
17
|
+
tasks = []
|
18
|
+
dirs.each do |dir|
|
19
|
+
path = "#{dir}/#{task_file_name}"
|
20
|
+
if File.exists?(path) then
|
21
|
+
yaml = Psych.load_file(path)
|
22
|
+
tasks.push(yaml["tasks"])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
tasks = tasks.flatten
|
27
|
+
|
28
|
+
tasks.each do |t|
|
29
|
+
puts "- #{t}"
|
30
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'fmn/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "forget_me_not"
|
8
|
+
spec.version = FMN::VERSION
|
9
|
+
spec.authors = ["Giovanni Lodi"]
|
10
|
+
spec.email = ["giovanni.lodi42@gmail.com"]
|
11
|
+
spec.summary = %q{A smart, contextualised todo list. Designed to live in your terminal, and to be in your face.
|
12
|
+
}
|
13
|
+
spec.description = %q{A smart, contextualised todo list. Designed to live in your terminal, and to be in your face.}
|
14
|
+
spec.homepage = "https://github.com/mokagio/forget-me-not"
|
15
|
+
spec.license = "MIT"
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.executables << 'fmn'
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
spec.add_development_dependency "bundler", "~> 1.9"
|
20
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
21
|
+
end
|
data/lib/fmn/version.rb
ADDED
data/lib/fmn.rb
ADDED
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: forget_me_not
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Giovanni Lodi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-08-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.9'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
description: A smart, contextualised todo list. Designed to live in your terminal,
|
42
|
+
and to be in your face.
|
43
|
+
email:
|
44
|
+
- giovanni.lodi42@gmail.com
|
45
|
+
executables:
|
46
|
+
- fmn
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- ".gitignore"
|
51
|
+
- Gemfile
|
52
|
+
- Gemfile.lock
|
53
|
+
- LICENSE.txt
|
54
|
+
- README.md
|
55
|
+
- Rakefile
|
56
|
+
- bin/fmn
|
57
|
+
- forget-me-not.rb
|
58
|
+
- forget_me_not.gemspec
|
59
|
+
- lib/fmn.rb
|
60
|
+
- lib/fmn/version.rb
|
61
|
+
homepage: https://github.com/mokagio/forget-me-not
|
62
|
+
licenses:
|
63
|
+
- MIT
|
64
|
+
metadata: {}
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 2.4.6
|
82
|
+
signing_key:
|
83
|
+
specification_version: 4
|
84
|
+
summary: A smart, contextualised todo list. Designed to live in your terminal, and
|
85
|
+
to be in your face.
|
86
|
+
test_files: []
|