Skip to content

HTTPS clone URL

Subversion checkout URL

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