vimgolf 0.4.5 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/emacs/ROADMAP.md DELETED
@@ -1,69 +0,0 @@
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>
@@ -1,24 +0,0 @@
1
- Feature: VimGolf Browser
2
- In order to browse and select VimGolf entries
3
- As a user
4
- I want to use the VimGolf browser
5
-
6
- Scenario: Press TAB on entry to view description
7
- Given I open the vimgolf browser
8
- Then I should not see "Continuing from the last challenge"
9
- When I press "TAB"
10
- Then I should see "Continuing from the last challenge"
11
- When I press "TAB"
12
- Then I should not see "Continuing from the last challenge"
13
-
14
- Scenario: Move through the browse list
15
- Given I open the vimgolf browser
16
- Then the cursor should be before "Compl"
17
- When I press "n"
18
- Then the cursor should be before "Make "
19
- When I press "n"
20
- Then the cursor should be before "Conve"
21
- When I press "p"
22
- Then the cursor should be before "Make "
23
- When I press "p"
24
- Then the cursor should be before "Compl"
@@ -1,53 +0,0 @@
1
- ;; This file contains your project specific step definitions. All
2
- ;; files in this directory whose names end with "-steps.el" will be
3
- ;; loaded automatically by Ecukes.
4
-
5
- (Given "^I open the vimgolf browser$"
6
- (lambda ()
7
- (setq *vimgolf-browse-list*
8
- '(("50128129201f450002000027"
9
- "Complete the circuit grid!"
10
- "Continuing from the last challenge, add additional rows to the grid. Change each of the names from 'A1'...'A10' to 'B1'...'B10', 'C1'...'C10', etc, and for each new row add 0.7 to the X values in the (X Y) at the end of each line. ")
11
- ("50127eba201f450002000024"
12
- "Make the circuit grid!"
13
- "Copy this command for a circuit layout program to create 10 total smd commands. Increment the number in quotes to name each pad, and add 0.7 to each of the (X Y) coordinates at the end of each line.")
14
- ("500855e60599d90002000073"
15
- "Convert pandoc unordered list to a numbered list"
16
- "I know it's possible to use #. in pandoc to auto-generate numbered lists, but then it's not easy to tell how many items there are when reading it in Markdown. How fast can you make the switch?")
17
- ("4fe62f8a8b2f800001000043"
18
- "Cleanining up 80 column concatenated text"
19
- "1. Put the whole query on one line, remove the concatenation operators
20
- ("4d1b4ac3c58eaa2a8a0005c2"
21
- "Ruby 1.9 compat"
22
- "Remember when Ruby supported `when &lt;expr&gt; :`? Well, it doesn't in 1.9, so let's make sure we use `then`, without ruining our lovely new hash syntax!")
23
- ))
24
- (vimgolf-browse)))
25
-
26
- (When "^I show the description$"
27
- (lambda ()
28
- (vimgolf-show-description)))
29
-
30
- (Given "^I have \"\\(.+\\)\"$"
31
- (lambda (something)
32
- ;; Do something
33
- ))
34
-
35
- (When "^I have \"\\(.+\\)\"$"
36
- (lambda (something)
37
- ;; Do something
38
- ))
39
-
40
- (Then "^I should have \"\\(.+\\)\"$"
41
- (lambda (something)
42
- ;; Do something
43
- ))
44
-
45
- (And "^I have \"\\(.+\\)\"$"
46
- (lambda (something)
47
- ;; Do something
48
- ))
49
-
50
- (But "^I should not have \"\\(.+\\)\"$"
51
- (lambda (something)
52
- ;; Do something
53
- ))
@@ -1,37 +0,0 @@
1
- ;; This is an example of how you could set up this file. This setup
2
- ;; requires a directory called util in the project root and that the
3
- ;; util directory contains the testing tools ert and espuds.
4
-
5
- (let* ((features-directory
6
- (file-name-directory
7
- (directory-file-name (file-name-directory load-file-name))))
8
- (project-directory
9
- (file-name-directory
10
- (directory-file-name features-directory))))
11
- (setq emacs-root-path project-directory)
12
- (setq emacs-util-path (expand-file-name "util" emacs-root-path)))
13
-
14
- (add-to-list 'load-path emacs-root-path)
15
- (add-to-list 'load-path (expand-file-name "espuds" emacs-util-path))
16
- (add-to-list 'load-path (expand-file-name "ert" emacs-util-path))
17
-
18
- (require 'vimgolf)
19
- (require 'espuds)
20
- (require 'ert)
21
-
22
-
23
- (Setup
24
- ;; Before anything has run
25
- )
26
-
27
- (Before
28
- ;; Before each scenario is run
29
- )
30
-
31
- (After
32
- ;; After each scenario is run
33
- )
34
-
35
- (Teardown
36
- ;; After when everything has been run
37
- )
data/emacs/todo.org DELETED
@@ -1,45 +0,0 @@
1
- * VimGolf TODO
2
-
3
- ** Game Excersizes
4
-
5
- ** Browser
6
- *** DONE Handle/fix character encoding
7
- CLOSED: [2012-07-28 Sat 23:07]
8
- :LOGBOOK:
9
- - State "DONE" from "TODO" [2012-07-28 Sat 23:07] \\
10
- Added a utility function to handling &lt, &gt, &amp, and &quot.
11
- :END:
12
- Things like &lt; and &gt;, etc.
13
- *** DONE Fix line endings
14
- CLOSED: [2012-07-28 Sat 22:51]
15
- :LOGBOOK:
16
- - State "DONE" from "TODO" [2012-07-28 Sat 22:51] \\
17
- Added a function to replace ^M with some replacement (default space).
18
- Currently only running this function on entry descriptions.
19
- :END:
20
- Need to convert ^M characters
21
- *** DONE Add/fix line wrapping
22
- CLOSED: [2012-07-28 Sat 22:04]
23
- :LOGBOOK:
24
- - State "DONE" from "TODO" [2012-07-28 Sat 22:04]
25
- :END:
26
- Can't assume that everyone's emacs will be set the same. Should really set a
27
- particular fill-column and enforce it.
28
- *** DONE Truncate long titles
29
- CLOSED: [2012-07-28 Sat 22:21]
30
- :LOGBOOK:
31
- - State "DONE" from "IN PROGRESS" [2012-07-28 Sat 22:21]
32
- - State "IN PROGRESS" from "TODO" [2012-07-28 Sat 22:09]
33
- :END:
34
- Use ellipses to truncate titles that would normally be longer than the
35
- fill-column width.
36
- *** DONE When first loading (via url-retrieve), list isn't showing after the call
37
- CLOSED: [2012-07-28 Sat 23:11]
38
- :LOGBOOK:
39
- - State "DONE" from "TODO" [2012-07-28 Sat 23:11] \\
40
- The list insertion was happening outside of the async callback. Now it happens
41
- during the callback (if url-retrieve is used) and during the browse function
42
- itself (if not).
43
- :END:
44
- I'm not sure if the call back isn't working or what. Manually refreshing
45
- will display the list.
data/emacs/vimgolf.el DELETED
@@ -1,484 +0,0 @@
1
- ;;; vimgolf.el --- VimGolf interface for the One True Editor
2
- ;; Copyright (C) never, by no one
3
-
4
- ;;; Author: Tim Visher <tim.visher@gmail.com>
5
- ;;; Maintainer: Tim Visher <tim.visher@gmail.com>
6
- ;;; Created: 2011-11-02
7
- ;;; Version: 0.9.3
8
- ;;; Keywords: games vimgolf vim
9
-
10
- ;; This file is not part of GNU Emacs
11
-
12
- ;;; Commentary:
13
-
14
- ;; This is a simple package that allows Emacs users to compete on [VimGolf][1]
15
- ;; using the One True Editor. Competition can be commenced utilizing `M-x
16
- ;; vimgolf`. When finished with a challenge, `C-c C-v C-c` should finish your
17
- ;; editing, ensure correctness, and submit your score and keystrokes to
18
- ;; [VimGolf][1].
19
- ;;
20
- ;; On second thought, let's not go to Camelot. It's a silly place.
21
- ;;
22
- ;; Patches are accepted at https://github.com/timvisher/vimgolf
23
- ;;
24
- ;; [1]: http://vimgolf.com/
25
-
26
- ;;; Installation:
27
-
28
- ;; Use package.el. You'll need to add Marmalade to your archives:
29
-
30
- ;; (require 'package)
31
- ;; (add-to-list 'package-archives
32
- ;; '("marmalade" . "http://marmalade-repo.org/packages/"))
33
-
34
- ;; If you use a version of Emacs prior to 24 that doesn't include
35
- ;; package.el, you can get it from http://bit.ly/pkg-el23. If you have
36
- ;; an older package.el installed from tromey.com, you should upgrade
37
- ;; in order to support installation from multiple sources.
38
-
39
- ;;; License:
40
-
41
- ;; [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/)
42
-
43
- ;;; Contributors
44
-
45
- ;; Tim Visher (@timvisher)
46
- ;; Steve Purcell (@sanityinc)
47
- ;; Adam Collard (@acollard)
48
-
49
- ;;; Code:
50
-
51
- (defgroup vimgolf nil
52
- "Compete on VimGolf with the One True Editor."
53
- :prefix "vimgolf-"
54
- :group 'applications)
55
-
56
- (defcustom vimgolf-key nil
57
- "Your VimGolf API Key. Must be set in order to submit your solution."
58
- :type 'string
59
- :group 'vimgolf)
60
-
61
- (defcustom vimgolf-mode-hook '((lambda () (whitespace-mode t)))
62
- "A list of functions to call upon the initialization of vimgolf-mode."
63
- :type 'hook
64
- :group 'vimgolf)
65
-
66
- (defvar vimgolf-mode-map
67
- (let ((map (make-sparse-keymap)))
68
- (define-key map (kbd "C-c C-v C-c") 'vimgolf-submit)
69
- (define-key map (kbd "C-c C-v r") 'vimgolf-revert)
70
- (define-key map (kbd "C-c C-v d") 'vimgolf-diff)
71
- (define-key map (kbd "C-c C-v c") 'vimgolf-continue)
72
- (define-key map (kbd "C-c C-v p") 'vimgolf-pause)
73
- (define-key map (kbd "C-c C-v q") 'vimgolf-quit)
74
- map))
75
-
76
- (define-minor-mode vimgolf-mode
77
- "Toggle VimGolf mode.
78
-
79
- With no argument, this command toggles the mode. Non-null prefix
80
- argument turns on the mode. Null prefix argument turns off the
81
- mode.
82
-
83
- When VimGolf mode is enabled, several key bindings are defined
84
- with `C-c C-v` prefixes to help in playing VimGolf.
85
-
86
- \\{vimgolf-mode-map}"
87
- ;; The initial value.
88
- nil
89
- ;; The indicator for the mode line.
90
- " VimGolf"
91
- ;; The minor mode bindings.
92
- :keymap vimgolf-mode-map
93
- :group 'vimgolf)
94
-
95
- (defvar vimgolf-challenge nil)
96
- (defvar vimgolf-challenge-history nil)
97
-
98
- (defvar vimgolf-prior-window-configuration nil)
99
-
100
- (defvar vimgolf-working-window-configuration nil)
101
-
102
- (defvar vimgolf-work-buffer-name "*vimgolf-work*")
103
- (defvar vimgolf-start-buffer-name "*vimgolf-start*")
104
- (defvar vimgolf-end-buffer-name "*vimgolf-end*")
105
- (defvar vimgolf-keystrokes-buffer-name "*vimgolf-keystrokes*")
106
-
107
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
108
- ;; Keystroke logging
109
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
110
-
111
- (defmacro vimgolf-with-saved-command-environment (&rest body)
112
- `(let ((deactivate-mark nil)
113
- (this-command this-command)
114
- (last-command last-command))
115
- ,@body))
116
-
117
- (defun vimgolf-capturable-keystroke-p ()
118
- (not (or executing-kbd-macro
119
- (member this-command
120
- '(digit-argument
121
- negative-argument
122
- universal-argument
123
- universal-argument-other-key
124
- universal-argument-minus
125
- universal-argument-more
126
- isearch-other-meta-char))
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-get-keystrokes-as-string (&optional separator)
156
- (unless separator (setq separator " "))
157
- (mapconcat 'key-description (mapcar 'car vimgolf-keystrokes) separator))
158
-
159
- (defun vimgolf-refresh-keystroke-log ()
160
- "Refresh the contents of the keystrokes log buffer."
161
- (let ((deactivate-mark nil))
162
- (with-current-buffer (get-buffer-create vimgolf-keystrokes-buffer-name)
163
- (vimgolf-mode t)
164
- (erase-buffer)
165
- (insert (format "Challenge ID: %s\n%s\n\n" vimgolf-challenge (vimgolf-challenge-url vimgolf-challenge))
166
- (format "Keystrokes (%d):\n\n" (vimgolf-count-keystrokes))
167
- (vimgolf-get-keystrokes-as-string)
168
- "\n\nFull command log:\n\n")
169
- (when vimgolf-keystrokes
170
- (let* ((descrs-and-commands
171
- (mapcar (lambda (entry) (cons (key-description (car entry)) (cdr entry))) vimgolf-keystrokes))
172
- (maxlen (apply 'max (mapcar 'length (mapcar 'car descrs-and-commands))))
173
- (fmt (format "%%-%ds %%s" maxlen)))
174
- (dolist (entry descrs-and-commands)
175
- (insert (format fmt (car entry) (prin1-to-string (cdr entry) t)) "\n")))))))
176
-
177
- (defun vimgolf-enable-capture (enable)
178
- "Enable keystroke logging if `ENABLE' is non-nil otherwise disable it."
179
- (let ((f (if enable 'add-hook 'remove-hook)))
180
- (funcall f 'pre-command-hook 'vimgolf-capture-keystroke)
181
- (funcall f 'post-command-hook 'vimgolf-capture-dangling-keystroke)
182
- (funcall f 'post-command-hook 'vimgolf-refresh-keystroke-log)))
183
-
184
- (defun vimgolf-count-keystrokes ()
185
- (apply '+ (mapcar 'length (mapcar 'car vimgolf-keystrokes))))
186
-
187
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
188
- ;; Managing and scoring challenges
189
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
190
-
191
- (defun vimgolf-solution-correct-p ()
192
- "Return t if the work text is identical to the solution, nil otherwise."
193
- (let ((working (with-current-buffer vimgolf-work-buffer-name (buffer-string)))
194
- (end (with-current-buffer vimgolf-end-buffer-name (buffer-string))))
195
- (string= working end)))
196
-
197
- (defun vimgolf-wrong-solution ()
198
- (message "Wrong!")
199
- (vimgolf-diff))
200
-
201
- (defun vimgolf-right-solution ()
202
- (delete-other-windows)
203
- (switch-to-buffer vimgolf-keystrokes-buffer-name)
204
- (message "Hurray! You solved %s in %d keystrokes!" vimgolf-challenge (vimgolf-count-keystrokes)))
205
-
206
- (defun vimgolf-submit ()
207
- "Stop the challenge and attempt to submit the solution to VimGolf."
208
- (interactive)
209
- (vimgolf-enable-capture nil)
210
- (if (vimgolf-solution-correct-p) (vimgolf-right-solution) (vimgolf-wrong-solution)))
211
-
212
- (defun vimgolf-clear-keystrokes ()
213
- (setq vimgolf-keystrokes nil))
214
-
215
- (defun vimgolf-reset-work-buffer ()
216
- "Reset the contents of the work buffer, and clear undo/macro history etc."
217
- (with-current-buffer (get-buffer-create vimgolf-work-buffer-name)
218
- (vimgolf-init-buffer (current-buffer)
219
- (with-current-buffer vimgolf-start-buffer-name
220
- (buffer-string)))
221
- (when defining-kbd-macro
222
- (end-kbd-macro))
223
- (vimgolf-clear-keystrokes)
224
- (setq buffer-undo-list nil)
225
- (set-buffer-modified-p nil)))
226
-
227
- (defun vimgolf-revert ()
228
- "Revert the work buffer to it's original state and reset keystrokes."
229
- (interactive)
230
- (vimgolf-reset-work-buffer)
231
- (set-window-configuration vimgolf-working-window-configuration)
232
- (message "If at first you don't succeed, try, try again."))
233
-
234
- (defun vimgolf-diff ()
235
- "Pause the competition and view differences between the buffers."
236
- (interactive)
237
- (vimgolf-enable-capture nil)
238
- (ediff-buffers (get-buffer-create vimgolf-work-buffer-name) (get-buffer-create vimgolf-end-buffer-name))
239
- (message "Remember to `C-c C-v c` when you're done."))
240
-
241
- (defun vimgolf-continue ()
242
- "Restore work and end buffers and begin recording keystrokes again."
243
- (interactive)
244
- (vimgolf-enable-capture t)
245
- (set-window-configuration vimgolf-working-window-configuration)
246
- (message "Golf away!"))
247
-
248
- (defun vimgolf-pause ()
249
- "Stop recording keystrokes."
250
- (interactive)
251
- (vimgolf-enable-capture nil)
252
- (message "Come `C-c C-v c` soon."))
253
-
254
- (defun vimgolf-quit ()
255
- "Cancel the competition."
256
- (interactive)
257
- (vimgolf-enable-capture nil)
258
- (vimgolf-kill-existing-session)
259
- (set-window-configuration vimgolf-prior-window-configuration)
260
- (message "I declare you, n00b!"))
261
-
262
- (defvar vimgolf-host "http://vimgolf.com/")
263
-
264
- ;; (setq vimgolf-host "http://vimgolf.local:8888/")
265
- ;; (setq vimgolf-host "http://vimgolf.com/")
266
- ;; Overall VimGolf Rank ID: 4d2fb20e63b08b08b0000075
267
- ;; Sort entries based on date ID: 4ea9bc988b36f70001000008
268
- ;; HTML to Haml ID: 4d3c51f1aabf526ed6000030
269
- ;; Assignment Allignment: 4d2c9d06eda6262e4e00007a
270
-
271
- (defvar vimgolf-challenge-extension ".yaml")
272
-
273
- (defun vimgolf-challenge-path (challenge-id)
274
- (concat "challenges/" challenge-id))
275
-
276
- (defun vimgolf-challenge-url (challenge-id)
277
- (concat vimgolf-host (vimgolf-challenge-path challenge-id) vimgolf-challenge-extension))
278
-
279
- (defun vimgolf-init-buffer (buffer text)
280
- (with-current-buffer buffer
281
- (erase-buffer)
282
- (insert text)
283
- (goto-char (point-min))
284
- (vimgolf-mode t)))
285
-
286
- (defun vimgolf-kill-existing-session ()
287
- "Kill any vimgolf-related buffers."
288
- (dolist (buf (list vimgolf-start-buffer-name
289
- vimgolf-work-buffer-name
290
- vimgolf-end-buffer-name
291
- vimgolf-keystrokes-buffer-name))
292
- (when (get-buffer buf)
293
- (kill-buffer buf))))
294
-
295
- (defun vimgolf-read-next-data-chunk ()
296
- "Return the next chunk of data as a string, leaving the point at the end of that chunk."
297
- (let ((data-start-regexp " data: |\\+\\{0,1\\}\n")
298
- (data-end-regexp "\\([ ]\\{4\\}\\|[ ]\\{0\\}\\)\n type: [-a-z]+"))
299
- (unless (re-search-forward data-start-regexp nil t)
300
- (error "Can't find data in response from vimgolf"))
301
- (let ((start (point)))
302
- (unless (re-search-forward data-end-regexp nil t)
303
- (error "Unclosed data section in response from vimgolf"))
304
- (let ((str (buffer-substring-no-properties start (match-beginning 0))))
305
- (replace-regexp-in-string "^ " "" str)))))
306
-
307
- (defun vimgolf-setup (status challenge-id)
308
- (vimgolf-clear-keystrokes)
309
- (setq vimgolf-prior-window-configuration (current-window-configuration)
310
- vimgolf-challenge challenge-id)
311
- (goto-char (point-min))
312
- (let* ((start-text (vimgolf-read-next-data-chunk))
313
- (end-text (vimgolf-read-next-data-chunk)))
314
-
315
- (vimgolf-kill-existing-session)
316
-
317
- (let ((vimgolf-start-buffer (get-buffer-create vimgolf-start-buffer-name))
318
- (vimgolf-work-buffer (get-buffer-create vimgolf-work-buffer-name))
319
- (vimgolf-end-buffer (get-buffer-create vimgolf-end-buffer-name)))
320
-
321
- (vimgolf-init-buffer vimgolf-start-buffer start-text)
322
- (vimgolf-init-buffer vimgolf-end-buffer end-text)
323
- (with-current-buffer vimgolf-end-buffer (setq buffer-read-only t))
324
- (vimgolf-reset-work-buffer)
325
-
326
- ;; Set up windows
327
- (delete-other-windows)
328
- (display-buffer vimgolf-end-buffer 'display-buffer-pop-up-window)
329
- (set-window-buffer (selected-window) vimgolf-work-buffer)
330
- (switch-to-buffer vimgolf-work-buffer)
331
- (setq vimgolf-working-window-configuration (current-window-configuration))
332
-
333
- (vimgolf-continue))))
334
-
335
- (defvar *vimgolf-browse-list* nil
336
- "Holds a list of parsed VimGolf challenges.")
337
-
338
- (defun vimgolf-browse (&optional force-pull)
339
- (interactive)
340
- (if (or (eq *vimgolf-browse-list* nil)
341
- force-pull)
342
- (url-retrieve vimgolf-host 'vimgolf-parse-browse-html)
343
- (vimgolf-browse-list)
344
- (vimgolf-browse-next)))
345
-
346
- (defun vimgolf-browse-refresh ()
347
- (interactive)
348
- (vimgolf-browse t))
349
-
350
- (defun vimgolf-replace-control-m (string &optional replace)
351
- (replace-regexp-in-string "
352
-
353
- (defun vimgolf-parse-html-entites (string)
354
- (replace-regexp-in-string
355
- "&lt;" "<"
356
- (replace-regexp-in-string
357
- "&gt;" ">"
358
- (replace-regexp-in-string
359
- "&amp;" "&"
360
- (replace-regexp-in-string
361
- "&quot" "\""
362
- string)))))
363
-
364
- (defun vimgolf-parse-browse-html (status)
365
- (with-current-buffer (current-buffer)
366
- (let ((html (vimgolf-parse-html-entites
367
- (replace-regexp-in-string "\n" "" (buffer-string))))
368
- (start 0))
369
- (setq *vimgolf-browse-list* nil)
370
- (while
371
- (string-match
372
- "<a href=\"/challenges/\\([a-zA-Z0-9]+\\)\">\\(.*?\\)</a>.*?<p>\\(.*?\\)</p>"
373
- html)
374
- (add-to-list '*vimgolf-browse-list*
375
- (cons (match-string 1 html)
376
- (list (match-string 2 html)
377
- (vimgolf-replace-control-m
378
- (match-string 3 html))))
379
- t)
380
- (setq html (substring html (match-end 0))))
381
- *vimgolf-browse-list*))
382
- (vimgolf-browse-list)
383
- (vimgolf-browse-next))
384
-
385
- (defun vimgolf-browse-list ()
386
- (let ((browse-buffer (get-buffer-create "*VimGolf Browse*")))
387
- (switch-to-buffer browse-buffer)
388
- (setq buffer-read-only nil)
389
- (kill-region (point-min) (point-max))
390
- (insert "VimGolf Challenges")
391
- (newline 2)
392
- (dolist (challenge *vimgolf-browse-list*)
393
- (let ((title (substring (cadr challenge)
394
- 0
395
- (min (length (cadr challenge))
396
- (- fill-column 3))))
397
- (description (car (cdr (cdr challenge))))
398
- (challenge-id (car challenge)))
399
- (when (< (length title) (length (cadr challenge)))
400
- (setq title (concat title "...")))
401
- (insert-text-button title
402
- 'action 'vimgolf-browse-select
403
- 'follow-link t
404
- 'challenge-id challenge-id
405
- 'help-echo description))
406
- (newline)))
407
- (beginning-of-buffer)
408
- (vimgolf-browse-mode))
409
-
410
- (defun vimgolf-browse-select (arg)
411
- (let ((challenge-id (get-text-property (point) 'challenge-id)))
412
- (vimgolf challenge-id)))
413
-
414
- (defun vimgolf-message-title ()
415
- (let ((challenge-id (get-text-property (point) 'challenge-id)))
416
- (when challenge-id
417
- (message (cadr (assoc challenge-id *vimgolf-browse-list*))))))
418
-
419
- (defun vimgolf-browse-next ()
420
- (interactive)
421
- (goto-char (next-single-property-change (point) 'challenge-id))
422
- (unless (get-text-property (point) 'challenge-id)
423
- (goto-char (next-single-property-change (point) 'challenge-id)))
424
- (vimgolf-message-title))
425
-
426
- (defun vimgolf-browse-previous ()
427
- (interactive)
428
- (goto-char (previous-single-property-change (point) 'challenge-id))
429
- (unless (get-text-property (point) 'challenge-id)
430
- (goto-char (previous-single-property-change (point) 'challenge-id)))
431
- (vimgolf-message-title))
432
-
433
- (defun vimgolf-show-description ()
434
- (interactive)
435
- (let ((challenge-id (get-text-property (point) 'challenge-id)))
436
- (save-excursion
437
- (setq buffer-read-only nil)
438
- (if (text-property-any (point-min) (point-max) 'challenge-description challenge-id)
439
- (progn
440
- (beginning-of-buffer)
441
- (while (not (eq (get-text-property (point) 'challenge-description) challenge-id))
442
- (goto-char (next-single-property-change (point) 'challenge-description)))
443
- (let ((start (point)))
444
- (goto-char (next-single-property-change (point) 'challenge-description))
445
- (delete-region start (point))
446
- (delete-blank-lines)
447
- (delete-blank-lines)))
448
- (end-of-line)
449
- (newline 3)
450
- (forward-line -1)
451
- (let ((start (point)))
452
- (insert " " (car (cddr (assoc challenge-id *vimgolf-browse-list*))))
453
- (fill-region start (point))
454
- (add-text-properties start (point) `(challenge-description ,challenge-id))))
455
- (setq buffer-read-only t))))
456
-
457
- ;;;###autoload
458
- (defun vimgolf (challenge-id)
459
- "Open a VimGolf Challenge"
460
- (interactive (list (read-from-minibuffer "Challenge ID: " nil nil nil 'vimgolf-challenge-history)))
461
- (url-retrieve (vimgolf-challenge-url challenge-id) 'vimgolf-setup `(,challenge-id)))
462
-
463
- (defvar vimgolf-browse-mode-map (make-sparse-keymap)
464
- "Keymap for vimgolf-mode.")
465
-
466
- (define-derived-mode vimgolf-browse-mode special-mode "vimgolf browse"
467
- "A major mode for completing vimgolf challenges.
468
-
469
- \\{vimgolf-browse-mode-map}"
470
- (define-key vimgolf-browse-mode-map (kbd "TAB") 'vimgolf-show-description)
471
- (define-key vimgolf-browse-mode-map "g" 'vimgolf-browse-refresh)
472
- (define-key vimgolf-browse-mode-map "n" 'vimgolf-browse-next)
473
- (define-key vimgolf-browse-mode-map "p" 'vimgolf-browse-previous)
474
- )
475
-
476
- (put 'vimgolf-mode 'mode-class 'special)
477
-
478
- (provide 'vimgolf)
479
-
480
- ;;; Local Variables:
481
- ;;; tab-width:2
482
- ;;; indent-tabs-mode:nil
483
- ;;; End:
484
- ;;; vimgolf.el ends here