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/.gitignore +1 -0
- data/Gemfile.lock +13 -16
- data/Rakefile +8 -0
- data/emacs/README.md +69 -0
- data/emacs/ROADMAP.md +69 -0
- data/emacs/vimgolf.el +343 -0
- data/lib/vimgolf.rb +2 -1
- data/lib/vimgolf/challenge.rb +108 -0
- data/lib/vimgolf/cli.rb +43 -104
- data/lib/vimgolf/keylog.rb +144 -24
- data/lib/vimgolf/ui.rb +26 -10
- data/lib/vimgolf/version.rb +1 -1
- data/spec/challenge_spec.rb +31 -0
- data/spec/cli_spec.rb +1 -17
- data/spec/helper.rb +1 -1
- data/spec/keylog_spec.rb +4 -3
- data/vimgolf.gemspec +3 -2
- metadata +85 -89
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,33 +1,30 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
vimgolf (0.
|
4
|
+
vimgolf (0.4.0)
|
5
5
|
highline
|
6
|
-
json
|
7
6
|
thor (>= 0.14.6)
|
8
7
|
|
9
8
|
GEM
|
10
9
|
remote: http://rubygems.org/
|
11
10
|
specs:
|
12
|
-
diff-lcs (1.1.
|
13
|
-
highline (1.6.
|
14
|
-
|
15
|
-
rspec (2.
|
16
|
-
rspec-core (~> 2.
|
17
|
-
rspec-expectations (~> 2.
|
18
|
-
rspec-mocks (~> 2.
|
19
|
-
rspec-core (2.
|
20
|
-
rspec-expectations (2.
|
21
|
-
diff-lcs (~> 1.1.
|
22
|
-
rspec-mocks (2.
|
11
|
+
diff-lcs (1.1.3)
|
12
|
+
highline (1.6.11)
|
13
|
+
rake (0.9.2.2)
|
14
|
+
rspec (2.9.0)
|
15
|
+
rspec-core (~> 2.9.0)
|
16
|
+
rspec-expectations (~> 2.9.0)
|
17
|
+
rspec-mocks (~> 2.9.0)
|
18
|
+
rspec-core (2.9.0)
|
19
|
+
rspec-expectations (2.9.0)
|
20
|
+
diff-lcs (~> 1.1.3)
|
21
|
+
rspec-mocks (2.9.0)
|
23
22
|
thor (0.14.6)
|
24
23
|
|
25
24
|
PLATFORMS
|
26
25
|
ruby
|
27
26
|
|
28
27
|
DEPENDENCIES
|
29
|
-
|
30
|
-
json
|
28
|
+
rake
|
31
29
|
rspec
|
32
|
-
thor (>= 0.14.6)
|
33
30
|
vimgolf!
|
data/Rakefile
CHANGED
data/emacs/README.md
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# VimGolf Minor Mode Roadmap
|
2
|
+
|
3
|
+
## Features
|
4
|
+
|
5
|
+
1. Completing read of challenges by title rather than by challenge id
|
6
|
+
|
7
|
+
2. `M-x vimgolf-browse`: Dired/Ibuffer/Magit-like interface to VimGolf challenges.
|
8
|
+
|
9
|
+
Bindings:
|
10
|
+
|
11
|
+
- Bindings should mimic Dired/Ibuffer wherever possible. Magit is listed primarily because I want TAB to open up the long description of the challenge.
|
12
|
+
|
13
|
+
At least:
|
14
|
+
|
15
|
+
- n/p
|
16
|
+
- ENTER/o: launch `vimgolf` with the correct arg.
|
17
|
+
|
18
|
+
Interface Mockup:
|
19
|
+
|
20
|
+
VimGolf in Emacs! Compete on vimgolf with the One True Editor.
|
21
|
+
|
22
|
+
Sort entries based on date - Sort some entries in a Ledger-file based on date.
|
23
|
+
PHP Array Syntax -> MailChimp Merge Syntax - I recently needed to send an e-m...
|
24
|
+
Refactor to Helpers
|
25
|
+
This Rails partial is almost all template escapes. Put it into a helper,
|
26
|
+
and refactor each case to methods so we can build out the controls for
|
27
|
+
each. (I've converted to tabs - fighting with Vimgolf's default config
|
28
|
+
shouldn't be part of the challenge.)
|
29
|
+
|
30
|
+
Alphabetize the directory - Put the contacts and their information in alphabe...
|
31
|
+
PHP <--> Java class conversion Part 2 - Same class but reverse!
|
32
|
+
PHP <--> Java class conversion Part 1 - Convert this tiny php class to adequa...
|
33
|
+
Multiplication table. - Create a multiplication table.
|
34
|
+
Complete the hex array data (Part II) - Do not use external tools(e.g. tac, s...
|
35
|
+
Interweave two blocks of text - Suppose you've got data on a list of things f...
|
36
|
+
.
|
37
|
+
.
|
38
|
+
.
|
39
|
+
|
40
|
+
--------------------------------------------------------------------------------
|
41
|
+
|
42
|
+
Commentary:
|
43
|
+
|
44
|
+
- Tab has been pressed on the Refactor to Helpers line and thus it's been expanded.
|
45
|
+
|
46
|
+
- The challenges `formatted text to markdown` and `Line Zipper` have both been completed and thus are hidden. Could provide a customization setting that turns this off completely, as well as an `M-x vimgolf-show-all` function to toggle the hiding.
|
47
|
+
|
48
|
+
- Fill column has been set to 80
|
49
|
+
|
50
|
+
- It would be fun if a local cache of the vimgolf data could be kept together so that you could record solutions or at least play offline.
|
51
|
+
|
52
|
+
3. Real submission to vimgolf.
|
53
|
+
|
54
|
+
This could look like:
|
55
|
+
|
56
|
+
Pop-open buffer
|
57
|
+
|
58
|
+
You solved the formatted text to markdown challenge in 25 keystrokes! The best entry for this challenge was 23.
|
59
|
+
|
60
|
+
M-x qrr ;; query-replace-regexp
|
61
|
+
SPC*2 ;; self-insert-command
|
62
|
+
dummy ;; self-insert-command * 5
|
63
|
+
.
|
64
|
+
.
|
65
|
+
.
|
66
|
+
|
67
|
+
Mini-buffer
|
68
|
+
|
69
|
+
Submit to your solution to vimgolf? <y-or-n-predicate>
|
data/emacs/ROADMAP.md
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# VimGolf Minor Mode Roadmap
|
2
|
+
|
3
|
+
## Features
|
4
|
+
|
5
|
+
1. Completing read of challenges by title rather than by challenge id
|
6
|
+
|
7
|
+
2. `M-x vimgolf-browse`: Dired/Ibuffer/Magit-like interface to VimGolf challenges.
|
8
|
+
|
9
|
+
Bindings:
|
10
|
+
|
11
|
+
- Bindings should mimic Dired/Ibuffer wherever possible. Magit is listed primarily because I want TAB to open up the long description of the challenge.
|
12
|
+
|
13
|
+
At least:
|
14
|
+
|
15
|
+
- n/p
|
16
|
+
- ENTER/o: launch `vimgolf` with the correct arg.
|
17
|
+
|
18
|
+
Interface Mockup:
|
19
|
+
|
20
|
+
VimGolf in Emacs! Compete on vimgolf with the One True Editor.
|
21
|
+
|
22
|
+
Sort entries based on date - Sort some entries in a Ledger-file based on date.
|
23
|
+
PHP Array Syntax -> MailChimp Merge Syntax - I recently needed to send an e-m...
|
24
|
+
Refactor to Helpers
|
25
|
+
This Rails partial is almost all template escapes. Put it into a helper,
|
26
|
+
and refactor each case to methods so we can build out the controls for
|
27
|
+
each. (I've converted to tabs - fighting with Vimgolf's default config
|
28
|
+
shouldn't be part of the challenge.)
|
29
|
+
|
30
|
+
Alphabetize the directory - Put the contacts and their information in alphabe...
|
31
|
+
PHP <--> Java class conversion Part 2 - Same class but reverse!
|
32
|
+
PHP <--> Java class conversion Part 1 - Convert this tiny php class to adequa...
|
33
|
+
Multiplication table. - Create a multiplication table.
|
34
|
+
Complete the hex array data (Part II) - Do not use external tools(e.g. tac, s...
|
35
|
+
Interweave two blocks of text - Suppose you've got data on a list of things f...
|
36
|
+
.
|
37
|
+
.
|
38
|
+
.
|
39
|
+
|
40
|
+
--------------------------------------------------------------------------------
|
41
|
+
|
42
|
+
Commentary:
|
43
|
+
|
44
|
+
- Tab has been pressed on the Refactor to Helpers line and thus it's been expanded.
|
45
|
+
|
46
|
+
- The challenges `formatted text to markdown` and `Line Zipper` have both been completed and thus are hidden. Could provide a customization setting that turns this off completely, as well as an `M-x vimgolf-show-all` function to toggle the hiding.
|
47
|
+
|
48
|
+
- Fill column has been set to 80
|
49
|
+
|
50
|
+
- It would be fun if a local cache of the vimgolf data could be kept together so that you could record solutions or at least play offline.
|
51
|
+
|
52
|
+
3. Real submission to vimgolf.
|
53
|
+
|
54
|
+
This could look like:
|
55
|
+
|
56
|
+
Pop-open buffer
|
57
|
+
|
58
|
+
You solved the formatted text to markdown challenge in 25 keystrokes! The best entry for this challenge was 23.
|
59
|
+
|
60
|
+
M-x qrr ;; query-replace-regexp
|
61
|
+
SPC*2 ;; self-insert-command
|
62
|
+
dummy ;; self-insert-command * 5
|
63
|
+
.
|
64
|
+
.
|
65
|
+
.
|
66
|
+
|
67
|
+
Mini-buffer
|
68
|
+
|
69
|
+
Submit to your solution to vimgolf? <y-or-n-predicate>
|
data/emacs/vimgolf.el
ADDED
@@ -0,0 +1,343 @@
|
|
1
|
+
;;; vimgolf.el --- VimGolf interface for the One True Editor
|
2
|
+
|
3
|
+
;; Copyright (C) never, by no one
|
4
|
+
|
5
|
+
;;; Author: Tim Visher <tim.visher@gmail.com>
|
6
|
+
;;; Maintainer: Tim Visher <tim.visher@gmail.com>
|
7
|
+
;;; Created: 2011-11-02
|
8
|
+
;;; Version: 0.9.2
|
9
|
+
;;; Keywords: games vimgolf vim
|
10
|
+
|
11
|
+
;; This file is not part of GNU Emacs
|
12
|
+
|
13
|
+
;;; Commentary:
|
14
|
+
|
15
|
+
;; This is a simple package that allows Emacs users to compete on [VimGolf][1]
|
16
|
+
;; using the One True Editor. Competition can be commenced utilizing `M-x
|
17
|
+
;; vimgolf`. When finished with a challenge, `C-c C-v C-c` should finish your
|
18
|
+
;; editing, ensure correctness, and submit your score and keystrokes to
|
19
|
+
;; [VimGolf][1].
|
20
|
+
;;
|
21
|
+
;; On second thought, let's not go to Camelot. It's a silly place.
|
22
|
+
;;
|
23
|
+
;; Patches are accepted at https://github.com/timvisher/vimgolf
|
24
|
+
;;
|
25
|
+
;; [1]: http://vimgolf.com/
|
26
|
+
|
27
|
+
;;; Installation:
|
28
|
+
|
29
|
+
;; Use package.el. You'll need to add Marmalade to your archives:
|
30
|
+
|
31
|
+
;; (require 'package)
|
32
|
+
;; (add-to-list 'package-archives
|
33
|
+
;; '("marmalade" . "http://marmalade-repo.org/packages/"))
|
34
|
+
|
35
|
+
;; If you use a version of Emacs prior to 24 that doesn't include
|
36
|
+
;; package.el, you can get it from http://bit.ly/pkg-el23. If you have
|
37
|
+
;; an older package.el installed from tromey.com, you should upgrade
|
38
|
+
;; in order to support installation from multiple sources.
|
39
|
+
|
40
|
+
;;; License:
|
41
|
+
|
42
|
+
;; [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/)
|
43
|
+
|
44
|
+
;;; Contributors
|
45
|
+
|
46
|
+
;; Tim Visher (@timvisher)
|
47
|
+
;; Steve Purcell (@sanityinc)
|
48
|
+
;; Adam Collard (@acollard)
|
49
|
+
|
50
|
+
;;; Code:
|
51
|
+
|
52
|
+
(defgroup vimgolf nil
|
53
|
+
"Compete on VimGolf with the One True Editor."
|
54
|
+
:prefix "vimgolf-"
|
55
|
+
:group 'applications)
|
56
|
+
|
57
|
+
(defcustom vimgolf-key nil
|
58
|
+
"Your VimGolf API Key. Must be set in order to submit your solution."
|
59
|
+
:type 'string
|
60
|
+
:group 'vimgolf)
|
61
|
+
|
62
|
+
(defcustom vimgolf-mode-hook '((lambda () (whitespace-mode t)))
|
63
|
+
"A list of functions to call upon the initialization of vimgolf-mode."
|
64
|
+
:type 'hook
|
65
|
+
:group 'vimgolf)
|
66
|
+
|
67
|
+
(defvar vimgolf-mode-map
|
68
|
+
(let ((map (make-sparse-keymap)))
|
69
|
+
(define-key map (kbd "C-c C-v C-c") 'vimgolf-submit)
|
70
|
+
(define-key map (kbd "C-c C-v r") 'vimgolf-revert)
|
71
|
+
(define-key map (kbd "C-c C-v d") 'vimgolf-diff)
|
72
|
+
(define-key map (kbd "C-c C-v c") 'vimgolf-continue)
|
73
|
+
(define-key map (kbd "C-c C-v p") 'vimgolf-pause)
|
74
|
+
(define-key map (kbd "C-c C-v q") 'vimgolf-quit)
|
75
|
+
map))
|
76
|
+
|
77
|
+
(define-minor-mode vimgolf-mode
|
78
|
+
"Toggle VimGolf mode.
|
79
|
+
|
80
|
+
With no argument, this command toggles the mode. Non-null prefix
|
81
|
+
argument turns on the mode. Null prefix argument turns off the
|
82
|
+
mode.
|
83
|
+
|
84
|
+
When VimGolf mode is enabled, several key bindings are defined
|
85
|
+
with `C-c C-v` prefixes to help in playing VimGolf.
|
86
|
+
|
87
|
+
\\{vimgolf-mode-map}"
|
88
|
+
;; The initial value.
|
89
|
+
nil
|
90
|
+
;; The indicator for the mode line.
|
91
|
+
" VimGolf"
|
92
|
+
;; The minor mode bindings.
|
93
|
+
:keymap vimgolf-mode-map
|
94
|
+
:group 'vimgolf)
|
95
|
+
|
96
|
+
(defvar vimgolf-challenge nil)
|
97
|
+
(defvar vimgolf-challenge-history nil)
|
98
|
+
|
99
|
+
(defvar vimgolf-prior-window-configuration nil)
|
100
|
+
|
101
|
+
(defvar vimgolf-working-window-configuration nil)
|
102
|
+
|
103
|
+
(defvar vimgolf-work-buffer-name "*vimgolf-work*")
|
104
|
+
(defvar vimgolf-start-buffer-name "*vimgolf-start*")
|
105
|
+
(defvar vimgolf-end-buffer-name "*vimgolf-end*")
|
106
|
+
(defvar vimgolf-keystrokes-buffer-name "*vimgolf-keystrokes*")
|
107
|
+
|
108
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
109
|
+
;; Keystroke logging
|
110
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
111
|
+
|
112
|
+
(defmacro vimgolf-with-saved-command-environment (&rest body)
|
113
|
+
`(let ((deactivate-mark nil)
|
114
|
+
(this-command this-command)
|
115
|
+
(last-command last-command))
|
116
|
+
,@body))
|
117
|
+
|
118
|
+
(defun vimgolf-capturable-keystroke-p ()
|
119
|
+
(not (or executing-kbd-macro
|
120
|
+
(member this-command
|
121
|
+
'(digit-argument
|
122
|
+
negative-argument
|
123
|
+
universal-argument
|
124
|
+
universal-argument-other-key
|
125
|
+
universal-argument-minus
|
126
|
+
universal-argument-more))
|
127
|
+
(string-prefix-p "vimgolf-" (symbol-name this-command)))))
|
128
|
+
|
129
|
+
(defun vimgolf-capturable-dangling-keystroke-p ()
|
130
|
+
(member this-command
|
131
|
+
'(calc-dispatch)))
|
132
|
+
|
133
|
+
(defvar vimgolf-keystrokes nil
|
134
|
+
"A list of (keys-vector . command) pairs for the keystrokes entered.
|
135
|
+
|
136
|
+
Each entry is a cons cell containing a key sequence vector
|
137
|
+
suitable for use with `key-description', and a symbol for the
|
138
|
+
command that was executed as a result (which may be nil if an
|
139
|
+
unknown key sequence was entered).")
|
140
|
+
|
141
|
+
(defun vimgolf-maybe-capture-keystroke (pred)
|
142
|
+
"Store the keystrokes for `this-command' if result of calling function `PRED' is not nil."
|
143
|
+
(vimgolf-with-saved-command-environment
|
144
|
+
(when (funcall pred)
|
145
|
+
(setq vimgolf-keystrokes
|
146
|
+
(append vimgolf-keystrokes (list (cons (this-command-keys-vector)
|
147
|
+
this-command)))))))
|
148
|
+
|
149
|
+
(defun vimgolf-capture-keystroke ()
|
150
|
+
(vimgolf-maybe-capture-keystroke 'vimgolf-capturable-keystroke-p))
|
151
|
+
|
152
|
+
(defun vimgolf-capture-dangling-keystroke ()
|
153
|
+
(vimgolf-maybe-capture-keystroke 'vimgolf-capturable-dangling-keystroke-p))
|
154
|
+
|
155
|
+
(defun vimgolf-refresh-keystroke-log ()
|
156
|
+
"Refresh the contents of the keystrokes log buffer."
|
157
|
+
(let ((deactivate-mark nil))
|
158
|
+
(with-current-buffer (get-buffer-create vimgolf-keystrokes-buffer-name)
|
159
|
+
(vimgolf-mode t)
|
160
|
+
(erase-buffer)
|
161
|
+
(insert (format "Challenge ID: %s\n%s\n\n" vimgolf-challenge (vimgolf-challenge-url vimgolf-challenge))
|
162
|
+
(format "Keystrokes (%d):\n\n" (vimgolf-count-keystrokes))
|
163
|
+
(mapconcat 'key-description (mapcar 'car vimgolf-keystrokes) " ")
|
164
|
+
"\n\nFull command log:\n\n")
|
165
|
+
(when vimgolf-keystrokes
|
166
|
+
(let* ((descrs-and-commands
|
167
|
+
(mapcar (lambda (entry) (cons (key-description (car entry)) (cdr entry))) vimgolf-keystrokes))
|
168
|
+
(maxlen (apply 'max (mapcar 'length (mapcar 'car descrs-and-commands))))
|
169
|
+
(fmt (format "%%-%ds %%s" maxlen)))
|
170
|
+
(dolist (entry descrs-and-commands)
|
171
|
+
(insert (format fmt (car entry) (prin1-to-string (cdr entry) t)) "\n")))))))
|
172
|
+
|
173
|
+
(defun vimgolf-enable-capture (enable)
|
174
|
+
"Enable keystroke logging if `ENABLE' is non-nil otherwise disable it."
|
175
|
+
(let ((f (if enable 'add-hook 'remove-hook)))
|
176
|
+
(funcall f 'pre-command-hook 'vimgolf-capture-keystroke)
|
177
|
+
(funcall f 'post-command-hook 'vimgolf-capture-dangling-keystroke)
|
178
|
+
(funcall f 'post-command-hook 'vimgolf-refresh-keystroke-log)))
|
179
|
+
|
180
|
+
(defun vimgolf-count-keystrokes ()
|
181
|
+
(apply '+ (mapcar 'length (mapcar 'car vimgolf-keystrokes))))
|
182
|
+
|
183
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
184
|
+
;; Managing and scoring challenges
|
185
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
186
|
+
|
187
|
+
(defun vimgolf-solution-correct-p ()
|
188
|
+
"Return t if the work text is identical to the solution, nil otherwise."
|
189
|
+
(let ((working (with-current-buffer vimgolf-work-buffer-name (buffer-string)))
|
190
|
+
(end (with-current-buffer vimgolf-end-buffer-name (buffer-string))))
|
191
|
+
(string= working end)))
|
192
|
+
|
193
|
+
(defun vimgolf-wrong-solution ()
|
194
|
+
(message "Wrong!")
|
195
|
+
(vimgolf-diff))
|
196
|
+
|
197
|
+
(defun vimgolf-right-solution ()
|
198
|
+
(delete-other-windows)
|
199
|
+
(switch-to-buffer vimgolf-keystrokes-buffer-name)
|
200
|
+
(message "Hurray! You solved %s in %d keystrokes!" vimgolf-challenge (vimgolf-count-keystrokes)))
|
201
|
+
|
202
|
+
(defun vimgolf-submit ()
|
203
|
+
"Stop the challenge and attempt to submit the solution to VimGolf."
|
204
|
+
(interactive)
|
205
|
+
(vimgolf-enable-capture nil)
|
206
|
+
(if (vimgolf-solution-correct-p) (vimgolf-right-solution) (vimgolf-wrong-solution)))
|
207
|
+
|
208
|
+
(defun vimgolf-clear-keystrokes ()
|
209
|
+
(setq vimgolf-keystrokes nil))
|
210
|
+
|
211
|
+
(defun vimgolf-reset-work-buffer ()
|
212
|
+
"Reset the contents of the work buffer, and clear undo/macro history etc."
|
213
|
+
(with-current-buffer (get-buffer-create vimgolf-work-buffer-name)
|
214
|
+
(vimgolf-init-buffer (current-buffer)
|
215
|
+
(with-current-buffer vimgolf-start-buffer-name
|
216
|
+
(buffer-string)))
|
217
|
+
(when defining-kbd-macro
|
218
|
+
(end-kbd-macro))
|
219
|
+
(vimgolf-clear-keystrokes)
|
220
|
+
(setq buffer-undo-list nil)
|
221
|
+
(set-buffer-modified-p nil)))
|
222
|
+
|
223
|
+
(defun vimgolf-revert ()
|
224
|
+
"Revert the work buffer to it's original state and reset keystrokes."
|
225
|
+
(interactive)
|
226
|
+
(vimgolf-reset-work-buffer)
|
227
|
+
(set-window-configuration vimgolf-working-window-configuration)
|
228
|
+
(message "If at first you don't succeed, try, try again."))
|
229
|
+
|
230
|
+
(defun vimgolf-diff ()
|
231
|
+
"Pause the competition and view differences between the buffers."
|
232
|
+
(interactive)
|
233
|
+
(vimgolf-enable-capture nil)
|
234
|
+
(ediff-buffers (get-buffer-create vimgolf-work-buffer-name) (get-buffer-create vimgolf-end-buffer-name))
|
235
|
+
(message "Remember to `C-c C-v c` when you're done."))
|
236
|
+
|
237
|
+
(defun vimgolf-continue ()
|
238
|
+
"Restore work and end buffers and begin recording keystrokes again."
|
239
|
+
(interactive)
|
240
|
+
(vimgolf-enable-capture t)
|
241
|
+
(set-window-configuration vimgolf-working-window-configuration)
|
242
|
+
(message "Golf away!"))
|
243
|
+
|
244
|
+
(defun vimgolf-pause ()
|
245
|
+
"Stop recording keystrokes."
|
246
|
+
(interactive)
|
247
|
+
(vimgolf-enable-capture nil)
|
248
|
+
(message "Come `C-c C-v c` soon."))
|
249
|
+
|
250
|
+
(defun vimgolf-quit ()
|
251
|
+
"Cancel the competition."
|
252
|
+
(interactive)
|
253
|
+
(vimgolf-enable-capture nil)
|
254
|
+
(vimgolf-kill-existing-session)
|
255
|
+
(set-window-configuration vimgolf-prior-window-configuration)
|
256
|
+
(message "I declare you, n00b!"))
|
257
|
+
|
258
|
+
(defvar vimgolf-host "http://vimgolf.com/")
|
259
|
+
|
260
|
+
;; (setq vimgolf-host "http://vimgolf.local:8888/")
|
261
|
+
;; (setq vimgolf-host "http://vimgolf.com/")
|
262
|
+
;; Overall VimGolf Rank ID: 4d2fb20e63b08b08b0000075
|
263
|
+
;; Sort entries based on date ID: 4ea9bc988b36f70001000008
|
264
|
+
;; HTML to Haml ID: 4d3c51f1aabf526ed6000030
|
265
|
+
;; Assignment Allignment: 4d2c9d06eda6262e4e00007a
|
266
|
+
|
267
|
+
(defvar vimgolf-challenge-extension ".yaml")
|
268
|
+
|
269
|
+
(defun vimgolf-challenge-path (challenge-id)
|
270
|
+
(concat "challenges/" challenge-id))
|
271
|
+
|
272
|
+
(defun vimgolf-challenge-url (challenge-id)
|
273
|
+
(concat vimgolf-host (vimgolf-challenge-path challenge-id) vimgolf-challenge-extension))
|
274
|
+
|
275
|
+
(defun vimgolf-init-buffer (buffer text)
|
276
|
+
(with-current-buffer buffer
|
277
|
+
(erase-buffer)
|
278
|
+
(insert text)
|
279
|
+
(goto-char (point-min))
|
280
|
+
(vimgolf-mode t)))
|
281
|
+
|
282
|
+
(defun vimgolf-kill-existing-session ()
|
283
|
+
"Kill any vimgolf-related buffers."
|
284
|
+
(dolist (buf (list vimgolf-start-buffer-name
|
285
|
+
vimgolf-work-buffer-name
|
286
|
+
vimgolf-end-buffer-name
|
287
|
+
vimgolf-keystrokes-buffer-name))
|
288
|
+
(when (get-buffer buf)
|
289
|
+
(kill-buffer buf))))
|
290
|
+
|
291
|
+
(defun vimgolf-read-next-data-chunk ()
|
292
|
+
"Return the next chunk of data as a string, leaving the point at the end of that chunk."
|
293
|
+
(let ((data-start-regexp " data: |\\+\\{0,1\\}\n")
|
294
|
+
(data-end-regexp "\\([ ]\\{4\\}\\|[ ]\\{0\\}\\)\n type: [-a-z]+"))
|
295
|
+
(unless (re-search-forward data-start-regexp nil t)
|
296
|
+
(error "Can't find data in response from vimgolf"))
|
297
|
+
(let ((start (point)))
|
298
|
+
(unless (re-search-forward data-end-regexp nil t)
|
299
|
+
(error "Unclosed data section in response from vimgolf"))
|
300
|
+
(let ((str (buffer-substring-no-properties start (match-beginning 0))))
|
301
|
+
(replace-regexp-in-string "^ " "" str)))))
|
302
|
+
|
303
|
+
(defun vimgolf-setup (status challenge-id)
|
304
|
+
(vimgolf-clear-keystrokes)
|
305
|
+
(setq vimgolf-prior-window-configuration (current-window-configuration)
|
306
|
+
vimgolf-challenge challenge-id)
|
307
|
+
(goto-char (point-min))
|
308
|
+
(let* ((start-text (vimgolf-read-next-data-chunk))
|
309
|
+
(end-text (vimgolf-read-next-data-chunk)))
|
310
|
+
|
311
|
+
(vimgolf-kill-existing-session)
|
312
|
+
|
313
|
+
(let ((vimgolf-start-buffer (get-buffer-create vimgolf-start-buffer-name))
|
314
|
+
(vimgolf-work-buffer (get-buffer-create vimgolf-work-buffer-name))
|
315
|
+
(vimgolf-end-buffer (get-buffer-create vimgolf-end-buffer-name)))
|
316
|
+
|
317
|
+
(vimgolf-init-buffer vimgolf-start-buffer start-text)
|
318
|
+
(vimgolf-init-buffer vimgolf-end-buffer end-text)
|
319
|
+
(with-current-buffer vimgolf-end-buffer (setq buffer-read-only t))
|
320
|
+
(vimgolf-reset-work-buffer)
|
321
|
+
|
322
|
+
;; Set up windows
|
323
|
+
(delete-other-windows)
|
324
|
+
(display-buffer vimgolf-end-buffer 'display-buffer-pop-up-window)
|
325
|
+
(set-window-buffer (selected-window) vimgolf-work-buffer)
|
326
|
+
(switch-to-buffer vimgolf-work-buffer)
|
327
|
+
(setq vimgolf-working-window-configuration (current-window-configuration))
|
328
|
+
|
329
|
+
(vimgolf-continue))))
|
330
|
+
|
331
|
+
;;;###autoload
|
332
|
+
(defun vimgolf (challenge-id)
|
333
|
+
"Open a VimGolf Challenge"
|
334
|
+
(interactive (list (read-from-minibuffer "Challenge ID: " nil nil nil 'vimgolf-challenge-history)))
|
335
|
+
(url-retrieve (vimgolf-challenge-url challenge-id) 'vimgolf-setup `(,challenge-id)))
|
336
|
+
|
337
|
+
(provide 'vimgolf)
|
338
|
+
|
339
|
+
;;; Local Variables:
|
340
|
+
;;; tab-width:2
|
341
|
+
;;; indent-tabs-mode:nil
|
342
|
+
;;; End:
|
343
|
+
;;; vimgolf.el ends here
|