From 673922c3edbdee60edf9f4ef9e0a3cd8ebd53247 Mon Sep 17 00:00:00 2001 From: Chris Mann Date: Wed, 8 Oct 2008 21:49:45 +1030 Subject: [PATCH] * wesnoth-mode.el: Remove cl requirements. (wesnoth-element-completion): Removed gensym usage. (wesnoth-determine-wml-version): New function. WIP. (wesnoth-completion-available): Removed. (wesnoth-complete-macro): Replaced `find' usage. Requires wesnoth-update. (wesnoth-build-completion): Replaced `find' usage. (wesnoth-check-element-type): Replaced `remove-if-not' usage. (wesnoth-line-number-at-pos): New function. (wesnoth-check-output): Use it. (wesnoth-check-wml): Require wesnoth-mode. Replaced `find' usage. (wesnoth-mode): Show version used in the mode-line. * wesnoth-update.el: Removed cl requirements. (wesnoth-default-version, wesnoth-wml-version): New custom variables. (wesnoth-files-in-dir): Replaced `remove-if' usage. (wesnoth-cfg-files-in-dir): Replaced `remove-if-not' usage. (wesnoth-handle-file): Replaced `subseq' usage. (wesnoth-append-tag-information): Replaced `find' usage. (wesnoth-output-path): Fixed a bug where a variable was passed as an argument, instead of the variable's symbol. (wesnoth-update): Iterate over all versions defined in `wesnoth-wml-version'. No longer output `provide' form to file. --- wesnoth-mode.el | 133 ++++++++++++++++++++++++++---------------------------- wesnoth-update.el | 88 ++++++++++++++++++++---------------- 2 files changed, 113 insertions(+), 108 deletions(-) diff --git a/wesnoth-mode.el b/wesnoth-mode.el index ab49bc0..49848b2 100644 --- a/wesnoth-mode.el +++ b/wesnoth-mode.el @@ -124,10 +124,9 @@ ;; * Added support for #ifndef. ;;; Code: -(require 'cl) -;; The following provide WML data, but otherwise are not strictly necessary. -(require 'wesnoth-wml-data nil t) -(require 'wesnoth-update nil t) +(eval-when-compile + (require 'cl)) +(require 'wesnoth-update) (defconst wesnoth-mode-version "1.3.0-git" "The current version of `wesnoth-mode'.") @@ -263,20 +262,30 @@ level as their parent.") ;;; Insertion and completion (defmacro wesnoth-element-completion (completions prompt) "Process completion of COMPLETIONS, displaying PROMPT." - (let ((partial (gensym)) - (element (gensym))) - `(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 + `(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 + ((not (member element ,completions)) + (setq element (completing-read ,prompt ,completions - nil nil ,partial)))) - ,element))) + 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) +;; )) (defun wesnoth-parent-tag () "Return the name of the parent tag, nil otherwise." @@ -288,13 +297,7 @@ level as their parent.") (when parent (if (string-match wesnoth-preprocessor-closing-regexp parent) t - (subseq parent 2 (1- (length parent)))))))) - -(defmacro wesnoth-completion-available (list) - "Return symbol value of LIST when bound. -Used to support lack of completion data." - `(when (boundp ,list) - (symbol-value ,list))) + (substring parent 2 (1- (length parent)))))))) (defun wesnoth-indent-or-complete () "Indent or complete the line at point, depending on context." @@ -321,10 +324,8 @@ Used to support lack of completion data." "Complete and insert the macro at point. If COMPLETEP is non-nil, attempt to complete the macro at point." (interactive) - (let* ((macro-information (append (wesnoth-completion-available - 'wesnoth-macro-data) - (wesnoth-completion-available - 'wesnoth-local-macro-data))) + (let* ((macro-information (append wesnoth-macro-data + wesnoth-local-macro-data)) (completions (wesnoth-emacs-completion-formats (mapcar 'car macro-information))) (partial (when completep @@ -334,8 +335,7 @@ If COMPLETEP is non-nil, attempt to complete the macro at point." (match-string 1))))) (macro (or (wesnoth-element-completion completions "Macro: ") partial)) - (args (second (find macro macro-information - :key 'car :test 'string=)))) + (args (cadr (assoc macro macro-information)))) (when macro (if partial (progn @@ -410,11 +410,10 @@ than 22. POSITION is the argument passed to `nth' for (let* ((parent (wesnoth-parent-tag)) (candidates (if (or (stringp parent) (null parent)) - (nth position - (find (wesnoth-parent-tag) - (wesnoth-completion-available 'wesnoth-tag-data) - :key 'car :test 'string=)) - (mapcar 'car (wesnoth-completion-available 'wesnoth-tag-data))))) + (dolist (tag wesnoth-tag-data) + (when (string= (car tag) (wesnoth-parent-tag)) + (return (nth position tag)))) + (mapcar 'car wesnoth-tag-data)))) (wesnoth-emacs-completion-formats candidates))) (defun wesnoth-emacs-completion-formats (candidates) @@ -729,19 +728,16 @@ LAST-TAG is the parent element." (string= last-tag "#ifndef") (string= last-tag "#ifdef")) (member (match-string-no-properties 1) - (mapcar 'car (wesnoth-completion-available 'wesnoth-tag-data))) - (member last-tag - (mapcar 'car - (remove-if-not - (lambda (list) - (member (match-string-no-properties 1) - list)) - (wesnoth-completion-available 'wesnoth-tag-data) - :key position))))) - -;; Define line-number-at-pos if necessary (not available in Emacs 21). -(unless (fboundp 'line-number-at-pos) - (defun line-number-at-pos (&optional pos) + (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)))) + (member last-tag result)))) + +;; 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. Counting starts at (point-min), so the value refers @@ -752,7 +748,7 @@ to the contents of the accessible portion of the buffer." (setq start (point)) (goto-char opoint) (forward-line 0) - (1+ (count-lines start (point))))))) + (1+ (count-lines start (point)))))) (defun wesnoth-check-output (buffer format-string &rest args) "Output the string as passed to `format'. @@ -760,7 +756,7 @@ BUFFER is the buffer to output the result. FORMAT-STRING is the string as the first argument of `format'. ARGS is any additional data required by `format' to handle FORMAT-STRING." (save-excursion - (let ((lnap (line-number-at-pos))) + (let ((lnap (wesnoth-line-number-at-pos))) (set-buffer buffer) (insert (apply 'format (concat "%d: " format-string "\n") lnap args))))) @@ -768,9 +764,8 @@ ARGS is any additional data required by `format' to handle FORMAT-STRING." (defun wesnoth-check-wml () "Perform context-sensitive analysis of WML-code." (interactive) - (when (fboundp 'wesnoth-update-project-information) - (funcall 'wesnoth-update-project-information)) - (unless (wesnoth-completion-available 'wesnoth-tag-data) + (wesnoth-update-project-information) + (unless wesnoth-tag-data (error "WML data not available; can not generate report")) (let ((unmatched-tag-list '()) (outbuf (get-buffer-create "*WML*"))) @@ -801,12 +796,12 @@ ARGS is any additional data required by `format' to handle FORMAT-STRING." unmatched-tag-list))) ((looking-at wesnoth-preprocessor-closing-regexp) (unless (string= (car unmatched-tag-list) - (second (find (match-string-no-properties 1) + (second (assoc (match-string-no-properties 1) '(("enddef" "#define") ("ifdef" "#endif") - ("ifndef" "#endif")) - :key 'car :test 'string=))) - (wesnoth-check-output outbuf + ("ifndef" "#endif"))))) + (wesnoth-check-output + outbuf "Preprocessor statement does not nest correctly")) (setq unmatched-tag-list (cdr unmatched-tag-list))) ((looking-at "^[\t ]*\\(\\(\\w\\|_\\)+\\)=\\(.+\\)?") @@ -814,7 +809,7 @@ ARGS is any additional data required by `format' to handle FORMAT-STRING." (car unmatched-tag-list)) (wesnoth-check-output outbuf "Attribute not available in this context: '%s'" - (match-string-no-properties 1))) + (match-string-no-properties 1))) (unless (match-string 3) (wesnoth-check-output outbuf "Attribute has no value"))) @@ -826,25 +821,21 @@ ARGS is any additional data required by `format' to handle FORMAT-STRING." (wesnoth-check-output outbuf "Expecting: '[/%s]'" (car unmatched-tag-list))))) ((looking-at "^[\t ]*{\\(\\(\\w\\|_\\)+\\).*}") - (unless (find (match-string-no-properties 1) - (append (wesnoth-completion-available - 'wesnoth-local-macro-data) - (wesnoth-completion-available - 'wesnoth-macro-data)) - :test 'string= :key 'car) + (unless (assoc (match-string-no-properties 1) + (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\\|_\\)+\\)\\]")) (unless (string= (match-string-no-properties 1) (car unmatched-tag-list)) - (if (string= "#" (subseq (car unmatched-tag-list) 0 1)) + (if (string-match-p "^#.+" (car unmatched-tag-list)) (wesnoth-check-output outbuf "Expecting: '#%s'" (car - (find (car unmatched-tag-list) - '(("enddef" "#define") - ("ifdef" "#endif") - ("ifndef" "#endif")) - :key 'second :test 'string=))) + (assoc (car unmatched-tag-list) + '(("define" "#enddef") + ("endif" "#ifdef") + ("endif" "#ifndef"))))) (wesnoth-check-output outbuf "Expecting: '[/%s]'" (car unmatched-tag-list)))) (setq unmatched-tag-list (cdr unmatched-tag-list)))) @@ -949,7 +940,9 @@ positions of the buffer, respectively." nil t nil nil (font-lock-syntactic-keywords . wesnoth-syntactic-keywords))) (setq indent-tabs-mode nil) - (setq mode-name "WML") + (let ((ver (wesnoth-determine-wml-version wesnoth-wml-version))) + (load (format "wesnoth-wml-data-%s.el" ver)) + (setq mode-name (format "WML-%s" ver))) (run-hooks 'wesnoth-mode-hook)) (provide 'wesnoth-mode) diff --git a/wesnoth-update.el b/wesnoth-update.el index 3cce907..d61af24 100644 --- a/wesnoth-update.el +++ b/wesnoth-update.el @@ -58,15 +58,22 @@ ;; * Initial version ;;; Code: -(require 'cl) - (defvar wesnoth-update-version "0.1" "Version of `wesnoth-update'.") -(defcustom wesnoth-root-directory nil - "Path to the root directory of wesnoth. -Path must end in trailing slash." - :type 'directory +(defcustom wesnoth-default-version "1.5" + "Default version of WML to use. +This should correspond to a version string in `wesnoth-wml-version'." + :type 'string + :group 'wesnoth-wml-version) + +(defcustom wesnoth-wml-version '(("1.4" "~/src/wesnoth-1.4/" ("~/.wesnoth-1.4")) + ("1.5" "~/src/wesnoth/" ())) + "WML version information. +This should be in the form: +'((version-string wesnoth-version-path (list of WML project directories)) + (version-string ...))" + :type 'list :group 'wesnoth-mode) (defcustom wesnoth-addition-file nil @@ -80,9 +87,9 @@ Ensure this directory is in your `load-path'." :type 'directory :group 'wesnoth-mode) -(defvar wesnoth-macro-directory (concat wesnoth-root-directory "data/core/macros") +(defconst wesnoth-macro-directory "data/core/macros" "Directory which built-in macros are stored. -This is relative to `wesnoth-root-directory'.") +This is relative to the wesnoth directory in `wesnoth-wml-version.'.") (defvar wesnoth-found-cfgs '() "Temporary list of all .cfg files found.") @@ -114,17 +121,20 @@ Returns a list of sub-directories in DIR." (let ((cfgs (wesnoth-cfg-files-in-dir dir))) (when cfgs (setq wesnoth-found-cfgs (append cfgs wesnoth-found-cfgs)))) - (remove-if - (lambda (file) - (or (not (file-directory-p file)) - (string-match "^\\..+" (file-name-nondirectory file)))) - (file-expand-wildcards (concat dir "/*") t))) + (let ((result '())) + (dolist (file (file-expand-wildcards (concat dir "/*") t)) + (when (and (file-directory-p file) + (not (string-match "^\\..+" (file-name-nondirectory file)))) + (add-to-list 'result file))) + result)) (defun wesnoth-cfg-files-in-dir (dir) "Return all cfg files in DIR." - (remove-if-not 'wesnoth-file-cfg-p - (file-expand-wildcards - (concat dir "/*") t))) + (let ((result '())) + (dolist (file (file-expand-wildcards (concat dir "/*") t)) + (and (wesnoth-file-cfg-p file) + (add-to-list 'result file))) + result)) (defun wesnoth-determine-details (dir-or-file function) "Process .cfg files in DIR-OR-FILE using FUNCTION. @@ -149,7 +159,7 @@ DIR-OR-FILE can be a file, a directory, or a list of files." (when (and (string-match "^\\.#.*" (file-name-nondirectory file)) (file-symlink-p file)) (setq file (concat (file-name-directory file) - (subseq (file-name-nondirectory file) 1) "#"))) + (substring (file-name-nondirectory file) 1) "#"))) (when (file-exists-p file) (insert-file-contents file) (funcall function)))) @@ -191,7 +201,7 @@ DIR-OR-FILE can be a file, a directory, or a list of files." (defun wesnoth-append-tag-information (tag subtag attribute) "Add the information regarding TAG to the list. SUBTAG and ATTRIBUTE are a children of TAG to be added." - (let ((match (find tag wesnoth-tag-data :key 'car :test 'string=))) + (let ((match (assoc tag wesnoth-tag-data))) (if (not match) (add-to-list 'wesnoth-tag-data (list tag (and subtag (list subtag)) (and attribute (list attribute)))) @@ -205,7 +215,7 @@ SUBTAG and ATTRIBUTE are a children of TAG to be added." (add-to-list 'tmp attribute) (setq match (list tag (nth 1 match) tmp)))))) (setq wesnoth-tag-data - (remove (find tag wesnoth-tag-data :key 'car :test 'string=) + (remove (assoc tag wesnoth-tag-data) wesnoth-tag-data)) (add-to-list 'wesnoth-tag-data match)))) @@ -229,7 +239,7 @@ MACRO-LIST is the variable to append macro information." (defun wesnoth-output-path () "Determine the path to output wml information via `wesnoth-update'." (or wesnoth-update-output-directory - (and (boundp user-emacs-directory) + (and (boundp 'user-emacs-directory) user-emacs-directory) "~/.emacs.d/")) @@ -249,25 +259,27 @@ MACRO-LIST is the variable to append macro information." (defun wesnoth-update () "Update WML information. Path to WML information included in wesnoth is set by -`wesnoth-root-directory'." +`wesnoth-wml-version.'." (interactive) - (setq wesnoth-tag-data nil - wesnoth-macro-data nil) - (unless (and (stringp wesnoth-root-directory) - (file-exists-p wesnoth-root-directory)) - (error "%s: directory does not exist" - wesnoth-root-directory)) - (wesnoth-determine-details wesnoth-root-directory - 'wesnoth-extract-tag-information) - (wesnoth-update-wml-additions) - (wesnoth-determine-details wesnoth-macro-directory - 'wesnoth-determine-macro-builtins) - (with-temp-buffer - (insert (format "(defvar wesnoth-tag-data '%S)\n\n" wesnoth-tag-data)) - (insert (format "(defvar wesnoth-macro-data '%S)\n\n" wesnoth-macro-data)) - (insert (format "(provide 'wesnoth-wml-data)\n")) - (write-file (expand-file-name "wesnoth-wml-data.el" - (wesnoth-output-path))))) + (dolist (versions wesnoth-wml-version) + (setq wesnoth-tag-data nil + wesnoth-macro-data nil) + (unless (and (stringp (cadr versions)) + (file-exists-p (cadr versions))) + (error "%s: directory does not exist" + (cadr versions))) + (wesnoth-determine-details (cadr versions) + 'wesnoth-extract-tag-information) + (wesnoth-update-wml-additions) + (wesnoth-determine-details (concat (cadr versions) + wesnoth-macro-directory) + 'wesnoth-determine-macro-builtins) + (with-temp-buffer + (insert (format "(setq wesnoth-tag-data '%S)\n\n" wesnoth-tag-data)) + (insert (format "(setq wesnoth-macro-data '%S)\n" wesnoth-macro-data)) + (write-file (expand-file-name (format "wesnoth-wml-data-%s.el" + (car versions)) + (wesnoth-output-path)))))) (defun wesnoth-update-project-information () "Update WML macro information for the current project." -- 2.11.4.GIT