]> git.pld-linux.org Git - packages/emacs.git/blame - emacs-nemerle.el
- rebuild with ImageMagick 7.0.9.23
[packages/emacs.git] / emacs-nemerle.el
CommitLineData
fe590b1d 1;;; nemerle.el -- major mode for editing nemerle programs
2
3;; Copyright (C) 2003, 2004 The University of Wroclaw
4;; All rights reserved.
5
6;; Author: Jacek Sliwerski (rzyjontko) <rzyj@o2.pl>
7;; Maintainer: Jacek Sliwerski (rzyjontko) <rzyj@o2.pl>
8;; Created: 5 Oct 2003
9;; Version: 0.1
10;; Keywords: nemerle, mode, languages
11;; Website: http://nemerle.org
12
13
14;; This file is not part of GNU Emacs.
15;;
16;; Redistribution and use in source and binary forms, with or without
17;; modification, are permitted provided that the following conditions
18;; are met:
19;; 1. Redistributions of source code must retain the above copyright
20;; notice, this list of conditions and the following disclaimer.
21;; 2. Redistributions in binary form must reproduce the above copyright
22;; notice, this list of conditions and the following disclaimer in the
23;; documentation and/or other materials provided with the distribution.
24;; 3. The name of the University may not be used to endorse or promote
25;; products derived from this software without specific prior
26;; written permission.
27;;
28;; THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY ``AS IS'' AND ANY EXPRESS OR
29;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
30;; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
31;; NO EVENT SHALL THE UNIVERSITY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
33;; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34;; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35;; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39
40
41;;; Commentary:
42
43;; A major mode for editing nemerle source files. It provides syntax
44;; hilighting, proper indentation, and many other features.
45;; To install the nemerle mode, put the following lines into your
46;; ~/.emacs file:
47
48;; (setq load-path (cons "/path/to/dir/where/this/file/resides" load-path))
49;; (autoload 'nemerle-mode "nemerle.el"
50;; "Major mode for editing nemerle programs." t)
51;; (setq auto-mode-alist (cons '("\\.n$" . nemerle-mode) auto-mode-alist))
52
53;; If you'd like to have every line indented right after new line put
54;; these lines into your ~/.emacs files.
55
56;; (defun my-nemerle-mode-hook ()
57;; (setq nemerle-basic-offset 2)
58;; (define-key nemerle-mode-map "\C-m" 'newline-and-indent))
59;; (add-hook 'nemerle-mode-hook 'my-nemerle-mode-hook)
60
61
62
63;;; Change Log:
64
65;; 2004-04-27 rzyjontko <rzyj@o2.pl>
66;; * further coloring improvements
67;; * fixed syntax table
68
69;; 2004-01-24 rzyjontko <rzyj@o2.pl>
70;; * fixed coloring
71
72;; 2004-01-23 rzyjontko <rzyj@o2.pl>
73;; * indent to open parenthesis
74
75;; 2004-01-21 rzyjontko <rzyj@o2.pl>
76;; * improved indentation
77;; * changed syntax table
78;; * disabled tab-indent
79;; * switched to new grammar
80;; * electric-bar and electric-brace
81
82;; 2003-11-17 rzyjontko <rzyj@o2.pl>
83;; * updated copyright disclaimer
84;; * basic indentation engine
85
86;; 2003-10-09 rzyjontko <rzyj@o2.pl>
87;; * nemerle mode automatically sets file coding system to utf-8
88;; * syntax table changes
89;; * more colours
90;; * indentation framework
91
92;; 2003-10-05 rzyjontko <rzyj@o2.pl>
93;; * initial version
94
95
96
97;;; Todo:
98
99;; - further indentation improvements
100;; - imenu (with ncc execution)
101;; - make _ be a special symbol (write matcher functions)
102
103
104
105;;; Code:
106
107(provide 'nemerle-mode)
108
109
110(defvar nemerle-mode-map nil
111 "The keymap used in nemerle-mode.")
112
113(defvar nemerle-font-lock-keywords nil
114 "Font lock definitions for nemerle-mode.")
115
116(defvar nemerle-mode-syntax-table nil
117 "The syntax table used in nemerle-mode.")
118
119(defvar nemerle-mode-hook nil
120 "This hook is run when nemerle-mode is loaded, or a new nemerle-mode
121buffer created. This is a good place to put your customizations.")
122
123(defvar nemerle-basic-offset 4
124 "Indentation of blocks in nemerle.")
125
126(unless nemerle-mode-map
127 (let ((map (make-sparse-keymap)))
128 (define-key map "\C-c\C-c" 'comment-region)
129 (define-key map "|" 'nemerle-electric-bar)
130 (define-key map "}" 'nemerle-electric-brace)
131 (setq nemerle-mode-map map)))
132
133(unless nemerle-font-lock-keywords
134 (setq nemerle-font-lock-keywords
135 (list
136 ;; strings
137 '("[^']\\(\"[^\"]*\"\\)" 1 font-lock-string-face)
138 '("'[^\\']'\\|'\\\\.'" 0 font-lock-string-face)
139
140 ;; one-line comments
141 '("//.*" 0 font-lock-comment-face)
142
143 ;; keywords
144 '("\\<\\(_\\|abstract\\|and\\|as\\|base\\|catch\\|const\\|def\\|delegate\\|enum\\|extends\\|extern\\|finally\\|fun\\|implements\\|interface\\|internal\\|is\\|macro\\|match\\|matches\\|mutable\\|new\\|out\\|override\\|params\\|private\\|protected\\|public\\|ref\\|sealed\\|static\\|struct\\|syntax\\|this\\|throw\\|try\\|tymatch\\|type\\|typeof\\|virtual\\|where\\|partial\\)\\>"
145 0 font-lock-keyword-face)
146 ;; these aren't really keywords but we set them so
147 '("\\<\\(do\\|else\\|for\\|if\\|regexp\\|unless\\|while\\|when\\|in\\|foreach\\)\\>"
148 0 font-lock-keyword-face)
149 '("=>\\||" 0 font-lock-keyword-face)
150
151 '("\\<\\(foreach\\)\\s *(.*:\\s *\\(\\w*\\)\\s *\\(\\<in\\>\\)"
152 (1 font-lock-keyword-face) (2 font-lock-type-face) (3 font-lock-keyword-face))
153
154 '("\\<\\(variant\\|class\\|interface\\|module\\|namespace\\|using\\)\\s +\\(\\(\\w\\|\\.\\)*\\)"
155 (1 font-lock-keyword-face) (2 font-lock-function-name-face))
156
157 ;; types
158 '("\\<list\\s *<[^>]*[^\\-]>+" 0 font-lock-type-face t)
159 '("\\<option\\s *<[^>]*>+" 0 font-lock-type-face t)
160 '("\\<array\\s *<[^>]*>+" 0 font-lock-type-face t)
161 '("->" 0 font-lock-type-face)
162 '("\\<\\(void\\|int\\|uint\\|char\\|float\\|double\\|decimal\\|byte\\|sbyte\\|short\\|ushort\\|long\\|ulong\\|bool\\|string\\|object\\)\\>"
163 0 font-lock-type-face)
164
165 ;; constants
166 '("\\<[0-9]+\\>" 0 font-lock-constant-face)
167 '("\\<Nil\\>" 0 font-lock-constant-face)
168 '("\\<\\(false\\|true\\|null\\)\\>" 0 font-lock-constant-face))))
169
170
171(unless nemerle-mode-syntax-table
172 (setq nemerle-mode-syntax-table (copy-syntax-table c-mode-syntax-table))
173 (modify-syntax-entry ?< "(>" nemerle-mode-syntax-table)
174 (modify-syntax-entry ?> ")<" nemerle-mode-syntax-table))
175
176
177(defun nemerle-syntax ()
178 (save-excursion
179 (beginning-of-line)
180 (cond ((looking-at "[ \t]*\\<try\\>")
181 'try)
182 ((looking-at "[ \t]*\\<catch\\>")
183 'catch)
184 ((looking-at "[ \t]*|")
185 'match-case)
186 ((looking-at "[ \t]*$")
187 'empty)
188 ((looking-at "[ \t]*\\<if\\>")
189 'if)
190 ((looking-at "[ \t]*\\<else\\>")
191 'else)
192 ((looking-at "[^\n{]*}")
193 'block-end)
194 ((looking-at "[^\n]*{[^\n}]*$")
195 'block-beg)
196 ((looking-at "[ \t]*\\<when\\>")
197 'if)
198 ((looking-at "[ \t]*\\<unless\\>")
199 'if)
200 (t
201 'other))))
202
203
204(defun nemerle-prev-line ()
205 (save-excursion
206 (beginning-of-line)
207 (if (bobp)
208 0
209 (let ((there (point)))
210 (skip-chars-backward " \t\n")
211 (beginning-of-line)
212 (let* ((here (point))
213 (syntax (nemerle-syntax))
214 (indent (current-indentation))
215 (state (parse-partial-sexp here there)))
216 (cond ((and (< (nth 0 state) 0) (eq ?\) (nth 2 state)))
217 (goto-char (scan-lists (nth 2 state) -1 1))
218 (cons (current-indentation) (nemerle-syntax)))
219 ((null (nth 1 state))
220 (cons indent syntax))
221 ((eq (char-after (nth 1 state)) ?\()
222 (cons (- (nth 1 state) here) 'open-paren))
223 (t
224 (cons indent syntax))))))))
225
226
227(defun nemerle-calculate-indentation ()
228 (let* ((prev-info (nemerle-prev-line))
229 (prev-indent (car prev-info))
230 (prev-syntax (cdr prev-info))
231 (cur-syntax (nemerle-syntax)))
232 (cond ((eq prev-syntax 'open-paren)
233 (1+ prev-indent))
234 ((eq prev-syntax 'match-case) ; match-case
235 (cond ((eq cur-syntax 'match-case)
236 prev-indent)
237 ((eq cur-syntax 'block-end)
238 (- prev-indent nemerle-basic-offset))
239 (t
240 (+ prev-indent 2))))
241 ((eq prev-syntax 'try) ; try
242 (cond ((eq cur-syntax 'block-beg)
243 prev-indent)
244 ((eq cur-syntax 'catch)
245 prev-indent)
246 (t (+ prev-indent nemerle-basic-offset))))
247 ((eq prev-syntax 'catch)
248 (+ prev-indent nemerle-basic-offset))
249 ((eq prev-syntax 'block-beg) ; beginning of block
250 (+ prev-indent nemerle-basic-offset))
251 ((eq prev-syntax 'block-end) ; end of block
252 (cond ((eq cur-syntax 'block-end)
253 (- prev-indent nemerle-basic-offset))
254 (t
255 prev-indent)))
256 ((eq prev-syntax 'if) ; if
257 (+ prev-indent nemerle-basic-offset))
258 ((eq prev-syntax 'else) ; else
259 (+ prev-indent nemerle-basic-offset))
260 (t
261 (cond ((eq cur-syntax 'block-end)
262 (- prev-indent nemerle-basic-offset))
263 ((eq cur-syntax 'else)
264 (- prev-indent nemerle-basic-offset))
265 ((eq cur-syntax 'catch)
266 (- prev-indent nemerle-basic-offset))
267 (t
268 prev-indent))))))
269
270
271(defun nemerle-indent-to (level)
272 (save-excursion
273 (beginning-of-line)
274 (skip-chars-forward " \t")
275 (if (< level (current-indentation))
276 (delete-horizontal-space))
277 (indent-to level))
278 (if (< (current-column) (current-indentation))
279 (skip-chars-forward " \t")))
280
281
282
283(defun nemerle-indent-line ()
284 "Indent current line of nemerle code."
285 (interactive)
286 (let ((level (nemerle-calculate-indentation)))
287 (nemerle-indent-to level)))
288
289
290
291(defun nemerle-electric-bar (arg)
292 "Insert a bar.
293
294Also, the line is re-indented unless a numeric ARG is supplied
295or there are some non-blank symbols on the line."
296 (interactive "p")
297 (if (or (not (eq (nemerle-syntax) 'empty)) (and arg (> arg 1)))
298 (self-insert-command (or arg 1))
299 (message "ok")
300 (let* ((prev-info (nemerle-prev-line))
301 (prev-indent (car prev-info))
302 (prev-syntax (cdr prev-info))
303 (level prev-indent))
304 (if (eq prev-syntax 'block-beg)
305 (setq level (+ prev-indent nemerle-basic-offset)))
306 (nemerle-indent-to level)
307 (insert-char ?| 1))))
308
309
310(defun nemerle-electric-brace (arg)
311 "Insert a brace.
312
313Also, the line is re-indented unless a numeric ARG is supplied
314or there are some non-blank symbols on the line."
315 (interactive "p")
316 (if (or (not (eq (nemerle-syntax) 'empty)) (and arg (> arg 1)))
317 (self-insert-command (or arg 1))
318 (let* ((prev-info (nemerle-prev-line))
319 (prev-indent (car prev-info))
320 (prev-syntax (cdr prev-info))
321 (level prev-indent))
322 (nemerle-indent-to (- prev-indent nemerle-basic-offset))
323 (insert-char ?} 1))))
324
325
326(defun nemerle-comment-indent ()
327 "Indent current line of nemerle comment."
328 (interactive)
329 0)
330
331
332(defun nemerle-mode ()
333 "Major mode for editing nemerle source files.
334
335Mode map
336========
337\\{nemerle-mode-map}"
338
339 (interactive)
340 (kill-all-local-variables)
341
342 (setq mode-name "Nemerle")
343 (setq major-mode 'nemerle-mode)
344
345 (use-local-map nemerle-mode-map)
346 (set-syntax-table nemerle-mode-syntax-table)
347
348 (make-local-variable 'font-lock-defaults)
349 (setq font-lock-defaults '(nemerle-font-lock-keywords nil nil
350 ((?_ . "w") (?. . "w") (?\/ . ". 14b")
351 (?* . ". 23") (?\" . ".") (?\' . "."))))
352
353 (make-local-variable 'indent-line-function)
354 (setq indent-line-function 'nemerle-indent-line)
355
356 (make-local-variable 'comment-indent-function)
357 (setq comment-indent-function 'c-comment-indent)
358
359 (make-local-variable 'comment-start)
360 (setq comment-start "/* ")
361
362 (make-local-variable 'comment-end)
363 (setq comment-end " */")
364
365 (make-local-variable 'comment-start-skip)
366 (setq comment-start-skip "/\\*+[ \t]*\\|//+ *")
367
368 (setq buffer-file-coding-system 'utf-8)
369 (setq indent-tabs-mode nil)
370
371 (run-hooks 'nemerle-mode-hook))
372
373;;; nemerle.el ends here
This page took 0.11752 seconds and 4 git commands to generate.