vimgolf 0.4.8 → 0.4.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 <expr> :`? 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 < and >, 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,488 +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.10.0
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
- ;; Siddhanathan Shanmugam (@siddhanathan)
49
-
50
- ;;; Code:
51
-
52
- (require 'json)
53
-
54
- (defgroup vimgolf nil
55
- "Compete on VimGolf with the One True Editor."
56
- :prefix "vimgolf-"
57
- :group 'applications)
58
-
59
- (defcustom vimgolf-key nil
60
- "Your VimGolf API Key. Must be set in order to submit your solution."
61
- :type 'string
62
- :group 'vimgolf)
63
-
64
- (defcustom vimgolf-mode-hook '((lambda () (whitespace-mode t)))
65
- "A list of functions to call upon the initialization of vimgolf-mode."
66
- :type 'hook
67
- :group 'vimgolf)
68
-
69
- (defvar vimgolf-mode-map
70
- (let ((map (make-sparse-keymap)))
71
- (define-key map (kbd "C-c C-v C-c") 'vimgolf-submit)
72
- (define-key map (kbd "C-c C-v r") 'vimgolf-revert)
73
- (define-key map (kbd "C-c C-v d") 'vimgolf-diff)
74
- (define-key map (kbd "C-c C-v c") 'vimgolf-continue)
75
- (define-key map (kbd "C-c C-v p") 'vimgolf-pause)
76
- (define-key map (kbd "C-c C-v q") 'vimgolf-quit)
77
- map))
78
-
79
- (define-minor-mode vimgolf-mode
80
- "Toggle VimGolf mode.
81
-
82
- With no argument, this command toggles the mode. Non-null prefix
83
- argument turns on the mode. Null prefix argument turns off the
84
- mode.
85
-
86
- When VimGolf mode is enabled, several key bindings are defined
87
- with `C-c C-v` prefixes to help in playing VimGolf.
88
-
89
- \\{vimgolf-mode-map}"
90
- ;; The initial value.
91
- nil
92
- ;; The indicator for the mode line.
93
- " VimGolf"
94
- ;; The minor mode bindings.
95
- :keymap vimgolf-mode-map
96
- :group 'vimgolf)
97
-
98
- (defvar vimgolf-challenge nil)
99
- (defvar vimgolf-challenge-history nil)
100
-
101
- (defvar vimgolf-prior-window-configuration nil)
102
-
103
- (defvar vimgolf-working-window-configuration nil)
104
-
105
- (defvar vimgolf-work-buffer-name "*vimgolf-work*")
106
- (defvar vimgolf-start-buffer-name "*vimgolf-start*")
107
- (defvar vimgolf-end-buffer-name "*vimgolf-end*")
108
- (defvar vimgolf-keystrokes-buffer-name "*vimgolf-keystrokes*")
109
-
110
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
111
- ;; Keystroke logging
112
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
113
-
114
- (defmacro vimgolf-with-saved-command-environment (&rest body)
115
- `(let ((deactivate-mark nil)
116
- (this-command this-command)
117
- (last-command last-command))
118
- ,@body))
119
-
120
- (defun vimgolf-capturable-keystroke-p ()
121
- (not (or executing-kbd-macro
122
- (member this-command
123
- '(digit-argument
124
- negative-argument
125
- universal-argument
126
- universal-argument-other-key
127
- universal-argument-minus
128
- universal-argument-more
129
- isearch-other-meta-char))
130
- (string-prefix-p "vimgolf-" (symbol-name this-command)))))
131
-
132
- (defun vimgolf-capturable-dangling-keystroke-p ()
133
- (member this-command
134
- '(calc-dispatch)))
135
-
136
- (defvar vimgolf-keystrokes nil
137
- "A list of (keys-vector . command) pairs for the keystrokes entered.
138
-
139
- Each entry is a cons cell containing a key sequence vector
140
- suitable for use with `key-description', and a symbol for the
141
- command that was executed as a result (which may be nil if an
142
- unknown key sequence was entered).")
143
-
144
- (defun vimgolf-maybe-capture-keystroke (pred)
145
- "Store the keystrokes for `this-command' if result of calling function `PRED' is not nil."
146
- (vimgolf-with-saved-command-environment
147
- (when (funcall pred)
148
- (setq vimgolf-keystrokes
149
- (append vimgolf-keystrokes (list (cons (this-command-keys-vector)
150
- this-command)))))))
151
-
152
- (defun vimgolf-capture-keystroke ()
153
- (vimgolf-maybe-capture-keystroke 'vimgolf-capturable-keystroke-p))
154
-
155
- (defun vimgolf-capture-dangling-keystroke ()
156
- (vimgolf-maybe-capture-keystroke 'vimgolf-capturable-dangling-keystroke-p))
157
-
158
- (defun vimgolf-get-keystrokes-as-string (&optional separator)
159
- (unless separator (setq separator " "))
160
- (mapconcat 'key-description (mapcar 'car vimgolf-keystrokes) separator))
161
-
162
- (defun vimgolf-refresh-keystroke-log ()
163
- "Refresh the contents of the keystrokes log buffer."
164
- (let ((deactivate-mark nil))
165
- (with-current-buffer (get-buffer-create vimgolf-keystrokes-buffer-name)
166
- (vimgolf-mode t)
167
- (erase-buffer)
168
- (insert (format "Challenge ID: %s\n%s\n\n" vimgolf-challenge (vimgolf-challenge-url vimgolf-challenge))
169
- (format "Keystrokes (%d):\n\n" (vimgolf-count-keystrokes))
170
- (vimgolf-get-keystrokes-as-string)
171
- "\n\nFull command log:\n\n")
172
- (when vimgolf-keystrokes
173
- (let* ((descrs-and-commands
174
- (mapcar (lambda (entry) (cons (key-description (car entry)) (cdr entry))) vimgolf-keystrokes))
175
- (maxlen (apply 'max (mapcar 'length (mapcar 'car descrs-and-commands))))
176
- (fmt (format "%%-%ds %%s" maxlen)))
177
- (dolist (entry descrs-and-commands)
178
- (insert (format fmt (car entry) (prin1-to-string (cdr entry) t)) "\n")))))))
179
-
180
- (defun vimgolf-enable-capture (enable)
181
- "Enable keystroke logging if `ENABLE' is non-nil otherwise disable it."
182
- (let ((f (if enable 'add-hook 'remove-hook)))
183
- (funcall f 'pre-command-hook 'vimgolf-capture-keystroke)
184
- (funcall f 'post-command-hook 'vimgolf-capture-dangling-keystroke)
185
- (funcall f 'post-command-hook 'vimgolf-refresh-keystroke-log)))
186
-
187
- (defun vimgolf-count-keystrokes ()
188
- (apply '+ (mapcar 'length (mapcar 'car vimgolf-keystrokes))))
189
-
190
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
191
- ;; Managing and scoring challenges
192
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
193
-
194
- (defun vimgolf-solution-correct-p ()
195
- "Return t if the work text is identical to the solution, nil otherwise."
196
- (let ((working (with-current-buffer vimgolf-work-buffer-name (buffer-string)))
197
- (end (with-current-buffer vimgolf-end-buffer-name (buffer-string))))
198
- (string= working end)))
199
-
200
- (defun vimgolf-wrong-solution ()
201
- (message "Wrong!")
202
- (vimgolf-diff))
203
-
204
- (defun vimgolf-right-solution ()
205
- (delete-other-windows)
206
- (switch-to-buffer vimgolf-keystrokes-buffer-name)
207
- (message "Hurray! You solved %s in %d keystrokes!" vimgolf-challenge (vimgolf-count-keystrokes)))
208
-
209
- (defun vimgolf-submit ()
210
- "Stop the challenge and attempt to submit the solution to VimGolf."
211
- (interactive)
212
- (vimgolf-enable-capture nil)
213
- (if (vimgolf-solution-correct-p) (vimgolf-right-solution) (vimgolf-wrong-solution)))
214
-
215
- (defun vimgolf-clear-keystrokes ()
216
- (setq vimgolf-keystrokes nil))
217
-
218
- (defun vimgolf-reset-work-buffer ()
219
- "Reset the contents of the work buffer, and clear undo/macro history etc."
220
- (with-current-buffer (get-buffer-create vimgolf-work-buffer-name)
221
- (vimgolf-init-buffer (current-buffer)
222
- (with-current-buffer vimgolf-start-buffer-name
223
- (buffer-string)))
224
- (when defining-kbd-macro
225
- (end-kbd-macro))
226
- (vimgolf-clear-keystrokes)
227
- (setq buffer-undo-list nil)
228
- (set-buffer-modified-p nil)))
229
-
230
- (defun vimgolf-revert ()
231
- "Revert the work buffer to it's original state and reset keystrokes."
232
- (interactive)
233
- (vimgolf-reset-work-buffer)
234
- (set-window-configuration vimgolf-working-window-configuration)
235
- (message "If at first you don't succeed, try, try again."))
236
-
237
- (defun vimgolf-diff ()
238
- "Pause the competition and view differences between the buffers."
239
- (interactive)
240
- (vimgolf-enable-capture nil)
241
- (ediff-buffers (get-buffer-create vimgolf-work-buffer-name) (get-buffer-create vimgolf-end-buffer-name))
242
- (message "Remember to `C-c C-v c` when you're done."))
243
-
244
- (defun vimgolf-continue ()
245
- "Restore work and end buffers and begin recording keystrokes again."
246
- (interactive)
247
- (vimgolf-enable-capture t)
248
- (set-window-configuration vimgolf-working-window-configuration)
249
- (message "Golf away!"))
250
-
251
- (defun vimgolf-pause ()
252
- "Stop recording keystrokes."
253
- (interactive)
254
- (vimgolf-enable-capture nil)
255
- (message "Come `C-c C-v c` soon."))
256
-
257
- (defun vimgolf-quit ()
258
- "Cancel the competition."
259
- (interactive)
260
- (vimgolf-enable-capture nil)
261
- (vimgolf-kill-existing-session)
262
- (set-window-configuration vimgolf-prior-window-configuration)
263
- (message "I declare you, n00b!"))
264
-
265
- (defvar vimgolf-host "http://vimgolf.com/")
266
-
267
- ;; (setq vimgolf-host "http://vimgolf.local:8888/")
268
- ;; (setq vimgolf-host "http://vimgolf.com/")
269
- ;; Overall VimGolf Rank ID: 4d2fb20e63b08b08b0000075
270
- ;; Sort entries based on date ID: 4ea9bc988b36f70001000008
271
- ;; HTML to Haml ID: 4d3c51f1aabf526ed6000030
272
- ;; Assignment Allignment: 4d2c9d06eda6262e4e00007a
273
-
274
- (defvar vimgolf-challenge-extension ".json")
275
-
276
- (defun vimgolf-challenge-path (challenge-id)
277
- (concat "challenges/" challenge-id))
278
-
279
- (defun vimgolf-challenge-url (challenge-id)
280
- (concat vimgolf-host (vimgolf-challenge-path challenge-id) vimgolf-challenge-extension))
281
-
282
- (defun vimgolf-init-buffer (buffer text)
283
- (with-current-buffer buffer
284
- (erase-buffer)
285
- (insert text)
286
- (goto-char (point-min))
287
- (vimgolf-mode t)))
288
-
289
- (defun vimgolf-kill-existing-session ()
290
- "Kill any vimgolf-related buffers."
291
- (dolist (buf (list vimgolf-start-buffer-name
292
- vimgolf-work-buffer-name
293
- vimgolf-end-buffer-name
294
- vimgolf-keystrokes-buffer-name))
295
- (when (get-buffer buf)
296
- (kill-buffer buf))))
297
-
298
- (defun vimgolf-get-text (var response)
299
- (format "%s" (assoc-default 'data (assq var response))))
300
-
301
- (defun vimgolf-retrieve-challenge (challenge-id)
302
- (interactive)
303
- (with-current-buffer
304
- (url-retrieve-synchronously (vimgolf-challenge-url challenge-id))
305
- (goto-char url-http-end-of-headers)
306
- (json-read)))
307
-
308
- (defun vimgolf-setup (status challenge-id)
309
- (let ((url-mime-encoding-string "identity"))
310
- (setq vimgolf-response (vimgolf-retrieve-challenge challenge-id)))
311
-
312
- (vimgolf-clear-keystrokes)
313
- (setq vimgolf-prior-window-configuration (current-window-configuration)
314
- vimgolf-challenge challenge-id)
315
- (goto-char (point-min))
316
-
317
- (let* ((start-text (vimgolf-get-text 'in vimgolf-response))
318
- (end-text (vimgolf-get-text 'out vimgolf-response)))
319
- (vimgolf-kill-existing-session)
320
-
321
- (let ((vimgolf-start-buffer (get-buffer-create vimgolf-start-buffer-name))
322
- (vimgolf-work-buffer (get-buffer-create vimgolf-work-buffer-name))
323
- (vimgolf-end-buffer (get-buffer-create vimgolf-end-buffer-name)))
324
-
325
- (vimgolf-init-buffer vimgolf-start-buffer start-text)
326
- (vimgolf-init-buffer vimgolf-end-buffer end-text)
327
- (with-current-buffer vimgolf-end-buffer (setq buffer-read-only t))
328
- (vimgolf-reset-work-buffer)
329
-
330
- ;; Set up windows
331
- (delete-other-windows)
332
- (display-buffer vimgolf-end-buffer 'display-buffer-pop-up-window)
333
- (set-window-buffer (selected-window) vimgolf-work-buffer)
334
- (switch-to-buffer vimgolf-work-buffer)
335
- (setq vimgolf-working-window-configuration (current-window-configuration))
336
-
337
- (vimgolf-continue))))
338
-
339
- (defvar *vimgolf-browse-list* nil
340
- "Holds a list of parsed VimGolf challenges.")
341
-
342
- (defun vimgolf-browse (&optional force-pull)
343
- (interactive)
344
- (if (or (eq *vimgolf-browse-list* nil)
345
- force-pull)
346
- (url-retrieve vimgolf-host 'vimgolf-parse-browse-html)
347
- (vimgolf-browse-list)
348
- (vimgolf-browse-next)))
349
-
350
- (defun vimgolf-browse-refresh ()
351
- (interactive)
352
- (vimgolf-browse t))
353
-
354
- (defun vimgolf-replace-control-m (string &optional replace)
355
- (replace-regexp-in-string "
356
-
357
- (defun vimgolf-parse-html-entites (string)
358
- (replace-regexp-in-string
359
- "&lt;" "<"
360
- (replace-regexp-in-string
361
- "&gt;" ">"
362
- (replace-regexp-in-string
363
- "&amp;" "&"
364
- (replace-regexp-in-string
365
- "&quot" "\""
366
- string)))))
367
-
368
- (defun vimgolf-parse-browse-html (status)
369
- (with-current-buffer (current-buffer)
370
- (let ((html (vimgolf-parse-html-entites
371
- (replace-regexp-in-string "\n" "" (buffer-string))))
372
- (start 0))
373
- (setq *vimgolf-browse-list* nil)
374
- (while
375
- (string-match
376
- "<a href=\"/challenges/\\([a-zA-Z0-9]+\\)\">\\(.*?\\)</a>.*?<p>\\(.*?\\)</p>"
377
- html)
378
- (add-to-list '*vimgolf-browse-list*
379
- (cons (match-string 1 html)
380
- (list (match-string 2 html)
381
- (vimgolf-replace-control-m
382
- (match-string 3 html))))
383
- t)
384
- (setq html (substring html (match-end 0))))
385
- *vimgolf-browse-list*))
386
- (vimgolf-browse-list)
387
- (vimgolf-browse-next))
388
-
389
- (defun vimgolf-browse-list ()
390
- (let ((browse-buffer (get-buffer-create "*VimGolf Browse*")))
391
- (switch-to-buffer browse-buffer)
392
- (setq buffer-read-only nil)
393
- (kill-region (point-min) (point-max))
394
- (insert "VimGolf Challenges")
395
- (newline 2)
396
- (dolist (challenge *vimgolf-browse-list*)
397
- (let ((title (substring (cadr challenge)
398
- 0
399
- (min (length (cadr challenge))
400
- (- fill-column 3))))
401
- (description (car (cdr (cdr challenge))))
402
- (challenge-id (car challenge)))
403
- (when (< (length title) (length (cadr challenge)))
404
- (setq title (concat title "...")))
405
- (insert-text-button title
406
- 'action 'vimgolf-browse-select
407
- 'follow-link t
408
- 'challenge-id challenge-id
409
- 'help-echo description))
410
- (newline)))
411
- (beginning-of-buffer)
412
- (vimgolf-browse-mode))
413
-
414
- (defun vimgolf-browse-select (arg)
415
- (let ((challenge-id (get-text-property (point) 'challenge-id)))
416
- (vimgolf challenge-id)))
417
-
418
- (defun vimgolf-message-title ()
419
- (let ((challenge-id (get-text-property (point) 'challenge-id)))
420
- (when challenge-id
421
- (message (cadr (assoc challenge-id *vimgolf-browse-list*))))))
422
-
423
- (defun vimgolf-browse-next ()
424
- (interactive)
425
- (goto-char (next-single-property-change (point) 'challenge-id))
426
- (unless (get-text-property (point) 'challenge-id)
427
- (goto-char (next-single-property-change (point) 'challenge-id)))
428
- (vimgolf-message-title))
429
-
430
- (defun vimgolf-browse-previous ()
431
- (interactive)
432
- (goto-char (previous-single-property-change (point) 'challenge-id))
433
- (unless (get-text-property (point) 'challenge-id)
434
- (goto-char (previous-single-property-change (point) 'challenge-id)))
435
- (vimgolf-message-title))
436
-
437
- (defun vimgolf-show-description ()
438
- (interactive)
439
- (let ((challenge-id (get-text-property (point) 'challenge-id)))
440
- (save-excursion
441
- (setq buffer-read-only nil)
442
- (if (text-property-any (point-min) (point-max) 'challenge-description challenge-id)
443
- (progn
444
- (beginning-of-buffer)
445
- (while (not (eq (get-text-property (point) 'challenge-description) challenge-id))
446
- (goto-char (next-single-property-change (point) 'challenge-description)))
447
- (let ((start (point)))
448
- (goto-char (next-single-property-change (point) 'challenge-description))
449
- (delete-region start (point))
450
- (delete-blank-lines)
451
- (delete-blank-lines)))
452
- (end-of-line)
453
- (newline 3)
454
- (forward-line -1)
455
- (let ((start (point)))
456
- (insert " " (car (cddr (assoc challenge-id *vimgolf-browse-list*))))
457
- (fill-region start (point))
458
- (add-text-properties start (point) `(challenge-description ,challenge-id))))
459
- (setq buffer-read-only t))))
460
-
461
- ;;;###autoload
462
- (defun vimgolf (challenge-id)
463
- "Open a VimGolf Challenge"
464
- (interactive (list (read-from-minibuffer "Challenge ID: " nil nil nil 'vimgolf-challenge-history)))
465
- (url-retrieve (vimgolf-challenge-url challenge-id) 'vimgolf-setup `(,challenge-id)))
466
-
467
- (defvar vimgolf-browse-mode-map (make-sparse-keymap)
468
- "Keymap for vimgolf-mode.")
469
-
470
- (define-derived-mode vimgolf-browse-mode special-mode "vimgolf browse"
471
- "A major mode for completing vimgolf challenges.
472
-
473
- \\{vimgolf-browse-mode-map}"
474
- (define-key vimgolf-browse-mode-map (kbd "TAB") 'vimgolf-show-description)
475
- (define-key vimgolf-browse-mode-map "g" 'vimgolf-browse-refresh)
476
- (define-key vimgolf-browse-mode-map "n" 'vimgolf-browse-next)
477
- (define-key vimgolf-browse-mode-map "p" 'vimgolf-browse-previous)
478
- )
479
-
480
- (put 'vimgolf-mode 'mode-class 'special)
481
-
482
- (provide 'vimgolf)
483
-
484
- ;;; Local Variables:
485
- ;;; tab-width:2
486
- ;;; indent-tabs-mode:nil
487
- ;;; End:
488
- ;;; vimgolf.el ends here