-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
haxe-mode.el
339 lines (281 loc) · 10.5 KB
/
haxe-mode.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
;;; haxe-mode.el --- Major mode for editing Haxe files
;; Copyright (C) 2006-2007 Jens Peter Secher <[email protected]>
;; Copyright (C) 2019-2024 Shen, Jen-Chieh <[email protected]>
;; Author: Jens Peter Secher (original)
;; Maintainer: Jen-Chieh Shen <[email protected]>
;; URL: https://github.com/emacsorphanage/haxe-mode
;; Version: 0.3.3
;; This file is NOT part of GNU Emacs.
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; This is haxe-mode, an Emacs major mode for the Haxe programming
;; language (http://haxe.org).
;; haxe-mode is built on top of the excellent cc-mode, inspired by the
;; guide http://cc-mode.sourceforge.net/derived-mode-ex.el.
;;; Versions:
;;
;; 0.1.0 - Initial release.
;; 0.1.1 - Fixed typedef indentation.
;; Fixed lexical analysis so that type names can contain digits.
;; 0.2.0 - Base on java-mode instead of c++-mode.
;; Added compile-error parser for the Haxe compiler output.
;; Loads of improvements.
;; 0.2.1 - Fix buffer-local comment-start-skip problem.
;; 0.2.2 - Recognise keyword override.
;; 0.3.0 - Switched to GPLv3 license because that is what cc-mode is using.
;; 0.3.1 - Fix compile problem with emacs23.
;; 0.3.2 - Fix autoload issue.
;; 0.3.3 - Fix copyright information.
;;
;;; Usage:
;;
;; Include something like this in your .emacs:
;; (require 'haxe-mode)
;; (defconst my-haxe-style
;; '("java" (c-offsets-alist . ((case-label . +)
;; (arglist-intro . +)
;; (arglist-cont-nonempty . 0)
;; (arglist-close . 0)
;; (cpp-macro . 0))))
;; "My Haxe Programming Style")
;; (add-hook 'haxe-mode-hook
;; (function (lambda () (c-add-style "haxe" my-haxe-style t))))
;; (add-hook 'haxe-mode-hook
;; (function
;; (lambda ()
;; (setq tab-width 4)
;; (setq indent-tabs-mode t)
;; (setq fill-column 80)
;; (local-set-key [(return)] 'newline-and-indent))))
;;; Code:
(require 'cc-mode)
(require 'cc-fonts)
(require 'cc-langs)
(require 'cc-bytecomp)
(require 'compile)
;; The language constants are needed when compiling.
(eval-when-compile
(let ((load-path
(if (and (boundp 'byte-compile-dest-file)
(stringp byte-compile-dest-file))
(cons (file-name-directory byte-compile-dest-file) load-path)
load-path)))
(load "cc-mode" nil t)
(load "cc-fonts" nil t)
(load "cc-langs" nil t)
(load "cc-bytecomp" nil t)))
(eval-and-compile
;; Tell the language constant system about Haxe and base it on Java.
(c-add-language 'haxe-mode 'java-mode))
;;; Lexer-level syntax (identifiers, tokens etc).
;; No other operators in identifiers.
(c-lang-defconst c-after-id-concat-ops
haxe nil)
;; Conditional compilation prefix.
(c-lang-defconst c-opt-cpp-prefix
haxe "\\s *#")
;; No strings in conditional compilation.
(c-lang-defconst c-cpp-message-directives
haxe nil)
;; No file name in angle brackets or quotes in conditional compilation.
(c-lang-defconst c-cpp-include-directives
haxe nil)
;; No macro definition in conditional compilation.
(c-lang-defconst c-opt-cpp-macro-define
haxe nil)
;; Conditional compilation directives followed by expressions.
(c-lang-defconst c-cpp-expr-directives
haxe '("if" "else"))
;; No functions in conditional compilation.
(c-lang-defconst c-cpp-expr-functions
haxe nil)
;; Haxe operators.
(c-lang-defconst c-operators
haxe `(
;; Preprocessor.
(prefix "#")
;; Standard operators.
,@(c-lang-const c-identifier-ops)
;; Generics.
(postfix-if-paren "<" ">")
;; Postfix.
(left-assoc "." "->")
(postfix "++" "--" "[" "]" "(" ")")
;; Unary.
(prefix "++" "--" "+" "-" "!" "~" "new")
;; Multiplicative.
(left-assoc "*" "/" "%")
;; Additive.
(left-assoc "+" "-")
;; Shift.
(left-assoc "<<" ">>" ">>>")
;; Relational.
(left-assoc "<" ">" "<=" ">=")
;; Iteration.
(left-assoc "...")
;; Equality.
(left-assoc "==" "!=" "===" "!==")
;; Bitwise and.
(left-assoc "&")
;; Bitwise exclusive or.
(left-assoc "^")
;; Bitwise or.
(left-assoc "|")
;; Logical and.
(left-assoc "&&")
;; Logical or.
(left-assoc "||")
;; Assignment.
(right-assoc ,@(c-lang-const c-assignment-operators))
;; Exception.
(prefix "throw")
;; Sequence.
(left-assoc ",")))
;; No overloading.
(c-lang-defconst c-overloadable-operators
haxe nil)
(c-lang-defconst c-opt-op-identitier-prefix
haxe nil)
;;; Keywords.
;; I will treat types uniformly below since they all start with capital
;; letters.
(c-lang-defconst c-primitive-type-kwds
haxe nil)
;; TODO: check double occurrence of enum.
;; Type-introduction is straight forward in Haxe.
(c-lang-defconst c-class-decl-kwds
haxe '( "class" "interface" "enum" "typedef" "abstract" ))
;; Recognises enum constants.
;; TODO: find a way to also recognise parameterised constants.
(c-lang-defconst c-brace-list-decl-kwds
haxe '( "enum" ))
;; Keywords introducing declarations where the identifier follows directly
;; after the keyword, without any type.
(c-lang-defconst c-typeless-decl-kwds
haxe (append '( "function" "var" )
(c-lang-const c-class-decl-kwds)
(c-lang-const c-brace-list-decl-kwds)))
;; Definition modifiers.
(c-lang-defconst c-modifier-kwds
haxe '( "private" "public" "static" "override" "inline"))
(c-lang-defconst c-other-decl-kwds
haxe nil)
;; Namespaces.
(c-lang-defconst c-ref-list-kwds
haxe '( "import" "package" "using"))
;; Statement keywords followed directly by a substatement.
(c-lang-defconst c-block-stmt-1-kwds
haxe '( "do" "else" "try" ))
;; Statement keywords followed by a paren sexp and then by a substatement.
(c-lang-defconst c-block-stmt-2-kwds
haxe '( "for" "if" "switch" "while" "catch" ))
;; Statement keywords followed by an expression or nothing.
(c-lang-defconst c-simple-stmt-kwds
haxe '( "break" "continue" "return" "default" "new" ))
;; No ';' inside 'for'.
(c-lang-defconst c-paren-stmt-kwds
haxe nil)
;; Keywords for constants.
(c-lang-defconst c-constant-kwds
haxe '( "false" "true" "null" ))
;; Keywords for expressions.
(c-lang-defconst c-primary-expr-kwds
haxe '( "this" "super" ))
(c-lang-defconst c-decl-hangon-kwds
haxe '( "in" ))
;; No other labels.
(c-lang-defconst c-before-label-kwds
haxe nil)
;; No classes inside expressions.
(c-lang-defconst c-inexpr-class-kwds
haxe nil)
;; No brace lists inside expressions.
(c-lang-defconst c-inexpr-brace-list-kwds
haxe nil)
;; All identifiers starting with a capital letter are types.
(c-lang-defconst c-cpp-matchers
haxe (append
(c-lang-const c-cpp-matchers c)
'(("\\<\\([A-Z][A-Za-z0-9_]*\\)\\>" 1 font-lock-type-face))))
;; Generic types.
(c-lang-defconst c-recognize-<>-arglists
haxe t)
;; Fontification degrees.
(defconst haxe-font-lock-keywords-1 (c-lang-const c-matchers-1 haxe)
"Minimal highlighting for haxe mode.")
(defconst haxe-font-lock-keywords-2 (c-lang-const c-matchers-2 haxe)
"Fast normal highlighting for haxe mode.")
(defconst haxe-font-lock-keywords-3 (c-lang-const c-matchers-3 haxe)
"Accurate normal highlighting for haxe mode.")
(defvar haxe-font-lock-keywords haxe-font-lock-keywords-3
"Default expressions to highlight in haxe mode.")
(defvar haxe-mode-syntax-table nil
"Syntax table used in HaXe mode buffers.")
(or haxe-mode-syntax-table
(setq haxe-mode-syntax-table
(funcall (c-lang-const c-make-mode-syntax-table haxe))))
(defvar haxe-mode-abbrev-table nil
"Abbreviation table used in haxe mode buffers.")
(c-define-abbrev-table 'haxe-mode-abbrev-table
;; Keywords that, if they occur first on a line, might alter the
;; syntactic context, and which therefore should trigger
;; reindentation when they are completed.
'(("else" "else" c-electric-continued-statement 0)
("while" "while" c-electric-continued-statement 0)
("catch" "catch" c-electric-continued-statement 0)))
(defvar haxe-mode-map ()
"Keymap used in haxe mode buffers.")
(if haxe-mode-map
nil
(setq haxe-mode-map (c-make-inherited-keymap)))
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.hx\\'" . haxe-mode))
;; Tell compilation-mode how to parse error messages. You need to set
;; compilation-error-screen-columns to nil to get the right
;; interpretation of tabs.
(add-to-list 'compilation-error-regexp-alist
'("^\\([^: ]+\\):\\([0-9]+\\): characters \\([0-9]+\\)-[0-9]+ : "
1 2 3))
(defcustom haxe-mode-hook nil
"*Hook called by `haxe-mode'."
:type 'hook
:group 'c)
;;;###autoload
(defun haxe-mode ()
"Major mode for editing Haxe code.
The hook `c-mode-common-hook' is run with no args at mode
initialization, then `haxe-mode-hook'.
Key bindings:
\\{haxe-mode-map}"
(interactive)
(kill-all-local-variables)
(c-initialize-cc-mode t)
(set-syntax-table haxe-mode-syntax-table)
(setq major-mode 'haxe-mode
mode-name "Haxe"
local-abbrev-table haxe-mode-abbrev-table
abbrev-mode t)
(use-local-map haxe-mode-map)
;; `c-init-language-vars' is a macro that is expanded at compile
;; time to a large `setq' with all the language variables and their
;; customized values for our language.
(c-init-language-vars haxe-mode)
;; `c-common-init' initializes most of the components of a CC Mode
;; buffer, including setup of the mode menu, font-lock, etc.
;; There's also a lower level routine `c-basic-common-init' that
;; only makes the necessary initialization to get the syntactic
;; analysis and similar things working.
(c-common-init 'haxe-mode)
(run-hooks 'c-mode-common-hook 'haxe-mode-hook)
(c-update-modeline))
(provide 'haxe-mode)
;;; haxe-mode.el ends here