Skip to content

Commit

Permalink
import matthewd's keylog parser + specs... ftw!
Browse files Browse the repository at this point in the history
  • Loading branch information
igrigorik committed Dec 31, 2010
1 parent d48b34b commit 025bda1
Show file tree
Hide file tree
Showing 11 changed files with 131 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
vimgolf (0.1.1)
vimgolf (0.1.3)
highline
json
thor (>= 0.14.6)
Expand Down
2 changes: 2 additions & 0 deletions lib/vimgolf.rb
@@ -1,9 +1,11 @@
require 'fileutils'
require 'net/http'
require 'strscan'
require 'json'
require 'thor'

require 'vimgolf/version'
require 'vimgolf/config'
require 'vimgolf/keylog'
require 'vimgolf/cli'
require 'vimgolf/ui'
4 changes: 2 additions & 2 deletions lib/vimgolf/cli.rb
Expand Up @@ -85,7 +85,7 @@ def put(id = nil)
return
end

score = File.size(log(id))
score = Keylog.score(IO.read(log(id)))
VimGolf.ui.info "Success! Your output matches. Your score: #{score}"

if VimGolf.ui.yes? "Upload result to VimGolf? (yes / no)"
Expand Down Expand Up @@ -197,4 +197,4 @@ def debug(msg)
p [caller.first, msg] if GOLFDEBUG
end
end
end
end
105 changes: 105 additions & 0 deletions lib/vimgolf/keylog.rb
@@ -0,0 +1,105 @@
module VimGolf
class Session < Array
def to_s(sep = '')
@log.join(sep)
end
end

class Keylog
def self.parse(input)
session = Session.new
scan(input) {|s| session << s }
session
end

def self.convert(input)
parse(input).join('')
end

def self.score(input)
keys = 0
scan(input) {|s| keys += 1 }
keys
end

def self.scan(input)
scanner = StringScanner.new(input)
output = ""

until scanner.eos?
c = scanner.get_byte
n = c.unpack('C').first

out_char = \
case n

# Special platform-independent encoding stuff
when 0x80
code = scanner.get_byte + scanner.get_byte

# This list has been populated by experimentation so far,
# because I haven't bothered looking for a more authoritative
# source.
case code
when "k1"; "<F1>"
when "k2"; "<F2>"
when "k3"; "<F3>"
when "k4"; "<F4>"
when "k5"; "<F5>"
when "k6"; "<F6>"
when "k7"; "<F7>"
when "k8"; "<F8>"
when "k9"; "<F9>"
when "k;"; "<F10>"
when "F1"; "<F11>"
when "F2"; "<F12>"

when "kP"; "<PageUp>"
when "kN"; "<PageDown>"
when "kh"; "<Home>"
when "@7"; "<End>"
when "kI"; "<Insert>"
when "kD"; "<Del>"
when "kb"; "<BS>"

when "ku"; "<Up>"
when "kd"; "<Down>"
when "kl"; "<Left>"
when "kr"; "<Right>"
when "#4"; "<S-Left>"
when "%i"; "<S-Right>"

when "kB"; "<S-Tab>"
when "\xffX"; "<C-Space>"

else
#puts "Unknown Vim code: #{code.inspect}"
'<%02x-%02x>' % code.unpack('CC')
end

# Control characters with special names
when 0; "<Nul>"
when 9; "<Tab>"
when 10; "<NL>"
when 13; "<CR>"
when 27; "<Esc>"

when 127; "<Del>"

# Otherwise, use <C-x> format
when 0..31; "<C-#{(n + 64).chr}>"

# The rest of ANSI is printable
when 32..126; c

else
#puts "Unexpected extended ASCII: #{'%#04x' % n}"
'<%#04x>' % n

end

yield out_char
end
end
end
end
2 changes: 1 addition & 1 deletion spec/cli_spec.rb
Expand Up @@ -30,7 +30,7 @@
end

it "should return type of challenge on success" do
c.download('4d1a21e88ae121365c00000e').should == "rb"
c.download('4d1a1c36567bac34a9000002').should == "rb"
end

it "should raise error on invalid upload id" do
Expand Down
1 change: 1 addition & 0 deletions spec/fixtures/4d19832d8ae121365c00000b.log
@@ -0,0 +1 @@
��5ibbb�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kb�kb�kb�kb�kb�kb�kb�kb�kb�kb�kb�kb�kb�kb�kb�kb�kb�kb:wq
1 change: 1 addition & 0 deletions spec/fixtures/4d1a1c36567bac34a9000002.log
@@ -0,0 +1 @@
�kdd3di�kb�kb�kd�kr�kr�kb�kb �kd�kl�kb�ku�kr�kb�ku�kl�kr�kr�kb�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr*�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kl�kb�kb�kb�kb�kb�kb�kba�kd.join(',')�kr�krd$i�kr":wq
1 change: 1 addition & 0 deletions spec/fixtures/4d1a1c69567bac34a9000004.log
@@ -0,0 +1 @@
��5�kd�kd�kd�kdA "Vi IMproved"�kd�kd�kd�kdAa�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kli�kb�kb�kb�kb�kb�kb�kb�kb�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kroriginally �kd�kd�kdyyp�kddd:wq
1 change: 1 addition & 0 deletions spec/fixtures/4d1a21e88ae121365c00000e.log
@@ -0,0 +1 @@
��5�kdd3di�kb�kb�kd�kd�ku�ku�kb�ku�kr�kd�kd�kr�kb�kb�kd�kr�kb�ku�ku�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kl�kl*�kr�kr�kr�kr�kr�kr�kr�kb�kb�kb�kb�kb�kb�kd.join(',')�kr�krd$i"�kb�kr":wq
1 change: 1 addition & 0 deletions spec/fixtures/4d1a34ccfa85f32065000004.log
@@ -0,0 +1 @@
��5�kd�kd�kd�kdAi �kb�kb "Vi IMproved"�kd�kd�kd�kd�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kl�kr�kr�kr�kr�kr�kr originallyG�ku�ku�ku�kudwdw�kd�kd�kd�kd�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kr�kld$:wq
15 changes: 15 additions & 0 deletions spec/keylog_spec.rb
@@ -0,0 +1,15 @@
require "helper"

describe VimGolf::Keylog do
include VimGolf

Dir['spec/fixtures/*'].each do |f|
it "should parse #{f} logfile" do
lambda { Keylog.convert(IO.read(f)) }.should_not raise_error
end

it "should score #{f} logfile" do
lambda { Keylog.score(IO.read(f)) }.should_not raise_error
end
end
end

0 comments on commit 025bda1

Please sign in to comment.