Cogito, ergo sum

Difference between revisions of "Legacy:Emacs"

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search
(Header had a funky non-ascii arrow entity instead of the standard "---" specified in Info node "(elisp) Library Headers" -- fix.)
(Updating to new version that actually works)
 
Line 4: Line 4:
  
 
<pre>
 
<pre>
;;; unrealscript-mode.el --- unrealscript mode derived from cc-mode
+
(defvar unrealscript-mode-hook nil)
  
;; Author:    2007 John Connors
+
(defvar unrealscript-mode-map
;; Maintainer: John Connors <johnc at yagc dot co dot uk>
+
  (let ((unrealscript-mode-map (make-sparse-keymap)))
;; Created:    March 2007
+
(define-key unrealscript-mode-map "\C-j" 'newline-and-indent)
;; Version:    See cc-mode.el
+
unrealscript-mode-map)
;; Keywords:  unrealscript cc-mode languages oop
+
  "Keymap for UNREALSCRIPT major mode")
  
;; This program 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 of the License, or
 
;; (at your option) any later version.
 
;;
 
;; This program 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 this program; see the file COPYING.  If not, write to
 
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
;; Boston, MA 02111-1307, USA.
 
  
;;; Commentary:
+
(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.")
  
;; Note: The interface used in this file requires CC Mode 5.30 or
 
;; later.
 
  
;;; Code:
+
(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.")
  
(require 'cc-mode)
+
(defvar unrealscript-font-lock-keywords unrealscript-font-lock-keywords-3
 +
  "Default highlighting expressions for UNREALSCRIPT mode.")
  
;; These are only required at compile time to get the sources for the
 
;; language constants.  (The cc-fonts require and the font-lock
 
;; related constants could additionally be put inside an
 
;; (eval-after-load "font-lock" ...) but then some trickery is
 
;; necessary to get them compiled.)
 
(eval-when-compile
 
  (require 'cc-langs)
 
  (require 'cc-fonts))
 
  
(eval-and-compile
+
(defvar unrealscript-indent-width 4)
  ;; Make our mode known to the language constant system.  Use Java
+
  ;; mode as the fallback for the constants we don't change here.
+
  ;; This needs to be done also at compile time since the language
+
  ;; constants are evaluated then.
+
  (c-add-language 'unrealscript-mode 'java-mode))
+
  
;; unrealscript has no boolean but a string and a vector type.
+
(defun looking-at-unrealscript-indent-keyword ()
(c-lang-defconst c-primitive-type-kwds
+
   (or (looking-at "^[\t ]*while") (looking-at "^[\t ]*if") (looking-at "^[\t ]*else") (looking-at "^[\t ]*for")))
  unrealscript
+
   (append
+
  '("bool" "name" "object" "actor" "string" "vector")
+
  (delete "boolean"
+
          ;; Use append to not be destructive on the
+
          ;; return value below.
+
          (append
+
            ;; Due to the fallback to Java, we need not give
+
            ;; a language to `c-lang-const'.
+
            (c-lang-const c-primitive-type-kwds)
+
            nil))))
+
  
(c-lang-defconst c-type-modifier-keywds
+
(defun looking-at-unrealscript-block-end ()
  unrealscript
+
  (or (looking-at "^[\t ]*end") (and (looking-at "^.*}[ \t]*$") (not (looking-at "^.*{")))))
    (append
+
      '("config" "deprecated" "edfindable" "editconstarray"
+
        "editinline" "export" "noexport" "globalconfig"
+
        "localized" "const" "editconst" "input" "travel"
+
        "skip" "export")  
+
      (c-lang-const c-type-modifier-keywds)  
+
      nil))
+
  
 +
(defun looking-at-unrealscript-block-start ()
 +
  (or (looking-at "^[\t ]*begin") (and (looking-at "^.*{") (not (looking-at "^.*}[ \t]*$")))))
  
;;  "Keywords introducing extra declaration specifiers in the region
+
;; Function to control indenting.
;; between the header and the body \(i.e. the \"K&R-region\") in
+
(defun unrealscript-indent-line ()
;; declarations."
+
   "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)))))
  
(c-lang-defconst c-postfix-decl-spec-kwds
+
(defun unrealscript-populate-syntax-table (table)
   unrealscript
+
   "Populate the given syntax table as necessary for a C-like language.
  (append
+
This includes setting ' and \" as string delimiters, and setting up
  '("abstract" "native" "nativereplication" "nousercreate" "within"  
+
the comment syntax to handle both line style \"//\" and block style
    "perobjectconfig" "transient" "noexport" "dependson" "exportstructs"  
+
\"/*\" \"*/\" comments."
    "cacheexempt" "hidedropdown" "parseconfig" "dontcollapsecategories"
+
    "collapsecategories" "hidecategories" "showcategories" "placeable"
+
    "notplaceable" "instanced")
+
  (c-lang-const c-postfix-decl-spec-kwds)
+
  nil))
+
  
;;   "Keywords that may be followed by a comma separated list of type
+
   (modify-syntax-entry ?_ "_"   table)
;; identifiers, where each optionally can be prefixed by keywords.  (Can
+
  (modify-syntax-entry ?\\ "\\"   table)
;; also be used for the special case when the list can contain only one
+
  (modify-syntax-entry ?+ "."   table)
;; element.)"
+
  (modify-syntax-entry ?- "."   table)
(c-lang-defconst c-type-list-kwds
+
  (modify-syntax-entry ?= "."   table)
   unrealscript
+
   (modify-syntax-entry ?% "."   table)
   (cons "within"
+
   (modify-syntax-entry ?< "."   table)
        (c-lang-const c-type-list-kwds)))
+
  (modify-syntax-entry ?> "."   table)
 +
  (modify-syntax-entry ?& "."   table)
 +
  (modify-syntax-entry ?| "."   table)
 +
  (modify-syntax-entry ?\' "\""   table)
 +
  (modify-syntax-entry ?\240 "." table)
  
;; Function declarations begin with "function" in this language.
+
  ;; Set up block and line oriented comments. The new C
;; There's currently no special keyword list for that in CC Mode, but
+
  ;; standard mandates both comment styles even in C, so since
;; treating it as a modifier works fairly well.
+
  ;; all languages now require dual comments, we make this the
(c-lang-defconst c-modifier-kwds
+
  ;; default.
  unrealscript
+
  (modify-syntax-entry ?/ ". 124b" table)
  (cons
+
  (modify-syntax-entry ?* ". 23" table)
    "function"  
+
  (c-lang-const c-modifier-kwds)))
+
  
 +
  (modify-syntax-entry ?\n "> b" table)
 +
  ;; Give CR the same syntax as newline, for selective-display
 +
  (modify-syntax-entry ?\^m "> b" table)
 +
  table)
  
(c-lang-defconst c-block-decls-with-vars
+
(defvar unrealscript-mode-syntax-table
  unrealscript
+
   (let ((unrealscript-mode-syntax-table (unrealscript-populate-syntax-table (make-syntax-table))))
   (cons
+
unrealscript-mode-syntax-table)
  "state"
+
  "Syntax table for unrealscript-mode")
        (c-lang-const c-other-block-decl-kwds)))
+
  
;; "Keywords that may be followed by a parenthesis expression that doesn't
 
;; contain type identifiers."
 
(c-lang-defconst c-paren-nontype-kwds
 
  unrealscript
 
  (append
 
  '("state" "var")
 
  (c-lang-const c-paren-nontype-kwds)
 
  nil))
 
 
 
;;  "Keywords that may be followed by a parenthesis expression containing
 
;; type identifiers separated by arbitrary tokens."
 
(c-lang-defconst c-paren-type-kwds
 
  unrealscript
 
  (append
 
  '("config" "dependson")
 
  (c-lang-const c-paren-type-kwds)))
 
 
;; ;; No cpp in this language, but there's still a "#exec" directive to
 
;; ;; fontify.  (The definitions for the extra keywords above are enough
 
;; ;; to incorporate them into the fontification regexps for types and
 
;; ;; keywords, so no additional font-lock patterns are required.)
 
;; (c-lang-defconst c-cpp-matchers
 
;;  unrealscript
 
;;      ;; Use the eval form for `font-lock-keywords' to be able to use
 
;;      ;; the `c-preprocessor-face-name' variable that maps to a
 
;;      ;; suitable face depending on the (X)Emacs version.
 
;;      '(eval . (list "^\\s *\\(#exec\\)\\>\\(.*\\)"
 
;;     (list 1 c-preprocessor-face-name)
 
;;     '(2 font-lock-string-face))))
 
 
(defcustom unrealscript-font-lock-extra-types nil
 
  "*List of extra types (aside from the type keywords) to recognize in Unrealscript mode.
 
Each list item should be a regexp matching a single identifier.")
 
 
(defconst unrealscript-font-lock-keywords-1
 
  (c-lang-const c-matchers-1 unrealscript)
 
  "Minimal highlighting for UNREALSCRIPT mode.")
 
 
(defconst unrealscript-font-lock-keywords-2
 
  (c-lang-const c-matchers-2 unrealscript)
 
  "Fast normal highlighting for UNREALSCRIPT mode.")
 
 
(defconst unrealscript-font-lock-keywords-3
 
  (c-lang-const c-matchers-3 unrealscript)
 
  "Accurate normal highlighting for UNREALSCRIPT mode.")
 
 
(defvar unrealscript-font-lock-keywords unrealscript-font-lock-keywords-3
 
  "Default expressions to highlight in UNREALSCRIPT mode.")
 
 
(defvar unrealscript-mode-syntax-table nil
 
  "Syntax table used in unrealscript-mode buffers.")
 
(or unrealscript-mode-syntax-table
 
    (setq unrealscript-mode-syntax-table
 
  (funcall (c-lang-const c-make-mode-syntax-table unrealscript))))
 
 
(defvar unrealscript-mode-abbrev-table nil
 
  "Abbreviation table used in unrealscript-mode buffers.")
 
 
(c-define-abbrev-table 'unrealscript-mode-abbrev-table
 
  ;; Keywords that if they occur first on a line might alter the
 
  ;; syntactic context, and which therefore should trig reindentation
 
  ;; when they are completed.
 
  '(("else" "else" c-electric-continued-statement 0)
 
    ("while" "while" c-electric-continued-statement 0)))
 
 
(defvar unrealscript-mode-map (let ((map (c-make-inherited-keymap)))
 
      ;; Add bindings which are only useful for UNREALSCRIPT
 
      map)
 
  "Keymap used in unrealscript-mode buffers.")
 
 
(easy-menu-define unrealscript-menu unrealscript-mode-map "UNREALSCRIPT Mode Commands"
 
  ;; Can use `unrealscript' as the language for `c-mode-menu'
 
  ;; since its definition covers any language.  In
 
  ;; this case the language is used to adapt to the
 
  ;; nonexistence of a cpp pass and thus removing some
 
  ;; irrelevant menu alternatives.
 
  (cons "UNREALSCRIPT" (c-lang-const c-mode-menu unrealscript)))
 
 
;;;###Autoload
 
(add-to-list 'auto-mode-alist '("\\.uc\\'" . unrealscript-mode))
 
 
;;;###autoload
 
 
(defun unrealscript-mode ()
 
(defun unrealscript-mode ()
   "Major mode for editing UNREALSCRIPT UnrealScript is a
+
   "Major mode for editing Unrealscript files"
Java-like object-orientated programming (OOP) language created by
+
Epic Games for programming in-game content for the UnrealEngine.
+
+
The hook `c-mode-common-hook' is run with no args at mode
+
initialization, then `unrealscript-mode-hook'.
+
 
+
Key bindings:
+
\\{unrealscript-mode-map}"
+
 
   (interactive)
 
   (interactive)
 
   (kill-all-local-variables)
 
   (kill-all-local-variables)
  (c-initialize-cc-mode t)
 
 
   (set-syntax-table unrealscript-mode-syntax-table)
 
   (set-syntax-table unrealscript-mode-syntax-table)
   (setq major-mode 'unrealscript-mode
+
   (use-local-map unrealscript-mode-map)
mode-name "UnrealScript"
+
   (setq indent-line-function 'unrealscript-indent-line)
local-abbrev-table unrealscript-mode-abbrev-table
+
   (setq font-lock-defaults '(unrealscript-font-lock-keywords nil t))
abbrev-mode t)
+
   (setq major-mode 'unrealscript-mode)
   (use-local-map c-mode-map)
+
   (setq mode-name "UNREALSCRIPT")
   ;; `c-init-language-vars' is a macro that is expanded at compile
+
  ;; time to a large `setq' with all the language variables and their
+
  ;; customized values for our language.
+
  (c-init-language-vars unrealscript-mode)
+
  ;; `c-common-init' initializes most of the components of a CC Mode
+
  ;; buffer, including setup of the mode menu, font-lock, etc.
+
  ;; There's also a lower level routine `c-basic-common-init' that
+
  ;; only makes the necessary initialization to get the syntactic
+
  ;; analysis and similar things working.
+
   (c-common-init 'unrealscript-mode)
+
   (easy-menu-add unrealscript-menu)
+
  (run-hooks 'c-mode-common-hook)
+
 
   (run-hooks 'unrealscript-mode-hook)
 
   (run-hooks 'unrealscript-mode-hook)
   (setq font-lock-keywords-case-fold-search t)
+
  (setq case-fold-search t)
  (c-update-modeline))
+
   (setq font-lock-keywords-case-fold-search t))
 +
 
  
 
(provide 'unrealscript-mode)
 
(provide 'unrealscript-mode)
 
</pre>
 
</pre>

Latest revision as of 10:48, 1 December 2010

Emacs can do everything. Check out shell-mode or compile-mode for compiling unrealscript, and launching unreal.

Here is the source of unrealscript-mode. Suggestions, bug reports, etc, welcome,

(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 ]*if") (looking-at "^[\t ]*else") (looking-at "^[\t ]*for")))

(defun looking-at-unrealscript-block-end ()      
  (or (looking-at "^[\t ]*end") (and (looking-at "^.*}[ \t]*$") (not (looking-at "^.*{")))))

(defun looking-at-unrealscript-block-start ()
  (or (looking-at "^[\t ]*begin") (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)