* wesnoth-mode.el (wesnoth-jump-to-matching): Format error message.
[wesnoth-mode.git] / wesnoth-mode.el
blobeb18dd76f1c8665d0d924cc254e11bf4cf86ecd6
1 ;; wesnoth-mode.el - A major mode for editing WML.
2 ;; Copyright (C) 2006, 2007 Chris Mann
4 ;; This program is free software; you can redistribute it and/or
5 ;; modify it under the terms of the GNU General Public License as
6 ;; published by the Free Software Foundation; either version 2 of the
7 ;; License, or (at your option) any later version.
9 ;; This program is distributed in the hope that it will be useful, but
10 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
11 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ;; General Public License for more details.
14 ;; You should have received a copy of the GNU General Public License
15 ;; along with this program; see the file COPYING. If not, write to the
16 ;; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
17 ;; MA 02139, USA.
19 ;; Description:
20 ;; wesnoth-mode is a major mode for Emacs which assists in the editing
21 ;; of Wesnoth Markup Language (WML) files. Currently, this mode
22 ;; features syntax highlighting support, automatic indentation,
23 ;; tag-completion and preliminary support for syntax checking.
25 ;; Usage:
26 ;; Add the following to your .emacs:
27 ;; (add-to-list 'load-path "path/to/wesnoth-mode")
28 ;; (require 'wesnoth-mode)
29 ;; Optionally adding:
30 ;; (add-to-list 'auto-mode-alist '("\\.cfg\\'" . wesnoth-mode))
31 ;; to automatically load wesnoth-mode for all files ending in '.cfg'.
33 (defconst wesnoth-mode-version "1.1.2.1"
34 "The current version of wesnoth-mode.")
36 (defgroup wesnoth-mode nil "Wesnoth-mode access"
37 :group 'languages
38 :prefix "wesnoth-")
40 (defcustom wesnoth-indent 2
41 "The number of columns to indent WML."
42 :type 'integer
43 :group 'wesnoth-mode)
45 (defcustom wesnoth-indentation-function 'wesnoth-indent-line-default
46 "Use the specified function when indenting WML.
47 You can specify either `wesnoth-indent-line-default' or
48 `wesnoth-indent-line-savefile' as the indentation style or a
49 customised function for indentation."
50 :type 'function
51 :group 'wesnoth-mode)
53 (defcustom wesnoth-auto-indent-flag t
54 "Whether to attempt tag indentation when a newline is created.
55 If nil, no indentation will be attempted. Otherwise, attempt to
56 indent the line."
57 :type 'boolean
58 :group 'wesnoth-mode)
60 (defconst wesnoth-preprocessor-regexp
61 "#\\(?:define \\|e\\(?:lse\\|nd\\(?:\\(?:de\\|i\\)f\\)\\)\\|\\(?:if\\|un\\)def \\)"
62 "Regular expression to match all preprocessor statements.")
64 (defconst wesnoth-preprocessor-opening-regexp
65 "#\\(?:define \\|else\\|ifdef \\)"
66 "Regular expression to match \"opening\" preprocessor statements.")
68 (defconst wesnoth-preprocessor-closing-regexp
69 "#e\\(?:lse\\|nd\\(?:\\(?:de\\|i\\)f\\)\\)"
70 "Regular expression to match \"closing\" preprocessor statements.")
72 (defvar wesnoth-mode-hook nil)
74 (defvar wesnoth-mode-map ()
75 "Keymap used in wesnoth mode.")
76 (unless wesnoth-mode-map
77 (setq wesnoth-mode-map (make-sparse-keymap))
78 (define-key wesnoth-mode-map "\C-\M-a" 'wesnoth-jump-backward)
79 (define-key wesnoth-mode-map "\C-\M-e" 'wesnoth-jump-forward)
80 (define-key wesnoth-mode-map "\C-c\C-m" 'wesnoth-jump-to-matching)
81 (define-key wesnoth-mode-map "\C-cm" 'wesnoth-jump-to-matching)
82 (define-key wesnoth-mode-map "\C-m" 'wesnoth-newline)
83 (define-key wesnoth-mode-map "\C-j" 'wesnoth-newline-and-indent)
84 (define-key wesnoth-mode-map "\C-c\C-c" 'wesnoth-check-structure)
85 (define-key wesnoth-mode-map "\C-cc" 'wesnoth-check-structure)
86 (define-key wesnoth-mode-map "\C-c\C-n" 'wesnoth-check-tag-names)
87 (define-key wesnoth-mode-map "\C-cf" 'wesnoth-fix-structure)
88 (define-key wesnoth-mode-map "\C-c\C-f" 'wesnoth-fix-structure)
89 (define-key wesnoth-mode-map "\C-cn" 'wesnoth-check-tag-names)
90 (define-key wesnoth-mode-map "\C-c\C-e" 'wesnoth-insert-tag)
91 (define-key wesnoth-mode-map "\C-ce" 'wesnoth-insert-tag))
93 (defvar wesnoth-syntax-table
94 (let ((wesnoth-syntax-table (make-syntax-table)))
95 (modify-syntax-entry ?= "." wesnoth-syntax-table)
96 (modify-syntax-entry ?\_ "w" wesnoth-syntax-table)
97 (modify-syntax-entry ?- "_" wesnoth-syntax-table)
98 (modify-syntax-entry ?. "_" wesnoth-syntax-table)
99 (modify-syntax-entry ?\n ">" wesnoth-syntax-table)
100 (modify-syntax-entry ?\r ">" wesnoth-syntax-table)
101 wesnoth-syntax-table)
102 "Syntax table for wesnoth-mode.")
104 ;; Prevents automatic syntax-highlighting of elements which might be
105 ;; pre-processor statements.
106 (defvar wesnoth-syntactic-keywords
107 (list
108 '("^[\t ]*\\(#\\(?:define \\|e\\(?:lse\\|nd\\(?:\\(?:de\\|i\\)f\\)\\)\\|\\(?:if\\|un\\)def \\)\\)" 1 "w")
109 '("\\(#[\t ]*.*$\\)" 1 "<"))
110 "Highlighting syntactic keywords within wesnoth-mode.")
112 (defvar wesnoth-font-lock-keywords
113 (list
114 '("\\(#\\(?:define\\|\\(?:if\\|un\\)def\\)\\)"
115 1 font-lock-preprocessor-face)
116 '("\\(#\\(?:define\\|\\(?:if\\|un\\)def\\)\\)[\t ]+\\(\\w+\\)"
117 2 font-lock-function-name-face)
118 '("\\(#e\\(?:lse\\|nd\\(?:\\(?:de\\|i\\)f\\)\\)\\)" . font-lock-preprocessor-face)
119 '("[\t ]*\\({[[:word:]/\.]+\\|{[@~][[:word:]/\.]+\\).*\\(}\\)"
120 (1 font-lock-function-name-face)
121 (2 font-lock-function-name-face))
122 '("\\[[^]]+\\]" . font-lock-type-face)
123 '("\\$\\w+" . font-lock-variable-name-face)
124 '("\\(\\w+\\(\\,[\t ]*\\w+\\)*\\)="
125 1 font-lock-variable-name-face))
126 "Syntax highlighting for wesnoth-mode.")
128 (defvar wesnoth-tags-list
129 (list
130 "abilities" "about" "advances" "advancefrom" "ai" "allow_recruit"
131 "and" "animation" "array" "attack" "attacks" "avoid" "binary_path"
132 "bold" "campaign" "capture_village" "choose""clear_variable"
133 "colour_adjust" "command" "deaths" "defend" "defends" "defense"
134 "delay" "destination" "disallow_recruit" "do" "effect" "else"
135 "end_turn" "endlevel" "era" "event" "expenses" "filter"
136 "filter_radius" "filter_second" "format" "frame" "game_config"
137 "generator" "gold" "have_unit" "header" "hide_unit" "if"
138 "illuminated_time" "image" "img" "income" "italic" "item" "jump"
139 "kill" "killed" "label" "language" "leader_goal" "main_map" "menu"
140 "message" "mini_map" "missile_frame" "modifications" "modify_side"
141 "modify_turns" "move" "move_unit_fake" "movement_costs" "movetype"
142 "multiplayer" "multiplayer_side" "music" "not" "num_units" "object"
143 "objectives" "objective" "observers" "option" "or" "panel" "part"
144 "place_shroud" "position" "print" "protect_location" "protect_unit"
145 "race" "random" "recall" "recalls" "recruit" "recruits" "redraw"
146 "ref" "remove_shroud" "remove_unit_overlay" "removeitem" "replay"
147 "replay_start" "resistance" "resolution" "results" "role" "save"
148 "scenario" "scroll" "scroll_to" "scroll_to_unit" "section"
149 "set_recruit" "set_variable" "side" "side_playing" "snapshot"
150 "sound" "source" "specials" "statistics" "status" "stone"
151 "store_gold" "store_locations" "store_starting_location"
152 "store_unit" "story" "target" "team" "teleport" "teleport_anim"
153 "terrain" "terrain_graphics" "test" "theme" "then" "tile" "time"
154 "time_area" "time_of_day" "topic" "toplevel" "trait" "turn"
155 "tutorial" "unhide_unit" "unit" "unit_abilities"
156 "unit_alignment" "unit_description" "unit_hp" "unit_image"
157 "unit_level" "unit_moves" "unit_overlay" "unit_profile"
158 "unit_status" "unit_traits" "unit_type" "unit_weapons" "unit_xp"
159 "units" "unstone" "unstore_unit" "upkeep" "variable" "variables"
160 "village" "villages" "while")
161 "A list containing all tags which are available for use in WML.")
163 (defun wesnoth-insert-tag ()
164 "Inserts the specified opening tag and it's matching closing tag.
165 Both the opening and closing tags will be placed on their own
166 lines with point positioned between them. Completion of tags at
167 the prompt uses `wesnoth-tags-list'."
168 (interactive)
169 (let ((tagname
170 (completing-read
171 "Tag: "
172 wesnoth-tags-list
173 nil nil)))
174 (progn
175 (beginning-of-line)
176 (unless (looking-at "^[\t ]*$")
177 (end-of-line)
178 (insert "\n"))
179 (end-of-line)
180 (insert "[" tagname "]")
181 (wesnoth-indent-line)
182 (insert "\n")
183 (wesnoth-indent-line)
184 (save-excursion
185 (insert "\n[/" tagname "]")
186 (wesnoth-indent-line)
187 (forward-line -1)))))
189 (defun wesnoth-jump-forward (repeat)
190 "Move point to the end of the next tag.
191 REPEAT is an optional numeric argument. If REPEAT is non-nil,
192 jump forward the specified number of tags."
193 (interactive "p")
194 (or repeat (setq repeat 1))
195 (and (< repeat 0) (wesnoth-jump-backward (abs repeat)))
196 (let ((iterations 0))
197 (while (< iterations repeat)
198 (end-of-line)
199 (search-forward-regexp
200 (concat "^[\t ]*\\(\\[\\w+\\]\\|"
201 wesnoth-preprocessor-opening-regexp "\\)")
202 (buffer-size) t)
203 (setq iterations (1+ iterations)))))
205 (defun wesnoth-jump-backward (repeat)
206 "Move point to the beginning of the previous tag.
207 REPEAT is an optional numeric argument. If REPEAT is non-nil,
208 jump backward the specified number of tags."
209 (interactive "p")
210 (or repeat (setq repeat 1))
211 (and (< repeat 0) (wesnoth-jump-forward (abs repeat)))
212 (let ((iterations 0))
213 (while (< iterations repeat)
214 (beginning-of-line)
215 (search-backward-regexp
216 (concat "^[\t ]*\\(\\[\\w+\\]\\|"
217 wesnoth-preprocessor-opening-regexp "\\)")
218 0 t)
219 (unless (bobp)
220 (search-forward-regexp "[^[:blank:]]")
221 (backward-char))
222 (setq iterations (1+ iterations)))))
224 (defun wesnoth-jump-to-matching ()
225 "Jump point to the matching opening/closing tag.
226 A tag must be on the same line as point for jumping to occur. If
227 the tag structure is not correct this may have unexpected
228 results."
229 (interactive)
230 (let ((open-tags 0)
231 (search-started nil)
232 (tag-position nil)
233 (search-backward nil))
234 (save-excursion
235 (beginning-of-line)
236 (if (looking-at
237 (concat "^[\t ]*\\(\\[\\|"
238 wesnoth-preprocessor-regexp "\\)"))
239 (when (looking-at
240 (concat "^[\t ]*\\(\\[/\\|#\\(?:endif\\|enddef\\)\\)"))
241 (setq search-backward t))
242 (if (wesnoth-wml-start-pos)
243 (if (> (point) (wesnoth-wml-start-pos))
244 (search-backward-regexp
245 (concat "^[\t ]*\\(\\[\\|"
246 wesnoth-preprocessor-regexp "\\)")
247 (point-min) t)
248 (goto-char (point-min))
249 (search-forward-regexp
250 (concat "^[\t ]*\\(\\[\\|"
251 wesnoth-preprocessor-regexp "\\)"))
252 (beginning-of-line))
253 (error "%s" "Unable to locate tag to jump from")))
254 (if search-backward
255 (progn
256 (end-of-line)
257 (while (and
258 (or (< open-tags 0) (not search-started))
259 (search-backward-regexp
260 (concat "^[\t ]*\\(\\[\\|"
261 wesnoth-preprocessor-regexp "\\)")
262 (point-min) t))
263 (setq search-started t)
264 (if (looking-at
265 "^[\t ]*\\(\\[\\w+\\]\\|#\\(?:define\\|ifdef\\) \\)")
266 (setq open-tags (1+ open-tags))
267 (when (looking-at
268 (concat "^[\t ]*\\(\\[/\\w+\\]\\|#\\(?:endif\\|enddef\\)\\)"))
269 (setq open-tags (1- open-tags))))))
270 (while (and
271 (or (> open-tags 0) (not search-started))
272 (search-forward-regexp
273 (concat "^[\t ]*\\(\\[\\|"
274 wesnoth-preprocessor-regexp "\\)")
275 (point-max) t))
276 (beginning-of-line)
277 (setq search-started t)
278 (if (looking-at
279 "^[\t ]*\\(\\[\\w+\\]\\|#\\(?:define\\|ifdef\\) \\)")
280 (setq open-tags (1+ open-tags))
281 (when (looking-at
282 (concat "^[\t ]*\\(\\[/\\w+\\]\\|#\\(?:endif\\|enddef\\)\\)"))
283 (setq open-tags (1- open-tags))))
284 (end-of-line)))
285 (setq tag-position (point)))
286 (if interactive-p
287 (goto-char tag-position)
288 tag-position))
289 (end-of-line)
290 (search-backward-regexp "\\[\\|#"))
292 (defun wesnoth-wml-start-pos ()
293 "Determine the position of `point' relative to where the actual WML begins.
294 Return the likely starting position of the WML if it is found.
295 Otherwise return nil."
296 (save-excursion
297 (goto-char (point-min))
298 (when (search-forward-regexp
299 (concat "^[\t ]*\\(\\[\\)\\|\\("
300 wesnoth-preprocessor-opening-regexp
301 "\\)")
302 (buffer-size) t)
303 (beginning-of-line)
304 (point))))
306 (defun wesnoth-indent-line-default ()
307 "Indent the current line as WML using normal-style indentation."
308 (beginning-of-line)
309 (if (or (not (wesnoth-wml-start-pos))
310 (<= (point) (wesnoth-wml-start-pos))
311 (nth 3 (syntax-ppss (point))))
312 (indent-line-to 0)
313 (let ((not-indented t) cur-indent)
314 (if (looking-at
315 (concat "^[ \t]*\\(\\[\\/[^]]*?\\|\\("
316 wesnoth-preprocessor-closing-regexp "\\)\\)"))
317 (progn
318 (save-excursion
319 (search-backward-regexp
320 (concat "^[\t ]*\\[\\|\\(" wesnoth-preprocessor-regexp "\\)"))
321 (setq cur-indent (current-indentation))
322 (beginning-of-line)
323 (when (looking-at
324 (concat "^[\t ]*\\(\\[/.+\\]\\|\\("
325 wesnoth-preprocessor-closing-regexp
326 "\\)\\)"))
327 (setq cur-indent (- (current-indentation) wesnoth-indent))))
328 (if (< cur-indent 0)
329 (setq cur-indent 0)))
330 (if (not (looking-at
331 (concat "^[ \t]*\\(\\[[^/]*?\\]\\|\\("
332 wesnoth-preprocessor-closing-regexp "\\)\\)")))
333 (save-excursion
334 (search-backward-regexp
335 (concat "^[\t ]*\\(\\[\\|\\("
336 wesnoth-preprocessor-regexp "\\)\\)"))
337 (if (looking-at
338 (concat "^[\t ]*\\(\\[/.+\\]\\|\\("
339 wesnoth-preprocessor-closing-regexp
340 "\\)\\)"))
341 (progn
342 (setq cur-indent (- (current-indentation) wesnoth-indent))
343 (if (< cur-indent 0)
344 (setq cur-indent 0))
345 (setq not-indented nil))
346 (setq cur-indent (current-indentation))
347 (setq not-indented nil)))
348 (save-excursion
349 (unless cur-indent
350 (search-backward-regexp
351 (concat "^[\t ]*\\([[}]\\|\\("
352 wesnoth-preprocessor-regexp
353 "\\)\\)"))
354 (if (looking-at
355 (concat "^[ \t]*\\(\\[[^/]*?\\]\\|\\("
356 wesnoth-preprocessor-opening-regexp "\\)\\)"))
357 (setq cur-indent (+ (current-indentation) wesnoth-indent))
358 (setq cur-indent (current-indentation)))))))
359 (unless (and (not cur-indent) (= (current-indentation) cur-indent))
360 (indent-line-to cur-indent))))
361 (end-of-line))
363 (defun wesnoth-indent-line-savefile ()
364 "Indent the current line as WML code using savefile-style indentation."
365 (beginning-of-line)
366 (if (or (not (wesnoth-wml-start-pos))
367 (<= (point) (wesnoth-wml-start-pos))
368 (nth 3 (syntax-ppss (point))))
369 (indent-line-to 0)
370 (let ((cur-indent))
371 (if (looking-at
372 (concat "^[ \t]*\\(\\[\\/[^]]*?\\|\\("
373 wesnoth-preprocessor-closing-regexp "\\)\\)"))
374 (progn
375 (save-excursion
376 (search-backward-regexp "^[ \t]+.\\|^[{[#]")
377 (setq cur-indent (- (current-indentation) wesnoth-indent))
378 (when (looking-at
379 (concat "^[ \t]*\\(\\[[^/].+\\]\\|\\("
380 wesnoth-preprocessor-opening-regexp "\\)\\)"))
381 (setq cur-indent (current-indentation))))
382 (if (< cur-indent 0)
383 (setq cur-indent 0)))
384 (save-excursion
385 (unless cur-indent
386 (search-backward-regexp "^[\t ]*\\([[#}]\\)")
387 (if (looking-at
388 (concat "^[ \t]*\\(\\[[^/]+?\\]\\|\\("
389 wesnoth-preprocessor-opening-regexp "\\)\\)"))
390 (setq cur-indent (+ (current-indentation) wesnoth-indent))
391 (setq cur-indent (current-indentation))))))
392 (unless (and (not cur-indent)
393 (= (current-indentation) cur-indent))
394 (indent-line-to cur-indent))))
395 (end-of-line))
397 (defun wesnoth-newline ()
398 "Indent both the current line and the newline created.
399 If `wesnoth-auto-indent-flag' is nil, indentation will not be
400 performed."
401 (interactive)
402 (when wesnoth-auto-indent-flag
403 (save-excursion
404 (beginning-of-line)
405 (if (looking-at "^[\t ]*$")
406 (indent-line-to 0)
407 (wesnoth-indent-line))))
408 (newline))
410 (defun wesnoth-newline-and-indent ()
411 "Indent both the current line and the newline created.
412 If `wesnoth-auto-indent-flag' is nil, indentation will not be
413 performed."
414 (interactive)
415 (wesnoth-newline)
416 (wesnoth-indent-line))
418 (defun wesnoth-check-tag-names ()
419 "Check the names of all tags in the buffer for correctness.
420 If a tag is found which is not present in the list an error will
421 be signalled and point will be moved to the corresponding
422 position."
423 (interactive)
424 (let ((tag-position nil)
425 (missing-tag-name nil))
426 (save-excursion
427 (goto-char (point-min))
428 (while (and
429 (search-forward-regexp "^[\t ]*\\[" (point-max) t)
430 (not tag-position))
431 (beginning-of-line)
432 (when (looking-at "^[\t ]*\\[[/]?\\(\\w+\\)\\]")
433 (unless (member (match-string-no-properties 1) wesnoth-tags-list)
434 (setq tag-position (point))
435 (setq missing-tag-name (match-string-no-properties 1))))
436 (end-of-line)))
437 (when tag-position
438 (goto-char tag-position)
439 (message "'%s' is not known to exist"
440 missing-tag-name))))
442 (defun wesnoth-check-structure ()
443 "Check the buffer for correct nesting of elements.
444 If a problem is found in the structure, point will be placed at
445 the location which an element was expected and the expected
446 element will be displayed in the minibuffer."
447 (interactive)
448 (let ((unmatched-tag-list '())
449 (error-position nil))
450 (save-excursion
451 (goto-char (point-min))
452 (while (and
453 (search-forward-regexp
454 (concat "^[\t ]*\\[\\|\\(" wesnoth-preprocessor-regexp "\\)")
455 (point-max) t)
456 (not error-position))
457 (beginning-of-line)
458 (if (looking-at "^[\t ]*#\\(\\w+\\)")
459 (let ((preprocessor-name (match-string-no-properties 1)))
460 (cond
461 ((string= preprocessor-name "define")
462 (setq unmatched-tag-list
463 (cons preprocessor-name unmatched-tag-list)))
464 ((string= preprocessor-name "ifdef")
465 (setq unmatched-tag-list
466 (cons preprocessor-name unmatched-tag-list)))
467 ((string= preprocessor-name "else")
468 (unless (string= (car unmatched-tag-list) "ifdef")
469 (setq error-position (point))))
470 ((string= preprocessor-name "endif")
471 (if (string= (car unmatched-tag-list) "ifdef")
472 (setq unmatched-tag-list (cdr unmatched-tag-list))
473 (setq error-position (point))))
474 ((string= preprocessor-name "enddef")
475 (if (string= (car unmatched-tag-list) "define")
476 (setq unmatched-tag-list (cdr unmatched-tag-list))
477 (setq error-position (point))))))
478 (if (looking-at "^[\t ]*\\[\\(\\w+\\)\\]")
479 (setq unmatched-tag-list
480 (cons (match-string-no-properties 1)
481 unmatched-tag-list))
482 (when (looking-at "^[\t ]*\\[/\\(\\w+\\)\\]")
483 (if (string= (match-string-no-properties 1)
484 (car unmatched-tag-list))
485 (setq unmatched-tag-list (cdr unmatched-tag-list))
486 (setq error-position (point))))))
487 (end-of-line)))
488 (when (or unmatched-tag-list error-position)
489 (if error-position
490 (goto-char error-position)
491 (goto-char (point-max)))
492 (let ((expected nil))
493 (cond ((string= (car unmatched-tag-list) "define")
494 (setq expected "#enddef"))
495 ((string= (car unmatched-tag-list) "ifdef")
496 (setq expected "#endif"))
497 ((not unmatched-tag-list)
498 (setq expected "end of file")))
499 (and (interactive-p)
500 (message "Expecting: '%s'"
502 expected (concat "[/" (car unmatched-tag-list)
503 "]"))))
504 (or expected (concat "[/" (car unmatched-tag-list) "]"))))))
506 (defun wesnoth-fix-structure ()
507 "Attempt to fix all faults in the structure of the current buffer."
508 (interactive)
509 (let ((element (wesnoth-check-structure)))
510 (while element
511 (if (string= element "end of file")
512 (delete-region (point) (point-max))
513 (beginning-of-line)
514 (open-line 1)
515 (insert element)
516 (wesnoth-indent-line))
517 (setq element (wesnoth-check-structure)))))
519 (defun wesnoth-indent-line ()
520 "Determine and performs indentation on the current line.
521 The Indentation style can be customised by modifying
522 `wesnoth-indentation-function'."
523 (interactive)
524 (funcall wesnoth-indentation-function))
526 (define-derived-mode wesnoth-mode fundamental-mode "wesnoth-mode"
527 "Major mode for editing WML."
528 (set-syntax-table wesnoth-syntax-table)
529 (set (make-local-variable 'outline-regexp) "^[\t ]*\\[\\w+")
530 (set (make-local-variable 'comment-start) "#")
531 (set (make-local-variable 'indent-line-function) 'wesnoth-indent-line)
532 (set (make-local-variable 'font-lock-defaults)
533 '(wesnoth-font-lock-keywords
534 nil t nil nil
535 (font-lock-syntactic-keywords . wesnoth-syntactic-keywords)))
536 (setq mode-name "WML")
537 (run-hooks 'wesnoth-mode-hook))
539 (provide 'wesnoth-mode)