From aa1d4f5ab97516d5c7df6c4a1802b3b20ba8a29b Mon Sep 17 00:00:00 2001 From: Chris Mann Date: Thu, 10 Jan 2008 12:06:25 +1030 Subject: [PATCH] * wesnoth-mode.el: Added two new indentation styles. (wesnoth-jump-to-matching): Signals a warning if nesting in jump region is not correct. --- wesnoth-mode.el | 210 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 114 insertions(+), 96 deletions(-) diff --git a/wesnoth-mode.el b/wesnoth-mode.el index eed1a4f..f0bade3 100644 --- a/wesnoth-mode.el +++ b/wesnoth-mode.el @@ -32,33 +32,35 @@ ;;; Changes: ;; 1.2.2 -;; * Font-locking is now correctly performed on #endif. +;; * Fixed a bug in savefile indentation where content was needed between +;; equivalent elements for indentation to work. +;; * Fixed `wesnoth-newline-and-indent' ignoring the state of +;; `wesnoth-auto-indent-flag'. +;; * Fixed font-locking on #endif. +;; * Added indentation styles: `wesnoth-indent-savefile-preproc', +;; `wesnoth-indent-default-preproc' which implement a a similar indentation +;; style to the existing styles, however all preprocessor statements are +;; indented to the first column. +;; * Added support for several new tags. +;; * Added functions: `wesnoth-indent', `wesnoth-closing-indent-element', +;; `wesnoth-indent-element', `wesnoth-opening-indent-element', +;; `wesnoth-insert-and-indent', `wesnoth-insert-missing-closing'. +;; * Renamed `wesnoth-indent-line-default', `wesnoth-indent-line-savefile' and +;; `wesnoth-jump-backward', `wesnoth-jump-forward' to +;; `wesnoth-indent-default', `wesnoth-indent-savefile' and +;; `wesnoth-backward-tag', `wesnoth-forward-tag', respectively. +;; * Changed `wesnoth-newline' to behave more consistently. ;; * `wesnoth-jump-to-matching' now attempts to find a target if necessary and -;; will now work on preprocessor statements. +;; will now work on preprocessor statements. Will now warn if jump +;; destination may not be correct. ;; * Indentation style is now determined by `wesnoth-indentation-function'. -;; * Both indentation styles now leave point at the first non-whitespace -;; character of the line. ;; * `wesnoth-check-structure' can now be applied over an active region and ;; now checks preprocessor statements for correct nesting. -;; * `wesnoth-insert-missing-closing' new function to insert the next -;; expected closing element. (Bound to C-c C-/.) -;; * Changed `wesnoth-newline' to behave more consistantly. ;; * `wesnoth-newline' and `wesnoth-newline-and-indent' can be forced to ;; perform indentation by providing a prefix argument. -;; * Fixed `wesnoth-newline-and-indent' ignoring the state of -;; `wesnoth-auto-indent-flag'. -;; * Renamed `wesnoth-indent-line-default' and `wesnoth-indent-line-savefile' -;; to `wesnoth-indent-default' and `wesnoth-indent-savefile', respectively. -;; Set default value for `wesnoth-indentation-function' accordingly. -;; * Renamed `wesnoth-jump-backward' and `wesnoth-jump-forward' to -;; `wesnoth-backward-tag' and `wesnoth-forward-tag', respectively. -;; * `wesnoth-forward-tag' now moves point to the end of the next closing tag, -;; which is closer to existing entity movement behaviour in Emacs. -;; * Re-wrote `wesnoth-insert-tag'. -;; * Added function: `wesnoth-insert-and-indent'. -;; * Fixed a bug in savefile indentation. -;; * Added functions: `wesnoth-indent', `wesnoth-closing-p', -;; `wesnoth-opening-p'. +;; * `wesnoth-indent-savefile' and `wesnoth-indent-default' now leave point at +;; the first non-whitespace character of the line. +;; * `wesnoth-check-tag-names' now reports on success. ;; 1.2.1 ;; * Base indent now defaults to 4. ;; * Added support for #ifndef. @@ -72,9 +74,10 @@ (defcustom wesnoth-indentation-function 'wesnoth-indent-default "Use the specified function when indenting WML. -You can specify either `wesnoth-indent-default' or -`wesnoth-indent-savefile' as the indentation style or a -customised function for indentation." +You can specify `wesnoth-indent-default', +`wesnoth-indent-savefile', `wesnoth-indent-default-preproc' or +`wesnoth-indent-savefile-preproc' or a custom function as the +indentation style." :type 'function :group 'wesnoth-mode) @@ -164,30 +167,30 @@ indent the line." "animation" "array" "attack" "attacks" "avoid" "binary_path" "bold" "campaign" "capture_village" "choose""clear_variable" "colour_adjust" "command" "deaths" "defend" "defends" "defense" "delay" "destination" - "disallow_recruit" "do" "effect" "else" "end_turn" "endlevel" "era" "event" - "expenses" "filter" "filter_radius" "filter_second" "format" "frame" - "game_config" "generator" "gold" "have_unit" "header" "hide_unit" "if" - "illuminated_time" "image" "img" "income" "italic" "item" "jump" "kill" - "killed" "label" "language" "leader_goal" "main_map" "menu" "message" - "mini_map" "missile_frame" "modifications" "modify_side" "modify_turns" - "move" "move_unit_fake" "movement_costs" "movetype" "multiplayer" - "multiplayer_side" "music" "not" "num_units" "object" "objectives" - "objective" "observers" "option" "or" "panel" "part" "place_shroud" - "position" "print" "protect_location" "protect_unit" "race" "random" - "recall" "recalls" "recruit" "recruits" "redraw" "ref" "remove_shroud" - "remove_unit_overlay" "removeitem" "replay" "replay_start" "resistance" - "resolution" "results" "role" "save" "scenario" "scroll" "scroll_to" - "scroll_to_unit" "section" "set_recruit" "set_variable" "side" - "side_playing" "snapshot" "sound" "source" "specials" "statistics" "status" - "stone" "store_gold" "store_locations" "store_starting_location" - "store_unit" "story" "target" "team" "teleport" "teleport_anim" "terrain" - "terrain_graphics" "test" "textdomain" "theme" "then" "tile" "time" - "time_area" "time_of_day" "topic" "toplevel" "trait" "turn" "tutorial" - "unhide_unit" "unit" "unit_abilities" "unit_alignment" "unit_description" - "unit_hp" "unit_image" "unit_level" "unit_moves" "unit_overlay" - "unit_profile" "unit_status" "unit_traits" "unit_type" "unit_weapons" - "unit_xp" "units" "unstone" "unstore_unit" "upkeep" "variable" "variables" - "village" "villages" "while") + "disallow_recruit" "do" "effect" "else" "end_turn" "endlevel" "entry" "era" + "event" "expenses" "filter" "filter_adjacent_location" "filter_radius" + "filter_second" "format" "frame" "game_config" "generator" "gold" + "have_unit" "header" "hide_unit" "if" "illuminated_time" "image" "img" + "income" "italic" "item" "jump" "kill" "killed" "label" "language" + "leader_goal" "main_map" "menu" "message" "mini_map" "missile_frame" + "modifications" "modify_side" "modify_turns" "move" "move_unit_fake" + "movement_costs" "movetype" "multiplayer" "multiplayer_side" "music" "not" + "num_units" "object" "objectives" "objective" "observers" "option" "or" + "panel" "part" "place_shroud" "position" "print" "protect_location" + "protect_unit" "race" "random" "recall" "recalls" "recruit" "recruits" + "redraw" "ref" "remove_shroud" "remove_unit_overlay" "removeitem" "replay" + "replay_start" "resistance" "resolution" "results" "role" "save" "scenario" + "scroll" "scroll_to" "scroll_to_unit" "section" "set_recruit" + "set_variable" "side" "side_playing" "snapshot" "sound" "source" "specials" + "statistics" "status" "stone" "store_gold" "store_locations" + "store_starting_location" "store_unit" "story" "target" "team" "teleport" + "teleport_anim" "terrain" "terrain_graphics" "test" "textdomain" "theme" + "then" "tile" "time" "time_area" "time_of_day" "topic" "toplevel" "trait" + "turn" "tutorial" "unhide_unit" "unit" "unit_abilities" "unit_alignment" + "unit_description" "unit_hp" "unit_image" "unit_level" "unit_moves" + "unit_overlay" "unit_profile" "unit_status" "unit_traits" "unit_type" + "unit_weapons" "unit_xp" "units" "unstone" "unstore_unit" "upkeep" + "variable" "variables" "village" "villages" "while") "A list containing all tags which are available for use in WML.") @@ -294,9 +297,9 @@ jump backward the specified number of tags." (defun wesnoth-jump-to-matching () "Jump point to the matching opening/closing tag. -A tag must be on the same line as point for jumping to occur. If -the tag structure is not correct this may have unexpected -results." +A tag must be on the same line as point for jumping to occur. +Tag structure between the start and target positions must be +consistent for jumping to occur." (interactive) (let ((open-tags 0) (search-started nil) @@ -307,7 +310,7 @@ results." (if (looking-at (concat "^[\t ]*\\(\\[\\|" wesnoth-preprocessor-regexp "\\)")) - (when (wesnoth-closing-p) + (when (looking-at (wesnoth-closing-indent-element nil)) (setq search-backward t)) (if (wesnoth-wml-start-pos) (if (> (point) (wesnoth-wml-start-pos)) @@ -331,9 +334,9 @@ results." wesnoth-preprocessor-regexp "\\)") (point-min) t)) (setq search-started t) - (if (wesnoth-opening-p) + (if (looking-at (wesnoth-opening-indent-element nil)) (setq open-tags (1+ open-tags)) - (when (wesnoth-closing-p) + (when (looking-at (wesnoth-closing-indent-element nil)) (setq open-tags (1- open-tags)))))) (while (and (or (> open-tags 0) (not search-started)) @@ -343,12 +346,14 @@ results." (point-max) t)) (beginning-of-line) (setq search-started t) - (if (wesnoth-opening-p) + (if (looking-at (wesnoth-opening-indent-element nil)) (setq open-tags (1+ open-tags)) - (when (wesnoth-closing-p) + (when (looking-at (wesnoth-closing-indent-element nil)) (setq open-tags (1- open-tags)))) (end-of-line))) (setq tag-position (point))) + (and (wesnoth-check-structure (point) tag-position) + (message "%s" "Region concerning jump does not nest correctly; target may not be correct")) (if (interactive-p) (goto-char tag-position) tag-position)) @@ -364,90 +369,101 @@ The Indentation style can be customised by modifying (interactive) (funcall wesnoth-indentation-function)) -(defun wesnoth-closing-p () - "Return non-nil if looking at a closing element." - (looking-at - (concat "^[ \t]*\\(\\[/.+\\]\\|\\(" - wesnoth-preprocessor-closing-regexp "\\)\\)"))) - -(defun wesnoth-opening-p () - "Return non-nil if looking at an opening element." - (looking-at +(defun wesnoth-closing-indent-element (preproc-bol) + "Return string to use for closing indentation element." + (if preproc-bol + "^[ \t]*\\[/.+\\]" + (concat "^[ \t]*\\(\\[/.+\\]\\|\\(" + wesnoth-preprocessor-closing-regexp "\\)\\)"))) + +(defun wesnoth-opening-indent-element (preproc-bol) + "Return string to use for opening indentation element." + (if preproc-bol + "^[ \t]*\\[[^/]*?\\]" (concat "^[ \t]*\\(\\[[^/]*?\\]\\|\\(" wesnoth-preprocessor-opening-regexp "\\)\\)"))) +(defun wesnoth-indent-element (preproc-bol) + "Return string to use for an opening or closing identation element." + (if preproc-bol + "^[\t ]*\\[" + (concat "^[\t ]*\\(\\[\\|" + wesnoth-preprocessor-regexp "\\)"))) + (defun wesnoth-wml-start-pos () "Determine the position of `point' relative to where the actual WML begins. Return the likely starting position of the WML if it is found. Otherwise return nil." (save-excursion (goto-char (point-min)) - (when (search-forward-regexp - (concat "^[\t ]*\\(\\[\\)\\|\\(" - wesnoth-preprocessor-opening-regexp - "\\)") + (when (search-forward-regexp (wesnoth-indent-element t) (buffer-size) t) (beginning-of-line) (point)))) -(defun wesnoth-indent (&optional savefile-style) +(defun wesnoth-indent (savefile preproc-bol) "Indent the current line as WML. If savefile-style is non-nil, use savefile-style indentation, otherwise use default style indentation." (beginning-of-line) (if (or (not (wesnoth-wml-start-pos)) (<= (point) (wesnoth-wml-start-pos)) - (nth 3 (syntax-ppss (point)))) + (nth 3 (syntax-ppss (point))) + (and preproc-bol (looking-at (concat "^[\t ]*" wesnoth-preprocessor-regexp)))) (indent-line-to 0) (let ((cur-indent)) (save-excursion (cond ;; Closing regexp - ((wesnoth-closing-p) + ((looking-at (wesnoth-closing-indent-element preproc-bol)) (search-backward-regexp - (concat "^[\t ]*\\[\\|\\(" wesnoth-preprocessor-regexp "\\)")) + (wesnoth-indent-element preproc-bol)) ;; If closing preceded by closing, decrease indentation - (when (wesnoth-closing-p) + (when (looking-at (wesnoth-closing-indent-element preproc-bol)) (setq cur-indent (- (current-indentation) wesnoth-base-indent)))) ;; Opening regexp - ((wesnoth-opening-p) + ((looking-at (wesnoth-opening-indent-element preproc-bol)) (search-backward-regexp - (concat "^[\t ]*\\(\\[\\|\\(" - wesnoth-preprocessor-regexp "\\)\\)")) + (wesnoth-indent-element preproc-bol)) ;; If opening preceded by opening, increase indentation - (when (wesnoth-opening-p) + (when (looking-at (wesnoth-opening-indent-element preproc-bol)) (setq cur-indent (+ (current-indentation) wesnoth-base-indent)))) ;; Not opening, not closing (t - (search-backward-regexp - (concat "^[\t ]*\\([[}]\\|\\(" - wesnoth-preprocessor-regexp - "\\)\\)")) + (search-backward-regexp (wesnoth-indent-element preproc-bol)) ;; Decrease indent if preceded by closing - (if savefile-style - (and (wesnoth-opening-p) + (if savefile + (and (looking-at (wesnoth-opening-indent-element preproc-bol)) (setq cur-indent (+ (current-indentation) wesnoth-base-indent))) - (and (wesnoth-closing-p) - (setq cur-indent (- (current-indentation) wesnoth-base-indent))))) + (and (looking-at (wesnoth-closing-indent-element preproc-bol)) + (setq cur-indent (- (current-indentation) wesnoth-base-indent)))))) ;; Indentation change unnecessary (unless cur-indent (setq cur-indent (current-indentation)))) (and (< cur-indent 0) (setq cur-indent 0)) - (unless (and (not cur-indent) (= (current-indentation) cur-indent)) - (indent-line-to cur-indent)))) + (unless (and (not cur-indent) (= (current-indentation) cur-indent)) + (indent-line-to cur-indent)))) (beginning-of-line) (search-forward-regexp "[\t ]*")) (defun wesnoth-indent-savefile () "Indent the current line as WML code using savefile-style indentation." - (wesnoth-indent t)) + (wesnoth-indent t nil)) (defun wesnoth-indent-default () - "Indent the current line as WML code using savefile-style indentation." - (wesnoth-indent nil)) + "Indent the current line as WML code using default-style indentation." + (wesnoth-indent nil nil)) + +(defun wesnoth-indent-default-preproc () + "Indent the current line as WML code using default-style indentation." + (wesnoth-indent nil t)) + +(defun wesnoth-indent-savefile-preproc () + "Indent the current line as WML code using default-style indentation." + (wesnoth-indent t t)) -;;; Checking +;;; WML checks (defun wesnoth-check-tag-names () "Check the names of all tags in the buffer for correctness. If a tag is found which is not present in the list an error will @@ -467,10 +483,12 @@ position." (setq tag-position (point)) (setq missing-tag-name (match-string-no-properties 1)))) (end-of-line))) - (when tag-position + (if tag-position + (progn (goto-char tag-position) (message "'%s' is not known to exist" - missing-tag-name)))) + missing-tag-name)) + (message "%s" "No unknown tag names found.")))) (defun wesnoth-check-structure (&optional start end) "Check the buffer for correct nesting of elements. @@ -507,10 +525,10 @@ element will be displayed in the minibuffer." (setq unmatched-tag-list (cons preprocessor-name unmatched-tag-list))) ((string= preprocessor-name "else") - (unless (= (string-match "ifn?def" (car unmatched-tag-list)) 0) + (unless (string-match "ifn?def" (car unmatched-tag-list)) (setq error-position (point)))) ((string= preprocessor-name "endif") - (if (= (string-match "ifn?def" (car unmatched-tag-list)) 0) + (if (string-match "ifn?def" (car unmatched-tag-list)) (setq unmatched-tag-list (cdr unmatched-tag-list)) (setq error-position (point)))) ((string= preprocessor-name "enddef") -- 2.11.4.GIT