Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

A few updates #24

Closed
wants to merge 26 commits into from

2 participants

@stephenmckinney
Collaborator

Most likely you're not still supporting this gem, but I've had fun using it and added a few features that made it more useful for myself after seeing the Pomodoro plugin for RubyMine I wanted something similar in iTerm2.

Here's the punchlist:

  • Added detach mode, on by default. To get the 1.x progress bar run pomo start -p. Closes #1
  • Added notification support for Mac OS X User Notifications on OS X 10.8+, and libnotify for Linux. Growl continues to be supported on OS X 10.7 or earlier. Closes #23
  • Added output of pomo timer to ~/.pomo_stat.
  • Added pomo ls as an alias to pomo list

The ~/.pomo_stat feature enables Tmux status lines, etc. to read this file and display the current time left in a Pomodoro e.g.

Screenshot

Screenshot

Screenshot

in tmux.conf

# status bar refresh rate (seconds)
set -g status-interval 3
# right status bar
set-option -g status-right '#[bold]⡇ #H ⡇ #(~/.bin/pomo)  ⡇ #(~/.bin/battery) ⡇ %b %d %I:%M%p '

~/.bin/pomo

#!/bin/sh

# Display timer as red if less than 5 mins and
# green for greater that 5 mins. 0 is not changed.
echo $(cat ~/.pomo_stat) | \
sed \
-e 's/^\([1-5]\):00/#[default]#[fg=red]\1:00#[default]#[bold]/' \
-e 's/^\([1-9][0-9]\{0,1\}\):00/#[default]#[fg=green]\1:00#[default]#[bold]/'
stephenmckinney added some commits
@stephenmckinney stephenmckinney Adds notification support for Mac OS X User Notifications and libnoti…
…fy [#23]
6b00908
@stephenmckinney stephenmckinney Updates required commander version 0c78130
@stephenmckinney stephenmckinney Improves notification messages [#23] c2eb6fc
@stephenmckinney stephenmckinney Adds `ls` as an alias to `list` 102dafb
@stephenmckinney stephenmckinney Refactors notification code slightly [#23] 140d5c1
@stephenmckinney stephenmckinney Updates gem structure to follow Bundler best practices 8d1eade
@stephenmckinney stephenmckinney Renames files to interim name for capitalization 640783c
@stephenmckinney stephenmckinney Capitalizes history and readme files 2f2b9a6
@stephenmckinney stephenmckinney Adds RSpec as a development dependency 240a1c6
@stephenmckinney stephenmckinney Refactors notifiers to easily extend in the future [#23] d844cd2
@stephenmckinney stephenmckinney Refactors notifier to accept a hash of options [#23] 28bf9a5
@stephenmckinney stephenmckinney Strips trailing whitespace 7c73078
@stephenmckinney stephenmckinney Adds detach mode. On by default. [#1] 73d0f3f
@stephenmckinney stephenmckinney Fixes list not saving in detached process [#1] 2c4400e
@stephenmckinney stephenmckinney Adds writing of pomo timer to ~/.pomo_stat
This enables Vim and Tmux status lines to read this file
and display the current time left in a Pomodoro.
65159c7
@stephenmckinney stephenmckinney Moves .pomo loading to List.initialize e998e0c
@stephenmckinney stephenmckinney Adds ability to add/rm tasks during running tasks in detach mode. [#1]
Also locks `pomo start` so that other pomo cannot be started
while others are running.
f4d5f06
@stephenmckinney stephenmckinney Bumps version to 2.0.0
Following SemVer as backwards incompatible changes have been
introduced. `pomo start` runs in the background by default.
To get 1.x progress bar, users must execute `pomo start -p`
bc24c62
@stephenmckinney stephenmckinney Updates HISTORY.md for 2.0.0 release 3d7ff73
@stephenmckinney stephenmckinney Updates README.md for 2.0.0 release f758d58
@stephenmckinney stephenmckinney Use ENV['HOME'] rather than expand_path 7d804a3
@stephenmckinney stephenmckinney Adds configuration file ~/.pomorc, tmux integration, refactors code
options include notifier, pomo_stat, and tmux.
* default notifier depends on OS
* default writing to ~/.pomo_stat file is false
* default tmux integration is false
6949162
@stephenmckinney stephenmckinney Adds Quicksilver notifier [#23] 6fbd692
@stephenmckinney stephenmckinney Removes Manifest file in favor of Bundler d22346c
@stephenmckinney stephenmckinney Updates README and HISTORY 777b3c9
@stephenmckinney stephenmckinney Adjust pomo_stat output for Breaks
Break output: *4:00

Task output: 4:00

The star can be used in regexp to add color in tmux
status bar.
1ce12d7
@stephenmckinney
Collaborator

If you're not interested in maintaining the pomo gem, there are some options:

  1. I can take over maintenance and you can give me access to push the gem to rubygems OR
  2. I could just make a fork called 'pomo2' or something and push my own gem

I'm interested in adding more features like: pomo pause/stop; having pomodoro sets so that you can take a long break after 3 or 4 pomodoros; adding pomo sets, duration, short break, and long break into .pomorc, etc.

@tj
Owner
tj commented

im happy to give you access, i dont remember how to do that with gem though

@stephenmckinney
Collaborator

To add me as an owner, you can execute the following:

gem owner pomo --add stevemckinney@gmail.com

@tj
Owner
tj commented

hmm apparently my credentials are gone haha, fuck it, ill have to look into it later, centralized registries ftw

@stephenmckinney
Collaborator
@tj
Owner
tj commented

k done

@stephenmckinney
Collaborator

nice. thx.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 7, 2012
  1. @stephenmckinney
  2. @stephenmckinney
  3. @stephenmckinney
  4. @stephenmckinney
  5. @stephenmckinney
  6. @stephenmckinney
  7. @stephenmckinney
  8. @stephenmckinney
  9. @stephenmckinney
  10. @stephenmckinney
  11. @stephenmckinney
  12. @stephenmckinney
  13. @stephenmckinney
  14. @stephenmckinney
  15. @stephenmckinney

    Adds writing of pomo timer to ~/.pomo_stat

    stephenmckinney authored
    This enables Vim and Tmux status lines to read this file
    and display the current time left in a Pomodoro.
  16. @stephenmckinney
  17. @stephenmckinney

    Adds ability to add/rm tasks during running tasks in detach mode. [#1]

    stephenmckinney authored
    Also locks `pomo start` so that other pomo cannot be started
    while others are running.
  18. @stephenmckinney

    Bumps version to 2.0.0

    stephenmckinney authored
    Following SemVer as backwards incompatible changes have been
    introduced. `pomo start` runs in the background by default.
    To get 1.x progress bar, users must execute `pomo start -p`
  19. @stephenmckinney
  20. @stephenmckinney
  21. @stephenmckinney
Commits on Dec 8, 2012
  1. @stephenmckinney

    Adds configuration file ~/.pomorc, tmux integration, refactors code

    stephenmckinney authored
    options include notifier, pomo_stat, and tmux.
    * default notifier depends on OS
    * default writing to ~/.pomo_stat file is false
    * default tmux integration is false
  2. @stephenmckinney
  3. @stephenmckinney
  4. @stephenmckinney
Commits on Dec 9, 2012
  1. @stephenmckinney

    Adjust pomo_stat output for Breaks

    stephenmckinney authored
    Break output: *4:00
    
    Task output: 4:00
    
    The star can be used in regexp to add color in tmux
    status bar.
This page is out of date. Refresh to see the latest.
View
18 .gitignore
@@ -1 +1,17 @@
-.pomo
+*.gem
+*.rbc
+.bundle
+.config
+.yardoc
+Gemfile.lock
+InstalledFiles
+_yardoc
+coverage
+doc/
+lib/bundler/man
+pkg
+rdoc
+spec/reports
+test/tmp
+test/version_tmp
+tmp
View
15 DEVELOPMENT
@@ -0,0 +1,15 @@
+To run the development rake tasks, you need bundler installed.
+
+Before you push any changes, run the RSpec suite:
+
+ $ rake spec
+
+To build a new version of the gem:
+
+ $ rake build
+
+To push the new version to Rubygems:
+
+ $ rake release
+
+(http://rubygems.org/gems/pomo)
View
4 Gemfile
@@ -0,0 +1,4 @@
+source 'https://rubygems.org'
+
+# Specify your gem's dependencies in pomo.gemspec
+gemspec
View
13 History.md → HISTORY.md
@@ -1,3 +1,14 @@
+2.0.0 / 2012-12-08
+==================
+
+ * Added detach mode, on by default. To get the 1.x progress bar run `pomo start -p`. Closes #1
+ * Added notification support for Mac OS X User Notifications, Quicksilver and libnotify.
+ Growl continues to be supported. Closes #23
+ * Added optional output of pomo timer to `~/.pomo_stat`.
+ This enables Tmux status lines, etc. to read this file and display the current time
+ left in a Pomodoro.
+ * Added optional refresh of Tmux status line when timer changes.
+ * Added `pomo ls` as an alias to `pomo list`
1.0.1 / 2010-03-10
==================
@@ -72,4 +83,4 @@
0.0.1 / 2009-10-15
==================
- * Initial release
+ * Initial release
View
22 LICENSE.txt
@@ -0,0 +1,22 @@
+Copyright (c) 2009 TJ Holowaychuk <tj@vision-media.ca>
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
17 Manifest
@@ -1,17 +0,0 @@
-History.md
-Manifest
-Rakefile
-Readme.md
-bin/pomo
-lib/pomo.rb
-lib/pomo/github_task.rb
-lib/pomo/list.rb
-lib/pomo/task.rb
-lib/pomo/version.rb
-pomo.gemspec
-spec/pomo_spec.rb
-spec/spec.opts
-spec/spec_helper.rb
-tasks/docs.rake
-tasks/gemspec.rake
-tasks/spec.rake
View
85 Readme.md → README.md
@@ -6,8 +6,9 @@
With Pomo you can add, remove, list, view, and start timing tasks all via the
command-line with a simple, slick interface. You are reminded of the remaining
-time on a task via Growl. These notifications appear half-way, at the 5 minute point,
-and when the task duration has expired.
+time on a task via Notification Center, Growl, libnotify, or Quicksilver.
+These notifications appear half-way, at the 5 minute point, and when the task
+duration has expired.
## Installation
@@ -58,11 +59,16 @@ Taken from `pomo help`:
$ pomo start
Started Fix IE stying issues, you have 25 minutes :)
+
+ * Alternatively, you can start the first incomplete task with a progress bar:
+
+ $ pomo start -p
+ Started Fix IE stying issues, you have 25 minutes :)
(=........................) 24 minutes remaining
- * Once you have completed the task, list again:
+ * Once you have completed the task, list again (alternatively `pomo ls`):
- $ pomo list
+ $ pomo ls
✓ 0. Fix IE stying issues : 25 minutes
1. Destroy IE : 25 minutes
@@ -74,12 +80,12 @@ Taken from `pomo help`:
* List only remaining tasks:
- $ pomo list --incomplete
+ $ pomo ls --incomplete
1. Destroy IE : 25 minutes
* List only completed tasks:
- $ pomo list --complete
+ $ pomo ls --complete
✓ 0. Fix IE stying issues : 25 minutes
* At any time mid-task you may terminate pomo via CTRL + C, at which
@@ -131,28 +137,45 @@ Taken from `pomo help`:
$ pomo init
-## License
-
-> (The MIT License)
->
-> Copyright (c) 2009 TJ Holowaychuk <tj@vision-media.ca>
->
-> Permission is hereby granted, free of charge, to any person
-> obtaining a copy of this software and associated documentation files
-> (the 'Software'), to deal in the Software without restriction,
-> including without limitation the rights to use, copy, modify, merge,
-> publish, distribute, sublicense, an d/or sell copies of the
-> Software, and to permit persons to whom the Software is furnished to
-> do so, subject to the following conditions:
->
-> The above copyright notice and this permission notice shall be
-> included in all copies or substantial portions of the Software.
->
-> THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-> BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-> ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-> CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-> THE SOFTWARE.
+## Configuration
+
+Pomo uses `~/.pomorc` for configuration options.
+
+Configuration options:
+
+* `:notifier`: Notification library
+ * Default: depends on OS. String.
+ * Valid values: `notification_center`, `libnotify`, `growl`, `quicksilver`
+* `:pomo_stat`: Write pomo timer to `~/.pomo_stat`
+ * Default: `false`. Boolean.
+ * Valid values: `true`, `false`
+* `:tmux`: Refresh tmux status bar
+ * Default: `false`. Boolean.
+ * Valid values: `true`, `false`
+
+For example on Mac OS X Mountain Lion, `~/.pomorc` defaults to:
+
+ ---
+ :notifier: notification_center
+ :pomo_stat: false
+ :tmux: false
+
+## Tmux Status Bar Integration
+
+The pomo timer can be displayed in tmux's status bar with the following
+configurations set:
+
+ :pomo_stat: true
+ :tmux: true
+
+Then add the below to your `~/.tmux.conf`:
+
+ set-option -g status-right '#(echo $\(cat ~/.pomo_stat\))'
+
+## Contributing
+
+1. Fork it
+2. Create your feature branch (`git checkout -b my-new-feature`)
+3. Commit your changes (`git commit -am 'Add some feature'`)
+4. Push to the branch (`git push origin my-new-feature`)
+5. Create new Pull Request
View
21 Rakefile
@@ -1,17 +1,8 @@
+require "rspec/core/rake_task"
+require "bundler/gem_tasks"
-$:.unshift 'lib'
-require 'pomo'
-require 'rubygems'
-require 'rake'
-require 'echoe'
-
-Echoe.new "pomo", Pomo::VERSION do |p|
- p.author = "TJ Holowaychuk"
- p.email = "tj@vision-media.ca"
- p.summary = "Pomodoro time management for the command-line"
- p.url = "http://github.com/visionmedia/pomo"
- p.runtime_dependencies << 'commander >=4.0.2'
- p.runtime_dependencies << 'growl >=1.0.3'
+desc "Run specs"
+RSpec::Core::RakeTask.new do |t|
+ t.verbose = false
+ t.rspec_opts = '--color'
end
-
-Dir['tasks/**/*.rake'].sort.each { |f| load f }
View
38 bin/pomo
@@ -1,18 +1,19 @@
#!/usr/bin/env ruby
# coding: utf-8
-$:.unshift File.dirname(__FILE__) + '/../lib'
+$:.unshift File.dirname(__FILE__) + '/../lib'
require 'rubygems'
require 'commander/import'
require 'pomo'
program :version, Pomo::VERSION
+
program :description, "Pomodoro time management.
- Most of the subcommands work directly with tasks, and
+ Most of the subcommands work directly with tasks, and
because of this pomo provides a unified task selection api
- shown below which can be used with most of the commands
- (those with [task ...] in their synopsis).
-
+ shown below which can be used with most of the commands
+ (those with [task ...] in their synopsis).
+
n : selects a single task by index : Ex: pomo remove 1
[n ]+ : selects several tasks by index : Ex: pomo remove 2 8 1
n..n : selects a range of tasks : Ex: pomo remove 5..9
@@ -28,7 +29,8 @@ 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 File.exists?('.pomo') ? '.pomo' : '~/.pomo'
+config = Pomo::Configuration.new
+list = Pomo::List.new
default_command :list
@@ -36,11 +38,11 @@ command :init do |c|
c.syntax = 'pomo init [options]'
c.description = 'Initialize pomo in the current directory'
c.action do |args, options|
- Pomo::List.new '.pomo'
+ 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
end
command :start do |c|
@@ -51,13 +53,16 @@ command :start do |c|
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 '-p', '--progress', 'Run with progress bar in foreground'
c.action do |args, options|
+ abort 'a task is already running' if list.running
+
+ options.default :progress => false
args = ['incomplete'] if args.empty?
list.find(*args) do |task, i|
abort 'task already completed' if task.complete?
say "Started #{task}, you have #{task.length} minutes :)"
- task.start
- list.save
+ task.start(config, :progress => options.progress, :list => list)
break
end
end
@@ -75,7 +80,7 @@ command :import do |c|
if repo = Octopi::Repository.find(:user => user, :name => project)
say "Importing items from http://github.com/#{user}/#{project}"
repo.issues.select { |i| not i.closed_at }.each do |issue|
- task = Pomo::GithubTask.new issue.title,
+ task = Pomo::GithubTask.new issue.title,
:username => user,
:project => project,
:description => issue.body,
@@ -88,7 +93,7 @@ command :import do |c|
end
end
end
-
+
command :add do |c|
c.syntax = 'pomo add <task> [options]'
c.summary = 'Add a task'
@@ -134,10 +139,12 @@ command :break do |c|
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 '-p', '--progress', 'Run with progress bar in foreground'
c.action do |args, options|
+ options.default :progress => false
options.default :length => args.first ? args.first.to_i : 5
- task = Pomo::Task.new('Break time', options.__hash__)
- task.start
+ task = Pomo::Break.new('Break time', options.__hash__)
+ task.start(config, :progress => options.progress)
end
end
@@ -220,7 +227,7 @@ command :incomplete do |c|
end
command :list do |c|
- c.syntax = 'pomo list [options]'
+ c.syntax = 'pomo [list|ls] [options]'
c.description = 'List all tasks'
c.example 'List all tasks', 'pomo list'
c.option '-c', '--complete', 'List only completed tasks'
@@ -236,4 +243,5 @@ command :list do |c|
say ' ' * 55 + '%d minutes' % total
end
end
+alias_command :ls, :list
View
35 lib/pomo.rb
@@ -1,29 +1,14 @@
-#--
-# Copyright (c) 2009 TJ Holowaychuk <tj@vision-media.ca>
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#++
-
require 'yaml'
-require 'growl'
+require 'terminal-notifier' if /darwin/ =~ RUBY_PLATFORM
+require 'growl' if /darwin/ =~ RUBY_PLATFORM
+require 'libnotify' if /linux/ =~ RUBY_PLATFORM
+require 'pomo/configuration'
+require 'pomo/notifier'
+require 'pomo/notifier/notification_center'
+require 'pomo/notifier/growl'
+require 'pomo/notifier/libnotify'
require 'pomo/list'
require 'pomo/task'
require 'pomo/github_task'
-require 'pomo/version'
+require 'pomo/break'
+require 'pomo/version'
View
10 lib/pomo/break.rb
@@ -0,0 +1,10 @@
+
+module Pomo
+ class Break < Task
+
+ def write_pomo_stat(time)
+ time > 0 ? super("*#{time}") : super(time)
+ end
+
+ end
+end
View
74 lib/pomo/configuration.rb
@@ -0,0 +1,74 @@
+if RUBY_PLATFORM =~ /darwin/
+ MACOS_FULL_VERSION = `/usr/bin/sw_vers -productVersion`.chomp
+ MACOS_VERSION = /(10\.\d+)(\.\d+)?/.match(MACOS_FULL_VERSION).captures.first.to_f
+ OS_VERSION = "Mac OS X #{MACOS_FULL_VERSION}"
+ MACOS = true
+else
+ MACOS_FULL_VERSION = MACOS_VERSION = 0
+ OS_VERSION = RUBY_PLATFORM
+ MACOS = false
+end
+
+module Pomo
+ class Configuration
+ ##
+ # Notification library.
+ #
+ # values: notification_center | libnotify | growl | quicksilver
+
+ attr_reader :notifier
+
+ ##
+ # Write ~/.pomo_stat file.
+ #
+ # values: true | false
+
+ attr_accessor :pomo_stat
+
+ ##
+ # Refresh tmux status bar.
+ #
+ # values: true | false
+
+ attr_accessor :tmux
+
+ ##
+ # Initialize configuration.
+ def initialize
+ options = {
+ :notifier => default_notifier,
+ :pomo_stat => false,
+ :tmux => false
+ }
+
+ config_file = File.join(ENV['HOME'],'.pomorc')
+
+ if File.exists? config_file
+ config_options = YAML.load_file(config_file)
+ options.merge!(config_options)
+ else
+ File.open(config_file, 'w') { |file| YAML::dump(options, file) }
+ STDERR.puts "Initialized configuration file in #{config_file}"
+ end
+
+ @notifier = options[:notifier]
+ @pomo_stat = options[:pomo_stat]
+ @tmux = options[:tmux]
+ end
+
+ private
+
+ def default_notifier
+ if MACOS
+ if (10.8 <= MACOS_VERSION)
+ return 'notification_center'
+ else
+ return 'growl'
+ end
+ else
+ return 'libnotify'
+ end
+ end
+
+ end
+end
View
48 lib/pomo/list.rb
@@ -1,26 +1,31 @@
module Pomo
class List
-
+
##
# List path.
-
+
attr_reader :path
-
+
##
# Task array.
-
+
attr_accessor :tasks
-
+
##
# Initialize with _path_.
-
- def initialize path
+
+ def initialize opts = {}
+ if opts[:init]
+ path = '.pomo'
+ else
+ path = File.exists?('.pomo') ? '.pomo' : File.join(ENV['HOME'],'.pomo')
+ end
@path = File.expand_path path
@tasks = []
load rescue save
end
-
+
##
# Find tasks by _args_, iterating with _block_.
#
@@ -36,7 +41,7 @@ def initialize path
# * complete[d]
# * all
#
-
+
def find *args, &block
found = []
found << tasks.first if args.empty?
@@ -54,39 +59,46 @@ def find *args, &block
found = tasks[$1.to_i..$2.to_i]
else
tasks.each_with_index do |task, i|
- found << task if args.any? { |a| a.to_i == i }
+ found << task if args.any? { |a| a.to_i == i }
end
end
found.each_with_index do |task, i|
yield task, i
end
end
-
+
+ ##
+ # Find currently running _task_ or nil.
+
+ def running
+ tasks.detect {|task| task.running? }
+ end
+
##
# Add _task_ to the list in memory (requires saving).
-
+
def add task
@tasks << task
end
alias :<< :add
-
+
##
# Save the list.
-
+
def save
File.open(path, 'w') do |file|
file.write YAML.dump(tasks)
end
self
end
-
+
##
# Load the list.
-
+
def load
@tasks = YAML.load_file path
self
end
-
+
end
-end
+end
View
26 lib/pomo/notifier.rb
@@ -0,0 +1,26 @@
+
+module Pomo
+ class Notifier
+
+ ##
+ # Initialize notifier library from configuration.
+ def initialize(config)
+ if config.notifier == 'notification_center'
+ @notifier = Pomo::Notifier::NotificationCenter.new
+ elsif config.notifier == 'libnotify'
+ @notifier = Pomo::Notifier::Growl.new
+ elsif config.notifier == 'growl'
+ @notifier = Pomo::Notifier::Libnotify.new
+ elsif config.notifier == 'quicksilver'
+ @notifier = Pomo::Notifier::Quicksilver.new
+ end
+ end
+
+ ##
+ # Send message to notification library.
+ def notify(message, opts = {})
+ @notifier.notify(message, opts)
+ end
+
+ end
+end
View
17 lib/pomo/notifier/growl.rb
@@ -0,0 +1,17 @@
+
+module Pomo
+ class Notifier
+ class Growl
+ def notify(message, opts = {})
+ full_message = [opts[:header], opts[:message]].join(' ').lstrip
+
+ if opts[:type].equal? :warning
+ Growl.notify_warning full_message
+ else
+ Growl.notify_info full_message
+ end
+ end
+ end
+
+ end
+end
View
14 lib/pomo/notifier/libnotify.rb
@@ -0,0 +1,14 @@
+
+module Pomo
+ class Notifier
+ class Libnotify
+ def notify(message, opts = {})
+ title = 'Pomo'
+ full_message = [opts[:header], opts[:message]].join(' ').lstrip
+
+ Libnotify.show :body => full_message, :summary => title
+ end
+ end
+
+ end
+end
View
13 lib/pomo/notifier/notification_center.rb
@@ -0,0 +1,13 @@
+
+module Pomo
+ class Notifier
+ class NotificationCenter
+ def notify(message, opts = {})
+ title = 'Pomo'
+
+ TerminalNotifier.notify message, :title => title, :subtitle => opts[:header]
+ end
+ end
+
+ end
+end
View
12 lib/pomo/notifier/quicksilver.rb
@@ -0,0 +1,12 @@
+
+module Pomo
+ class Notifier
+ class Quicksilver
+ def notify(message, opts = {})
+ `osascript -e 'tell application "Quicksilver" to show large type "#{message.gsub('"', '\"')}"'`
+ end
+ end
+
+ end
+end
+
View
140 lib/pomo/task.rb
@@ -1,75 +1,153 @@
module Pomo
class Task
-
- #--
- # Mixins
- #++
-
- include Growl
-
+
##
# Task name.
-
+
attr_accessor :name
-
+
##
# Length in minutes.
-
+
attr_accessor :length
-
+
##
# Verbose task description.
-
+
attr_accessor :description
-
+
+ ##
+ # Task currently running bool.
+
+ attr_accessor :running
+
##
# Task completion bool.
-
+
attr_accessor :complete
-
+
##
# Initialize with _name_ and _options_.
-
+
def initialize name = nil, options = {}
@name = name or raise '<task> required'
@description = options.delete :description
@length = options.fetch :length, 25
+ @running = false
@complete = false
end
-
+
##
# Quoted task name.
-
+
def to_s
name.inspect
end
-
+
+ ##
+ # Check if the task currently running.
+
+ def running?
+ running
+ end
+
##
# Check if the task has been completed.
-
+
def complete?
complete
end
-
+
##
# Start timing the task.
-
- def start
- complete_message = "time is up! hope you are finished #{self}"
+ def start(config, options = {})
+ list = options[:list]
+ progress = options[:progress]
+
+ @running = true
+ list.save unless list.nil?
+
+ if progress
+ foreground_progress(config)
+ else
+ background_progress(config)
+ end
+ end
+
+ private
+
+ def foreground_progress(config)
+ notifier = Pomo::Notifier.new(config)
+
+ complete_message = "Time is up! Hope you are finished #{self}"
format_message = "(:progress_bar) :remaining minutes remaining"
- progress (0..length).to_a.reverse, :format => format_message, :tokens => { :remaining => length }, :complete_message => complete_message do |remaining|
+ progress(
+ (0..length).to_a.reverse,
+ :format => format_message,
+ :tokens => { :remaining => length },
+ :complete_message => complete_message
+ ) do |remaining|
if remaining == length / 2
- notify_info "#{remaining} minutes remaining, half way there!"
+ notifier.notify "Half way there!", :header => "#{remaining} minutes remaining"
elsif remaining == 5
- notify_info "5 minutes remaining"
+ notifier.notify "Almost there!", :header => "5 minutes remaining"
end
sleep 60
{ :remaining => remaining }
end
- @complete = true
- notify_warning complete_message
+
+ notifier.notify "Hope you are finished #{self}", :header => "Time is up!", :type => :warning
+
+ list = Pomo::List.new
+ if task = list.running
+ task.running = false
+ task.complete = true
+ list.save
+ end
end
-
+
+ def background_progress(config)
+ notifier = Pomo::Notifier.new(config)
+
+ pid = Process.fork do
+ length.downto(1) do |remaining|
+ write_pomo_stat(remaining) if config.pomo_stat
+ refresh_tmux_status_bar if config.tmux
+ if remaining == length / 2
+ notifier.notify "Half way there!", :header => "#{remaining} minutes remaining"
+ elsif remaining == 5
+ notifier.notify "Almost there!", :header => "5 minutes remaining"
+ end
+ sleep 60
+ end
+
+ write_pomo_stat(0) if config.pomo_stat
+ refresh_tmux_status_bar if config.tmux
+ notifier.notify "Hope you are finished #{self}", :header => "Time is up!", :type => :warning
+
+ list = Pomo::List.new
+ if task = list.running
+ task.running = false
+ task.complete = true
+ list.save
+ end
+ end
+
+ Process.detach(pid)
+ end
+
+ def write_pomo_stat(time)
+ path = File.join(ENV['HOME'],'.pomo_stat')
+ File.open(path, 'w') {|file| file.write "#{time}:00" }
+ end
+
+ def refresh_tmux_status_bar
+ pid = Process.fork do
+ exec "tmux refresh-client -S -t $(tmux list-clients -F '\#{client_tty}')"
+ end
+ Process.detach(pid)
+ end
+
end
-end
+end
View
4 lib/pomo/version.rb
@@ -1,4 +1,4 @@
module Pomo
- VERSION = '1.0.1'
-end
+ VERSION = '2.0.0'
+end
View
55 pomo.gemspec
@@ -1,38 +1,29 @@
# -*- encoding: utf-8 -*-
+lib = File.expand_path('../lib', __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+require 'pomo/version'
-Gem::Specification.new do |s|
- s.name = %q{pomo}
- s.version = "1.0.1"
+Gem::Specification.new do |gem|
+ gem.name = "pomo"
+ gem.version = Pomo::VERSION
+ gem.authors = ["TJ Holowaychuk"]
+ gem.email = ["tj@vision-media.ca"]
+ gem.summary = "pomo-#{Pomo::VERSION}"
+ gem.description = "Pomodoro time management for the command-line"
+ gem.homepage = "http://github.com/visionmedia/pomo"
- s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
- s.authors = ["TJ Holowaychuk"]
- s.date = %q{2010-03-10}
- s.default_executable = %q{pomo}
- s.description = %q{Pomodoro time management for the command-line}
- s.email = %q{tj@vision-media.ca}
- s.executables = ["pomo"]
- s.extra_rdoc_files = ["bin/pomo", "lib/pomo.rb", "lib/pomo/github_task.rb", "lib/pomo/list.rb", "lib/pomo/task.rb", "lib/pomo/version.rb", "tasks/docs.rake", "tasks/gemspec.rake", "tasks/spec.rake"]
- s.files = ["History.md", "Manifest", "Rakefile", "Readme.md", "bin/pomo", "lib/pomo.rb", "lib/pomo/github_task.rb", "lib/pomo/list.rb", "lib/pomo/task.rb", "lib/pomo/version.rb", "pomo.gemspec", "spec/pomo_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/docs.rake", "tasks/gemspec.rake", "tasks/spec.rake"]
- s.homepage = %q{http://github.com/visionmedia/pomo}
- s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Pomo", "--main", "Readme.md"]
- s.require_paths = ["lib"]
- s.rubyforge_project = %q{pomo}
- s.rubygems_version = %q{1.3.6}
- s.summary = %q{Pomodoro time management for the command-line}
+ gem.rubyforge_project = "pomo"
- if s.respond_to? :specification_version then
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
- s.specification_version = 3
+ gem.files = `git ls-files`.split($/)
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
+ gem.require_paths = ["lib"]
+ gem.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Pomo", "--main", "Readme.md"]
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
- s.add_runtime_dependency(%q<commander>, [">= 4.0.2"])
- s.add_runtime_dependency(%q<growl>, [">= 1.0.3"])
- else
- s.add_dependency(%q<commander>, [">= 4.0.2"])
- s.add_dependency(%q<growl>, [">= 1.0.3"])
- end
- else
- s.add_dependency(%q<commander>, [">= 4.0.2"])
- s.add_dependency(%q<growl>, [">= 1.0.3"])
- end
+ gem.add_dependency("commander", [">= 4.1.2"])
+ gem.add_dependency("terminal-notifier", [">= 1.4.2"]) if /darwin/ =~ RUBY_PLATFORM
+ gem.add_dependency("growl", [">= 1.0.3"]) if /darwin/ =~ RUBY_PLATFORM
+ gem.add_dependency("libnotify", [">= 0.8.0"]) if /linux/ =~ RUBY_PLATFORM
+
+ gem.add_development_dependency("rspec", "~> 2.12")
end
View
2  spec/spec.opts
@@ -1,2 +0,0 @@
---color
---format specdoc
View
13 tasks/docs.rake
@@ -1,13 +0,0 @@
-
-namespace :docs do
-
- desc 'Remove rdoc products'
- task :remove => [:clobber_docs]
-
- desc 'Build docs, and open in browser for viewing (specify BROWSER)'
- task :open do
- browser = ENV["BROWSER"] || "safari"
- sh "open -a #{browser} doc/index.html"
- end
-
-end
View
3  tasks/gemspec.rake
@@ -1,3 +0,0 @@
-
-desc 'Build gemspec file'
-task :gemspec => [:build_gemspec]
View
25 tasks/spec.rake
@@ -1,25 +0,0 @@
-
-require 'spec/rake/spectask'
-
-desc "Run all specifications"
-Spec::Rake::SpecTask.new(:spec) do |t|
- t.libs << "lib"
- t.spec_opts = ["--color", "--require", "spec/spec_helper.rb"]
-end
-
-namespace :spec do
-
- desc "Run all specifications verbosely"
- Spec::Rake::SpecTask.new(:verbose) do |t|
- t.libs << "lib"
- t.spec_opts = ["--color", "--format", "specdoc", "--require", "spec/spec_helper.rb"]
- end
-
- desc "Run specific specification verbosely (specify SPEC)"
- Spec::Rake::SpecTask.new(:select) do |t|
- t.libs << "lib"
- t.spec_files = [ENV["SPEC"]]
- t.spec_opts = ["--color", "--format", "specdoc", "--require", "spec/spec_helper.rb"]
- end
-
-end
Something went wrong with that request. Please try again.