Attachment 'vala-mode.el'
Download 1 ;;; vala-mode.el --- Vala mode derived mode
2
3 ;; Author: 2005 Dylan R. E. Moonfire
4 ;; 2008 Étienne BERSAC
5 ;; Maintainer: Étienne BERSAC <bersace03@laposte.net>
6 ;; Modifier: Kentaro NAKAZAWA <kentaro.nakazawa@nifty.com>
7 ;; Created: 2008 May the 4th
8 ;; Modified: April 2011
9 ;; Version: 0.1
10 ;; Keywords: vala languages oop
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 of the License, or
15 ;; (at your option) 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; see the file COPYING. If not, write to
24 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 ;; Boston, MA 02111-1307, USA.
26
27 ;;; Commentary:
28 ;;
29 ;; See http://live.gnome.org/Vala for details about Vala language.
30 ;;
31 ;; This is a separate mode to implement the Vala constructs and
32 ;; font-locking. It is mostly the csharp-mode from
33 ;; http://mfgames.com/linux/csharp-mode with vala specific keywords
34 ;; and filename suffixes.
35 ;;
36 ;; Note: The interface used in this file requires CC Mode 5.30 or
37 ;; later.
38
39 ;;; .emacs (don't put in (require 'vala-mode))
40 ;; (autoload 'vala-mode "vala-mode" "Major mode for editing Vala code." t)
41 ;; (setq auto-mode-alist
42 ;; (append '(("\\.vala$" . vala-mode)) auto-mode-alist))
43
44 ;;; Versions:
45 ;;
46 ;; 0.1 : Initial version based on csharp-mode
47 ;;
48
49 ;; This is a copy of the function in cc-mode which is used to handle
50 ;; the eval-when-compile which is needed during other times.
51 (defun c-filter-ops (ops opgroup-filter op-filter &optional xlate)
52 ;; See cc-langs.el, a direct copy.
53 (unless (listp (car-safe ops))
54 (setq ops (list ops)))
55 (cond ((eq opgroup-filter t)
56 (setq opgroup-filter (lambda (opgroup) t)))
57 ((not (functionp opgroup-filter))
58 (setq opgroup-filter `(lambda (opgroup)
59 (memq opgroup ',opgroup-filter)))))
60 (cond ((eq op-filter t)
61 (setq op-filter (lambda (op) t)))
62 ((stringp op-filter)
63 (setq op-filter `(lambda (op)
64 (string-match ,op-filter op)))))
65 (unless xlate
66 (setq xlate 'identity))
67 (c-with-syntax-table (c-lang-const c-mode-syntax-table)
68 (delete-duplicates
69 (mapcan (lambda (opgroup)
70 (when (if (symbolp (car opgroup))
71 (when (funcall opgroup-filter (car opgroup))
72 (setq opgroup (cdr opgroup))
73 t)
74 t)
75 (mapcan (lambda (op)
76 (when (funcall op-filter op)
77 (let ((res (funcall xlate op)))
78 (if (listp res) res (list res)))))
79 opgroup)))
80 ops)
81 :test 'equal)))
82
83 ;; This inserts the bulk of the code.
84 (require 'cc-mode)
85
86 ;; These are only required at compile time to get the sources for the
87 ;; language constants. (The cc-fonts require and the font-lock
88 ;; related constants could additionally be put inside an
89 ;; (eval-after-load "font-lock" ...) but then some trickery is
90 ;; necessary to get them compiled.)
91 (eval-when-compile
92 (let ((load-path
93 (if (and (boundp 'byte-compile-dest-file)
94 (stringp byte-compile-dest-file))
95 (cons (file-name-directory byte-compile-dest-file) load-path)
96 load-path)))
97 (load "cc-mode" nil t)
98 (load "cc-fonts" nil t)
99 (load "cc-langs" nil t)))
100
101 (eval-and-compile
102 ;; Make our mode known to the language constant system. Use Java
103 ;; mode as the fallback for the constants we don't change here.
104 ;; This needs to be done also at compile time since the language
105 ;; constants are evaluated then.
106 (c-add-language 'vala-mode 'java-mode))
107
108 ;; Java uses a series of regexes to change the font-lock for class
109 ;; references. The problem comes in because Java uses Pascal (leading
110 ;; space in names, SomeClass) for class and package names, but
111 ;; Camel-casing (initial lowercase, upper case in words,
112 ;; i.e. someVariable) for variables.
113 ;;(error (byte-compile-dest-file))
114 ;;(error (c-get-current-file))
115 (c-lang-defconst c-opt-after-id-concat-key
116 vala (if (c-lang-const c-opt-identifier-concat-key)
117 (c-lang-const c-symbol-start)))
118
119 (c-lang-defconst c-basic-matchers-before
120 vala `(
121 ;;;; Font-lock the attributes by searching for the
122 ;;;; appropriate regex and marking it as TODO.
123 ;;,`(,(concat "\\(" vala-attribute-regex "\\)")
124 ;; 0 font-lock-function-name-face)
125
126 ;; Put a warning face on the opener of unclosed strings that
127 ;; can't span lines. Later font
128 ;; lock packages have a `font-lock-syntactic-face-function' for
129 ;; this, but it doesn't give the control we want since any
130 ;; fontification done inside the function will be
131 ;; unconditionally overridden.
132 ,(c-make-font-lock-search-function
133 ;; Match a char before the string starter to make
134 ;; `c-skip-comments-and-strings' work correctly.
135 (concat ".\\(" c-string-limit-regexp "\\)")
136 '((c-font-lock-invalid-string)))
137
138 ;; Fontify keyword constants.
139 ,@(when (c-lang-const c-constant-kwds)
140 (let ((re (c-make-keywords-re nil
141 (c-lang-const c-constant-kwds))))
142 `((eval . (list ,(concat "\\<\\(" re "\\)\\>")
143 1 c-constant-face-name)))))
144
145 ;; Fontify all keywords except the primitive types.
146 ,`(,(concat "\\<" (c-lang-const c-regular-keywords-regexp))
147 1 font-lock-keyword-face)
148
149 ;; Fontify leading identifiers in fully
150 ;; qualified names like "Foo.Bar".
151 ,@(when (c-lang-const c-opt-identifier-concat-key)
152 `((,(byte-compile
153 `(lambda (limit)
154 (while (re-search-forward
155 ,(concat "\\(\\<" ; 1
156 "\\(" (c-lang-const c-symbol-key)
157 "\\)" ; 2
158 "[ \t\n\r\f\v]*"
159 (c-lang-const
160 c-opt-identifier-concat-key)
161 "[ \t\n\r\f\v]*"
162 "\\)"
163 "\\("
164 (c-lang-const
165 c-opt-after-id-concat-key)
166 "\\)")
167 limit t)
168 (unless (progn
169 (goto-char (match-beginning 0))
170 (c-skip-comments-and-strings limit))
171 (or (get-text-property (match-beginning 2) 'face)
172 (c-put-font-lock-face (match-beginning 2)
173 (match-end 2)
174 c-reference-face-name))
175 (goto-char (match-end 1)))))))))
176 ))
177
178 ;; Vala does not allow a leading qualifier operator. It also doesn't
179 ;; allow the ".*" construct of Java. So, we redo this regex without
180 ;; the "\\|\\*" regex.
181 (c-lang-defconst c-identifier-key
182 vala (concat "\\(" (c-lang-const c-symbol-key) "\\)" ; 1
183 (concat "\\("
184 "[ \t\n\r\f\v]*"
185 (c-lang-const c-opt-identifier-concat-key)
186 "[ \t\n\r\f\v]*"
187 (concat "\\("
188 "\\(" (c-lang-const c-symbol-key) "\\)"
189 "\\)")
190 "\\)*")))
191
192 ;; Vala has a few rules that are slightly different than Java for
193 ;; operators. This also removed the Java's "super" and replaces it
194 ;; with the Vala's "base".
195 (c-lang-defconst c-operators
196 vala `((prefix "base")))
197
198 ;; Vala directives
199 (c-lang-defconst c-opt-cpp-prefix
200 vala "\\s *#\\s *")
201
202
203 ;; Vala uses the following assignment operators
204 (c-lang-defconst c-assignment-operators
205 vala '("=" "*=" "/=" "%=" "+=" "-=" ">>=" "<<="
206 "&=" "^=" "|=" "++" "--"))
207
208 ;; This defines the primative types for Vala
209 (c-lang-defconst c-primitive-type-kwds
210 vala '("void" "bool" "char" "uchar" "short" "ushort" "int" "uint" "long" "ulong"
211 "size_t" "ssize_t" "int8" "uint8" "int16" "uint16" "int32" "uint32" "int64" "uint64"
212 "unichar" "float" "double" "string"))
213
214 ;; The keywords that define that the following is a type, such as a
215 ;; class definition.
216 (c-lang-defconst c-type-prefix-kwds
217 vala '("class" "interface" "struct" "enum" "signal"))
218
219 ;; Type modifier keywords. They appear anywhere in types, but modifiy
220 ;; instead create one.
221 (c-lang-defconst c-type-modifier-kwds
222 vala '("const"))
223
224 ;; Structures that are similiar to classes.
225 (c-lang-defconst c-class-decl-kwds
226 vala '("class" "interface"))
227
228 ;; The various modifiers used for class and method descriptions.
229 (c-lang-defconst c-modifier-kwds
230 vala '("public" "partial" "private" "const" "abstract"
231 "protected" "ref" "in" "out" "static" "virtual"
232 "override" "params" "internal" "weak" "owned"
233 "unowned" "async" "yield"))
234
235 ;; We don't use the protection level stuff because it breaks the
236 ;; method indenting. Not sure why, though.
237 (c-lang-defconst c-protection-kwds
238 vala nil)
239
240 ;; Define the keywords that can have something following after them.
241 (c-lang-defconst c-type-list-kwds
242 vala '("struct" "class" "interface" "is" "as"
243 "delegate" "event" "set" "get" "add" "remove"
244 "callback" "signal" "var" "default"))
245
246 ;; This allows the classes after the : in the class declartion to be
247 ;; fontified.
248 (c-lang-defconst c-typeless-decl-kwds
249 vala '(":"))
250
251 ;; Sets up the enum to handle the list properly
252 (c-lang-defconst c-brace-list-decl-kwds
253 vala '("enum" "errordomain"))
254
255 ;; We need to remove Java's package keyword
256 (c-lang-defconst c-ref-list-kwds
257 vala '("using" "namespace" "construct"))
258
259 ;; Follow-on blocks that don't require a brace
260 (c-lang-defconst c-block-stmt-2-kwds
261 vala '("for" "if" "switch" "while" "catch" "foreach" "lock"))
262
263 ;; Statements that break out of braces
264 (c-lang-defconst c-simple-stmt-kwds
265 vala '("return" "continue" "break" "throw"))
266
267 ;; Statements that allow a label
268 ;; TODO?
269 (c-lang-defconst c-before-label-kwds
270 vala nil)
271
272 ;; Constant keywords
273 (c-lang-defconst c-constant-kwds
274 vala '("true" "false" "null"))
275
276 ;; Keywords that start "primary expressions."
277 (c-lang-defconst c-primary-expr-kwds
278 vala '("this" "base"))
279
280 ;; We need to treat namespace as an outer block to class indenting
281 ;; works properly.
282 (c-lang-defconst c-other-block-decl-kwds
283 vala '("namespace" "extern"))
284
285 ;; We need to include the "in" for the foreach
286 (c-lang-defconst c-other-kwds
287 vala '("in" "sizeof" "typeof"))
288
289 (require 'cc-awk)
290
291 (c-lang-defconst c-at-vsemi-p-fn
292 vala 'c-awk-at-vsemi-p)
293
294
295 ;; (defcustom vala-font-lock-extra-types nil
296 ;; "*List of extra types (aside from the type keywords) to recognize in Vala mode.
297 ;; Each list item should be a regexp matching a single identifier.")
298
299 (defconst vala-font-lock-keywords-1 (c-lang-const c-matchers-1 vala)
300 "Minimal highlighting for Vala mode.")
301
302 (defconst vala-font-lock-keywords-2 (c-lang-const c-matchers-2 vala)
303 "Fast normal highlighting for Vala mode.")
304
305 (defconst vala-font-lock-keywords-3 (c-lang-const c-matchers-3 vala)
306 "Accurate normal highlighting for Vala mode.")
307
308 (defvar vala-font-lock-keywords vala-font-lock-keywords-3
309 "Default expressions to highlight in Vala mode.")
310
311 (defvar vala-mode-syntax-table
312 nil
313 "Syntax table used in vala-mode buffers.")
314 (or vala-mode-syntax-table
315 (setq vala-mode-syntax-table
316 (funcall (c-lang-const c-make-mode-syntax-table vala))))
317
318 (defvar vala-mode-abbrev-table nil
319 "Abbreviation table used in vala-mode buffers.")
320 (c-define-abbrev-table 'vala-mode-abbrev-table
321 ;; Keywords that if they occur first on a line
322 ;; might alter the syntactic context, and which
323 ;; therefore should trig reindentation when
324 ;; they are completed.
325 '(("else" "else" c-electric-continued-statement 0)
326 ("while" "while" c-electric-continued-statement 0)
327 ("catch" "catch" c-electric-continued-statement 0)
328 ("finally" "finally" c-electric-continued-statement 0)))
329
330 (defvar vala-mode-map (let ((map (c-make-inherited-keymap)))
331 ;; Add bindings which are only useful for Vala
332 map)
333 "Keymap used in vala-mode buffers.")
334
335 ;;(easy-menu-define vala-menu vala-mode-map "Vala Mode Commands"
336 ;; ;; Can use `vala' as the language for `c-mode-menu'
337 ;; ;; since its definition covers any language. In
338 ;; ;; this case the language is used to adapt to the
339 ;; ;; nonexistence of a cpp pass and thus removing some
340 ;; ;; irrelevant menu alternatives.
341 ;; (cons "Vala" (c-lang-const c-mode-menu vala)))
342
343 ;;; Autoload mode trigger
344 (add-to-list 'auto-mode-alist '("\\.vala$" . vala-mode))
345 (add-to-list 'auto-mode-alist '("\\.vapi$" . vala-mode))
346
347 ;; Custom variables
348 (defcustom vala-mode-hook nil
349 "*Hook called by `vala-mode'."
350 :type 'hook
351 :group 'c)
352
353 ;;; The entry point into the mode
354 ;;;###autoload
355 (defun vala-mode ()
356 "Major mode for editing Vala code.
357 This is a simple example of a separate mode derived from CC Mode
358 to support a language with syntax similar to
359 C#/C/C++/ObjC/Java/IDL/Pike.
360
361 The hook `c-mode-common-hook' is run with no args at mode
362 initialization, then `vala-mode-hook'.
363
364 Key bindings:
365 \\{vala-mode-map}"
366 (interactive)
367 (kill-all-local-variables)
368 (c-initialize-cc-mode t)
369 (set-syntax-table vala-mode-syntax-table)
370 (setq major-mode 'vala-mode
371 mode-name "Vala"
372 local-abbrev-table vala-mode-abbrev-table
373 abbrev-mode t)
374 (use-local-map c-mode-map)
375 ;; `c-init-language-vars' is a macro that is expanded at compile
376 ;; time to a large `setq' with all the language variables and their
377 ;; customized values for our language.
378 (c-init-language-vars vala-mode)
379 ;; `c-common-init' initializes most of the components of a CC Mode
380 ;; buffer, including setup of the mode menu, font-lock, etc.
381 ;; There's also a lower level routine `c-basic-common-init' that
382 ;; only makes the necessary initialization to get the syntactic
383 ;; analysis and similar things working.
384 (c-common-init 'vala-mode)
385 ;;(easy-menu-add vala-menu)
386 (c-set-style "linux")
387 (setq indent-tabs-mode t)
388 (setq c-basic-offset 4)
389 (setq tab-width 4)
390 (c-toggle-auto-newline -1)
391 (c-toggle-hungry-state -1)
392 (run-hooks 'c-mode-common-hook)
393 (run-hooks 'vala-mode-hook)
394 (c-update-modeline))
395
396 (provide 'vala-mode)
397
398 ;;; vala-mode.el ends here
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.