Compare commits
13 Commits
Author | SHA1 | Date |
---|---|---|
Arthur Poulet | 327acf8078 | |
Arthur POULET | 69dbf17a3e | |
Arthur POULET | d87acadb37 | |
Arthur POULET | 2337888f47 | |
Arthur POULET | 0f2b1ca225 | |
Arthur POULET | 0b4f5ef753 | |
Arthur POULET | efd327e9dd | |
Arthur POULET | 0531035755 | |
Jens | ca20fef018 | |
Arthur POULET | 91e5a777bb | |
Arthur POULET | 0fafdaf9f0 | |
Arthur POULET | 825fb1dafc | |
Arthur POULET | 4af5ad1f3b |
8
Makefile
8
Makefile
|
@ -11,12 +11,14 @@ release:
|
|||
test:
|
||||
crystal spec
|
||||
deps:
|
||||
crystal deps install
|
||||
shards install
|
||||
deps_update:
|
||||
crystal deps update
|
||||
shards update
|
||||
deps_opt:
|
||||
@[ -d lib/ ] || make deps
|
||||
doc:
|
||||
crystal docs
|
||||
clean:
|
||||
rm $(NAME)
|
||||
|
||||
.PHONY: all run build release test deps deps_update doc
|
||||
.PHONY: all run build release test deps deps_update clean doc
|
||||
|
|
19
README.md
19
README.md
|
@ -1,3 +1,5 @@
|
|||
**Migrated to <https://git.sceptique.eu/Sceptique/todo>**
|
||||
|
||||
# todo
|
||||
|
||||
track your todo lists in your terminal
|
||||
|
@ -6,7 +8,7 @@ track your todo lists in your terminal
|
|||
|
||||
### Requirements
|
||||
|
||||
- crystal (see the shards.yml file)
|
||||
- crystal (see the shards.yml file) (tested with v0.27.0)
|
||||
- shards
|
||||
|
||||
### Build
|
||||
|
@ -41,7 +43,9 @@ There are several type of date format which are parsed automatically:
|
|||
## Configuration
|
||||
|
||||
### Hooks
|
||||
You can set some hooks, which will be executed. Write a yaml file ~/.config/todorc with the following structure:
|
||||
I you want someting to get executed right after or before an operation,
|
||||
you can setup some hooks.
|
||||
Write a yaml file `~/.config/todorc` with the following structure:
|
||||
|
||||
```yaml
|
||||
hooks:
|
||||
|
@ -65,6 +69,17 @@ hooks:
|
|||
after_save:
|
||||
```
|
||||
|
||||
Each hooks can take several parameters:
|
||||
|
||||
- `mode`: current operation
|
||||
- `date`: date of the task
|
||||
- `id`: id of the task
|
||||
- `list_name`: name of the list of task
|
||||
- `dir_name`: directory where the task is registered
|
||||
- `msg`: body on the task
|
||||
- `sort`: type of sort (date, id, ...)
|
||||
|
||||
|
||||
## Development
|
||||
|
||||
TODO: Write development instructions here
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: todo
|
||||
version: 0.2.1
|
||||
version: 1.0.1
|
||||
|
||||
authors:
|
||||
- Arthur Poulet <arthur.poulet@mailoo.org>
|
||||
|
@ -8,6 +8,6 @@ targets:
|
|||
todo:
|
||||
main: src/todo.cr
|
||||
|
||||
crystal: 0.20.5
|
||||
crystal: 0.24.2
|
||||
|
||||
license: GPL-3.0
|
||||
|
|
|
@ -24,6 +24,7 @@ parsed = OptionParser.parse! do |p|
|
|||
|
||||
p.on("-s", "--sort", "Sort by date (by default)") { sort = :date }
|
||||
p.on("-i", "--sort-id", "Sort by id") { sort = :id }
|
||||
p.on("-v", "--version", "Show version") { puts "Todo v#{Todo::VERSION}"; exit }
|
||||
p.on("-h", "--help", "Show this help") { puts p; exit }
|
||||
end
|
||||
Dir.mkdir_p(dir_name)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
require "yaml"
|
||||
require "yaml"
|
||||
|
||||
class Todo::Config
|
||||
FILE_PATH = File.expand_path ".config/todorc", ENV["HOME"]
|
||||
|
@ -17,13 +16,19 @@ class Todo::Config
|
|||
Config.from_yaml("{}")
|
||||
end
|
||||
|
||||
def exec(hook_name : String)
|
||||
def exec(hook_name : String, *args)
|
||||
hooks = self.hooks
|
||||
unless hooks.nil?
|
||||
current = hooks[hook_name]?
|
||||
unless current.nil?
|
||||
current.each { |hook| d = `#{hook}`.strip; puts d unless d.empty? }
|
||||
end
|
||||
current = (hooks[hook_name]?)
|
||||
exec_hooks(current, *args) unless (current.nil?)
|
||||
end
|
||||
end
|
||||
|
||||
private def exec_hooks(hooks : Array(String), *args)
|
||||
hooks.each do |hook|
|
||||
args_str = args.map { |e| "#{e.to_s.inspect}" }.join(" ")
|
||||
d = `#{hook} #{args_str}`.strip
|
||||
puts d unless d.empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,35 +1,49 @@
|
|||
require "colorize"
|
||||
require "./todo"
|
||||
require "./task"
|
||||
require "./list"
|
||||
require "./config"
|
||||
|
||||
module Todo::Exec
|
||||
extend self
|
||||
|
||||
private def copy_task(task, list_to, dir_name)
|
||||
list = List.load(list_to, dir_name)
|
||||
list << task
|
||||
list.save(list_to, dir_name)
|
||||
end
|
||||
|
||||
# :nodoc:
|
||||
# calls config.exec with the arguments
|
||||
private macro config_exec(config_to_exec)
|
||||
config.exec {{config_to_exec}}, mode, date, id, list_name, dir_name, msg, sort
|
||||
end
|
||||
|
||||
def run(mode, date, id, list_name, dir_name, msg, sort)
|
||||
config = Config.new
|
||||
|
||||
# new list
|
||||
config.exec "before_load"
|
||||
# Prepare the list
|
||||
config_exec "before_load"
|
||||
list = List.load(list_name, dir_name)
|
||||
config.exec "after_load"
|
||||
config_exec "after_load"
|
||||
|
||||
config.exec "before_#{mode}"
|
||||
# effect
|
||||
config_exec "before_#{mode}"
|
||||
# Execute the operation
|
||||
case mode
|
||||
when :add
|
||||
todo = ::Todo::Todo.new(msg, date)
|
||||
todo = ::Todo::Task.new(msg, date)
|
||||
list << todo
|
||||
puts "ADD [#{list.size - 1}] #{todo.date} #{todo.msg}"
|
||||
when :list
|
||||
display = [] of Array(String)
|
||||
list.each_with_index { |todo, idx| display << [todo.date, "#{idx.to_s.rjust(4, ' ').colorize.yellow} | #{todo.date.rjust(12, ' ').colorize.white.mode(:dim).to_s} | #{todo.msg}"] }
|
||||
list.each_with_index do |todo, idx|
|
||||
p_id = idx.to_s.rjust(4, ' ').colorize.yellow
|
||||
p_date_time = Time.parse_local(todo.date, ::Todo::Task::DATE_FORMAT) rescue nil
|
||||
p_date_red = p_date_time && p_date_time < Time.now
|
||||
p_date = todo.date.rjust(12, ' ').colorize.fore(p_date_red ? :red : :white).mode(p_date_red ? :bright : :dim).to_s
|
||||
display << [todo.date, "#{p_id} | #{p_date} | #{todo.msg}"]
|
||||
end
|
||||
display.sort_by! { |e| e[0] } if sort == :date
|
||||
max_msg_len = list.reduce(7) { |l, r| [l, r.msg.size].max }
|
||||
max_msg_len = [list.reduce(7) { |l, r| [l, r.msg.size].max }, 58].min
|
||||
puts " id | date | message"
|
||||
puts "---- | ------------ | #{"-" * max_msg_len} "
|
||||
puts display.map { |e| e[1] }.join("\n")
|
||||
|
@ -52,10 +66,11 @@ module Todo::Exec
|
|||
else
|
||||
puts "Error"
|
||||
end
|
||||
config.exec "after_#{mode}"
|
||||
config_exec "after_#{mode}"
|
||||
|
||||
config.exec "before_save"
|
||||
# Save the operation
|
||||
config_exec "before_save"
|
||||
list.save(list_name, dir_name)
|
||||
config.exec "after_save"
|
||||
config_exec "after_save"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
require "yaml"
|
||||
require "./todo"
|
||||
require "./task"
|
||||
|
||||
class Todo::List
|
||||
def self.load(path : String)
|
||||
|
@ -14,7 +14,7 @@ class Todo::List
|
|||
|
||||
property name
|
||||
YAML.mapping(
|
||||
todos: {type: Array(Todo), setter: false, nilable: false},
|
||||
todos: {type: Array(Todo::Task), setter: false, nilable: false},
|
||||
)
|
||||
|
||||
def save(list_name : String, dir_name : String)
|
||||
|
@ -26,7 +26,7 @@ class Todo::List
|
|||
self
|
||||
end
|
||||
|
||||
def <<(todo : Todo)
|
||||
def <<(todo : Todo::Task)
|
||||
self.todos << todo
|
||||
end
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
require "yaml"
|
||||
|
||||
class Todo::Todo
|
||||
class Todo::Task
|
||||
YAML.mapping(
|
||||
msg: {type: String},
|
||||
date: {type: String, setter: false},
|
||||
)
|
||||
|
||||
DATE_SEP = "(?:[/\-])"
|
||||
DATE_FORMAT = "%y/%m/%d"
|
||||
DATE_SEP = "(?:[/\-])"
|
||||
# DATE_MATCH_1 = Regex.new "(?:(\d+)#{DATE_SEP})?(?:(\d+)#{DATE_SEP})(?:(\d+))"
|
||||
DATE_MATCH_1 = /^(?:(\d+)#{DATE_SEP})?(\d+)#{DATE_SEP}(\d+)$/
|
||||
DATE_MATCH_2 = /^d\+(\d+)$/i
|
||||
|
@ -18,7 +19,7 @@ class Todo::Todo
|
|||
year = (m[1]? || Time.now.year - 2000).to_i
|
||||
"#{year}/#{m[2]}/#{m[3]}"
|
||||
elsif m = value.match DATE_MATCH_2
|
||||
(Time.now + m[1].to_i.days).to_s("%y/%m/%d")
|
||||
(Time.now + m[1].to_i.days).to_s(DATE_FORMAT)
|
||||
else
|
||||
STDERR.puts "[WARN] \"#{value}\" is not a valid date"
|
||||
value
|
Loading…
Reference in New Issue