From 7b7605a773ddfae6539c418be3544b4a6ada70e3 Mon Sep 17 00:00:00 2001 From: Chris Mann Date: Thu, 9 Oct 2008 23:54:18 +1030 Subject: [PATCH] * wesnoth-mode.el: Added easymenu support. Indented correctly. (wesnoth-preprocessor-face): New face. For xemacs face support. (wesnoth-mode-map): Updated for easymenu. (wesnoth-menu): New easy menu definition. (wesnoth-preprocessor-best-face, wesnoth-font-lock-keywords): Updated for xemacs. No longer use global-font-lock-mode (should never have used it anyway). (wesnoth-check-wml): Fix transient-mark-mode bug in xemacs. --- wesnoth-mode.el | 177 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 98 insertions(+), 79 deletions(-) diff --git a/wesnoth-mode.el b/wesnoth-mode.el index 49848b2..5e87acf 100644 --- a/wesnoth-mode.el +++ b/wesnoth-mode.el @@ -34,6 +34,7 @@ ;;; History: ;; 1.3.0 +;; * Added support for Xemacs. ;; * WML checking is now context sensitive; checks attributes and macros. ;; * WML checks are now always performed on the entire buffer, with results ;; displayed in a temporary buffer. @@ -126,6 +127,7 @@ ;;; Code: (eval-when-compile (require 'cl)) +(require 'easymenu) (require 'wesnoth-update) (defconst wesnoth-mode-version "1.3.0-git" @@ -152,6 +154,10 @@ level as their parent.") :type 'integer :group 'wesnoth-mode) +(defface wesnoth-preprocessor-face '() + "Face to use for preprocessor statements." + :group 'wesnoth-mode) + (defconst wesnoth-preprocessor-regexp "[\t ]*#\\(enddef\\|define \\|e\\(lse\\|nd\\(\\(de\\|i\\)f\\)\\)\\|\\(ifn?\\|un\\)def\\)" "Regular expression to match all preprocessor statements.") @@ -189,22 +195,20 @@ level as their parent.") (define-key map (kbd "C-c /") 'wesnoth-insert-missing-closing) (define-key map (kbd "C-c C-/") 'wesnoth-insert-missing-closing) (define-key map (kbd "TAB") 'wesnoth-indent-or-complete) - (define-key map [menu-bar wesnoth] - (cons "WML" (make-sparse-keymap "WML"))) - (define-key map [menu-bar wesnoth check-structure] - '("Check WML" . wesnoth-check-wml)) - (define-key map [menu-bar wesnoth insert-tag] - '("Insert Tag" . wesnoth-insert-tag)) - (define-key map [menu-bar wesnoth complete-attribute] - '("Insert Attribute" . wesnoth-complete-attribute)) - (define-key map [menu-bar wesnoth complete-macro] - '("Insert Macro" . wesnoth-complete-macro)) - (define-key map [menu-bar wesnoth jump-to-matching] - '("Jump to Matching" . wesnoth-jump-to-matching)) - (define-key map [menu-bar wesnoth insert-missing-closing] - '("Insert Missing Tag" . wesnoth-insert-missing-closing)) map) - "Keymap used in wesnoth mode.") + "Keymap used in wesnoth-mode.") + +(easy-menu-define wesnoth-menu wesnoth-mode-map "Menu for wesnoth-mode" + '("WML" + ["Check WML" wesnoth-check-wml t] + ["Indent buffer" (lambda () + (interactive) + (wesnoth-indent-region (point-min) (point-max))) t] + ["Insert Tag" wesnoth-insert-tag t] + ["Insert Attribute" wesnoth-complete-attribute t] + ["Insert Macro" wesnoth-complete-macro t] + ["Jump to Matching" wesnoth-jump-to-matching t] + ["Insert Missing Tag" wesnoth-insert-missing-closing t])) (defvar wesnoth-syntax-table (let ((wesnoth-syntax-table (make-syntax-table))) @@ -227,27 +231,35 @@ level as their parent.") (defun wesnoth-preprocessor-best-face () "Use `font-lock-preprocessor-face' when available." - (when global-font-lock-mode - (if (boundp 'font-lock-preprocessor-face) - (copy-face 'font-lock-preprocessor-face 'wesnoth-preprocessor-face) - (copy-face 'font-lock-keyword-face 'wesnoth-preprocessor-face)))) - + (if (boundp 'font-lock-preprocessor-face) + (copy-face 'font-lock-preprocessor-face 'wesnoth-preprocessor-face) + (and (boundp 'font-lock-keyword-face) + (copy-face 'font-lock-keyword-face 'wesnoth-preprocessor-face)))) + (defvar wesnoth-font-lock-keywords - (list - '("#\\(?:define\\|\\(?:ifn?\\|un\\)def\\)" . 'wesnoth-preprocessor-face) - '("\\(#\\(?:define\\|\\(?:ifn?\\|un\\)def\\)\\)[\t ]+\\(\\(\\w\\|_\\)+\\)" - 2 font-lock-function-name-face) - '("\\(#e\\(?:lse\\|nd\\(?:\\(?:de\\|i\\)f\\)\\)\\)" . - 'wesnoth-preprocessor-face) - '("\\({[@~]?\\(\\w\\|\\.\\|/\\|-\\)+}\\)" - (1 font-lock-function-name-face)) - '("\\({\\(\\w\\|:\\|_\\)+\\|{[~@]?\\)" - (1 font-lock-function-name-face)) - '("}" . font-lock-function-name-face) - '("^[\t ]*\\(\\[[^]]+\\]\\)" 1 font-lock-type-face) - '("\\$\\(\\w\\|_\\)+" . font-lock-variable-name-face) - '("\\(\\(\\w\\|_\\)+\\(\\,[\t ]*\\(\\w\\|_\\)+\\)*\\)=" - 1 font-lock-variable-name-face)) + (append (if (featurep 'xemacs) + (list '("#\\(?:define\\|\\(?:ifn?\\|un\\)def\\)" . + wesnoth-preprocessor-face) + '("\\(#\\(?:define\\|\\(?:ifn?\\|un\\)def\\)\\)[\t ]+\\(\\(\\w\\|_\\)+\\)" + 2 font-lock-function-name-face) + '("\\(#e\\(?:lse\\|nd\\(?:\\(?:de\\|i\\)f\\)\\)\\)" . + wesnoth-preprocessor-face)) + (list + '("#\\(?:define\\|\\(?:ifn?\\|un\\)def\\)" . 'wesnoth-preprocessor-face) + '("\\(#\\(?:define\\|\\(?:ifn?\\|un\\)def\\)\\)[\t ]+\\(\\(\\w\\|_\\)+\\)" + 2 font-lock-function-name-face) + '("\\(#e\\(?:lse\\|nd\\(?:\\(?:de\\|i\\)f\\)\\)\\)" . + 'wesnoth-preprocessor-face))) + (list + '("\\({[@~]?\\(\\w\\|\\.\\|/\\|-\\)+}\\)" + (1 font-lock-function-name-face)) + '("\\({\\(\\w\\|:\\|_\\)+\\|{[~@]?\\)" + (1 font-lock-function-name-face)) + '("}" . font-lock-function-name-face) + '("^[\t ]*\\(\\[[^]]+\\]\\)" 1 font-lock-type-face) + '("\\$\\(\\w\\|_\\)+" . font-lock-variable-name-face) + '("\\(\\(\\w\\|_\\)+\\(\\,[\t ]*\\(\\w\\|_\\)+\\)*\\)=" + 1 font-lock-variable-name-face))) "Syntax highlighting for `wesnoth-mode'.") (defconst wesnoth-element-closing "^[\t ]*\\(\\[/\\|#enddef\\)" @@ -263,28 +275,28 @@ level as their parent.") (defmacro wesnoth-element-completion (completions prompt) "Process completion of COMPLETIONS, displaying PROMPT." `(let* ((partial (match-string-no-properties 1)) - (element (when partial (try-completion partial ,completions)))) - (cond ((eq element t) - (setq element nil)) - ((null element) - (setq element - (completing-read ,prompt ,completions))) - ((not (member element ,completions)) - (setq element - (completing-read ,prompt ,completions - nil nil partial)))) - element)) + (element (when partial (try-completion partial ,completions)))) + (cond ((eq element t) + (setq element nil)) + ((null element) + (setq element + (completing-read ,prompt ,completions))) + ((not (member element ,completions)) + (setq element + (completing-read ,prompt ,completions + nil nil partial)))) + element)) (defun wesnoth-determine-wml-version (wml-versions) "Determine version information for the current file." -;;(or (dolist (dirs (caddr wml-versions)) -;; (when (string-match (concat "^" (expand-file-name -;; dirs) ".+") -;; buffer-file-name) -;; (return (car version-info)))) -;; (or (when wesnoth-default-version -;; (car (assoc wesnoth-default-version wesnoth-wml-version))) - wesnoth-default-version) + ;;(or (dolist (dirs (caddr wml-versions)) + ;; (when (string-match (concat "^" (expand-file-name + ;; dirs) ".+") + ;; buffer-file-name) + ;; (return (car version-info)))) + ;; (or (when wesnoth-default-version + ;; (car (assoc wesnoth-default-version wesnoth-wml-version))) + wesnoth-default-version) ;; )) (defun wesnoth-parent-tag () @@ -338,10 +350,10 @@ If COMPLETEP is non-nil, attempt to complete the macro at point." (args (cadr (assoc macro macro-information)))) (when macro (if partial - (progn - (delete-region (progn (back-to-indentation) (point)) - (progn (end-of-line) (point))) - (insert "{" macro (if args " }" "}"))) + (progn + (delete-region (progn (back-to-indentation) (point)) + (progn (end-of-line) (point))) + (insert "{" macro (if args " }" "}"))) (wesnoth-insert-element-separately "{" macro (if args " }" "}"))) (save-excursion (wesnoth-indent)) @@ -388,10 +400,10 @@ If COMPLETEP is non-nil, attempt to complete tag at point." (let ((closed-p nil)) (save-excursion (wesnoth-jump-to-matching) - (back-to-indentation) - (when (and (looking-at "\\[/\\(\\(\\w\\|_\\)+\\)") - (string= tag (match-string 1))) - (setq closed-p t))) + (back-to-indentation) + (when (and (looking-at "\\[/\\(\\(\\w\\|_\\)+\\)") + (string= tag (match-string 1))) + (setq closed-p t))) (when completep (delete-region (progn (back-to-indentation) (point)) (progn (end-of-line) (point)))) @@ -497,7 +509,9 @@ specified will be used as START and END. Otherwise, START and END will be the minimum and maximum positions of the buffer, respectively." (interactive) - (if (and transient-mark-mode mark-active) + (if (and (boundp 'transient-mark-mode) + transient-mark-mode + mark-active) (setq start (region-beginning) end (copy-marker (region-end))) (setq start (point-min) @@ -731,12 +745,12 @@ LAST-TAG is the parent element." (mapcar 'car wesnoth-tag-data)) (let ((result '())) (dolist (tag wesnoth-tag-data) - (when (member (match-string-no-properties 1) - (funcall position tag)) - (add-to-list 'result (car tag)))) + (when (member (match-string-no-properties 1) + (funcall position tag)) + (add-to-list 'result (car tag)))) (member last-tag result)))) -;; Provide line-number-at-pos implementation (not available in Emacs 21). +;; Provide `line-number-at-pos' implementation (not available in Emacs 21). (defun wesnoth-line-number-at-pos (&optional pos) "Return (narrowed) buffer line number at position POS. If POS is nil, use current buffer location. @@ -797,9 +811,9 @@ ARGS is any additional data required by `format' to handle FORMAT-STRING." ((looking-at wesnoth-preprocessor-closing-regexp) (unless (string= (car unmatched-tag-list) (second (assoc (match-string-no-properties 1) - '(("enddef" "#define") - ("ifdef" "#endif") - ("ifndef" "#endif"))))) + '(("enddef" "#define") + ("ifdef" "#endif") + ("ifndef" "#endif"))))) (wesnoth-check-output outbuf "Preprocessor statement does not nest correctly")) @@ -822,8 +836,8 @@ ARGS is any additional data required by `format' to handle FORMAT-STRING." (car unmatched-tag-list))))) ((looking-at "^[\t ]*{\\(\\(\\w\\|_\\)+\\).*}") (unless (assoc (match-string-no-properties 1) - (append wesnoth-local-macro-data - wesnoth-macro-data)) + (append wesnoth-local-macro-data + wesnoth-macro-data)) (wesnoth-check-output outbuf "Unknown macro definition: '{%s}'" (match-string-no-properties 1)))) ((or (looking-at "^[\t ]*\\[/\\(\\(\\w\\|_\\)+\\)\\]")) @@ -833,9 +847,9 @@ ARGS is any additional data required by `format' to handle FORMAT-STRING." (wesnoth-check-output outbuf "Expecting: '#%s'" (car (assoc (car unmatched-tag-list) - '(("define" "#enddef") - ("endif" "#ifdef") - ("endif" "#ifndef"))))) + '(("define" "#enddef") + ("endif" "#ifdef") + ("endif" "#ifndef"))))) (wesnoth-check-output outbuf "Expecting: '[/%s]'" (car unmatched-tag-list)))) (setq unmatched-tag-list (cdr unmatched-tag-list)))) @@ -895,7 +909,8 @@ checked. Otherwise START and END will be the minimum and maximum positions of the buffer, respectively." (interactive) (unless (or start end) - (if (and transient-mark-mode mark-active) + (if (and (boundp 'transient-mark-mode) + transient-mark-mode mark-active) (setq start (region-beginning) end (copy-marker (region-end))) (setq start (point-min) @@ -929,6 +944,12 @@ positions of the buffer, respectively." ;;; wesnoth-mode (define-derived-mode wesnoth-mode fundamental-mode "wesnoth-mode" "Major mode for editing WML." + (kill-all-local-variables) + (use-local-map wesnoth-mode-map) + (setq major-mode 'wesnoth-mode) + (let ((ver (wesnoth-determine-wml-version wesnoth-wml-version))) + (load (format "wesnoth-wml-data-%s.el" ver)) + (setq mode-name (format "WML-%s" ver))) (wesnoth-preprocessor-best-face) (set-syntax-table wesnoth-syntax-table) (set (make-local-variable 'outline-regexp) "[\t ]*#define") @@ -940,9 +961,7 @@ positions of the buffer, respectively." nil t nil nil (font-lock-syntactic-keywords . wesnoth-syntactic-keywords))) (setq indent-tabs-mode nil) - (let ((ver (wesnoth-determine-wml-version wesnoth-wml-version))) - (load (format "wesnoth-wml-data-%s.el" ver)) - (setq mode-name (format "WML-%s" ver))) + (easy-menu-add wesnoth-menu wesnoth-mode-map) (run-hooks 'wesnoth-mode-hook)) (provide 'wesnoth-mode) -- 2.11.4.GIT