bin/pomo
#!/usr/bin/env ruby
# coding: utf-8
require 'commander/import'
require 'pomo'
program :version, Pomo::VERSION
program :description, "Pomodoro time management.
pomo provides a unified task selection api which can be used
with most of the commands. Commands with [task] or [task ...]
in their synopsis accept only single or both single and multiple
task selection, respectively.
Single task selection:
n : selects a single task by index : Ex: pomo remove 1
first : selects the first task : Ex: pomo remove first
last : selects the last task : Ex: pomo remove last
Multiple task selection:
[n ]+ : selects several tasks by index : Ex: pomo remove 2 8 1
[n..n]+ : selects a range of tasks : Ex: pomo remove 5..9 11..14
[n..-n]+ : selects a range of tasks : Ex: pomo remove 2..-1
[api ]+ : selects several tasks by api : Ex: pomo remove first last
complete : selects complete tasks : Ex: pomo remove complete
incomplete : selects incomplete tasks : Ex: pomo remove incomplete
all : selects all tasks : Ex: pomo remove all"
program :help_formatter, :compact
program :int_message, "\nTerminated pomo" \
"\n * previously running tasks not marked as complete" \
"\n * manually complete a task with `$ pomo complete <task>`"
list = Pomo::List.new
default_command :list
command :initconfig do |c|
c.syntax = 'pomo initconfig [options]'
c.description = 'Initialize default configuration'
c.example 'Configure with notification center, no progress bar, and tmux integration', 'pomo initconfig --notifier notification_center --no-progress --tmux'
c.option '--notifier <lib>', String, 'Specify notificaiton library: `notification_center`, `libnotify`, `growl`, `quicksilver`'
c.option '--[no-]progress' , 'Run with progress bar'
c.option '--[no-]tmux' , 'Refresh tmux status bar on timer change'
c.option '--[no-]force' , 'force overwrite of existing config file'
c.action do |args, options|
Pomo::Configuration.save(options.__hash__)
end
end
command :init do |c|
c.syntax = 'pomo init [options]'
c.description = 'Initialize pomo in the current directory'
c.action do |args, options|
config = Pomo::Configuration.load
Pomo::List.new :init => true
say 'Initialized at `./.pomo`'
say ' - Any commands run while in this directory will reference this file for tasks'
say ' - To remove simply execute `rm .pomo`'
end
end
command :start do |c|
c.syntax = 'pomo start [task] [options]'
c.summary = 'Start a task'
c.description = 'Start a task, given the task [task] or the first task'
c.example 'Start the first incomplete task', 'pomo start'
c.example 'Start the first task' , 'pomo start 0'
c.example 'Start the first task' , 'pomo start first'
c.example 'Start the fifth task' , 'pomo start 5'
c.option '--notifier <lib>', String, 'Specify notificaiton library: `notification_center`, `libnotify`, `growl`, `quicksilver`'
c.option '--[no-]progress' , 'Run with progress bar'
c.option '--[no-]tmux' , 'Refresh tmux status bar on timer change'
c.action do |args, options|
abort 'a task is already running' if list.running
config = Pomo::Configuration.load(options.__hash__)
args = ['incomplete'] if args.empty?
list.find(*args) do |task|
abort 'task already completed' if task.complete?
task.start(config, :progress => options.progress, :list => list)
break
end
end
end
command :import do |c|
c.syntax = 'pomo import <user> <project> [issue_number]'
c.summary = 'Import Github issue(s)'
c.description = 'Import Github project issues which have not yet been closed'
c.example 'Import all open Github issues from "visionmedia/pomo"', 'pomo import visionmedia pomo'
c.example 'Import Github issue #3 from "visionmedia/pomo"' , 'pomo import visionmedia pomo 3'
c.action do |args, options|
config = Pomo::Configuration.load
user = args.shift or raise('Github <user> is required')
project = args.shift or raise('Github <project> is required')
number = args.shift
say "Importing issues from https://github.com/#{user}/#{project}"
tasks = Pomo::GithubTask.import(user, project, number)
tasks.each do |task|
list << task
say " - Added #{task}"
end
list.save
end
end
command :add do |c|
c.syntax = 'pomo add <task> [options]'
c.summary = 'Add a task'
c.description = 'Add a task to the current list of tasks'
c.example 'Adds the task "fix IE styling issues"', 'pomo add "fix IE styling issues"'
c.example 'Add a task with 60 minute limit' , 'pomo add "create executable" --length 60'
c.option '-d', '--description string', 'Add verbose task description'
c.option '-l', '--length minutes', Integer, 'Change the default length in minutes'
c.action do |args, options|
config = Pomo::Configuration.load
task = Pomo::Task.new(args.shift, options.__hash__)
list << task
list.save
say " - Added #{task}"
end
end
command :edit do |c|
c.syntax = 'pomo edit [task ...] [options]'
c.summary = 'Edit task(s)'
c.description = 'Edit the given task(s) or the first task'
c.example 'Changes the description for the first task' , 'pomo edit first -d "fix IE styling issues"'
c.example 'Changes the description and length for the third task', 'pomo edit 3 -d "fix IE styling issues" -l 60'
c.example 'Changes the length of several tasks' , 'pomo edit 1..5 -l 10'
c.option '-n', '--name string', 'Change the task name'
c.option '-d', '--description string', 'Change the task description'
c.option '-l', '--length minutes', Integer, 'Change the task length'
c.action do |args, options|
config = Pomo::Configuration.load
list.find(*args) do |task|
options.__hash__.each do |key, value|
task.send :"#{key}=", value
end
say " - Updated #{task}"
end
list.save
end
end
command :break do |c|
c.syntax = 'pomo break [length] [options]'
c.summary = 'Start a break'
c.description = 'Take a break, defaults to 5 minutes or [length] or --length'
c.example 'Take a five minute break', 'pomo break'
c.example 'Take a 30 minute break' , 'pomo break 30'
c.example 'Take a 30 minute break' , 'pomo break --length 30'
c.option '-l', '--length minutes', Integer, 'Change the default length in minutes'
c.option '--notifier <lib>', String, 'Specify notificaiton library: `notification_center`, `libnotify`, `growl`, `quicksilver`'
c.option '--[no-]progress' , 'Run with progress bar'
c.option '--[no-]tmux' , 'Refresh tmux status bar on timer change'
c.action do |args, options|
options.default :length => args.first ? args.first.to_i : 5
config = Pomo::Configuration.load(options.__hash__)
task = Pomo::Break.new('Break time', options.__hash__)
task.start(config, :progress => options.progress)
end
end
command :remove do |c|
c.syntax = 'pomo [remove|rm] [task ...] [options]'
c.summary = 'Remove task(s)'
c.description = 'Remove task(s) or the first task'
c.example 'Remove the first task' , 'pomo remove first'
c.example 'Remove the fifth task' , 'pomo rm 5'
c.example 'Remove the fifth and second task', 'pomo rm 5 2'
c.example 'Remove a range of tasks' , 'pomo rm 2..6'
c.example 'Remove all but the first task' , 'pomo rm 2..-1'
c.example 'Remove all tasks' , 'pomo rm all'
c.action do |args, options|
config = Pomo::Configuration.load
list.find(*args) do |task|
list.tasks -= [task]
say " - Removed #{task}"
end
list.save
end
end
alias_command :rm, :remove
alias_command :clear, :remove, 'all'
command :copy do |c|
c.syntax = 'pomo [copy|cp] [task...]'
c.summary = 'Copy task(s)'
c.description = 'Copy task(s) to the end of the current list as an incomplete task'
c.example 'Copy first task' , 'pomo copy first'
c.example 'Copy the fourth task' , 'pomo cp 4'
c.example 'Copy the fifth and second task', 'pomo cp 5 2'
c.example 'Copy a range of tasks' , 'pomo cp 2..6'
c.example 'Copy all but the first task' , 'pomo cp 2..-1'
c.example 'Copy all tasks' , 'pomo cp all'
c.action do |args, options|
config = Pomo::Configuration.load
list.find(*args) do |task|
dup_task = Marshal::load(Marshal.dump(task))
dup_task.complete = false
list.tasks << dup_task
say " - Copied #{task}"
end
list.save
end
end
alias_command :cp, :copy
command :move do |c|
c.syntax = 'pomo move [from] [to]'
c.summary = 'Move a task'
c.description = 'Move a task to a different position in the current list'
c.example 'Move task 4 to position 2' , 'pomo move 4 2'
c.example 'Move last task to first position', 'pomo mv last first'
c.action do |args, options|
config = Pomo::Configuration.load
from = args.shift or raise('<from> is required')
to = args.shift or raise('<to> is required')
list.find(from) do |task|
list.find(to) do |other_task|
list.move(from, to)
say " - Moved #{task} from position #{from} to #{to}"
end
end
list.save
end
end
alias_command :mv, :move
# TODO remove view alias in 3.0 release
command :show do |c|
c.syntax = 'pomo show [task ...] [options]'
c.summary = 'Show verbose task information'
c.description = 'Show verbose information for the given task(s) or the first task'
c.example 'Show the first task', 'pomo show first'
c.example 'Show the last task' , 'pomo show last'
c.example 'Show the fifth task', 'pomo show 5'
c.action do |args, options|
config = Pomo::Configuration.load
list.find(*args) do |task|
say "\n"
format = "%15s : %s\n"
task.verbose_output(format)
end
say "\n"
end
end
alias_command :view, :show
command :complete do |c|
c.syntax = 'pomo complete [task ...] [options]'
c.summary = 'Mark task(s) as completed'
c.description = 'Mark the given task(s) or the first task to complete'
c.example 'Mark first task as complete', 'pomo complete first'
c.example 'Mark last task as complete' , 'pomo complete last'
c.example 'Mark fifth task as complete', 'pomo complete 5'
c.action do |args, options|
config = Pomo::Configuration.load
list.find(*args) do |task|
task.complete = true
say " - Completed #{task}"
end
list.save
end
end
command :incomplete do |c|
c.syntax = 'pomo incomplete [task ...] [options]'
c.summary = 'Mark task(s) as incompleted'
c.description = 'Mark the given task(s) or the first task as not completed'
c.example 'Mark first task as not completed', 'pomo incomplete first'
c.example 'Mark last task as not completed' , 'pomo incomplete last'
c.example 'Mark fifth task as not completed', 'pomo incomplete 5'
c.action do |args, options|
config = Pomo::Configuration.load
list.find(*args) do |task|
task.complete = false
say " - #{task} marked incomplete"
end
list.save
end
end
command :list do |c|
c.syntax = 'pomo [list|ls] [options]'
c.description = 'List tasks'
c.example 'List incomplete tasks', 'pomo list'
c.example 'List all tasks', 'pomo list --all'
c.example 'List completed tasks', 'pomo list --complete'
c.option '-a', '--all', 'List all tasks'
c.option '-c', '--complete', 'List only completed tasks'
c.action do |args, options|
abort "invalid command. See 'pomo help' for more information" unless args.empty?
config = Pomo::Configuration.load
total = 0
list.tasks.each_with_index do |task, i|
next if task.complete? && !options.all && !options.complete
next if !task.complete? && options.complete
say ' %s %2d. %-50s : %d minutes' % [task.complete? ? '✓' : ' ', i, task.to_s, task.length]
total += task.length
end
say ' ' * 60 + '%d minutes' % total
end
end
alias_command :ls, :list