Skip to content

Commit 3f3990f

Browse files
committed
Merge pull request #12 from expez/keyboard
Add support for keyboard events
2 parents 5d44c8b + ba6ae36 commit 3f3990f

13 files changed

+142
-12
lines changed

.rvmrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
77
# Only full ruby name is supported here, for short names use:
88
# echo "rvm use 1.9.3" > .rvmrc
9-
environment_id="rbx-head@hatter"
9+
environment_id="ruby-head@hatter"
1010

1111
# Uncomment the following lines if you want to verify rvm version per project
1212
# rvmrc_rvm_version="1.18.3 (stable)" # 1.10.1 seams as a safe start

Gemfile

+2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ source 'http://rubygems.org'
22

33
group :development, :test do
44
gem 'rspec'
5+
gem 'rspec-spies'
56
gem 'pry'
7+
gem 'pry-doc'
68
gem 'rake'
79
gem 'mail'
810
gem 'rb_termbox'

Gemfile.lock

+8
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ GEM
3131
method_source (~> 0.8)
3232
slop (~> 3.4)
3333
win32console (~> 1.3)
34+
pry-doc (0.4.4)
35+
pry (>= 0.9.9.6)
36+
yard (~> 0.8.1)
3437
rake (10.0.3)
3538
rb_termbox (0.1.0)
3639
ffi
@@ -43,11 +46,14 @@ GEM
4346
rspec-expectations (2.12.1)
4447
diff-lcs (~> 1.1.3)
4548
rspec-mocks (2.12.2)
49+
rspec-spies (2.1.3)
50+
rspec (~> 2.0)
4651
slop (3.4.3)
4752
treetop (1.4.12)
4853
polyglot
4954
polyglot (>= 0.3.1)
5055
win32console (1.3.2-x86-mingw32)
56+
yard (0.8.5.2)
5157

5258
PLATFORMS
5359
ruby
@@ -58,6 +64,8 @@ DEPENDENCIES
5864
configtoolkit
5965
mail
6066
pry
67+
pry-doc
6168
rake
6269
rb_termbox
6370
rspec
71+
rspec-spies

lib/command_factory.rb

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class CommandFactory
2+
3+
def initialize(terminal)
4+
@terminal = terminal
5+
commands = File.join(File.dirname(__FILE__), "commands") + "/*"
6+
Dir[commands].each { |file| eval "require '#{file}'" }
7+
end
8+
9+
# Instantiates the command object corresponding to `key`.
10+
# @param key [Symbol] the key the user pressed on the keyboard.
11+
# @return [Command] the command the user wishes to execute.
12+
def command(key)
13+
case key
14+
when :q
15+
QuitCommand.new(@terminal)
16+
else
17+
NoOpCommand.new
18+
end
19+
end
20+
21+
end

lib/commands/no_op.rb

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class NoOpCommand
2+
3+
def execute
4+
end
5+
6+
def unexecute
7+
end
8+
9+
end

lib/commands/quit.rb

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
require 'terminal'
2+
3+
class QuitCommand
4+
5+
def initialize terminal
6+
@terminal = terminal
7+
end
8+
9+
def execute
10+
@terminal.shutdown
11+
end
12+
13+
def unexecute
14+
end
15+
end

lib/configuration.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ def initialize(config_file = CONFIG_FILE)
1414
end
1515

1616
class Colors < ConfigToolkit::BaseConfig
17-
add_required_param(:foreground, String)
18-
add_required_param(:background, String)
17+
add_required_param(:foreground, String)
18+
add_required_param(:background, String)
1919
end
2020

2121
add_required_param(:maildir, String)

lib/hatter.rb

+14-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
require 'terminal'
2+
require 'command_factory'
23

3-
terminal = Terminal.new
4-
begin
5-
terminal.draw
6-
sleep(10)
7-
ensure
8-
terminal.shutdown
4+
unless ENV["HEADLESS"]
5+
begin
6+
terminal = Terminal.new
7+
command_factory = CommandFactory.new terminal
8+
while true do
9+
terminal.draw
10+
key = terminal.get_user_input
11+
cmd = command_factory.cmd key
12+
cmd.execute
13+
end
14+
rescue
15+
terminal.shutdown
16+
end
917
end

lib/terminal.rb

+14
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,24 @@ def initialize
1515
initialize_views
1616
end
1717

18+
# Updates the terminal view by redrawing all currently active views.
1819
def draw
1920
Termbox.tb_clear
2021
@views.each {|view| view.draw}
2122
Termbox.tb_present
2223
end
2324

25+
# Shuts off the terminal in a safe manner and then exits the ruby process.
2426
def shutdown
2527
Termbox.tb_shutdown
28+
exit
29+
end
30+
31+
# Blocks until the user presses a key
32+
# @return [Symbol] the key pressed as a symbol
33+
def get_user_input
34+
Termbox.tb_poll_event(@event)
35+
ascii_to_symbol @event[:ch]
2636
end
2737

2838
private
@@ -36,6 +46,10 @@ def initialize_views
3646
FolderView.new(folder_view_location)]
3747
end
3848

49+
def ascii_to_symbol(i)
50+
i.chr.to_sym
51+
end
52+
3953
def initialize_termbox
4054
libtermbox_path = Configuration.instance.termbox_library_path
4155
Termbox.initialize_library libtermbox_path

spec/command_factory_spec.rb

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
require 'spec_helper'
2+
3+
describe CommandFactory do
4+
5+
subject(:factory) { CommandFactory.new nil }
6+
let(:command) { factory.command(:foo) }
7+
8+
context "creates commands which:" do
9+
subject { command }
10+
it_behaves_like "a command"
11+
end
12+
13+
let(:key) { :q }
14+
15+
describe "instantiates commands matching the user's input." do
16+
context "the returned command" do
17+
subject { factory.command(key) }
18+
it { should be_a(QuitCommand) }
19+
end
20+
end
21+
end

spec/commands/quit_spec.rb

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
require 'spec_helper'
2+
3+
describe QuitCommand do
4+
5+
6+
let(:terminal) { double('terminal', shutdown: true ) }
7+
let(:command) { QuitCommand.new terminal }
8+
9+
subject{ command }
10+
it_behaves_like "a command"
11+
12+
describe "after #execute" do
13+
context "the terminal" do
14+
before { command.execute }
15+
subject { terminal }
16+
17+
it { should have_received :shutdown }
18+
end
19+
end
20+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
shared_examples "a command" do
2+
3+
it { should respond_to :execute }
4+
it { should respond_to :unexecute }
5+
6+
end

spec/spec_helper.rb

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
require 'rspec'
2+
require 'rspec-spies'
23

3-
require './lib/hatter.rb'
4-
require './lib/configuration.rb'
5-
require './lib/views/view.rb'
4+
ENV["HEADLESS"] = "ya, don't GUI for testing."
5+
6+
require './lib/hatter'
7+
require './lib/configuration'
8+
require './lib/views/view'
9+
require './lib/command_factory'
10+
require './lib/commands/quit'
11+
require './spec/commands/shared_examples_for_commands'

0 commit comments

Comments
 (0)