Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 535 lines (421 sloc) 16.548 kb
4a11c70 Chris Wanstrath documentation
authored
1 ;;; coffee-mode.el --- Major mode to edit CoffeeScript files in Emacs
2
3 ;; Copyright (C) 2010 Chris Wanstrath
4
5 ;; Version 0.1.0
6 ;; Keywords: CoffeeScript major mode
7 ;; Author: Chris Wanstrath <chris@ozmm.org>
8 ;; URL: http://github.com/defunkt/coffee-script
9
10 ;; This file is not part of GNU Emacs.
11
12 ;; This program is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; any later version.
16
17 ;; This program is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with this program; if not, write to the Free Software
24 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26 ;;; Commentary
27
28 ;; For commentary please see the README.md or
29 ;; http://github.com/defunkt/coffee-mode#readme
30
31 ;;; Installation
32
33 ;; In your shell:
34
35 ;; $ cd ~/.emacs.d/vendor
36 ;; $ git clone git://github.com/defunkt/coffee-mode.git
37
38 ;; In your emacs config:
39
40 ;; (add-to-list 'load-path "~/.emacs.d/vendor/coffee-mode")
41 ;; (require 'coffee-mode)
42
43 ;;; Thanks
44
0480381 Chris Wanstrath mini docs
authored
45 ;; Major thanks to http://xahlee.org/emacs/elisp_syntax_coloring.html
46 ;; the instructions.
4a11c70 Chris Wanstrath documentation
authored
47
38ce8da Chris Wanstrath small tweaks
authored
48 ;; Also thanks to Jason Blevins's markdown-mode.el for guidance.
49
12bd5d0 Chris Wanstrath todo
authored
50 ;; TODO:
51 ;; - Fix indentation toggling on blank (pure whitespace) lines
52 ;; - imenu support
53 ;; - Make prototype accessor assignments like `String::length: -> 10` pretty.
5b00ae2 Chris Wanstrath more todo
authored
54 ;; - Automatically `delete-trailing-whitespace' on save, configurable.
55 ;; - mirror-mode - close brackets and parens automatically
12bd5d0 Chris Wanstrath todo
authored
56
57 ;;; Code:
58
38ce8da Chris Wanstrath small tweaks
authored
59 (require 'easymenu)
60 (require 'font-lock)
14ab5a0 Chris Wanstrath Use Common Lisp's `some` despite its inferior API.
authored
61 (require 'cl)
0480381 Chris Wanstrath mini docs
authored
62
7557530 Chris Wanstrath compilation commands
authored
63 ;;
38ce8da Chris Wanstrath small tweaks
authored
64 ;; Customizable Variables
7557530 Chris Wanstrath compilation commands
authored
65 ;;
66
38ce8da Chris Wanstrath small tweaks
authored
67 (defconst coffee-mode-version "0.1.0"
5f14029 Chris Wanstrath Menu
authored
68 "The version of this `coffee-mode'.")
69
c063681 Chris Wanstrath no more debug mode
authored
70 (defvar coffee-debug-mode nil
ce05b32 Chris Wanstrath debug mode, t for now
authored
71 "Whether to run in debug mode or not. Logs to `*Messages*'.")
72
38ce8da Chris Wanstrath small tweaks
authored
73 (defvar coffee-mode-hook nil
74 "A hook for you to run your own code when the mode is loaded.")
75
7557530 Chris Wanstrath compilation commands
authored
76 (defvar coffee-command "coffee"
77 "The CoffeeScript command used for evaluating code. Must be in your
78 path.")
79
28485fa Chris Wanstrath `coffee-repl'
authored
80 (defvar coffee-repl-args '("-i")
81 "The command line arguments to pass to `coffee-command' to start a REPL.")
82
5f14029 Chris Wanstrath Menu
authored
83 (defvar coffee-command-args '("-s" "-p" "--no-wrap")
84 "The command line arguments to pass to `coffee-command' to get it to
85 print the compiled JavaScript.")
86
7557530 Chris Wanstrath compilation commands
authored
87 (defvar coffee-js-mode 'js2-mode
88 "The mode to use when viewing compiled JavaScript.")
89
90 (defvar coffee-compiled-buffer-name "*coffee-compiled*"
91 "The name of the scratch buffer used when compiling CoffeeScript.")
92
eee29e0 Chris Wanstrath defvar the keymap
authored
93 (defvar coffee-mode-map (make-keymap)
94 "Keymap for CoffeeScript major mode.")
95
38ce8da Chris Wanstrath small tweaks
authored
96 ;;
c5ffe04 Chris Wanstrath setd macro for logging variable values when setting them
authored
97 ;; Macros
5b00ae2 Chris Wanstrath more todo
authored
98 ;;
99
c5ffe04 Chris Wanstrath setd macro for logging variable values when setting them
authored
100 (defmacro setd (var val)
101 "Like setq but optionally logs the variable's value using `coffee-debug'."
21ce2da Chris Wanstrath The kind of optimization that turns on every Lisp hacker: macro-time.
authored
102 (if coffee-debug-mode
c6562af Chris Wanstrath Make `coffee-debug' a macro
authored
103 `(progn
104 (coffee-debug "%s: %s" ',var ,val)
105 (setq ,var ,val))
106 `(setq ,var ,val)))
107
2799609 Chris Wanstrath back out that macro change for now, something is funny
authored
108 (defun coffee-debug (string &rest args)
c6562af Chris Wanstrath Make `coffee-debug' a macro
authored
109 "Print a message when in debug mode."
110 (when coffee-debug-mode
2799609 Chris Wanstrath back out that macro change for now, something is funny
authored
111 (apply 'message (append (list string) args))))
c5ffe04 Chris Wanstrath setd macro for logging variable values when setting them
authored
112
5b00ae2 Chris Wanstrath more todo
authored
113 ;;
38ce8da Chris Wanstrath small tweaks
authored
114 ;; Commands
115 ;;
116
28485fa Chris Wanstrath `coffee-repl'
authored
117 (defun coffee-repl ()
118 "Launch a CoffeeScript REPL using `coffee-command' as an inferior mode."
119 (interactive)
120
17150cf Chris Wanstrath docs and starting to implement indenters
authored
121 (unless (comint-check-proc "*CoffeeREPL*")
28485fa Chris Wanstrath `coffee-repl'
authored
122 (set-buffer
17150cf Chris Wanstrath docs and starting to implement indenters
authored
123 (apply 'make-comint "CoffeeREPL"
28485fa Chris Wanstrath `coffee-repl'
authored
124 coffee-command nil coffee-repl-args)))
125
126 (pop-to-buffer "*CoffeeScript*"))
38ce8da Chris Wanstrath small tweaks
authored
127
7557530 Chris Wanstrath compilation commands
authored
128 (defun coffee-compile-buffer ()
17150cf Chris Wanstrath docs and starting to implement indenters
authored
129 "Compiles the current buffer and displays the JS in another buffer."
7557530 Chris Wanstrath compilation commands
authored
130 (interactive)
131 (save-excursion
132 (coffee-compile-region (point-min) (point-max))))
133
134 (defun coffee-compile-region (start end)
17150cf Chris Wanstrath docs and starting to implement indenters
authored
135 "Compiles a region and displays the JS in another buffer."
7557530 Chris Wanstrath compilation commands
authored
136 (interactive "r")
137
138 (let ((buffer (get-buffer coffee-compiled-buffer-name)))
139 (when buffer
140 (kill-buffer buffer)))
141
142 (call-process-region start end coffee-command nil
143 (get-buffer-create coffee-compiled-buffer-name)
144 nil
145 "-s" "-p" "--no-wrap")
146 (switch-to-buffer-other-frame (get-buffer coffee-compiled-buffer-name))
147 (funcall coffee-js-mode)
148 (beginning-of-buffer))
3a47b28 Chris Wanstrath docs
authored
149
5f14029 Chris Wanstrath Menu
authored
150 (defun coffee-show-version ()
151 "Prints the `coffee-mode' version."
152 (interactive)
153 (message (concat "coffee-mode v" coffee-mode-version)))
154
fd314cc Chris Wanstrath menu tweaks
authored
155 (defun coffee-open-reference ()
156 "Open browser to CoffeeScript reference."
157 (interactive)
158 (browse-url "http://jashkenas.github.com/coffee-script/"))
159
5f14029 Chris Wanstrath Menu
authored
160 (defun coffee-open-github ()
fd314cc Chris Wanstrath menu tweaks
authored
161 "Open browser to `coffee-mode' project on GithHub."
5f14029 Chris Wanstrath Menu
authored
162 (interactive)
163 (browse-url "http://github.com/defunkt/coffee-mode"))
164
165 ;;
166 ;; Menubar
167 ;;
168
169 (easy-menu-define coffee-mode-menu coffee-mode-map
170 "Menu for CoffeeScript mode"
171 '("CoffeeScript"
172 ["Compile Buffer" coffee-compile-buffer]
173 ["Compile Region" coffee-compile-region]
5256afd Chris Wanstrath tweaks
authored
174 ["REPL" coffee-repl]
5f14029 Chris Wanstrath Menu
authored
175 "---"
fd314cc Chris Wanstrath menu tweaks
authored
176 ["CoffeeScript reference" coffee-open-reference]
177 ["coffee-mode on GitHub" coffee-open-github]
5f14029 Chris Wanstrath Menu
authored
178 ["Version" coffee-show-version]
179 ))
180
3a47b28 Chris Wanstrath docs
authored
181 ;;
182 ;; Define Language Syntax
183 ;;
184
185 ;; Instance variables (implicit this)
5256afd Chris Wanstrath tweaks
authored
186 (defvar coffee-this-regexp "@\\w*\\|this")
3a47b28 Chris Wanstrath docs
authored
187
88e7b95 Chris Wanstrath better regexps, @blah: and {blah: true, blah2:true}
authored
188 ;; Assignment
30d2af5 Chris Wanstrath Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
189 (defvar coffee-assign-regexp "\\(\\(\\w\\|\\.\\|_\\| \\|$\\)+?\\):")
190
191 ;; Lambda
00c197b Chris Wanstrath elisp regexps are fun
authored
192 (defvar coffee-lambda-regexp "\\((.+)\\)?\\s *\\(->\\|=>\\)")
88e7b95 Chris Wanstrath better regexps, @blah: and {blah: true, blah2:true}
authored
193
76ed341 Chris Wanstrath class support in imenu
authored
194 ;; Namespaces
195 (defvar coffee-namespace-regexp "\\b\\(class\\s +\\(\\S +\\)\\)\\b")
196
af34f91 Chris Wanstrath Booleans, better colors
authored
197 ;; Booleans
5256afd Chris Wanstrath tweaks
authored
198 (defvar coffee-boolean-regexp "\\b\\(true\\|false\\|yes\\|no\\|on\\|off\\)\\b")
3a47b28 Chris Wanstrath docs
authored
199
dbb4ec5 Chris Wanstrath comment tweaks
authored
200 ;; Regular Expressions
5256afd Chris Wanstrath tweaks
authored
201 (defvar coffee-regexp-regexp "\\/.+?\\/")
3a47b28 Chris Wanstrath docs
authored
202
cf028f8 Chris Wanstrath basics
authored
203 ;; JavaScript Keywords
d6b78ed Chris Wanstrath defvars and basic indentation
authored
204 (defvar coffee-js-keywords
af34f91 Chris Wanstrath Booleans, better colors
authored
205 '("if" "else" "new" "return" "try" "catch"
cf028f8 Chris Wanstrath basics
authored
206 "finally" "throw" "break" "continue" "for" "in" "while"
207 "delete" "instanceof" "typeof" "switch" "super" "extends"
208 "class"))
209
210 ;; Reserved keywords either by JS or CS.
d6b78ed Chris Wanstrath defvars and basic indentation
authored
211 (defvar coffee-js-reserved
cf028f8 Chris Wanstrath basics
authored
212 '("case" "default" "do" "function" "var" "void" "with"
213 "const" "let" "debugger" "enum" "export" "import" "native"
214 "__extends" "__hasProp"))
215
216 ;; CoffeeScript keywords.
d6b78ed Chris Wanstrath defvars and basic indentation
authored
217 (defvar coffee-cs-keywords
af34f91 Chris Wanstrath Booleans, better colors
authored
218 '("then" "unless" "and" "or" "is"
cf028f8 Chris Wanstrath basics
authored
219 "isnt" "not" "of" "by" "where" "when"))
220
0480381 Chris Wanstrath mini docs
authored
221 ;; Regular expression combining the above three lists.
d6b78ed Chris Wanstrath defvars and basic indentation
authored
222 (defvar coffee-keywords-regexp (regexp-opt
cf028f8 Chris Wanstrath basics
authored
223 (append
224 coffee-js-reserved
225 coffee-js-keywords
226 coffee-cs-keywords) 'words))
227
228
ff61700 Chris Wanstrath that was bothering me
authored
229 ;; Create the list for font-lock. Each class of keyword is given a
230 ;; particular face.
5256afd Chris Wanstrath tweaks
authored
231 (defvar coffee-font-lock-keywords
ff61700 Chris Wanstrath that was bothering me
authored
232 ;; *Note*: order below matters. `coffee-keywords-regexp' goes last
233 ;; because otherwise the keyword "state" in the function
234 ;; "state_entry" would be highlighted.
235 `((,coffee-this-regexp . font-lock-variable-name-face)
236 (,coffee-assign-regexp . font-lock-type-face)
237 (,coffee-regexp-regexp . font-lock-constant-face)
238 (,coffee-boolean-regexp . font-lock-constant-face)
239 (,coffee-keywords-regexp . font-lock-keyword-face)))
cf028f8 Chris Wanstrath basics
authored
240
3a47b28 Chris Wanstrath docs
authored
241 ;;
242 ;; Helper Functions
243 ;;
244
0480381 Chris Wanstrath mini docs
authored
245 ;; The command to comment/uncomment text
9ff612a Chris Wanstrath single quotes
authored
246 (defun coffee-comment-dwim (arg)
247 "Comment or uncomment current line or region in a smart way.
248 For detail, see `comment-dwim'."
249 (interactive "*P")
250 (require 'newcomment)
251 (let ((deactivate-mark nil) (comment-start "#") (comment-end ""))
252 (comment-dwim arg)))
84ab684 Chris Wanstrath comments
authored
253
5b00ae2 Chris Wanstrath more todo
authored
254 (defun coffee-command-full ()
255 "The full `coffee-command' complete with args."
256 (mapconcat 'identity (append (list coffee-command) coffee-command-args) " "))
257
2504ebe Chris Wanstrath explain indentation plan
authored
258 ;;
30d2af5 Chris Wanstrath Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
259 ;; imenu support
260 ;;
261
262 ;; This is a pretty naive but workable way of doing it. First we look
263 ;; for any lines that starting with `coffee-assign-regexp' that include
264 ;; `coffee-lambda-regexp' then add those tokens to the list.
265 ;;
266 ;; Should cover cases like these:
267 ;;
268 ;; minus: (x, y) -> x - y
269 ;; String::length: -> 10
270 ;; block: ->
271 ;; print('potion')
272 ;;
273 ;; Next we look for any line that starts with `class' or
274 ;; `coffee-assign-regexp' followed by `{` and drop into a
275 ;; namespace. This means we search one indentation level deeper for
276 ;; more assignments and add them to the alist prefixed with the
277 ;; namespace name.
278 ;;
279 ;; Should cover cases like these:
280 ;;
281 ;; class Person
282 ;; print: ->
283 ;; print 'My name is ' + this.name + '.'
284 ;;
285 ;; class Policeman extends Person
286 ;; constructor: (rank) ->
287 ;; @rank: rank
288 ;; print: ->
289 ;; print 'My name is ' + this.name + " and I'm a " + this.rank + '.'
290 ;;
76ed341 Chris Wanstrath class support in imenu
authored
291 ;; TODO:
30d2af5 Chris Wanstrath Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
292 ;; app = {
293 ;; window: {width: 200, height: 200}
294 ;; para: -> 'Welcome.'
295 ;; button: -> 'OK'
296 ;; }
297
298 (defun coffee-imenu-create-index ()
299 "Create an imenu index of all methods in the buffer."
300 (interactive)
301
302 ;; This function is called within a `save-excursion' so we're safe.
303 (beginning-of-buffer)
304
76ed341 Chris Wanstrath class support in imenu
authored
305 (let ((index-alist '()) assign pos indent ns-name ns-indent)
30d2af5 Chris Wanstrath Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
306 ;; Go through every assignment that includes -> or => on the same
c6562af Chris Wanstrath Make `coffee-debug' a macro
authored
307 ;; line or starts with `class'.
30d2af5 Chris Wanstrath Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
308 (while (re-search-forward
76ed341 Chris Wanstrath class support in imenu
authored
309 (concat "^\\(\\s *\\)"
310 "\\("
311 coffee-assign-regexp
312 ".+?"
313 coffee-lambda-regexp
314 "\\|"
315 coffee-namespace-regexp
316 "\\)")
30d2af5 Chris Wanstrath Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
317 (point-max)
318 t)
319
e1b9c83 Chris Wanstrath print full match to debug
authored
320 (coffee-debug "Match: %s" (match-string 0))
321
76ed341 Chris Wanstrath class support in imenu
authored
322 ;; If this is the start of a new namespace, save the namespace's
323 ;; indentation level and name.
00c197b Chris Wanstrath elisp regexps are fun
authored
324 (when (and (not ns-name) (setq ns-name (match-string 8)))
76ed341 Chris Wanstrath class support in imenu
authored
325 ;; If this is a class declaration, add :: to the namespace.
326 (setq ns-name (concat ns-name "::"))
327
328 ;; Save the indentation level.
329 (setq ns-indent (length (match-string 1)))
330
331 ;; Debug
332 (coffee-debug "ns: Found %s with indent %s" ns-name ns-indent))
333
334 ;; If this is an assignment, save the token being
335 ;; assigned. `Please.print:` will be `Please.print`, `block:`
336 ;; will be `block`, etc.
337 (when (setq assign (match-string 3))
338 ;; The position of the match in the buffer.
339 (setq pos (match-beginning 3))
340
341 ;; The indent level of this match
342 (setq indent (length (match-string 1)))
343
344 ;; If we're within the context of a namespace, add that to the
345 ;; front of the assign, e.g.
346 ;; constructor: => Policeman::constructor
347 (when (and ns-name (> indent ns-indent))
348 (setq assign (concat ns-name assign)))
349
350 (coffee-debug "=: Found %s with indent %s" assign indent)
351
352 ;; Clear the namespace if we're no longer indented deeper
353 ;; than it.
354 (when (and ns-name (<= indent ns-indent))
355 (coffee-debug "ns: Clearing %s" ns-name)
356 (setq ns-name nil)
357 (setq ns-indent nil))
358
359 ;; Add this to the alist. Done.
360 (push (cons assign pos) index-alist)))
30d2af5 Chris Wanstrath Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
361
362 ;; Return the alist.
363 index-alist))
364
365 ;;
d6b78ed Chris Wanstrath defvars and basic indentation
authored
366 ;; Indentation
2504ebe Chris Wanstrath explain indentation plan
authored
367 ;;
368
dbb4ec5 Chris Wanstrath comment tweaks
authored
369 ;;; The theory is explained in the README.
97a1001 Chris Wanstrath basic indentation with TAB
authored
370
d6b78ed Chris Wanstrath defvars and basic indentation
authored
371 (defun coffee-indent-line ()
7b03a71 Chris Wanstrath indentation theory
authored
372 "Indent current line as CoffeeScript."
d6b78ed Chris Wanstrath defvars and basic indentation
authored
373 (interactive)
374
97ef92b Chris Wanstrath Bugfix: Indentation works when point is at beginning of the line
authored
375 ;; Bail early by indenting if point as the front of the line.
376 (if (= (point) (point-at-bol))
97a1001 Chris Wanstrath basic indentation with TAB
authored
377 (insert-tab)
97ef92b Chris Wanstrath Bugfix: Indentation works when point is at beginning of the line
authored
378 (save-excursion
379 (let ((prev-indent 0) (cur-indent 0))
380 ;; Figure out the indentation of the previous line
381 (forward-line -1)
c5ffe04 Chris Wanstrath setd macro for logging variable values when setting them
authored
382 (setd prev-indent (current-indentation))
97ef92b Chris Wanstrath Bugfix: Indentation works when point is at beginning of the line
authored
383
384 ;; Figure out the current line's indentation
385 (forward-line 1)
c5ffe04 Chris Wanstrath setd macro for logging variable values when setting them
authored
386 (setd cur-indent (current-indentation))
97ef92b Chris Wanstrath Bugfix: Indentation works when point is at beginning of the line
authored
387
388 ;; Shift one column to the left
97a1001 Chris Wanstrath basic indentation with TAB
authored
389 (backward-to-indentation 0)
97ef92b Chris Wanstrath Bugfix: Indentation works when point is at beginning of the line
authored
390 (insert-tab)
391
392 ;; We're too far, remove all indentation.
393 (when (> (- (current-indentation) prev-indent) tab-width)
394 (backward-to-indentation 0)
395 (delete-region (point-at-bol) (point)))))))
df08186 Chris Wanstrath indenters
authored
396
17150cf Chris Wanstrath docs and starting to implement indenters
authored
397 (defun coffee-newline-and-indent ()
398 "Inserts a newline and indents it to the same level as the previous line."
399 (interactive)
400
401 ;; Remember the current line indentation level,
402 ;; insert a newline, and indent the newline to the same
403 ;; level as the previous line.
404 (let ((prev-indent (current-indentation)) (indent-next nil))
405 (newline)
406 (insert-tab (/ prev-indent tab-width))
3a47b28 Chris Wanstrath docs
authored
407
17150cf Chris Wanstrath docs and starting to implement indenters
authored
408 ;; We need to insert an additional tab because the last line was special.
409 (when (coffee-line-wants-indent)
410 (insert-tab)))
411
412 ;; Last line was a comment so this one should probably be,
413 ;; too. Makes it easy to write multi-line comments (like the one I'm
414 ;; writing right now).
415 (when (coffee-previous-line-is-comment)
416 (insert "# ")))
417
418 ;; Indenters help determine whether the current line should be
419 ;; indented further based on the content of the previous line. If a
420 ;; line starts with `class', for instance, you're probably going to
421 ;; want to indent the next line.
422
423 (defvar coffee-indenters-bol '("class" "for" "if" "try")
7d338d1 Chris Wanstrath coffee-indenters
authored
424 "Keywords or syntax whose presence at the start of a line means the
425 next line should probably be indented.")
426
427 (defun coffee-indenters-bol-regexp ()
428 "Builds a regexp out of `coffee-indenters-bol' words."
429 (concat "^" (regexp-opt coffee-indenters-bol 'words)))
430
5e170be Chris Wanstrath get it working (with a fake function though)
authored
431 (defvar coffee-indenters-eol '(?> ?{ ?\[)
432 "Single characters at the end of a line that mean the next line
433 should probably be indented.")
7d338d1 Chris Wanstrath coffee-indenters
authored
434
17150cf Chris Wanstrath docs and starting to implement indenters
authored
435 (defun coffee-line-wants-indent ()
436 "Does the current line want to be indented deeper than the previous
df08186 Chris Wanstrath indenters
authored
437 line? Returns `t' or `nil'. See the README for more details."
8bfb7ed Chris Wanstrath Keep same indentation of last line when creating a new line
authored
438 (interactive)
439
17150cf Chris Wanstrath docs and starting to implement indenters
authored
440 (save-excursion
441 (let ((indenter-at-bol) (indenter-at-eol))
442 ;; Go back a line and to the first character.
443 (forward-line -1)
444 (backward-to-indentation 0)
8bfb7ed Chris Wanstrath Keep same indentation of last line when creating a new line
authored
445
17150cf Chris Wanstrath docs and starting to implement indenters
authored
446 ;; If the next few characters match one of our magic indenter
447 ;; keywords, we want to indent the line we were on originally.
448 (when (looking-at (coffee-indenters-bol-regexp))
c5ffe04 Chris Wanstrath setd macro for logging variable values when setting them
authored
449 (setd indenter-at-bol t))
17150cf Chris Wanstrath docs and starting to implement indenters
authored
450
451 ;; If that didn't match, go to the back of the line and check to
5e170be Chris Wanstrath get it working (with a fake function though)
authored
452 ;; see if the last character matches one of our indenter
453 ;; characters.
17150cf Chris Wanstrath docs and starting to implement indenters
authored
454 (when (not indenter-at-bol)
455 (end-of-line)
456
5e170be Chris Wanstrath get it working (with a fake function though)
authored
457 ;; Optimized for speed - checks only the last character.
14ab5a0 Chris Wanstrath Use Common Lisp's `some` despite its inferior API.
authored
458 (when (some (lambda (char)
459 (= (char-before) char))
460 coffee-indenters-eol)
c5ffe04 Chris Wanstrath setd macro for logging variable values when setting them
authored
461 (setd indenter-at-eol t)))
17150cf Chris Wanstrath docs and starting to implement indenters
authored
462
463 ;; If we found an indenter, return `t'.
464 (or indenter-at-bol indenter-at-eol))))
465
8bfb7ed Chris Wanstrath Keep same indentation of last line when creating a new line
authored
466 (defun coffee-previous-line-is-comment ()
467 "Returns `t' if the previous line is a CoffeeScript comment."
468 (save-excursion
469 (forward-line -1)
470 (coffee-line-is-comment)))
471
472 (defun coffee-line-is-comment ()
473 "Returns `t' if the current line is a CoffeeScript comment."
474 (save-excursion
475 (backward-to-indentation 0)
476 (= (char-after) (string-to-char "#"))))
477
3a47b28 Chris Wanstrath docs
authored
478 ;;
479 ;; Define Major Mode
480 ;;
481
af021a5 Joshua Peek magic autoload comments
josh authored
482 ;;;###autoload
cf028f8 Chris Wanstrath basics
authored
483 (define-derived-mode coffee-mode fundamental-mode
484 "coffee-mode"
485 "Major mode for editing CoffeeScript..."
486
7557530 Chris Wanstrath compilation commands
authored
487 (define-key coffee-mode-map (kbd "A-r") 'coffee-compile-buffer)
79333bf Chris Wanstrath Bugfix: Bad binding
authored
488 (define-key coffee-mode-map (kbd "A-R") 'coffee-compile-region)
eee29e0 Chris Wanstrath defvar the keymap
authored
489 (define-key coffee-mode-map (kbd "A-M-r") 'coffee-repl)
7557530 Chris Wanstrath compilation commands
authored
490 (define-key coffee-mode-map [remap comment-dwim] 'coffee-comment-dwim)
8bfb7ed Chris Wanstrath Keep same indentation of last line when creating a new line
authored
491 (define-key coffee-mode-map "\C-m" 'coffee-newline-and-indent)
7557530 Chris Wanstrath compilation commands
authored
492
cf028f8 Chris Wanstrath basics
authored
493 ;; code for syntax highlighting
494 (setq font-lock-defaults '((coffee-font-lock-keywords)))
495
84ab684 Chris Wanstrath comments
authored
496 ;; perl style comment: "# ..."
497 (modify-syntax-entry ?# "< b" coffee-mode-syntax-table)
498 (modify-syntax-entry ?\n "> b" coffee-mode-syntax-table)
0480381 Chris Wanstrath mini docs
authored
499 (setq comment-start "#")
84ab684 Chris Wanstrath comments
authored
500
9ff612a Chris Wanstrath single quotes
authored
501 ;; single quote strings
502 (modify-syntax-entry ?' "\"" coffee-mode-syntax-table)
503 (modify-syntax-entry ?' "\"" coffee-mode-syntax-table)
504
d6b78ed Chris Wanstrath defvars and basic indentation
authored
505 ;; indentation
506 (make-local-variable 'indent-line-function)
507 (setq indent-line-function 'coffee-indent-line)
508
30d2af5 Chris Wanstrath Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
509 ;; imenu
510 (make-local-variable 'imenu-create-index-function)
511 (setq imenu-create-index-function 'coffee-imenu-create-index)
512
d6b78ed Chris Wanstrath defvars and basic indentation
authored
513 ;; no tabs
514 (setq indent-tabs-mode nil)
515
cf028f8 Chris Wanstrath basics
authored
516 ;; clear memory
30d2af5 Chris Wanstrath Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
517 ;; TODO: make these accurate
cf028f8 Chris Wanstrath basics
authored
518 (setq coffee-keywords-regexp nil)
519 (setq coffee-types-regexp nil)
520 (setq coffee-constants-regexp nil)
521 (setq coffee-events-regexp nil)
522 (setq coffee-functions-regexp nil))
eaf28ab Chris Wanstrath register as .coffee handler
authored
523
27ffada Chris Wanstrath provide something
authored
524 (provide 'coffee-mode)
525
eaf28ab Chris Wanstrath register as .coffee handler
authored
526 ;;
527 ;; On Load
528 ;;
529
530 ;; Run coffee-mode for files ending in .coffee.
af021a5 Joshua Peek magic autoload comments
josh authored
531 ;;;###autoload
eaf28ab Chris Wanstrath register as .coffee handler
authored
532 (add-to-list 'auto-mode-alist '("\\.coffee$" . coffee-mode))
af021a5 Joshua Peek magic autoload comments
josh authored
533 ;;;###autoload
605a330 Chris Wanstrath highlight Cakefile too
authored
534 (add-to-list 'auto-mode-alist '("Cakefile" . coffee-mode))
Something went wrong with that request. Please try again.