lib/vimgolf/cli.rb in vimgolf-0.4.6 vs lib/vimgolf/cli.rb in vimgolf-0.4.7
- old
+ new
@@ -1,10 +1,9 @@
module VimGolf
GOLFDEBUG = ENV['GOLFDEBUG'].to_sym rescue false
GOLFHOST = ENV['GOLFHOST'] || "http://www.vimgolf.com"
- GOLFDIFF = ENV['GOLFDIFF'] || 'diff'
GOLFSHOWDIFF = ENV['GOLFSHOWDIFF'] || 'vim -d -n'
GOLFVIM = ENV['GOLFVIM'] || 'vim'
PROXY = ENV['http_proxy'] || ''
class Error
@@ -41,12 +40,17 @@
If you have the key, simply run the setup and paste in your key.
DESC
def setup
- key = VimGolf.ui.ask "Please specify your VimGolf API key (register on vimgolf.com to get it):"
+ VimGolf.ui.info "\nLet's setup your VimGolf key..."
+ VimGolf.ui.warn "1) Open vimgolf.com in your browser."
+ VimGolf.ui.warn "2) Click \"Sign in with Twitter\"."
+ VimGolf.ui.warn "3) Once signed in, copy your key (black box, top right)."
+ key = VimGolf.ui.ask "\nPaste your VimGolf key:"
+
if key =~ /[\w\d]{32}/
FileUtils.mkdir_p Config.path
FileUtils.mkdir_p Config.put_path
Config.save({'key' => key})
@@ -54,57 +58,86 @@
else
VimGolf.ui.error "Invalid key, please double check your key on vimgolf.com"
end
end
- desc "put [ID]", "launch Vim session"
+ desc "put CHALLENGE_ID", "launch vimgolf.com challenge"
long_desc <<-DESC
Launch a VimGolf session for the specified challenge ID. To find a currently
active challenge ID, please visit vimgolf.com!
DESC
- def put(id = nil)
+ def put(id)
+ FileUtils.mkdir_p Config.put_path
VimGolf.ui.warn "Downloading Vimgolf challenge: #{id}"
VimGolf::Challenge.path(Config.put_path)
challenge = Challenge.new(id)
challenge.download
+ play(challenge)
+ end
+
+ desc "local INFILE OUTFILE", "launch local challenge"
+ long_desc <<-DESC
+ Launch a local VimGolf challenge. A temporary copy of INFILE is made; the original files will not be touched.
+ DESC
+
+ def local(infile, outfile)
+ # make sure our files are sane
+ if !(File.file?(infile) and File.file?(outfile))
+ VimGolf.ui.error "INFILE and OUTFILE must exist and be regular files."
+ exit 1
+ end
+
+ challenge = Challenge.new(infile) # use the filename as id
+ challenge.local(infile, outfile)
+
+ play(challenge)
+ end
+
+ private
+
+ def play(challenge)
begin
- VimGolf.ui.warn "Launching VimGolf session for challenge: #{id}"
- # - n - no swap file, memory only editing
- # - +0 - always start on line 0
- # - --noplugin - don't load any plugins, lets be fair!
- # -i NONE - don't load .viminfo (for saved macros and the like)
- # - u - load vimgolf .vimrc to level the playing field
- vimcmd = "#{GOLFVIM} -Z -n --noplugin -i NONE +0 -u \"#{challenge.vimrc_path}\" -W \"#{challenge.log_path}\" \"#{challenge.work_path}\""
+ challenge.start
+ VimGolf.ui.warn "Launching VimGolf session for challenge: #{challenge.id}"
+ # -Z - restricted mode, utilities not allowed
+ # -n - no swap file, memory only editing
+ # --noplugin - don't load any plugins, lets be fair!
+ # --nofork - otherwise GOLFVIM=gvim forks and returns immediately
+ # -i NONE - don't load .viminfo (for saved macros and the like)
+ # +0 - always start on line 0
+ # -u vimrc - load vimgolf .vimrc to level the playing field
+ # -U NONE - don't load .gvimrc
+ # -W logfile - keylog file (overwrites if already exists)
+ vimcmd = GOLFVIM.shellsplit + %W{-Z -n --noplugin --nofork -i NONE +0 -u #{challenge.vimrc_path} -U NONE -W #{challenge.log_path} #{challenge.work_path}}
debug(vimcmd)
- system(vimcmd)
+ system(*vimcmd) # assembled as an array, bypasses the shell
if $?.exitstatus.zero?
- diff_files = "\"#{challenge.work_path}\" \"#{challenge.output_path}\""
- diff = `#{GOLFDIFF} #{diff_files}`
log = Keylog.new(IO.read(challenge.log_path))
+ VimGolf.ui.info "\nHere are your keystrokes:"
+ VimGolf.ui.print_log log
+
# Handle incorrect solutions
- if diff.size > 0
+ if !challenge.correct?()
VimGolf.ui.error "\nUh oh, looks like your entry does not match the desired output."
VimGolf.ui.error "Your score for this failed attempt was: #{log.score}"
-
loop do
VimGolf.ui.warn "[d] Show diff"
VimGolf.ui.warn "[r] Retry the current challenge"
VimGolf.ui.warn "[q] Quit vimgolf"
case VimGolf.ui.ask_question "Choice> ",
:type => :warn,
:choices => [:diff, :retry, :quit]
when :diff
VimGolf.ui.warn "Showing vimdiff of your attempt (left) and correct output (right)"
- system("#{GOLFSHOWDIFF} #{diff_files}")
+ system(*GOLFSHOWDIFF.shellsplit + [challenge.work_path, challenge.output_path])
when :retry
VimGolf.ui.warn "Retrying current challenge..."
- challenge.start
raise RetryException
when :quit
raise Interrupt
end
end
@@ -112,36 +145,45 @@
# Handle correct solutions
VimGolf.ui.info "\nSuccess! Your output matches. Your score: #{log.score}"
loop do
- VimGolf.ui.warn "[w] Upload result and retry the challenge"
- VimGolf.ui.warn "[x] Upload result and quit"
+ choices = []
+ begin
+ Config.load # raises error if user hasn't finished setup
+ choices = [:w, :x]
+ VimGolf.ui.warn "[w] Upload result and retry the challenge"
+ VimGolf.ui.warn "[x] Upload result and quit"
+ rescue
+ choices = [:setup]
+ VimGolf.ui.warn "[s] Set up vimgolf.com key to submit result"
+ end if challenge.remote
VimGolf.ui.warn "[r] Do not upload result and retry the challenge"
VimGolf.ui.warn "[q] Do not upload result and quit"
case VimGolf.ui.ask_question "Choice> ",
:type => :warn,
- :choices => [:w, :x, :retry, :quit]
+ :choices => choices + [:retry, :quit]
when :w
next unless upload?(challenge)
- challenge.start
raise RetryException
when :x
next unless upload?(challenge)
raise Interrupt
+ when :setup
+ setup
+ next # we can hopefully submit this time
when :retry
- challenge.start
raise RetryException
when :quit
raise Interrupt
end
end
else
error = <<-MSG
- Uh oh, Vim did not exit properly.
+ Uh oh, Vim did not exit properly.
Please ensure you can execute 'Vim' from the commandline.
If the problem persists, please report the error on github.com/igrigorik/vimgolf
MSG
VimGolf.ui.error error
@@ -155,11 +197,9 @@
VimGolf.ui.info "\nThanks for playing!"
rescue RuntimeError, Exception => e
VimGolf.ui.error "Uh oh, something went wrong! Error: #{e}"
VimGolf.ui.error "If the error persists, please report it to github.com/igrigorik/vimgolf"
end
-
- private
def upload?(challenge)
VimGolf.ui.warn "Uploading to VimGolf..."
if challenge.upload == :ok