Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 899 lines (729 sloc) 29.38 kb
4a11c70 @defunkt documentation
authored
1 ;;; coffee-mode.el --- Major mode to edit CoffeeScript files in Emacs
2
3 ;; Copyright (C) 2010 Chris Wanstrath
4
89203e8 @rrthomas Make version consistent and bump it to 0.4.1 (Fixes #61).
rrthomas authored
5 ;; Version: 0.4.1
4a11c70 @defunkt documentation
authored
6 ;; Keywords: CoffeeScript major mode
7 ;; Author: Chris Wanstrath <chris@ozmm.org>
1d2aed3 @defunkt Use correct URL. Fixes #71
authored
8 ;; URL: http://github.com/defunkt/coffee-mode
4a11c70 @defunkt documentation
authored
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
20c919a @rrthomas Change installation instructions to advise use of ELPA.
rrthomas authored
28 ;; Provides syntax highlighting, indentation support, imenu support,
29 ;; a menu bar, and a few cute commands.
4a11c70 @defunkt documentation
authored
30
20c919a @rrthomas Change installation instructions to advise use of ELPA.
rrthomas authored
31 ;; ## Indentation
4a11c70 @defunkt documentation
authored
32
20c919a @rrthomas Change installation instructions to advise use of ELPA.
rrthomas authored
33 ;; ### TAB Theory
4a11c70 @defunkt documentation
authored
34
20c919a @rrthomas Change installation instructions to advise use of ELPA.
rrthomas authored
35 ;; It goes like this: when you press `TAB`, we indent the line unless
36 ;; doing so would make the current line more than two indentation levels
37 ;; deepers than the previous line. If that's the case, remove all
38 ;; indentation.
4a11c70 @defunkt documentation
authored
39
20c919a @rrthomas Change installation instructions to advise use of ELPA.
rrthomas authored
40 ;; Consider this code, with point at the position indicated by the
41 ;; caret:
4a11c70 @defunkt documentation
authored
42
20c919a @rrthomas Change installation instructions to advise use of ELPA.
rrthomas authored
43 ;; line1()
44 ;; line2()
45 ;; line3()
46 ;; ^
4a11c70 @defunkt documentation
authored
47
20c919a @rrthomas Change installation instructions to advise use of ELPA.
rrthomas authored
48 ;; Pressing `TAB` will produce the following code:
4a11c70 @defunkt documentation
authored
49
20c919a @rrthomas Change installation instructions to advise use of ELPA.
rrthomas authored
50 ;; line1()
51 ;; line2()
52 ;; line3()
53 ;; ^
4a11c70 @defunkt documentation
authored
54
20c919a @rrthomas Change installation instructions to advise use of ELPA.
rrthomas authored
55 ;; Pressing `TAB` again will produce this code:
56
57 ;; line1()
58 ;; line2()
59 ;; line3()
60 ;; ^
61
62 ;; And so on. I think this is a pretty good way of getting decent
63 ;; indentation with a whitespace-sensitive language.
64
65 ;; ### Newline and Indent
66
67 ;; We all love hitting `RET` and having the next line indented
68 ;; properly. Given this code and cursor position:
69
70 ;; line1()
71 ;; line2()
72 ;; line3()
73 ;; ^
74
75 ;; Pressing `RET` would insert a newline and place our cursor at the
76 ;; following position:
77
78 ;; line1()
79 ;; line2()
80 ;; line3()
81
82 ;; ^
83
84 ;; In other words, the level of indentation is maintained. This
85 ;; applies to comments as well. Combined with the `TAB` you should be
86 ;; able to get things where you want them pretty easily.
87
88 ;; ### Indenters
89
90 ;; `class`, `for`, `if`, and possibly other keywords cause the next line
91 ;; to be indented a level deeper automatically.
92
93 ;; For example, given this code and cursor position::
94
95 ;; class Animal
96 ;; ^
97
98 ;; Pressing enter would produce the following:
99
100 ;; class Animal
101
102 ;; ^
103
104 ;; That is, indented a column deeper.
105
106 ;; This also applies to lines ending in `->`, `=>`, `{`, `[`, and
107 ;; possibly more characters.
108
109 ;; So this code and cursor position:
110
111 ;; $('#demo').click ->
112 ;; ^
113
114 ;; On enter would produce this:
115
116 ;; $('#demo').click ->
117
118 ;; ^
119
120 ;; Pretty slick.
121
122 ;; Thanks to Jeremy Ashkenas for CoffeeScript, and to
123 ;; http://xahlee.org/emacs/elisp_syntax_coloring.html, Jason
124 ;; Blevins's markdown-mode.el and Steve Yegge's js2-mode for guidance.
38ce8da @defunkt small tweaks
authored
125
12bd5d0 @defunkt todo
authored
126 ;; TODO:
127 ;; - Make prototype accessor assignments like `String::length: -> 10` pretty.
5b00ae2 @defunkt more todo
authored
128 ;; - mirror-mode - close brackets and parens automatically
12bd5d0 @defunkt todo
authored
129
130 ;;; Code:
131
6639c36 @mkhl Silence byte-compiler warnings.
mkhl authored
132 (require 'comint)
38ce8da @defunkt small tweaks
authored
133 (require 'easymenu)
134 (require 'font-lock)
6639c36 @mkhl Silence byte-compiler warnings.
mkhl authored
135
136 (eval-when-compile
137 (require 'cl))
0480381 @defunkt mini docs
authored
138
7557530 @defunkt compilation commands
authored
139 ;;
38ce8da @defunkt small tweaks
authored
140 ;; Customizable Variables
7557530 @defunkt compilation commands
authored
141 ;;
142
89203e8 @rrthomas Make version consistent and bump it to 0.4.1 (Fixes #61).
rrthomas authored
143 (defconst coffee-mode-version "0.4.1"
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
144 "The version of `coffee-mode'.")
5f14029 @defunkt Menu
authored
145
7976bc4 @defunkt Make config options available from `customize-group`, document in README
authored
146 (defgroup coffee nil
147 "A CoffeeScript major mode."
148 :group 'languages)
149
150 (defcustom coffee-tab-width tab-width
151 "The tab width to use when indenting."
152 :type 'integer
153 :group 'coffee)
154
155 (defcustom coffee-command "coffee"
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
156 "The CoffeeScript command used for evaluating code."
7976bc4 @defunkt Make config options available from `customize-group`, document in README
authored
157 :type 'string
158 :group 'coffee)
7557530 @defunkt compilation commands
authored
159
1561b47 Adds an option to move the output directory for the JavaScript files
Ivan Stoyanov Arabadzhiev authored
160 (defcustom coffee-js-directory ""
161 "The directory for compiled JavaScript files output"
162 :type 'string
163 :group 'coffee)
164
2c204ef @mizchi add coffee-js2coffee-replace-region
mizchi authored
165 (defcustom js2coffee-command "js2coffee"
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
166 "The js2coffee command used for evaluating code."
2c204ef @mizchi add coffee-js2coffee-replace-region
mizchi authored
167 :type 'string
168 :group 'coffee)
169
3b0962d @defunkt Rename `args` variables to be more consistent.
authored
170 (defcustom coffee-args-repl '("-i")
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
171 "The arguments to pass to `coffee-command' to start a REPL."
7976bc4 @defunkt Make config options available from `customize-group`, document in README
authored
172 :type 'list
173 :group 'coffee)
28485fa @defunkt `coffee-repl'
authored
174
227a360 @orlandohill Customize args for compiling files and display the first compiler error
orlandohill authored
175 (defcustom coffee-args-compile '("-c")
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
176 "The arguments to pass to `coffee-command' to compile a file."
7976bc4 @defunkt Make config options available from `customize-group`, document in README
authored
177 :type 'list
178 :group 'coffee)
5f14029 @defunkt Menu
authored
179
7976bc4 @defunkt Make config options available from `customize-group`, document in README
authored
180 (defcustom coffee-compiled-buffer-name "*coffee-compiled*"
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
181 "The name of the scratch buffer used for compiled CoffeeScript."
7976bc4 @defunkt Make config options available from `customize-group`, document in README
authored
182 :type 'string
183 :group 'coffee)
7557530 @defunkt compilation commands
authored
184
14a0d56 @errge Added coffee-compile-jump-to-error.
errge authored
185 (defcustom coffee-compile-jump-to-error t
186 "Whether to jump to the first error if compilation fails.
e5f93e8 @rrthomas Improve the coffee-compile-jump-to-error docstring.
rrthomas authored
187 Since the coffee compiler does not always include a line number in
188 its error messages, this is not always possible."
14a0d56 @errge Added coffee-compile-jump-to-error.
errge authored
189 :type 'boolean
190 :group 'coffee)
191
0b06b86 @semperos Add support for coffee --watch, and in process also add function for run...
semperos authored
192 (defcustom coffee-watch-buffer-name "*coffee-watch*"
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
193 "The name of the scratch buffer used when using the --watch flag
194 with CoffeeScript."
0b06b86 @semperos Add support for coffee --watch, and in process also add function for run...
semperos authored
195 :type 'string
196 :group 'coffee)
197
6d1d92d @rrthomas Make coffee-mode-hook customizable.
rrthomas authored
198 (defcustom coffee-mode-hook nil
20c919a @rrthomas Change installation instructions to advise use of ELPA.
rrthomas authored
199 "Hook called by `coffee-mode'. Examples:
200
201 ;; CoffeeScript uses two spaces.
202 (make-local-variable 'tab-width)
203 (set 'tab-width 2)
204
205 ;; If you don't want your compiled files to be wrapped
206 (setq coffee-args-compile '(\"-c\" \"--bare\"))
207
208 ;; Emacs key binding
209 (define-key coffee-mode-map [(meta r)] 'coffee-compile-buffer)
210
211 ;; Bleeding edge.
212 (setq coffee-command \"~/dev/coffee\")
213
214 ;; Compile '.coffee' files on every save
215 (and (file-exists-p (buffer-file-name))
216 (file-exists-p (coffee-compiled-file-name))
217 (coffee-cos-mode t)))"
6d1d92d @rrthomas Make coffee-mode-hook customizable.
rrthomas authored
218 :type 'hook
219 :group 'coffee)
1b887a5 @defunkt clean whitespace on save
authored
220
677cf42 fix some really obnoxious indentation
Justine Tunney authored
221 (defvar coffee-mode-map
222 (let ((map (make-sparse-keymap)))
223 ;; key bindings
224 (define-key map (kbd "A-r") 'coffee-compile-buffer)
225 (define-key map (kbd "A-R") 'coffee-compile-region)
226 (define-key map (kbd "A-M-r") 'coffee-repl)
227 (define-key map [remap comment-dwim] 'coffee-comment-dwim)
228 (define-key map [remap newline-and-indent] 'coffee-newline-and-indent)
229 (define-key map "\C-m" 'coffee-newline-and-indent)
230 (define-key map "\C-c\C-o\C-s" 'coffee-cos-mode)
67e8727 backspace now de-indents instead of just going back a space.
Shawn Krisman authored
231 (define-key map "\177" 'coffee-dedent-line-backspace)
e45ce09 @akheron Add functions for shifting blocks of code left and right
akheron authored
232 (define-key map (kbd "C-c C-<") 'coffee-indent-shift-left)
233 (define-key map (kbd "C-c C->") 'coffee-indent-shift-right)
677cf42 fix some really obnoxious indentation
Justine Tunney authored
234 map)
eee29e0 @defunkt defvar the keymap
authored
235 "Keymap for CoffeeScript major mode.")
236
38ce8da @defunkt small tweaks
authored
237 ;;
238 ;; Commands
239 ;;
240
28485fa @defunkt `coffee-repl'
authored
241 (defun coffee-repl ()
242 "Launch a CoffeeScript REPL using `coffee-command' as an inferior mode."
243 (interactive)
244
17150cf @defunkt docs and starting to implement indenters
authored
245 (unless (comint-check-proc "*CoffeeREPL*")
28485fa @defunkt `coffee-repl'
authored
246 (set-buffer
17150cf @defunkt docs and starting to implement indenters
authored
247 (apply 'make-comint "CoffeeREPL"
d06825b @fred-o Workaround to avoid getting garbage chars in the comint buffer.
fred-o authored
248 "env"
249 nil (append (list "NODE_NO_READLINE=1" coffee-command) coffee-args-repl))))
28485fa @defunkt `coffee-repl'
authored
250
8a3d6f5 Updating coffee-repl to pop-to-buffer using the name '*CoffeeREPL*' inst...
Nick Parker authored
251 (pop-to-buffer "*CoffeeREPL*"))
38ce8da @defunkt small tweaks
authored
252
62c84fb @knu Add a function coffee-compiled-file-name for ease of scripting.
knu authored
253 (defun coffee-compiled-file-name (&optional filename)
1561b47 Adds an option to move the output directory for the JavaScript files
Ivan Stoyanov Arabadzhiev authored
254 (setq working-on-file (expand-file-name (or filename (buffer-file-name))))
255 (unless (string= coffee-js-directory "")
256 (setq working-on-file (expand-file-name (concat (file-name-directory working-on-file) coffee-js-directory (file-name-nondirectory working-on-file)))))
62c84fb @knu Add a function coffee-compiled-file-name for ease of scripting.
knu authored
257 "Returns the name of the JavaScript file compiled from a CoffeeScript file.
258 If FILENAME is omitted, the current buffer's file name is used."
1561b47 Adds an option to move the output directory for the JavaScript files
Ivan Stoyanov Arabadzhiev authored
259 (concat (file-name-sans-extension working-on-file) ".js"))
62c84fb @knu Add a function coffee-compiled-file-name for ease of scripting.
knu authored
260
cbd31f9 @defunkt coffee-compile-file
authored
261 (defun coffee-compile-file ()
20c919a @rrthomas Change installation instructions to advise use of ELPA.
rrthomas authored
262 "Compiles and saves the current file to disk in a file of the same
263 base name, with extension `.js'. Subsequent runs will overwrite the
264 file.
265
266 If there are compilation errors, point is moved to the first
267 (see `coffee-compile-jump-to-error')."
cbd31f9 @defunkt coffee-compile-file
authored
268 (interactive)
227a360 @orlandohill Customize args for compiling files and display the first compiler error
orlandohill authored
269 (let ((compiler-output (shell-command-to-string (coffee-command-compile (buffer-file-name)))))
270 (if (string= compiler-output "")
62c84fb @knu Add a function coffee-compiled-file-name for ease of scripting.
knu authored
271 (message "Compiled and saved %s" (coffee-compiled-file-name))
14a0d56 @errge Added coffee-compile-jump-to-error.
errge authored
272 (let* ((msg (car (split-string compiler-output "[\n\r]+")))
66c326b @rrthomas Remove custom debug code; should use the standard Emacs debugging tools ...
rrthomas authored
273 (line (and (string-match "on line \\([0-9]+\\)" msg)
274 (string-to-number (match-string 1 msg)))))
275 (message msg)
276 (when (and coffee-compile-jump-to-error line (> line 0))
277 (goto-char (point-min))
278 (forward-line (1- line)))))))
cbd31f9 @defunkt coffee-compile-file
authored
279
7557530 @defunkt compilation commands
authored
280 (defun coffee-compile-buffer ()
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
281 "Compiles the current buffer and displays the JavaScript in a buffer
282 called `coffee-compiled-buffer-name'."
7557530 @defunkt compilation commands
authored
283 (interactive)
284 (save-excursion
285 (coffee-compile-region (point-min) (point-max))))
286
287 (defun coffee-compile-region (start end)
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
288 "Compiles a region and displays the JavaScript in a buffer called
289 `coffee-compiled-buffer-name'."
7557530 @defunkt compilation commands
authored
290 (interactive "r")
291
292 (let ((buffer (get-buffer coffee-compiled-buffer-name)))
293 (when buffer
af89c39 @lcoq coffee-compile-region does not give focus to the compiled buffer, and cl...
lcoq authored
294 (with-current-buffer buffer
295 (erase-buffer))))
7557530 @defunkt compilation commands
authored
296
b4270de @semperos Allow existing `coffee-args-compile` to be used for `coffee-compile-regi...
semperos authored
297 (apply (apply-partially 'call-process-region start end coffee-command nil
298 (get-buffer-create coffee-compiled-buffer-name)
299 nil)
300 (append coffee-args-compile (list "-s" "-p")))
af89c39 @lcoq coffee-compile-region does not give focus to the compiled buffer, and cl...
lcoq authored
301
302 (let ((buffer (get-buffer coffee-compiled-buffer-name)))
303 (display-buffer buffer)
304 (with-current-buffer buffer
305 (let ((buffer-file-name "tmp.js")) (set-auto-mode)))))
3a47b28 @defunkt docs
authored
306
2c204ef @mizchi add coffee-js2coffee-replace-region
mizchi authored
307 (defun coffee-js2coffee-replace-region (start end)
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
308 "Convert JavaScript in the region into CoffeeScript."
2c204ef @mizchi add coffee-js2coffee-replace-region
mizchi authored
309 (interactive "r")
310
311 (let ((buffer (get-buffer coffee-compiled-buffer-name)))
312 (when buffer
313 (kill-buffer buffer)))
314
66c326b @rrthomas Remove custom debug code; should use the standard Emacs debugging tools ...
rrthomas authored
315 (call-process-region start end
2c204ef @mizchi add coffee-js2coffee-replace-region
mizchi authored
316 js2coffee-command nil
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
317 (current-buffer))
318 (delete-region start end))
2c204ef @mizchi add coffee-js2coffee-replace-region
mizchi authored
319
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
320 (defun coffee-version ()
321 "Show the `coffee-mode' version in the echo area."
5f14029 @defunkt Menu
authored
322 (interactive)
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
323 (message (concat "coffee-mode version " coffee-mode-version)))
5f14029 @defunkt Menu
authored
324
0b06b86 @semperos Add support for coffee --watch, and in process also add function for run...
semperos authored
325 (defun coffee-watch (dir-or-file)
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
326 "Run `coffee-run-cmd' with the --watch flag on a directory or file."
0b06b86 @semperos Add support for coffee --watch, and in process also add function for run...
semperos authored
327 (interactive "fDirectory or File: ")
328 (let ((coffee-compiled-buffer-name coffee-watch-buffer-name)
66c326b @rrthomas Remove custom debug code; should use the standard Emacs debugging tools ...
rrthomas authored
329 (args (mapconcat 'identity (append coffee-args-compile (list "--watch" (expand-file-name dir-or-file))) " ")))
0b06b86 @semperos Add support for coffee --watch, and in process also add function for run...
semperos authored
330 (coffee-run-cmd args)))
331
5f14029 @defunkt Menu
authored
332 ;;
333 ;; Menubar
334 ;;
335
336 (easy-menu-define coffee-mode-menu coffee-mode-map
337 "Menu for CoffeeScript mode"
338 '("CoffeeScript"
cbd31f9 @defunkt coffee-compile-file
authored
339 ["Compile File" coffee-compile-file]
5f14029 @defunkt Menu
authored
340 ["Compile Buffer" coffee-compile-buffer]
341 ["Compile Region" coffee-compile-region]
5256afd @defunkt tweaks
authored
342 ["REPL" coffee-repl]
5f14029 @defunkt Menu
authored
343 "---"
a707d2d @jmcejuela Update coffee-mode.el
jmcejuela authored
344 ["Version" coffee-version]
5f14029 @defunkt Menu
authored
345 ))
346
3a47b28 @defunkt docs
authored
347 ;;
348 ;; Define Language Syntax
349 ;;
350
c5831bb @sstephenson Fix for string literals with escaped quotes
sstephenson authored
351 ;; String literals
352 (defvar coffee-string-regexp "\"\\([^\\]\\|\\\\.\\)*?\"\\|'\\([^\\]\\|\\\\.\\)*?'")
353
3a47b28 @defunkt docs
authored
354 ;; Instance variables (implicit this)
2bb69be Regex for "this" variable includes underscore.
Ryan Koopmans authored
355 (defvar coffee-this-regexp "@\\(\\w\\|_\\)*\\|this")
3a47b28 @defunkt docs
authored
356
dc85f42 @tav Added support for the shorthand::syntax for .prototype.
tav authored
357 ;; Prototype::access
358 (defvar coffee-prototype-regexp "\\(\\(\\w\\|\\.\\|_\\| \\|$\\)+?\\)::\\(\\(\\w\\|\\.\\|_\\| \\|$\\)+?\\):")
359
88e7b95 @defunkt better regexps, @blah: and {blah: true, blah2:true}
authored
360 ;; Assignment
37b481e @defunkt Better assignment highlighting for `:`
authored
361 (defvar coffee-assign-regexp "\\(\\(\\w\\|\\.\\|_\\|$\\)+?\s*\\):")
30d2af5 @defunkt Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
362
7c5b19b local variable assignment is now highlighted.
Shawn Krisman authored
363 ;; Local Assignment
279bd3c allow member assignment to be highlighted just like local vars.
Shawn Krisman authored
364 (defvar coffee-local-assign-regexp "\\(\\(_\\|\\w\\|\\$\\)+\\)\s+=")
7c5b19b local variable assignment is now highlighted.
Shawn Krisman authored
365
30d2af5 @defunkt Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
366 ;; Lambda
00c197b @defunkt elisp regexps are fun
authored
367 (defvar coffee-lambda-regexp "\\((.+)\\)?\\s *\\(->\\|=>\\)")
88e7b95 @defunkt better regexps, @blah: and {blah: true, blah2:true}
authored
368
76ed341 @defunkt class support in imenu
authored
369 ;; Namespaces
370 (defvar coffee-namespace-regexp "\\b\\(class\\s +\\(\\S +\\)\\)\\b")
371
af34f91 @defunkt Booleans, better colors
authored
372 ;; Booleans
3900a8c @Wilfred adding undefined to reserved words as part of coffee-boolean-regexp (not...
Wilfred authored
373 (defvar coffee-boolean-regexp "\\b\\(true\\|false\\|yes\\|no\\|on\\|off\\|null\\|undefined\\)\\b")
3a47b28 @defunkt docs
authored
374
dbb4ec5 @defunkt comment tweaks
authored
375 ;; Regular Expressions
1fb4956 @levskaya small fix of coffee-regexp-regexp so it doesn't cause massive hangs when...
levskaya authored
376 (defvar coffee-regexp-regexp "\\/\\(\\\\.\\|\\[\\(\\\\.\\|.\\)+?\\]\\|[^/
377 ]\\)+?\\/")
3a47b28 @defunkt docs
authored
378
cf028f8 @defunkt basics
authored
379 ;; JavaScript Keywords
d6b78ed @defunkt defvars and basic indentation
authored
380 (defvar coffee-js-keywords
af34f91 @defunkt Booleans, better colors
authored
381 '("if" "else" "new" "return" "try" "catch"
cf028f8 @defunkt basics
authored
382 "finally" "throw" "break" "continue" "for" "in" "while"
383 "delete" "instanceof" "typeof" "switch" "super" "extends"
7803688 Until and loop are keywords.
Ryan Koopmans authored
384 "class" "until" "loop"))
cf028f8 @defunkt basics
authored
385
386 ;; Reserved keywords either by JS or CS.
d6b78ed @defunkt defvars and basic indentation
authored
387 (defvar coffee-js-reserved
cf028f8 @defunkt basics
authored
388 '("case" "default" "do" "function" "var" "void" "with"
389 "const" "let" "debugger" "enum" "export" "import" "native"
390 "__extends" "__hasProp"))
391
392 ;; CoffeeScript keywords.
d6b78ed @defunkt defvars and basic indentation
authored
393 (defvar coffee-cs-keywords
0a39a40 add support for the "own" keyword (for own k, v of obj ...)
Justine Tunney authored
394 '("then" "unless" "and" "or" "is" "own"
134d8a8 "where" isn't a coffeescript keyword
Justine Tunney authored
395 "isnt" "not" "of" "by" "when"))
cf028f8 @defunkt basics
authored
396
80ebae6 Added support for iced coffeescript await and defer keywords.
Marius Kjeldahl authored
397 ;; Iced CoffeeScript keywords
398 (defvar iced-coffee-cs-keywords
399 '("await" "defer"))
400
0480381 @defunkt mini docs
authored
401 ;; Regular expression combining the above three lists.
fad39cc keywords can now be member names.
Shawn Krisman authored
402 (defvar coffee-keywords-regexp
403 ;; keywords can be member names.
0686a8a only the keywords are highlighted instead of text before them.
Shawn Krisman authored
404 (concat "[^.]"
405 (regexp-opt (append coffee-js-reserved
406 coffee-js-keywords
407 coffee-cs-keywords
408 iced-coffee-cs-keywords) 'words)))
cf028f8 @defunkt basics
authored
409
410
ff61700 @defunkt that was bothering me
authored
411 ;; Create the list for font-lock. Each class of keyword is given a
412 ;; particular face.
5256afd @defunkt tweaks
authored
413 (defvar coffee-font-lock-keywords
ff61700 @defunkt that was bothering me
authored
414 ;; *Note*: order below matters. `coffee-keywords-regexp' goes last
415 ;; because otherwise the keyword "state" in the function
416 ;; "state_entry" would be highlighted.
c5831bb @sstephenson Fix for string literals with escaped quotes
sstephenson authored
417 `((,coffee-string-regexp . font-lock-string-face)
418 (,coffee-this-regexp . font-lock-variable-name-face)
dc85f42 @tav Added support for the shorthand::syntax for .prototype.
tav authored
419 (,coffee-prototype-regexp . font-lock-variable-name-face)
ff61700 @defunkt that was bothering me
authored
420 (,coffee-assign-regexp . font-lock-type-face)
279bd3c allow member assignment to be highlighted just like local vars.
Shawn Krisman authored
421 (,coffee-local-assign-regexp 1 font-lock-variable-name-face)
ff61700 @defunkt that was bothering me
authored
422 (,coffee-regexp-regexp . font-lock-constant-face)
423 (,coffee-boolean-regexp . font-lock-constant-face)
bdb258b color -> and => as functions.
Shawn Krisman authored
424 (,coffee-lambda-regexp . (2 font-lock-function-name-face))
0686a8a only the keywords are highlighted instead of text before them.
Shawn Krisman authored
425 (,coffee-keywords-regexp 1 font-lock-keyword-face)))
cf028f8 @defunkt basics
authored
426
3a47b28 @defunkt docs
authored
427 ;;
428 ;; Helper Functions
429 ;;
430
9ff612a @defunkt single quotes
authored
431 (defun coffee-comment-dwim (arg)
432 "Comment or uncomment current line or region in a smart way.
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
433 For details, see `comment-dwim'."
9ff612a @defunkt single quotes
authored
434 (interactive "*P")
435 (require 'newcomment)
436 (let ((deactivate-mark nil) (comment-start "#") (comment-end ""))
437 (comment-dwim arg)))
84ab684 @defunkt comments
authored
438
227a360 @orlandohill Customize args for compiling files and display the first compiler error
orlandohill authored
439 (defun coffee-command-compile (file-name)
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
440 "Run `coffee-command' to compile FILE."
1561b47 Adds an option to move the output directory for the JavaScript files
Ivan Stoyanov Arabadzhiev authored
441 (let (
442 (full-file-name
443 (expand-file-name file-name))
444 (output-directory
445 (concat " -o " (file-name-directory (expand-file-name file-name)) coffee-js-directory)))
446 (mapconcat 'identity (append (list coffee-command) coffee-args-compile (list output-directory) (list full-file-name)) " ")))
5b00ae2 @defunkt more todo
authored
447
0b06b86 @semperos Add support for coffee --watch, and in process also add function for run...
semperos authored
448 (defun coffee-run-cmd (args)
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
449 "Run `coffee-command' with the given arguments, and display the
450 output in a compilation buffer."
0b06b86 @semperos Add support for coffee --watch, and in process also add function for run...
semperos authored
451 (interactive "sArguments: ")
452 (let ((compilation-buffer-name-function (lambda (this-mode)
453 (generate-new-buffer-name coffee-compiled-buffer-name))))
454 (compile (concat coffee-command " " args))))
455
2504ebe @defunkt explain indentation plan
authored
456 ;;
30d2af5 @defunkt Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
457 ;; imenu support
458 ;;
459
460 ;; This is a pretty naive but workable way of doing it. First we look
461 ;; for any lines that starting with `coffee-assign-regexp' that include
462 ;; `coffee-lambda-regexp' then add those tokens to the list.
463 ;;
464 ;; Should cover cases like these:
465 ;;
466 ;; minus: (x, y) -> x - y
467 ;; String::length: -> 10
468 ;; block: ->
469 ;; print('potion')
470 ;;
471 ;; Next we look for any line that starts with `class' or
472 ;; `coffee-assign-regexp' followed by `{` and drop into a
473 ;; namespace. This means we search one indentation level deeper for
474 ;; more assignments and add them to the alist prefixed with the
475 ;; namespace name.
476 ;;
477 ;; Should cover cases like these:
478 ;;
479 ;; class Person
480 ;; print: ->
481 ;; print 'My name is ' + this.name + '.'
482 ;;
483 ;; class Policeman extends Person
484 ;; constructor: (rank) ->
485 ;; @rank: rank
486 ;; print: ->
487 ;; print 'My name is ' + this.name + " and I'm a " + this.rank + '.'
488 ;;
76ed341 @defunkt class support in imenu
authored
489 ;; TODO:
30d2af5 @defunkt Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
490 ;; app = {
491 ;; window: {width: 200, height: 200}
492 ;; para: -> 'Welcome.'
493 ;; button: -> 'OK'
494 ;; }
495
496 (defun coffee-imenu-create-index ()
497 "Create an imenu index of all methods in the buffer."
498 (interactive)
499
500 ;; This function is called within a `save-excursion' so we're safe.
6639c36 @mkhl Silence byte-compiler warnings.
mkhl authored
501 (goto-char (point-min))
30d2af5 @defunkt Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
502
76ed341 @defunkt class support in imenu
authored
503 (let ((index-alist '()) assign pos indent ns-name ns-indent)
30d2af5 @defunkt Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
504 ;; Go through every assignment that includes -> or => on the same
c6562af @defunkt Make `coffee-debug' a macro
authored
505 ;; line or starts with `class'.
30d2af5 @defunkt Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
506 (while (re-search-forward
76ed341 @defunkt class support in imenu
authored
507 (concat "^\\(\\s *\\)"
508 "\\("
509 coffee-assign-regexp
510 ".+?"
511 coffee-lambda-regexp
512 "\\|"
513 coffee-namespace-regexp
514 "\\)")
30d2af5 @defunkt Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
515 (point-max)
516 t)
517
76ed341 @defunkt class support in imenu
authored
518 ;; If this is the start of a new namespace, save the namespace's
519 ;; indentation level and name.
7f5e1b3 @defunkt Bugfix: Clear old namespace when a new one is found
authored
520 (when (match-string 8)
521 ;; Set the name.
522 (setq ns-name (match-string 8))
523
76ed341 @defunkt class support in imenu
authored
524 ;; If this is a class declaration, add :: to the namespace.
525 (setq ns-name (concat ns-name "::"))
526
527 ;; Save the indentation level.
66c326b @rrthomas Remove custom debug code; should use the standard Emacs debugging tools ...
rrthomas authored
528 (setq ns-indent (length (match-string 1))))
76ed341 @defunkt class support in imenu
authored
529
530 ;; If this is an assignment, save the token being
531 ;; assigned. `Please.print:` will be `Please.print`, `block:`
532 ;; will be `block`, etc.
533 (when (setq assign (match-string 3))
534 ;; The position of the match in the buffer.
535 (setq pos (match-beginning 3))
536
537 ;; The indent level of this match
538 (setq indent (length (match-string 1)))
539
540 ;; If we're within the context of a namespace, add that to the
541 ;; front of the assign, e.g.
542 ;; constructor: => Policeman::constructor
543 (when (and ns-name (> indent ns-indent))
544 (setq assign (concat ns-name assign)))
545
546 ;; Clear the namespace if we're no longer indented deeper
547 ;; than it.
548 (when (and ns-name (<= indent ns-indent))
549 (setq ns-name nil)
550 (setq ns-indent nil))
551
552 ;; Add this to the alist. Done.
553 (push (cons assign pos) index-alist)))
30d2af5 @defunkt Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
554
555 ;; Return the alist.
556 index-alist))
557
558 ;;
d6b78ed @defunkt defvars and basic indentation
authored
559 ;; Indentation
2504ebe @defunkt explain indentation plan
authored
560 ;;
561
dbb4ec5 @defunkt comment tweaks
authored
562 ;;; The theory is explained in the README.
97a1001 @defunkt basic indentation with TAB
authored
563
d6b78ed @defunkt defvars and basic indentation
authored
564 (defun coffee-indent-line ()
7b03a71 @defunkt indentation theory
authored
565 "Indent current line as CoffeeScript."
d6b78ed @defunkt defvars and basic indentation
authored
566 (interactive)
567
df7ae3b @defunkt Bugfix: Indenting blank lines with TAB
authored
568 (if (= (point) (point-at-bol))
569 (insert-tab)
570 (save-excursion
3f4271f @rrthomas Simplify coffee-indent-line and coffee-previous-indent.
rrthomas authored
571 (let ((prev-indent (coffee-previous-indent))
572 (cur-indent (current-indentation)))
df7ae3b @defunkt Bugfix: Indenting blank lines with TAB
authored
573 ;; Shift one column to the left
574 (beginning-of-line)
575 (insert-tab)
576
577 (when (= (point-at-bol) (point))
7976bc4 @defunkt Make config options available from `customize-group`, document in README
authored
578 (forward-char coffee-tab-width))
df7ae3b @defunkt Bugfix: Indenting blank lines with TAB
authored
579
580 ;; We're too far, remove all indentation.
7976bc4 @defunkt Make config options available from `customize-group`, document in README
authored
581 (when (> (- (current-indentation) prev-indent) coffee-tab-width)
df7ae3b @defunkt Bugfix: Indenting blank lines with TAB
authored
582 (backward-to-indentation 0)
583 (delete-region (point-at-bol) (point)))))))
b7ee8b8 @defunkt start cleaning up indentation code
authored
584
585 (defun coffee-previous-indent ()
586 "Return the indentation level of the previous non-blank line."
587 (save-excursion
588 (forward-line -1)
d063614 @superbobry Fix hanging of `coffee-previous-indent` at start of buffer.
superbobry authored
589 (if (bobp)
590 0
591 (progn
3f4271f @rrthomas Simplify coffee-indent-line and coffee-previous-indent.
rrthomas authored
592 (while (and (looking-at "^[ \t]*$") (not (bobp))) (forward-line -1))
d063614 @superbobry Fix hanging of `coffee-previous-indent` at start of buffer.
superbobry authored
593 (current-indentation)))))
b7ee8b8 @defunkt start cleaning up indentation code
authored
594
17150cf @defunkt docs and starting to implement indenters
authored
595 (defun coffee-newline-and-indent ()
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
596 "Insert a newline and indent it to the same level as the previous line."
17150cf @defunkt docs and starting to implement indenters
authored
597 (interactive)
598
599 ;; Remember the current line indentation level,
600 ;; insert a newline, and indent the newline to the same
601 ;; level as the previous line.
602 (let ((prev-indent (current-indentation)) (indent-next nil))
74a9135 @piranha do not leave trailing whitespaces on newline
piranha authored
603 (delete-horizontal-space t)
17150cf @defunkt docs and starting to implement indenters
authored
604 (newline)
7976bc4 @defunkt Make config options available from `customize-group`, document in README
authored
605 (insert-tab (/ prev-indent coffee-tab-width))
3a47b28 @defunkt docs
authored
606
17150cf @defunkt docs and starting to implement indenters
authored
607 ;; We need to insert an additional tab because the last line was special.
608 (when (coffee-line-wants-indent)
609 (insert-tab)))
610
611 ;; Last line was a comment so this one should probably be,
612 ;; too. Makes it easy to write multi-line comments (like the one I'm
613 ;; writing right now).
614 (when (coffee-previous-line-is-comment)
615 (insert "# ")))
616
fc4e054 dedent respects increments of `coffee-tab-width`
Le Wang authored
617 (defun coffee-dedent-line-backspace (arg)
618 "Unindent to increment of `coffee-tab-width' with ARG==1 when
619 called from first non-blank char of line.
620
621 Delete ARG spaces if ARG!=1."
622 (interactive "*p")
623 (if (and (= 1 arg)
624 (= (point) (save-excursion
625 (back-to-indentation)
626 (point)))
fed87e1 check bol properly
Le Wang authored
627 (not (bolp)))
fc4e054 dedent respects increments of `coffee-tab-width`
Le Wang authored
628 (let ((extra-space-count (% (current-column) coffee-tab-width)))
629 (backward-delete-char-untabify
630 (if (zerop extra-space-count)
631 coffee-tab-width
632 extra-space-count)))
633 (backward-delete-char-untabify arg)))
67e8727 backspace now de-indents instead of just going back a space.
Shawn Krisman authored
634
17150cf @defunkt docs and starting to implement indenters
authored
635 ;; Indenters help determine whether the current line should be
636 ;; indented further based on the content of the previous line. If a
637 ;; line starts with `class', for instance, you're probably going to
638 ;; want to indent the next line.
639
9eca4aa @theJohnnyBrown indent following while statement
theJohnnyBrown authored
640 (defvar coffee-indenters-bol '("class" "for" "if" "try" "while")
7d338d1 @defunkt coffee-indenters
authored
641 "Keywords or syntax whose presence at the start of a line means the
642 next line should probably be indented.")
643
644 (defun coffee-indenters-bol-regexp ()
645 "Builds a regexp out of `coffee-indenters-bol' words."
27df14a @defunkt Fix coffee-indenters-bol-regexp. Closes #36
authored
646 (regexp-opt coffee-indenters-bol 'words))
7d338d1 @defunkt coffee-indenters
authored
647
5e170be @defunkt get it working (with a fake function though)
authored
648 (defvar coffee-indenters-eol '(?> ?{ ?\[)
649 "Single characters at the end of a line that mean the next line
650 should probably be indented.")
7d338d1 @defunkt coffee-indenters
authored
651
17150cf @defunkt docs and starting to implement indenters
authored
652 (defun coffee-line-wants-indent ()
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
653 "Return t if the current line should be indented relative to the
654 previous line."
8bfb7ed @defunkt Keep same indentation of last line when creating a new line
authored
655 (interactive)
656
17150cf @defunkt docs and starting to implement indenters
authored
657 (save-excursion
658 (let ((indenter-at-bol) (indenter-at-eol))
659 ;; Go back a line and to the first character.
660 (forward-line -1)
661 (backward-to-indentation 0)
8bfb7ed @defunkt Keep same indentation of last line when creating a new line
authored
662
17150cf @defunkt docs and starting to implement indenters
authored
663 ;; If the next few characters match one of our magic indenter
664 ;; keywords, we want to indent the line we were on originally.
665 (when (looking-at (coffee-indenters-bol-regexp))
66c326b @rrthomas Remove custom debug code; should use the standard Emacs debugging tools ...
rrthomas authored
666 (setq indenter-at-bol t))
17150cf @defunkt docs and starting to implement indenters
authored
667
668 ;; If that didn't match, go to the back of the line and check to
5e170be @defunkt get it working (with a fake function though)
authored
669 ;; see if the last character matches one of our indenter
670 ;; characters.
17150cf @defunkt docs and starting to implement indenters
authored
671 (when (not indenter-at-bol)
672 (end-of-line)
673
5e170be @defunkt get it working (with a fake function though)
authored
674 ;; Optimized for speed - checks only the last character.
65797fa @jaeyeom Fix missing function `some' issue when loading compiled elisp.
jaeyeom authored
675 (let ((indenters coffee-indenters-eol))
676 (while indenters
df0dfbc resolved issue #63. Fixed inspired by tzeskimo 6c5eb29.
Keith Simmons authored
677 (if (and (char-before) (/= (char-before) (car indenters)))
65797fa @jaeyeom Fix missing function `some' issue when loading compiled elisp.
jaeyeom authored
678 (setq indenters (cdr indenters))
679 (setq indenter-at-eol t)
680 (setq indenters nil)))))
17150cf @defunkt docs and starting to implement indenters
authored
681
682 ;; If we found an indenter, return `t'.
683 (or indenter-at-bol indenter-at-eol))))
684
8bfb7ed @defunkt Keep same indentation of last line when creating a new line
authored
685 (defun coffee-previous-line-is-comment ()
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
686 "Return t if the previous line is a CoffeeScript comment."
8bfb7ed @defunkt Keep same indentation of last line when creating a new line
authored
687 (save-excursion
688 (forward-line -1)
689 (coffee-line-is-comment)))
690
691 (defun coffee-line-is-comment ()
579e270 @rrthomas Overhaul the docstrings.
rrthomas authored
692 "Return t if the current line is a CoffeeScript comment."
8bfb7ed @defunkt Keep same indentation of last line when creating a new line
authored
693 (save-excursion
694 (backward-to-indentation 0)
695 (= (char-after) (string-to-char "#"))))
696
168b32d @disnet fixing triple quoted strings issue with code from python-mode
disnet authored
697
c5fb056 remove triple quotes, seems to be doing strange things to python-mode
Justine Tunney authored
698 ;; (defun coffee-quote-syntax (n)
699 ;; "Put `syntax-table' property correctly on triple quote.
700 ;; Used for syntactic keywords. N is the match number (1, 2 or 3)."
701 ;; ;; From python-mode...
702 ;; ;;
703 ;; ;; Given a triple quote, we have to check the context to know
704 ;; ;; whether this is an opening or closing triple or whether it's
705 ;; ;; quoted anyhow, and should be ignored. (For that we need to do
706 ;; ;; the same job as `syntax-ppss' to be correct and it seems to be OK
707 ;; ;; to use it here despite initial worries.) We also have to sort
708 ;; ;; out a possible prefix -- well, we don't _have_ to, but I think it
709 ;; ;; should be treated as part of the string.
710
711 ;; ;; Test cases:
712 ;; ;; ur"""ar""" x='"' # """
713 ;; ;; x = ''' """ ' a
714 ;; ;; '''
715 ;; ;; x '"""' x """ \"""" x
716 ;; (save-excursion
717 ;; (goto-char (match-beginning 0))
718 ;; (cond
719 ;; ;; Consider property for the last char if in a fenced string.
720 ;; ((= n 3)
721 ;; (let* ((font-lock-syntactic-keywords nil)
722 ;; (syntax (syntax-ppss)))
723 ;; (when (eq t (nth 3 syntax)) ; after unclosed fence
724 ;; (goto-char (nth 8 syntax)) ; fence position
725 ;; ;; (skip-chars-forward "uUrR") ; skip any prefix
726 ;; ;; Is it a matching sequence?
727 ;; (if (eq (char-after) (char-after (match-beginning 2)))
728 ;; (eval-when-compile (string-to-syntax "|"))))))
729 ;; ;; Consider property for initial char, accounting for prefixes.
730 ;; ((or (and (= n 2) ; leading quote (not prefix)
731 ;; (not (match-end 1))) ; prefix is null
732 ;; (and (= n 1) ; prefix
733 ;; (match-end 1))) ; non-empty
734 ;; (let ((font-lock-syntactic-keywords nil))
735 ;; (unless (eq 'string (syntax-ppss-context (syntax-ppss)))
736 ;; (eval-when-compile (string-to-syntax "|")))))
737 ;; ;; Otherwise (we're in a non-matching string) the property is
738 ;; ;; nil, which is OK.
739 ;; )))
168b32d @disnet fixing triple quoted strings issue with code from python-mode
disnet authored
740
ae2875f @akheron coffee-indent-shift-*: Indent to the closest increment of coffee-tab-wid...
akheron authored
741 (defun coffee-indent-shift-amount (start end dir)
742 "Compute distance to the closest increment of `coffee-tab-width'."
743 (let ((min most-positive-fixnum) rem)
744 (save-excursion
745 (goto-char start)
746 (while (< (point) end)
747 (let ((current (current-indentation)))
748 (when (< current min) (setq min current)))
749 (forward-line))
750 (setq rem (% min coffee-tab-width))
751 (if (zerop rem)
752 coffee-tab-width
753 (cond ((eq dir 'left) rem)
754 ((eq dir 'right) (- coffee-tab-width rem))
755 (t 0))))))
756
e45ce09 @akheron Add functions for shifting blocks of code left and right
akheron authored
757 (defun coffee-indent-shift-left (start end &optional count)
758 "Shift lines contained in region START END by COUNT columns to the left.
ae2875f @akheron coffee-indent-shift-*: Indent to the closest increment of coffee-tab-wid...
akheron authored
759 If COUNT is not given, indents to the closest increment of
760 `coffee-tab-width'. If region isn't active, the current line is
761 shifted. The shifted region includes the lines in which START and
762 END lie. An error is signaled if any lines in the region are
763 indented less than COUNT columns."
e45ce09 @akheron Add functions for shifting blocks of code left and right
akheron authored
764 (interactive
765 (if mark-active
766 (list (region-beginning) (region-end) current-prefix-arg)
767 (list (line-beginning-position) (line-end-position) current-prefix-arg)))
ae2875f @akheron coffee-indent-shift-*: Indent to the closest increment of coffee-tab-wid...
akheron authored
768 (let ((amount (if count (prefix-numeric-value count)
769 (coffee-indent-shift-amount start end 'left))))
770 (when (> amount 0)
771 (let (deactivate-mark)
772 (save-excursion
773 (goto-char start)
774 ;; Check that all lines can be shifted enough
775 (while (< (point) end)
776 (if (and (< (current-indentation) amount)
777 (not (looking-at "[ \t]*$")))
778 (error "Can't shift all lines enough"))
779 (forward-line))
780 (indent-rigidly start end (- amount)))))))
e45ce09 @akheron Add functions for shifting blocks of code left and right
akheron authored
781
782 (add-to-list 'debug-ignored-errors "^Can't shift all lines enough")
783
784 (defun coffee-indent-shift-right (start end &optional count)
ae2875f @akheron coffee-indent-shift-*: Indent to the closest increment of coffee-tab-wid...
akheron authored
785 "Shift lines contained in region START END by COUNT columns to the right.
786 if COUNT is not given, indents to the closest increment of
787 `coffee-tab-width'. If region isn't active, the current line is
788 shifted. The shifted region includes the lines in which START and
789 END lie."
e45ce09 @akheron Add functions for shifting blocks of code left and right
akheron authored
790 (interactive
791 (if mark-active
792 (list (region-beginning) (region-end) current-prefix-arg)
793 (list (line-beginning-position) (line-end-position) current-prefix-arg)))
ae2875f @akheron coffee-indent-shift-*: Indent to the closest increment of coffee-tab-wid...
akheron authored
794 (let (deactivate-mark
795 (amount (if count (prefix-numeric-value count)
796 (coffee-indent-shift-amount start end 'right))))
797 (indent-rigidly start end amount)))
e45ce09 @akheron Add functions for shifting blocks of code left and right
akheron authored
798
3a47b28 @defunkt docs
authored
799 ;;
800 ;; Define Major Mode
801 ;;
802
099e94a @jvshahid woot, finally got the block comment working, i love emacs extensibility.
jvshahid authored
803 (defun coffee-block-comment-delimiter (match)
804 (progn
805 (goto-char match)
806 (beginning-of-line)
807 (add-text-properties (point) (+ (point) 1) `(syntax-table (14 . nil)))))
808
809 (defun coffee-propertize-function (start end)
810 ;; return if we don't have anything to parse
811 (unless (>= start end)
812 (save-excursion
813 (progn
814 (goto-char start)
815 (let ((match (re-search-forward "^###.*$" end t)))
816 (if match
817 (progn
818 (coffee-block-comment-delimiter match)
819 (goto-char match)
820 (next-line)
821 (coffee-propertize-function (point) end))))))))
822
af021a5 @josh magic autoload comments
josh authored
823 ;;;###autoload
cf028f8 @defunkt basics
authored
824 (define-derived-mode coffee-mode fundamental-mode
4631aa1 Use "Coffee" as mode name rather than the idiosynchratic "coffee-mode".
Daniel Brockman authored
825 "Coffee"
826 "Major mode for editing CoffeeScript."
cf028f8 @defunkt basics
authored
827
828 ;; code for syntax highlighting
829 (setq font-lock-defaults '((coffee-font-lock-keywords)))
830
1c8aea3 @chellmuth Fix syntax highlighting for variables containing keywords bounded by
chellmuth authored
831 ;; treat "_" as part of a word
832 (modify-syntax-entry ?_ "w" coffee-mode-syntax-table)
833
84ab684 @defunkt comments
authored
834 ;; perl style comment: "# ..."
835 (modify-syntax-entry ?# "< b" coffee-mode-syntax-table)
836 (modify-syntax-entry ?\n "> b" coffee-mode-syntax-table)
40a5bf1 @defunkt comment-start is buffer local. fixes #10
authored
837 (make-local-variable 'comment-start)
0480381 @defunkt mini docs
authored
838 (setq comment-start "#")
84ab684 @defunkt comments
authored
839
9ff612a @defunkt single quotes
authored
840 ;; single quote strings
841 (modify-syntax-entry ?' "\"" coffee-mode-syntax-table)
842
c5fb056 remove triple quotes, seems to be doing strange things to python-mode
Justine Tunney authored
843 ;; (setq font-lock-syntactic-keywords
844 ;; ;; Make outer chars of matching triple-quote sequences into generic
845 ;; ;; string delimiters.
846 ;; ;; First avoid a sequence preceded by an odd number of backslashes.
847 ;; `((,(concat "\\(?:^\\|[^\\]\\(?:\\\\.\\)*\\)" ;Prefix.
848 ;; "\\(?:\\('\\)\\('\\)\\('\\)\\|\\(?1:\"\\)\\(?2:\"\\)\\(?3:\"\\)\\)")
849 ;; (1 (coffee-quote-syntax 1) nil lax)
850 ;; (2 (coffee-quote-syntax 2))
851 ;; (3 (coffee-quote-syntax 3)))))
168b32d @disnet fixing triple quoted strings issue with code from python-mode
disnet authored
852
d6b78ed @defunkt defvars and basic indentation
authored
853 ;; indentation
854 (make-local-variable 'indent-line-function)
855 (setq indent-line-function 'coffee-indent-line)
b4b2a53 @kelleyk Small patch to fix indentation behavior; before, the global tab-width se...
kelleyk authored
856 (set (make-local-variable 'tab-width) coffee-tab-width)
099e94a @jvshahid woot, finally got the block comment working, i love emacs extensibility.
jvshahid authored
857 (set (make-local-variable 'syntax-propertize-function) 'coffee-propertize-function)
d6b78ed @defunkt defvars and basic indentation
authored
858
30d2af5 @defunkt Basic imenu support - makes things like `textmate-goto-symbol' work!
authored
859 ;; imenu
860 (make-local-variable 'imenu-create-index-function)
861 (setq imenu-create-index-function 'coffee-imenu-create-index)
862
d6b78ed @defunkt defvars and basic indentation
authored
863 ;; no tabs
be2305f @rrthomas Remove support for removing trailing whitespace: whitepace-mode does tha...
rrthomas authored
864 (setq indent-tabs-mode nil))
eaf28ab @defunkt register as .coffee handler
authored
865
6eb6d99 @knu Introduce a minor mode `coffee-cos-mode'.
knu authored
866 ;;
867 ;; Compile-on-Save minor mode
868 ;;
869
870 (defvar coffee-cos-mode-line " CoS")
871 (make-variable-buffer-local 'coffee-cos-mode-line)
872
873 (define-minor-mode coffee-cos-mode
20c919a @rrthomas Change installation instructions to advise use of ELPA.
rrthomas authored
874 "Toggle compile-on-save for coffee-mode.
875
876 Add `'(lambda () (coffee-cos-mode t))' to `coffee-mode-hook' to turn
877 it on by default."
6eb6d99 @knu Introduce a minor mode `coffee-cos-mode'.
knu authored
878 :group 'coffee-cos :lighter coffee-cos-mode-line
879 (cond
880 (coffee-cos-mode
881 (add-hook 'after-save-hook 'coffee-compile-file nil t))
882 (t
883 (remove-hook 'after-save-hook 'coffee-compile-file t))))
884
27ffada @defunkt provide something
authored
885 (provide 'coffee-mode)
886
eaf28ab @defunkt register as .coffee handler
authored
887 ;;
888 ;; On Load
889 ;;
890
891 ;; Run coffee-mode for files ending in .coffee.
af021a5 @josh magic autoload comments
josh authored
892 ;;;###autoload
eaf28ab @defunkt register as .coffee handler
authored
893 (add-to-list 'auto-mode-alist '("\\.coffee$" . coffee-mode))
af021a5 @josh magic autoload comments
josh authored
894 ;;;###autoload
95bbfe3 autoload coffee-mode for .iced files (IcedCoffeeScript)
Justine Tunney authored
895 (add-to-list 'auto-mode-alist '("\\.iced$" . coffee-mode))
896 ;;;###autoload
605a330 @defunkt highlight Cakefile too
authored
897 (add-to-list 'auto-mode-alist '("Cakefile" . coffee-mode))
a9c8f48 Formatting changes for complians with elp/Marmalade
Scott Barron authored
898 ;;; coffee-mode.el ends here
Something went wrong with that request. Please try again.