My tools of choice are Emacs AutoComplete mode, which gives Emacs intelli-sense like capabilities over a broad range of languages (it's pretty magical with Lisp, as you'd expect) and the good old Exuberant Ctags, primed to tag Unrealscript, with the following regular expressions in ~/ectags.cnf. I have to say ectags-select is very handy for working with these, as an alternative to the usual way of working with tags in Emacs as it lets you browse the enormous range of options that pop up.
These are the expressions to use for Exubrerant Ctags when tagging Unrealscript.
This is the support code I have: a set of interactive functions for invoking the udk, building code, running the editor. It creates a group of settings that can be customised with M-x customize-group udk. I watch the log in an emacs buffer via global-revert-tail mode. I have not yet added support for UDK log files to compilation mode, but thats an obvious tweak I'll try at some point. I've had enough fiddling with regular expressions for now.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; -- UNREALSCRIPT -------------------------------------------------------------- | |
(require 'unrealscript-mode) | |
(defcustom udk-location "C:\\UDK\\UDK-2011-11\\" | |
"Directory where udk executables are found" | |
:type 'directory | |
:group 'udk) | |
(defcustom udk-map "TestMap" | |
"Name of the map to launch the Unreal game with" | |
:type 'string | |
:group 'udk) | |
(defcustom udk-game "AwesomeGame.AwesomeGameInfo" | |
"Name of the Game Info Class in Unrealscript that runs the game" | |
:type 'string | |
:group 'udk) | |
(defcustom udk-executable (concat udk-location "Binaries\\UDKLift.exe") | |
"Executable to launch game or editor with" | |
:type 'file | |
:group 'udk) | |
(defcustom udk-log (concat udk-location "UDKGame\\Logs\\Launch.log") | |
"Log file to monitor for game progress" | |
:type 'file | |
:group 'udk) | |
(defun udk-build (arg) | |
(interactive "P") | |
(shell-command (concat udk-executable " make " (if arg "" " -DEBUG")) "*Build*" "*UDK Build Errors*") | |
(select-window (split-window)) | |
(find-file-read-only udk-log) | |
(end-of-buffer) | |
(compilation-minor-mode 1) | |
(auto-revert-tail-mode 1)) | |
(defun udk-rebuild (arg) | |
(interactive "P") | |
(shell-command (concat udk-executable " make " (if arg "" " -debug") " -full") "*UDK Rebuild*" "*UDK Rebuild Errors*") | |
(select-window (split-window)) | |
(find-file-read-only udk-log) | |
(end-of-buffer) | |
(compilation-minor-mode 1) | |
(auto-revert-tail-mode 1)) | |
(defun udk-game () | |
(interactive) | |
(shell-command (concat udk-executable (format " %s?%s -vadebug -nomoviestartup -ConsolePosX=0 -ConsolePosY=0" udk-map udk-game " &") "*UDK Game*" "*UDK Game Errors*") | |
(select-window (split-window)) | |
(find-file-read-only udk-log) | |
(end-of-buffer) | |
(compilation-minor-mode 1) | |
(auto-revert-tail-mode 1))) | |
(defun udk-edit () | |
(interactive) | |
(shell-command (concat udk-executable " editor " (format "%s.upk" udk-map) " &")) | |
(select-window (split-window)) | |
(find-file-read-only udk-log) | |
(end-of-buffer) | |
(compilation-minor-mode 1) | |
(auto-revert-tail-mode 1)) | |
(defconst unrealscript-keywords | |
(sort | |
(list | |
"abstract" "always" "array" "arraycount" "assert" | |
"auto" "automated" "bool" "break" "button" | |
"byte" "case" "class" "coerce" "collapsecategories" | |
"config" "const" "continue" "default" "defaultproperties" | |
"delegate" "dependson" "deprecated" "do" "dontcollapsecategories" | |
"edfindable" "editconst" "editconstarray" "editinline" "editinlinenew" | |
"editinlinenotify" "editinlineuse" "else" "enum" "enumcount" | |
"event" "exec" "expands" "export" "exportstructs" | |
"extends" "false" "final" "float" "for" | |
"foreach" "function" "global" "globalconfig" "goto" | |
"guid" "hidecategories" "if" "ignores" "import" | |
"init" "input" "insert" "instanced" "int" | |
"intrinsic" "invariant" "iterator" "latent" "length" | |
"local" "localized" "name" "native" "nativereplication" | |
"new" "noexport" "none" "noteditinlinenew" "notplaceable" | |
"nousercreate" "operator" "optional" "out" "perobjectconfig" | |
"placeable" "pointer" "postoperator" "preoperator" "private" | |
"protected" "reliable" "remove" "replication" "return" | |
"rng" "rot" "safereplace" "self" "showcategories" | |
"simulated" "singular" "skip" "state" "static" | |
"stop" "string" "struct" "super" "switch" | |
"transient" "travel" "true" "unreliable" "until" | |
"var" "vect" "while" "within") #'(lambda (a b) (> (length a) (length b)))) | |
"Source for unrealscript keywords.") | |
(defvar ac-source-unrealscript-keywords | |
'((candidates | |
. (lambda () | |
(all-completions ac-target unrealscript-keywords)))) | |
(add-hook 'unrealascript-mode-hook | |
(lambda () | |
(mirror-mode 1) | |
(setq ac-sources '(ac-source-unrealscript-keywords ac-source-words-in-same-mode-buffers ac-source-etags)) | |
(auto-complete-mode 1) | |
;; (yas/minor-mode-on) when we try adding snippets | |
(c-set-style "unrealscript")))) | |
(defun grep-udk (pattern) | |
;; This needs to be set for grep to work under Win32. Path must point to GnuWin32 find and not windows find | |
(setq grep-find-template "find . <X> -type f <F> -print0 | xargs -0 -e grep <C> -inH -e <R>") | |
(interactive "MSearch for: ") | |
(rgrep pattern "*.uc" udk-location)) | |
(defun tag-unrealscript () | |
(interactive) | |
(shell-command | |
(concat | |
"dir /b /s " udk-location "Development\\Src\\*.uc | ectags --verbose -e -o " udk-location "\\Development\\Src\\TAGS --options=\"" (expand-file-name "~/ectags.cnf") "\" --language-force=unrealscript -L - &"))) | |
(defun load-udk-tags () | |
(interactive) | |
(visit-tags-table (concat udk-location "Development\\Src\\TAGS"))) |
PS: I thought I'd reproduce the unrealscript mode here, just in case. It lives where you put your other extra mode files.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Unrealscript major mode | |
;; Copyright (C) 2012 John Connors | |
;; Author: John Connors | |
;; Keywords: extensions | |
;; This file is free software; you can redistribute it and/or modify | |
;; it under the terms of the GNU General Public License as published by | |
;; the Free Software Foundation; either version 2, or (at your option) | |
;; any later version. | |
;; This file is distributed in the hope that it will be useful, | |
;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
;; GNU General Public License for more details. | |
;; You should have received a copy of the GNU General Public License | |
;; along with GNU Emacs; see the file COPYING. If not, write to | |
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
;; Boston, MA 02111-1307, USA. | |
;;; Commentary: | |
;; | |
(defvar unrealscript-mode-hook nil) | |
(defvar unrealscript-mode-map | |
(let ((unrealscript-mode-map (make-sparse-keymap))) | |
(define-key unrealscript-mode-map "\C-j" 'newline-and-indent) | |
unrealscript-mode-map) | |
"Keymap for UNREALSCRIPT major mode") | |
(defconst unrealscript-font-lock-keywords-1 | |
(list | |
'("\\<\\(?:break\\|c\\(?:\\(?:as\\|ontinu\\)e\\)\\|do\\|e\\(?:lse\\|xtends\\)\\|for\\(?:each\\)?\\|i\\(?:f\\|nterface\\)\\|new\\|return\\|switch\\|var\\|while\\|class\\)\\>" . font-lock-keyword-face)) | |
"Minimal highlighting expressions for UNREALSCRIPT mode.") | |
(defconst unrealscript-font-lock-keywords-2 | |
(append unrealscript-font-lock-keywords-1 | |
(list | |
'("\\<\\(?:array\\|b\\(?:ool\\|yte\\)\\|c\\(?:lass\\|o\\(?:erce\\|lor\\|ords\\)\\)\\|de\\(?:faultproperties\\|legate\\)\\|e\\(?:num\\|vent\\)\\|f\\(?:alse\\|loat\\|unction\\)\\|int\\|local\\|name\\|o\\(?:ptional\\|ut\\)\\|plane\\|r\\(?:egion\\|otator\\)\\|st\\(?:ate\\|r\\(?:ing\\|uct\\)\\)\\|true\\|v\\(?:\\(?:a\\|ecto\\)r\\)\\)\\>" . font-lock-keyword-face))) | |
"Additional Keywords to highlight in UNREALSCRIPT mode.") | |
(defconst unrealscript-font-lock-keywords-3 | |
(append unrealscript-font-lock-keywords-2 | |
(list | |
'("\\<\\(?:A\\(?:bstract\\|llowAbstract\\|uto\\(?:Comment\\|ExpandCategories\\)\\)\\|Co\\(?:llapseCategories\\|nfig\\)\\|D\\(?:ep\\(?:endsOn\\|recated\\)\\|isplayName\\|ontCollapseCategories\\)\\|Edit\\(?:Condition\\|InlineNew\\)\\|FriendlyName\\|Hide\\(?:Categories\\|DropDown\\)\\|I\\(?:\\(?:mplemen\\|nheri\\)ts\\)\\|N\\(?:ative\\(?:Replication\\)?\\|o\\(?:Export\\|nTransient\\|t\\(?:EditInlineNew\\|Placeable\\)\\)\\)\\|P\\(?:erObject\\(?:Config\\|Localized\\)\\|laceable\\)\\|ShowCategories\\|T\\(?:oolTip\\|ransient\\)\\|Within\\)\\>" . font-lock-type-face) | |
'("\\<\\(?:auto\\|c\\(?:lient\\|on\\(?:fig\\|st\\)\\)\\|d\\(?:atabinding\\|eprecated\\|uplicatetransient\\)\\|e\\(?:dit\\(?:const\\|fixedsize\\|inline\\(?:use\\)?\\|oronly\\)\\|x\\(?:ec\\|port\\)\\)\\|globalconfig\\|i\\(?:gnores\\|n\\(?:it\\|put\\|stanced\\|terp\\)\\|terator\\)\\|l\\(?:atent\\|ocalized\\)\\|n\\(?:ative\\(?:replication\\)?\\|o\\(?:clear\\|export\\|import\\|ntransactional\\|tforconsole\\)\\)\\|operator\\|p\\(?:o\\(?:\\(?:inte\\|stoperato\\)r\\)\\|r\\(?:eoperator\\|ivate\\|otected\\)\\|ublic\\)\\|re\\(?:liable\\|pnotify\\)\\|s\\(?:erver\\|i\\(?:mulated\\|ngular\\)\\|kip\\|tatic\\)\\|tra\\(?:nsient\\|vel\\)\\|unreliable\\)\\>" . font-lock-keyword-face) | |
'("\\<\\(?:A\\(?:bs\\|cos\\|dd\\(?:Item\\)?\\|llActors\\|s\\(?:c\\|in\\)\\|tan\\)\\|B\\(?:asedActors\\|egin\\(?:Play\\|State\\)\\)\\|C\\(?:aps\\|eil\\|h\\(?:ildActors\\|r\\)\\|l\\(?:amp\\|earTimer\\)\\|o\\(?:\\(?:llidingActor\\)?s\\)\\)\\|D\\(?:estroyed\\|i\\(?:\\(?:sabl\\|vid\\)e\\)\\|ynamicActors\\)\\|E\\(?:mpty\\|n\\(?:\\(?:abl\\|dStat\\)e\\)\\|val\\|xp\\)\\|F\\(?:Clamp\\|M\\(?:ax\\|in\\)\\|Rand\\|astTrace\\|in\\(?:d\\|ish\\(?:Anim\\|Interpolation\\)\\)\\)\\|G\\(?:etTimer\\(?:Count\\|Rate\\)\\|oTo\\(?:State\\)?\\)\\|I\\(?:n\\(?:Str\\|itGame\\|sert\\(?:Item\\)?\\|vert\\)\\|s\\(?:\\(?:InStat\\|TimerActiv\\)e\\)\\)\\|L\\(?:e\\(?:ft\\|n\\|rp\\)\\|o\\(?:cs\\|ge\\)\\)\\|M\\(?:ax\\|i\\(?:rrorVectorByNormal\\|[dn]\\)\\)\\|Normal\\|OverlappingActors\\|P\\(?:o\\(?:pState\\|stBeginPlay\\)\\|reBeginPlay\\|ushState\\)\\|R\\(?:and\\|e\\(?:move\\(?:I\\(?:ndex\\|tem\\)\\)?\\|pl\\(?:ace\\)?\\)\\|ight\\|ound\\)\\|S\\(?:et\\(?:State\\|Timer\\)\\|in\\|leep\\|merp\\|p\\(?:awn\\|lit\\)\\|q\\(?:rt\\|uare\\)\\)\\|T\\(?:an\\|ick\\|ouchingActors\\|race\\(?:Actors\\)?\\)\\|V\\(?:Rand\\|Size\\|isible\\(?:\\(?:Colliding\\)?Actors\\)\\)\\|\\(?:ro\\|vec\\)t\\)\\>" . font-lock-function-name-face))) | |
"Balls-out highlighting in UNREALSCRIPT mode.") | |
(defvar unrealscript-font-lock-keywords unrealscript-font-lock-keywords-3 | |
"Default highlighting expressions for UNREALSCRIPT mode.") | |
(defvar unrealscript-indent-width 4) | |
(defun looking-at-unrealscript-indent-keyword () | |
(or (looking-at "^[\t ]*while") (looking-at "^[ \t]*foreach") (looking-at "^[ \t]*do") (looking-at "^[\t ]*if") (looking-at "^[\t ]*else") (looking-at "^[\t ]*for"))) | |
(defun looking-at-unrealscript-block-end () | |
(or (looking-at "^[\t ]*end") (looking-at "^[\t ]*break[\t ]*;") (and (looking-at "^.*};*[ \t]*$") (not (looking-at "^.*{"))))) | |
(defun looking-at-unrealscript-block-start () | |
(or (looking-at "^[\t ]*begin") (looking-at "^[\t ]*default[\t ]*:") (looking-at "^[\t ]*case.*:") (and (looking-at "^.*{") (not (looking-at "^.*};*[ \t]*$"))))) | |
;; Function to control indenting. | |
(defun unrealscript-indent-line () | |
"Indent current line as Unrealscript code" | |
(interactive) | |
;; Set the point to beginning of line. | |
(beginning-of-line) | |
(if (bobp) | |
(indent-line-to 0) | |
(let ((not-indented t) (lines-back 0) cur-indent) | |
(if (looking-at-unrealscript-block-end) ; Check for closing brace | |
;; if we are at the end of a block | |
(progn | |
(save-excursion | |
(forward-line -1) | |
(setq lines-back (+ lines-back 1)) | |
(setq cur-indent (- (current-indentation) unrealscript-indent-width))) | |
;; Safety check to make sure we don't indent negative. | |
(if (< cur-indent 0) | |
(setq cur-indent 0))) | |
;; else scan backward | |
(save-excursion | |
(if (looking-at-unrealscript-block-start) ; Opening block | |
(progn | |
(forward-line -1) | |
(setq lines-back (+ lines-back 1)) | |
(setq cur-indent (current-indentation)) | |
(setq not-indented nil)) | |
(while not-indented | |
(forward-line -1) | |
(setq lines-back (+ lines-back 1)) | |
(if (looking-at-unrealscript-block-end) ;; Closing Block | |
(progn | |
(setq cur-indent (current-indentation)) | |
(setq not-indented nil)) | |
(if (looking-at-unrealscript-block-start) | |
(progn | |
(setq cur-indent (+ (current-indentation) unrealscript-indent-width)) | |
(setq not-indented nil)) | |
(if (looking-at-unrealscript-indent-keyword) | |
(progn | |
(setq cur-indent (current-indentation)) | |
(forward-line 1) | |
(setq lines-back (- lines-back 1)) | |
(if (looking-at-unrealscript-block-start) | |
(setq not-indented nil) ;; has block | |
(if (zerop lines-back) ;; no block | |
(progn | |
(setq cur-indent (+ cur-indent unrealscript-indent-width)) | |
(setq not-indented nil)) | |
(setq not-indented nil)))) | |
(if (bobp) | |
(setq not-indented nil))))))))) | |
(if cur-indent | |
(indent-line-to cur-indent) | |
(indent-line-to 0))))) | |
(defun unrealscript-populate-syntax-table (table) | |
"Populate the given syntax table as necessary for a C-like language. | |
This includes setting ' and \" as string delimiters, and setting up | |
the comment syntax to handle both line style \"//\" and block style | |
\"/*\" \"*/\" comments." | |
(modify-syntax-entry ?_ "_" table) | |
(modify-syntax-entry ?\\ "\\" table) | |
(modify-syntax-entry ?+ "." table) | |
(modify-syntax-entry ?- "." table) | |
(modify-syntax-entry ?= "." table) | |
(modify-syntax-entry ?% "." table) | |
(modify-syntax-entry ?< "." table) | |
(modify-syntax-entry ?> "." table) | |
(modify-syntax-entry ?& "." table) | |
(modify-syntax-entry ?| "." table) | |
(modify-syntax-entry ?\' "\"" table) | |
(modify-syntax-entry ?\240 "." table) | |
;; Set up block and line oriented comments. The new C | |
;; standard mandates both comment styles even in C, so since | |
;; all languages now require dual comments, we make this the | |
;; default. | |
(modify-syntax-entry ?/ ". 124b" table) | |
(modify-syntax-entry ?* ". 23" table) | |
(modify-syntax-entry ?\n "> b" table) | |
;; Give CR the same syntax as newline, for selective-display | |
(modify-syntax-entry ?\^m "> b" table) | |
table) | |
(defvar unrealscript-mode-syntax-table | |
(let ((unrealscript-mode-syntax-table (unrealscript-populate-syntax-table (make-syntax-table)))) | |
unrealscript-mode-syntax-table) | |
"Syntax table for unrealscript-mode") | |
(defun unrealscript-mode () | |
"Major mode for editing Unrealscript files" | |
(interactive) | |
(kill-all-local-variables) | |
(set-syntax-table unrealscript-mode-syntax-table) | |
(use-local-map unrealscript-mode-map) | |
(setq indent-line-function 'unrealscript-indent-line) | |
(setq font-lock-defaults '(unrealscript-font-lock-keywords nil t)) | |
(setq major-mode 'unrealscript-mode) | |
(setq mode-name "UNREALSCRIPT") | |
(run-hooks 'unrealscript-mode-hook) | |
(setq case-fold-search t) | |
(setq font-lock-keywords-case-fold-search t)) | |
(provide 'unrealscript-mode) |
No comments:
Post a Comment