;; --------------------------------------------------------------------------- ;; Author: Stuart Robinson ;; Date: 19 June 2008 ;; Description: This file provides a lexc mode for emacs ;; Versions: 0.1 -- initial implementation ;; --------------------------------------------------------------------------- (defvar lexc-mode-hook nil) (defvar lexc-mode-map (let ((lexc-mode-map (make-keymap))) (define-key lexc-mode-map "\C-j" 'newline-and-indent) lexc-mode-map) "Keymap for lexc major mode") ;; built-ins & variables (defconst lexc-font-lock-keywords-1 (list ;; NOTE: The regex is wrapped in \\< and \\> to ensure that it only matches words ;; (i.e., it doesn't match substrings). It is generated by running the program ;; keyword-list-to-emacs-regex.rb on the file lexc-keywords-no-spaces.txt. '("\\<\\(LEXICON\\)\\>" . font-lock-builtin-face) '("\\(+\\w*\\)" . font-lock-variable-name-face)) "Minimal highlighting expressions for LEXC mode") ;; keywords and constants (defconst lexc-font-lock-keywords-2 (append lexc-font-lock-keywords-1 (list '("\\(;\\|:\\|>\\|<\\|@\\)" . font-lock-keyword-face) '("\\<\\(ON\\|OFF\\|NONE\\)\\>" . font-lock-constant-face))) "Additional Keywords to highlight in LEXC mode") ;; don't understand why this is necessary... (defconst lexc-font-lock-keywords-3 (append lexc-font-lock-keywords-2 (list '("" . font-lock-constant-face))) "Balls-out highlighting in LEXC mode") (defvar lexc-font-lock-keywords lexc-font-lock-keywords-3 "Default highlighting expressions for LEXC mode") ;; Indentation not being handled properly--needs to be updated (defun lexc-indent-line () "Indent current line as LEXC code" (interactive) (beginning-of-line) ; Check for rule 1 (if (bobp) (indent-line-to 0) (let ((not-indented t) cur-indent) ; Check for rule 2 (if (looking-at "^[ \t]*END_") (progn (save-excursion (forward-line -1) (setq cur-indent (- (current-indentation) default-tab-width))) (if (< cur-indent 0) (setq cur-indent 0))) (save-excursion (while not-indented (forward-line -1) ; Check for rule 3 (if (looking-at "^[ \t]*END_") (progn (setq cur-indent (current-indentation)) (setq not-indented nil)) ; Check for rule 4 (if (looking-at "^[ \t]*\\(PARTICIPANT\\|MODEL\\|APPLICATION\\|WORKFLOW\\|ACTIVITY\\|DATA\\|TOOL_LIST\\|TRANSITION\\)") (progn (setq cur-indent (+ (current-indentation) default-tab-width)) (setq not-indented nil)) ; Check for rule 5 (if (bobp) (setq not-indented nil))))))) ; If we didn't see an indentation hint, then allow no indentation (if cur-indent (indent-line-to cur-indent) (indent-line-to 0))))) ;; Change the interpretation of particular chars in Emacs' syntax table (defvar lexc-mode-syntax-table (let ( (lexc-mode-syntax-table (make-syntax-table) ) ) (modify-syntax-entry ?! "<" lexc-mode-syntax-table) ; start comment (modify-syntax-entry ?\n ">" lexc-mode-syntax-table) ; end comment (modify-syntax-entry ?\\ "_" lexc-mode-syntax-table) ; don't escape quote (modify-syntax-entry ?% "/" lexc-mode-syntax-table) ; functions as escape char lexc-mode-syntax-table ) "Syntax table for lexc-mode" ) (defun lexc-mode () "Major mode for editing lexc scripts" (interactive) (kill-all-local-variables) (set-syntax-table lexc-mode-syntax-table) (use-local-map lexc-mode-map) (set (make-local-variable 'font-lock-defaults) '(lexc-font-lock-keywords)) (set (make-local-variable 'indent-line-function) 'lexc-indent-line) (setq major-mode 'lexc-mode) (setq mode-name "LEXC") (run-hooks 'lexc-mode-hook)) ;; Make LEXC mode available for .infile and .script files (provide 'lexc-mode) (add-to-list 'auto-mode-alist '("\\.lexc\\'" . lexc-mode))