vimgolf 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/vimgolf.rb CHANGED
@@ -7,5 +7,6 @@ require 'thor'
7
7
  require 'vimgolf/version'
8
8
  require 'vimgolf/config'
9
9
  require 'vimgolf/keylog'
10
+ require 'vimgolf/challenge'
10
11
  require 'vimgolf/cli'
11
- require 'vimgolf/ui'
12
+ require 'vimgolf/ui'
@@ -0,0 +1,108 @@
1
+ module VimGolf
2
+ class Challenge
3
+ attr_reader :id, :type
4
+
5
+ def self.path(path)
6
+ @@path = path if path
7
+ @@path
8
+ end
9
+
10
+ def initialize(id)
11
+ @id = id
12
+ end
13
+
14
+ def download
15
+ begin
16
+ url = URI.parse("#{GOLFHOST}/challenges/#{@id}.yaml")
17
+ req = Net::HTTP::Get.new(url.path)
18
+
19
+ proxy_url, proxy_user, proxy_pass = get_proxy
20
+ proxy = Net::HTTP::Proxy(proxy_url.host, proxy_url.port, proxy_user, proxy_pass)
21
+ res = proxy.start(url.host, url.port) { |http| http.request(req) }
22
+
23
+ @data = YAML.load(res.body)
24
+
25
+ if !@data.is_a? Hash
26
+ raise
27
+
28
+ elsif @data['client'] != Vimgolf::VERSION
29
+ VimGolf.ui.error "Client version mismatch. Installed: #{Vimgolf::VERSION}, Required: #{@data['client']}."
30
+ VimGolf.ui.error "\t gem install vimgolf"
31
+ raise "Bad Version"
32
+ end
33
+
34
+ @type = @data['in']['type']
35
+ save
36
+ start
37
+ rescue Exception => e
38
+ debug(e)
39
+ raise "Uh oh, couldn't download or parse challenge, please verify your challenge id & client version."
40
+ end
41
+ end
42
+
43
+ def start
44
+ File.open(work_path, "w") {|f| f.puts @data['in']['data']}
45
+ end
46
+
47
+ def save
48
+ File.open(input_path, "w") {|f| f.puts @data['in']['data']}
49
+ File.open(output_path, "w") {|f| f.puts @data['out']['data']}
50
+ File.open(vimrc_path, "w") {|f| f.puts @data['vimrc']}
51
+ end
52
+
53
+ def upload
54
+ begin
55
+ url = URI.parse("#{GOLFHOST}/entry.yaml")
56
+
57
+ proxy_url, proxy_user, proxy_pass = get_proxy
58
+ proxy = Net::HTTP::Proxy(proxy_url.host, proxy_url.port, proxy_user, proxy_pass)
59
+
60
+ proxy.start(url.host, url.port) do |http|
61
+ request = Net::HTTP::Post.new(url.request_uri)
62
+ request.set_form_data({"challenge_id" => @id, "apikey" => Config.load['key'], "entry" => IO.read(log_path)})
63
+ request["Accept"] = "text/yaml"
64
+
65
+ res = http.request(request)
66
+ res = YAML.load(res.body)
67
+
68
+ raise if !res.is_a? Hash
69
+ res['status'].to_sym
70
+
71
+ end
72
+ rescue Exception => e
73
+ debug(e)
74
+ raise "Uh oh, entry upload has failed, please check your key."
75
+ end
76
+ end
77
+
78
+ def input_path; path + ".#{@type}"; end
79
+ def work_path; path + ".work.#{@type}"; end
80
+ def output_path; path + ".output"; end
81
+ def log_path; path + ".log"; end
82
+ def vimrc_path; path + ".golfrc"; end
83
+
84
+ def path
85
+ @@path + "/#{@id}"
86
+ end
87
+
88
+ private
89
+ def get_proxy
90
+ begin
91
+ proxy_url = URI.parse(PROXY)
92
+ rescue Exception => e
93
+ VimGolf.ui.error "Invalid proxy uri in http_proxy environment variable - will try to run with out proxy"
94
+ proxy_url = URI.parse("");
95
+ end
96
+
97
+ proxy_url.port ||= 80
98
+ proxy_user, proxy_pass = proxy_url.userinfo.split(/:/) if proxy_url.userinfo
99
+
100
+ return proxy_url, proxy_user, proxy_pass
101
+ end
102
+
103
+ def debug(msg)
104
+ p [caller.first, msg] if GOLFDEBUG
105
+ end
106
+
107
+ end
108
+ end
data/lib/vimgolf/cli.rb CHANGED
@@ -1,14 +1,17 @@
1
1
  module VimGolf
2
2
 
3
- GOLFHOST = ENV['GOLFHOST'] || "http://vimgolf.com"
4
- GOLFDEBUG = ENV['GOLFDEBUG'].to_sym rescue false
5
- GOLFDIFF = ENV['GOFLDIFF'] || 'diff'
6
- GOLFVIM = ENV['GOLFVIM'] || 'vim'
7
- PROXY = ENV['http_proxy'] || ''
3
+ GOLFDEBUG = ENV['GOLFDEBUG'].to_sym rescue false
4
+ GOLFHOST = ENV['GOLFHOST'] || "http://vimgolf.com"
5
+ GOLFDIFF = ENV['GOLFDIFF'] || 'diff'
6
+ GOLFSHOWDIFF = ENV['GOLFSHOWDIFF'] || 'vim -d -n'
7
+ GOLFVIM = ENV['GOLFVIM'] || 'vim'
8
+ PROXY = ENV['http_proxy'] || ''
8
9
 
9
10
  class Error
10
11
  end
11
12
 
13
+ class RetryException < Exception; end
14
+
12
15
  class UI
13
16
  def debug(*); end
14
17
  end
@@ -60,39 +63,53 @@ module VimGolf
60
63
  DESC
61
64
 
62
65
  def put(id = nil)
63
- VimGolf.ui.warn "Launching VimGolf session for challenge: #{id}"
66
+ VimGolf.ui.warn "Downloading Vimgolf challenge: #{id}"
67
+ VimGolf::Challenge.path(Config.put_path)
68
+ challenge = Challenge.new(id)
69
+ challenge.download
64
70
 
65
71
  begin
66
- type = download(id)
67
-
72
+ VimGolf.ui.warn "Launching VimGolf session for challenge: #{id}"
68
73
  # - n - no swap file, memory only editing
69
74
  # - +0 - always start on line 0
70
75
  # - --noplugin - don't load any plugins, lets be fair!
71
76
  # -i NONE - don't load .viminfo (for saved macros and the like)
72
77
  # - u - load vimgolf .vimrc to level the playing field
73
- vimcmd = "#{GOLFVIM} -n --noplugin -i NONE +0 -u \"#{vimrc(id)}\" -W \"#{log(id)}\" \"#{input(id, type)}\""
78
+ vimcmd = "#{GOLFVIM} -Z -n --noplugin -i NONE +0 -u \"#{vimrc(id)}\" -W \"#{log(id)}\" \"#{input(id, type)}\""
74
79
  debug(vimcmd)
75
80
  system(vimcmd)
76
81
 
77
82
  if $?.exitstatus.zero?
78
- diff = `#{GOLFDIFF} \"#{input(id, type)}\" \"#{output(id)}\"`
79
- score = Keylog.score(IO.read(log(id)))
83
+ diff_files = "\"#{challenge.work_path}\" \"#{challenge.output_path}\""
84
+ diff = `#{GOLFDIFF} #{diff_files}`
85
+ log = Keylog.new(IO.read(challenge.log_path))
80
86
 
81
87
  if diff.size > 0
82
- VimGolf.ui.warn "Uh oh, looks like your entry does not match the desired output:"
83
- VimGolf.ui.warn "#"*50
84
- puts diff
85
- VimGolf.ui.warn "#"*50
86
- VimGolf.ui.warn "Please try again! Your score for this (failed) attempt was: #{score}"
87
- return
88
+ VimGolf.ui.warn "Uh oh, looks like your entry does not match the desired output."
89
+ loop do
90
+ case VimGolf.ui.ask_question "Would you like to see a [d]iff or [r]etry or [q]uit ?",
91
+ :type => :warn,
92
+ :choices => [:diff, :retry, :quit]
93
+ when :diff
94
+ VimGolf.ui.warn "Showing vimdiff of your attempt (left) and correct output (right)"
95
+ system("#{GOLFSHOWDIFF} #{diff_files}")
96
+ when :retry
97
+ VimGolf.ui.warn "Your score for this (failed) attempt was: #{log.score}. Let's try again!!\n#{'#'*50}"
98
+ challenge.start
99
+ raise RetryException
100
+ when :quit
101
+ VimGolf.ui.warn "Please try again! Your score for this (failed) attempt was: #{log.score}"
102
+ return
103
+ end
104
+ end
88
105
  end
89
106
 
90
- VimGolf.ui.info "Success! Your output matches. Your score: #{score}"
107
+ VimGolf.ui.info "Success! Your output matches. Your score: #{log.score}"
91
108
 
92
109
  if VimGolf.ui.yes? "Upload result to VimGolf? (yes / no)"
93
110
  VimGolf.ui.warn "Uploading to VimGolf..."
94
111
 
95
- if upload(id) == :ok
112
+ if challenge.upload == :ok
96
113
  VimGolf.ui.info "Uploaded entry, thanks for golfing!"
97
114
  VimGolf.ui.info "View the leaderboard: #{GOLFHOST}/challenges/#{id}"
98
115
  else
@@ -112,97 +129,19 @@ module VimGolf
112
129
  VimGolf.ui.error error
113
130
  end
114
131
 
115
- rescue Exception => e
116
- VimGolf.ui.error "Uh oh, something went wrong! Error: #{e}"
117
- VimGolf.ui.error "If the error persists, please report it to github.com/igrigorik/vimgolf"
118
- end
119
- end
120
-
121
- no_tasks do
122
- def download(id)
123
- begin
124
- url = URI.parse("#{GOLFHOST}/challenges/#{id}.yaml")
125
- req = Net::HTTP::Get.new(url.path)
126
-
127
- proxy_url, proxy_user, proxy_pass = get_proxy
128
- proxy = Net::HTTP::Proxy(proxy_url.host, proxy_url.port, proxy_user, proxy_pass)
129
- res = proxy.start(url.host, url.port) { |http| http.request(req) }
130
-
131
- data = YAML.load(res.body)
132
-
133
- if !data.is_a? Hash
134
- raise
135
-
136
- elsif data['client'] != Vimgolf::VERSION
137
- VimGolf.ui.error "Client version mismatch. Installed: #{Vimgolf::VERSION}, Required: #{data['client']}."
138
- VimGolf.ui.error "\t gem install vimgolf"
139
- raise "Bad Version"
140
- end
141
-
142
- File.open(Config.put_path + "/#{id}.#{data['in']['type']}", "w") {|f| f.puts data['in']['data']}
143
- File.open(Config.put_path + "/#{id}.output", "w") {|f| f.puts data['out']['data']}
144
- File.open(Config.put_path + "/#{id}.golfrc", "w") {|f| f.puts data['vimrc']}
145
-
146
- data['in']['type']
147
-
148
- rescue Exception => e
149
- debug(e)
150
- raise "Uh oh, couldn't download or parse challenge, please verify your challenge id & client version."
151
- end
132
+ rescue RetryException => e
133
+ retry
152
134
  end
153
135
 
154
- def upload(id)
155
- begin
156
- url = URI.parse("#{GOLFHOST}/entry.yaml")
157
-
158
- proxy_url, proxy_user, proxy_pass = get_proxy
159
- proxy = Net::HTTP::Proxy(proxy_url.host, proxy_url.port, proxy_user, proxy_pass)
160
-
161
- proxy.start(url.host, url.port) do |http|
162
- request = Net::HTTP::Post.new(url.request_uri)
163
- request.set_form_data({"challenge_id" => id, "apikey" => Config.load['key'], "entry" => IO.read(log(id))})
164
- request["Accept"] = "text/yaml"
165
-
166
- res = http.request(request)
167
- res = YAML.load(res.body)
168
-
169
- raise if !res.is_a? Hash
170
- res['status'].to_sym
171
-
172
- end
173
- rescue Exception => e
174
- debug(e)
175
- raise "Uh oh, entry upload has failed, please check your key."
176
- end
177
- end
136
+ rescue Exception => e
137
+ VimGolf.ui.error "Uh oh, something went wrong! Error: #{e}"
138
+ VimGolf.ui.error "If the error persists, please report it to github.com/igrigorik/vimgolf"
178
139
  end
179
140
 
180
141
  private
181
- def input(id, type); challenge(id) + ".#{type}"; end
182
- def output(id); challenge(id) + ".output"; end
183
- def log(id); challenge(id) + ".log"; end
184
- def vimrc(id); challenge(id) + ".golfrc"; end
185
-
186
- def challenge(id)
187
- Config.put_path + "/#{id}"
188
- end
189
-
190
- def get_proxy
191
- begin
192
- proxy_url = URI.parse(PROXY)
193
- rescue Exception => e
194
- VimGolf.ui.error "Invalid proxy uri in http_proxy environment variable - will try to run with out proxy"
195
- proxy_url = URI.parse("");
196
- end
197
-
198
- proxy_url.port ||= 80
199
- proxy_user, proxy_pass = proxy_url.userinfo.split(/:/) if proxy_url.userinfo
200
-
201
- return proxy_url, proxy_user, proxy_pass
202
- end
203
-
204
142
  def debug(msg)
205
143
  p [caller.first, msg] if GOLFDEBUG
206
144
  end
207
145
  end
208
- end
146
+
147
+ end
@@ -1,29 +1,20 @@
1
1
  module VimGolf
2
- class Session < Array
3
- def to_s(sep = '')
4
- @log.join(sep)
5
- end
6
- end
7
-
8
2
  class Keylog
9
- def self.parse(input)
10
- session = Session.new
11
- scan(input) {|s| session << s }
12
- session
13
- end
3
+ include Enumerable
4
+
5
+ alias_method :convert , :to_s
6
+ alias_method :score , :count
14
7
 
15
- def self.convert(input)
16
- parse(input).join('')
8
+ def initialize(input)
9
+ @input = input
17
10
  end
18
11
 
19
- def self.score(input)
20
- keys = 0
21
- scan(input) {|s| keys += 1 }
22
- keys
12
+ def to_s(sep = '')
13
+ to_a.join(sep)
23
14
  end
24
15
 
25
- def self.scan(input)
26
- scanner = StringScanner.new(input)
16
+ def each
17
+ scanner = StringScanner.new(@input)
27
18
  output = ""
28
19
 
29
20
  until scanner.eos?
@@ -37,9 +28,9 @@ module VimGolf
37
28
  when 0x80
38
29
  code = scanner.get_byte + scanner.get_byte
39
30
 
40
- # This list has been populated by experimentation so far,
41
- # because I haven't bothered looking for a more authoritative
42
- # source.
31
+ # This list has been populated by looking at
32
+ # :h terminal-options and vim source files:
33
+ # keymap.h and misc2.c
43
34
  case code
44
35
  when "k1"; "<F1>"
45
36
  when "k2"; "<F2>"
@@ -53,6 +44,38 @@ module VimGolf
53
44
  when "k;"; "<F10>"
54
45
  when "F1"; "<F11>"
55
46
  when "F2"; "<F12>"
47
+ when "F3"; "<F13>"
48
+ when "F4"; "<F14>"
49
+ when "F5"; "<F15>"
50
+ when "F6"; "<F16>"
51
+ when "F7"; "<F17>"
52
+ when "F8"; "<F18>"
53
+ when "F9"; "<F19>"
54
+
55
+ when "%1"; "<Help>"
56
+ when "&8"; "<Undo>"
57
+ when "#2"; "<S-Home>"
58
+ when "*7"; "<S-End>"
59
+ when "K1"; "<kHome>"
60
+ when "K4"; "<kEnd>"
61
+ when "K3"; "<kPageUp>"
62
+ when "K5"; "<kPageDown>"
63
+ when "K6"; "<kPlus>"
64
+ when "K7"; "<kMinus>"
65
+ when "K8"; "<kDivide>"
66
+ when "K9"; "<kMultiply>"
67
+ when "KA"; "<kEnter>"
68
+ when "KB"; "<kPoint>"
69
+ when "KC"; "<k0>"
70
+ when "KD"; "<k1>"
71
+ when "KE"; "<k2>"
72
+ when "KF"; "<k3>"
73
+ when "KG"; "<k4>"
74
+ when "KH"; "<k5>"
75
+ when "KI"; "<k6>"
76
+ when "KJ"; "<k7>"
77
+ when "KK"; "<k8>"
78
+ when "KL"; "<k9>"
56
79
 
57
80
  when "kP"; "<PageUp>"
58
81
  when "kN"; "<PageDown>"
@@ -70,7 +93,104 @@ module VimGolf
70
93
  when "%i"; "<S-Right>"
71
94
 
72
95
  when "kB"; "<S-Tab>"
73
- when "\xffX"; "<C-Space>"
96
+ when "\xffX"; "<C-@>"
97
+
98
+ when "\xfd\x4"; "<S-Up>"
99
+ when "\xfd\x5"; "<S-Down>"
100
+ when "\xfd\x6"; "<S-F1>"
101
+ when "\xfd\x7"; "<S-F2>"
102
+ when "\xfd\x8"; "<S-F3>"
103
+ when "\xfd\x9"; "<S-F4>"
104
+ when "\xfd\xa"; "<S-F5>"
105
+ when "\xfd\xb"; "<S-F6>"
106
+ when "\xfd\xc"; "<S-F7>"
107
+ when "\xfd\xd"; "<S-F9>"
108
+ when "\xfd\xe"; "<S-F10>"
109
+ when "\xfd\xf"; "<S-F10>"
110
+ when "\xfd\x10"; "<S-F11>"
111
+ when "\xfd\x11"; "<S-F12>"
112
+ when "\xfd\x12"; "<S-F13>"
113
+ when "\xfd\x13"; "<S-F14>"
114
+ when "\xfd\x14"; "<S-F15>"
115
+ when "\xfd\x15"; "<S-F16>"
116
+ when "\xfd\x16"; "<S-F17>"
117
+ when "\xfd\x17"; "<S-F18>"
118
+ when "\xfd\x18"; "<S-F19>"
119
+ when "\xfd\x19"; "<S-F20>"
120
+ when "\xfd\x1a"; "<S-F21>"
121
+ when "\xfd\x1b"; "<S-F22>"
122
+ when "\xfd\x1c"; "<S-F23>"
123
+ when "\xfd\x1d"; "<S-F24>"
124
+ when "\xfd\x1e"; "<S-F25>"
125
+ when "\xfd\x1f"; "<S-F26>"
126
+ when "\xfd\x20"; "<S-F27>"
127
+ when "\xfd\x21"; "<S-F28>"
128
+ when "\xfd\x22"; "<S-F29>"
129
+ when "\xfd\x23"; "<S-F30>"
130
+ when "\xfd\x24"; "<S-F31>"
131
+ when "\xfd\x25"; "<S-F32>"
132
+ when "\xfd\x26"; "<S-F33>"
133
+ when "\xfd\x27"; "<S-F34>"
134
+ when "\xfd\x28"; "<S-F35>"
135
+ when "\xfd\x29"; "<S-F36>"
136
+ when "\xfd\x2a"; "<S-F37>"
137
+ when "\xfd\x2b"; "<Mouse>"
138
+ when "\xfd\x2c"; "<LeftMouse>"
139
+ when "\xfd\x2d"; "<LeftDrag>"
140
+ when "\xfd\x2e"; "<LeftRelease>"
141
+ when "\xfd\x2f"; "<MiddleMouse>"
142
+ when "\xfd\x30"; "<MiddleDrag>"
143
+ when "\xfd\x31"; "<MiddleRelease>"
144
+ when "\xfd\x32"; "<RightMouse>"
145
+ when "\xfd\x33"; "<RightDrag>"
146
+ when "\xfd\x34"; "<RightRelease>"
147
+ #when "\xfd\x35"; "KE_IGNORE"
148
+ #when "\xfd\x36"; "KE_TAB"
149
+ #when "\xfd\x37"; "KE_S_TAB_OLD"
150
+ #when "\xfd\x38"; "KE_SNIFF"
151
+ #when "\xfd\x39"; "KE_XF1"
152
+ #when "\xfd\x3a"; "KE_XF2"
153
+ #when "\xfd\x3b"; "KE_XF3"
154
+ #when "\xfd\x3c"; "KE_XF4"
155
+ #when "\xfd\x3d"; "KE_XEND"
156
+ #when "\xfd\x3e"; "KE_ZEND"
157
+ #when "\xfd\x3f"; "KE_XHOME"
158
+ #when "\xfd\x40"; "KE_ZHOME"
159
+ #when "\xfd\x41"; "KE_XUP"
160
+ #when "\xfd\x42"; "KE_XDOWN"
161
+ #when "\xfd\x43"; "KE_XLEFT"
162
+ #when "\xfd\x44"; "KE_XRIGHT"
163
+ #when "\xfd\x45"; "KE_LEFTMOUSE_NM"
164
+ #when "\xfd\x46"; "KE_LEFTRELEASE_NM"
165
+ #when "\xfd\x47"; "KE_S_XF1"
166
+ #when "\xfd\x48"; "KE_S_XF2"
167
+ #when "\xfd\x49"; "KE_S_XF3"
168
+ #when "\xfd\x4a"; "KE_S_XF4"
169
+ when "\xfd\x4b"; "<MouseDown>"
170
+ when "\xfd\x4c"; "<MouseUp>"
171
+ when "\xfd\x4d"; "<MouseLeft>"
172
+ when "\xfd\x4e"; "<MouseRight>"
173
+ #when "\xfd\x4f"; "KE_KINS"
174
+ #when "\xfd\x50"; "KE_KDEL"
175
+ #when "\xfd\x51"; "KE_CSI"
176
+ #when "\xfd\x52"; "KE_SNR"
177
+ #when "\xfd\x53"; "KE_PLUG"
178
+ #when "\xfd\x54"; "KE_CMDWIN"
179
+ when "\xfd\x55"; "<C-Left>"
180
+ when "\xfd\x56"; "<C-Right>"
181
+ when "\xfd\x57"; "<C-Home>"
182
+ when "\xfd\x58"; "<C-End>"
183
+ #when "\xfd\x59"; "KE_X1MOUSE"
184
+ #when "\xfd\x5a"; "KE_X1DRAG"
185
+ #when "\xfd\x5b"; "KE_X1RELEASE"
186
+ #when "\xfd\x5c"; "KE_X2MOUSE"
187
+ #when "\xfd\x5d"; "KE_X2DRAG"
188
+ #when "\xfd\x5e"; "KE_X2RELEASE"
189
+ #when "\xfd\x5f"; "KE_DROP"
190
+ #when "\xfd\x5e"; "KE_CURSORHOLD"
191
+ #when "\xfd\x61"; "KE_NOP"
192
+ when "\xfd\x62"; nil # Focus Gained (GVIM)
193
+ when "\xfd\x63"; nil # Focus Lost (GVIM)
74
194
 
75
195
  else
76
196
  #puts "Unknown Vim code: #{code.inspect}"
@@ -98,7 +218,7 @@ module VimGolf
98
218
 
99
219
  end
100
220
 
101
- yield out_char
221
+ yield out_char if out_char
102
222
  end
103
223
  end
104
224
  end