Mercurial > urweb
comparison src/elisp/urweb-mode.el @ 360:c1e96b387115
Syntax highlighting for embedded XML
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Tue, 14 Oct 2008 16:37:43 -0400 |
parents | 465593c024ca |
children | 24a31b35e08f |
comparison
equal
deleted
inserted
replaced
359:465593c024ca | 360:c1e96b387115 |
---|---|
158 | 158 |
159 ;;; Font-lock settings ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 159 ;;; Font-lock settings ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
160 | 160 |
161 ;; The font lock regular expressions. | 161 ;; The font lock regular expressions. |
162 | 162 |
163 (defun inXml (depth) | 163 (defun inXml () |
164 (and | 164 (save-excursion |
165 (re-search-backward "[<>{}]" nil t) | 165 (let ( |
166 (cond | 166 (depth 0) |
167 ((looking-at "{") | 167 (finished nil) |
168 (and (> depth 0) | 168 (answer nil) |
169 (inXml (- depth 1)))) | 169 ) |
170 ((looking-at "}") | 170 (while (and (not finished) (re-search-backward "[<>{}]" nil t)) |
171 (inXml (+ depth 1))) | 171 (cond |
172 ((save-excursion (backward-char 1) (or (looking-at "=>") (looking-at "->"))) | 172 ((looking-at "{") |
173 (inXml depth)) | 173 (if (> depth 0) |
174 ((looking-at "<") | 174 (setq depth (- depth 1)) |
175 nil) | 175 (setq finished t))) |
176 ((looking-at ">") | 176 ((looking-at "}") |
177 (if (> depth 0) | 177 (setq depth (+ depth 1))) |
178 (and (re-search-backward "<" nil t) | 178 ((save-excursion (backward-char 1) (or (looking-at "=>") (looking-at "->"))) |
179 (inXml depth)) | 179 nil) |
180 (progn (backward-char 5) (not (looking-at "/html")))))))) | 180 ((looking-at "<") |
181 (setq finished t)) | |
182 ((looking-at ">") | |
183 (if (> depth 0) | |
184 (if (not (re-search-backward "<" nil t)) | |
185 (setq finished t)) | |
186 (progn (backward-char 4) | |
187 (setq answer (not (or | |
188 (looking-at "/xml") | |
189 (looking-at "xml/")))) | |
190 (setq finished t)))))) | |
191 answer))) | |
192 | |
193 (defun amAttribute (face) | |
194 (if (ignore-errors (save-excursion (backward-word 2) (backward-char 1) (looking-at "<"))) | |
195 nil | |
196 face)) | |
181 | 197 |
182 (defconst urweb-font-lock-keywords | 198 (defconst urweb-font-lock-keywords |
183 `(;;(urweb-font-comments-and-strings) | 199 `(;;(urweb-font-comments-and-strings) |
184 ("\\(<\\sw+\\)\\(\\s-\\|\\sw\\|=\\|\"[^\"]*\"\\|{[^}]*}\\)*/?\\(>\\)" | 200 ("\\(<\\sw+\\)\\(\\s-\\|\\sw\\|=\\|\"[^\"]*\"\\|{[^}]*}\\)*/?\\(>\\)" |
185 (1 font-lock-tag-face) | 201 (1 font-lock-tag-face) |
186 (3 font-lock-tag-face)) | 202 (3 font-lock-tag-face)) |
187 ("\\(</\\sw+>\\)" | 203 ("\\(</\\sw+>\\)" |
188 (1 font-lock-tag-face)) | 204 (1 font-lock-tag-face)) |
189 ("\\([^<>{}]+\\)" | 205 ("\\([^<>{}]+\\)" |
190 (1 (if (save-excursion (inXml 0)) | 206 (1 (if (inXml) |
191 font-lock-string-face | 207 font-lock-string-face |
192 nil))) | 208 nil))) |
193 | 209 |
194 ("\\<\\(fun\\|and\\)\\s-+\\(\\sw+\\)\\s-+[^ \t\n=]" | 210 ("\\<\\(fun\\|and\\)\\s-+\\(\\sw+\\)\\s-+[^ \t\n=]" |
195 (1 font-lock-keyword-face) | 211 (1 font-lock-keyword-face) |
196 (2 font-lock-function-name-face)) | 212 (2 (amAttribute font-lock-function-name-face))) |
197 ("\\<\\(\\(data\\)?type\\|con\\|class\\)\\s-+\\(\\sw+\\)" | 213 ("\\<\\(\\(data\\)?type\\|con\\|class\\)\\s-+\\(\\sw+\\)" |
198 (1 font-lock-keyword-face) | 214 (1 font-lock-keyword-face) |
199 (3 font-lock-type-def-face)) | 215 (3 (amAttribute font-lock-type-def-face))) |
200 ("\\<\\(val\\|table\\|sequence\\)\\s-+\\(\\sw+\\>\\s-*\\)?\\(\\sw+\\)\\s-*[=:]" | 216 ("\\<\\(val\\|table\\|sequence\\)\\s-+\\(\\sw+\\>\\s-*\\)?\\(\\sw+\\)\\s-*[=:]" |
201 (1 font-lock-keyword-face) | 217 (1 font-lock-keyword-face) |
202 (3 font-lock-variable-name-face)) | 218 (3 (amAttribute font-lock-variable-name-face))) |
203 ("\\<\\(structure\\|functor\\)\\s-+\\(\\sw+\\)" | 219 ("\\<\\(structure\\|functor\\)\\s-+\\(\\sw+\\)" |
204 (1 font-lock-keyword-face) | 220 (1 font-lock-keyword-face) |
205 (2 font-lock-module-def-face)) | 221 (2 (amAttribute font-lock-module-def-face))) |
206 ("\\<\\(signature\\)\\s-+\\(\\sw+\\)" | 222 ("\\<\\(signature\\)\\s-+\\(\\sw+\\)" |
207 (1 font-lock-keyword-face) | 223 (1 font-lock-keyword-face) |
208 (2 font-lock-interface-def-face)) | 224 (2 (amAttribute font-lock-interface-def-face))) |
209 | 225 |
210 (,urweb-keywords-regexp . font-lock-keyword-face) | 226 (,urweb-keywords-regexp . font-lock-keyword-face) |
211 (,urweb-sql-keywords-regexp . font-lock-sql-face) | 227 (,urweb-sql-keywords-regexp . font-lock-sql-face) |
212 (,urweb-cident-regexp . font-lock-cvariable-face)) | 228 (,urweb-cident-regexp . font-lock-cvariable-face)) |
213 "Regexps matching standard Ur/Web keywords.") | 229 "Regexps matching standard Ur/Web keywords.") |
334 | 350 |
335 ;;;###autoload (add-to-list 'load-path (file-name-directory load-file-name)) | 351 ;;;###autoload (add-to-list 'load-path (file-name-directory load-file-name)) |
336 ;;;###autoload | 352 ;;;###autoload |
337 (add-to-list 'auto-mode-alist '("\\.s\\(ml\\|ig\\)\\'" . urweb-mode)) | 353 (add-to-list 'auto-mode-alist '("\\.s\\(ml\\|ig\\)\\'" . urweb-mode)) |
338 | 354 |
339 ;(mmm-add-classes | |
340 ; '((urweb-html | |
341 ; :submode html-mode | |
342 ; :front "<html>" | |
343 ; :back "</html>"))) | |
344 | |
345 ;;;###autoload | 355 ;;;###autoload |
346 (define-derived-mode urweb-mode fundamental-mode "Ur/Web" | 356 (define-derived-mode urweb-mode fundamental-mode "Ur/Web" |
347 "\\<urweb-mode-map>Major mode for editing Ur/Web code. | 357 "\\<urweb-mode-map>Major mode for editing Ur/Web code. |
348 This mode runs `urweb-mode-hook' just before exiting. | 358 This mode runs `urweb-mode-hook' just before exiting. |
349 \\{urweb-mode-map}" | 359 \\{urweb-mode-map}" |
361 ;; forward-sexp-function is an experimental variable in my hacked Emacs. | 371 ;; forward-sexp-function is an experimental variable in my hacked Emacs. |
362 (set (make-local-variable 'forward-sexp-function) 'urweb-user-forward-sexp) | 372 (set (make-local-variable 'forward-sexp-function) 'urweb-user-forward-sexp) |
363 ;; For XEmacs | 373 ;; For XEmacs |
364 (easy-menu-add urweb-mode-menu) | 374 (easy-menu-add urweb-mode-menu) |
365 | 375 |
366 ; (setq mmm-classes '(urweb-html)) | |
367 | |
368 ;; Compatibility. FIXME: we should use `-' in Emacs-CVS. | 376 ;; Compatibility. FIXME: we should use `-' in Emacs-CVS. |
369 (unless (boundp 'skeleton-positions) (set (make-local-variable '@) nil)) | 377 (unless (boundp 'skeleton-positions) (set (make-local-variable '@) nil)) |
370 | 378 |
371 (urweb-mode-variables) | 379 (urweb-mode-variables)) |
372 ; (mmm-mode-on) | |
373 ) | |
374 | 380 |
375 (defun urweb-mode-variables () | 381 (defun urweb-mode-variables () |
376 (set-syntax-table urweb-mode-syntax-table) | 382 (set-syntax-table urweb-mode-syntax-table) |
377 (setq local-abbrev-table urweb-mode-abbrev-table) | 383 (setq local-abbrev-table urweb-mode-abbrev-table) |
378 ;; A paragraph is separated by blank lines or ^L only. | 384 ;; A paragraph is separated by blank lines or ^L only. |