Find file
Fetching contributors…
Cannot retrieve contributors at this time
197 lines (186 sloc) 7.17 KB
;; rules-mode.el
;; A major mode for writing Netcool Probe rules
;; Tested on GNU Emacs 23.1.1
;; Created by Lining (Larry) Song (
;; Copy this into your local Emacs library directory (~/.emacs.d/lisp
;; in my case) and add a line:
;; (require 'rules-mode)
;; to your .emacs file. All files with a .rules extension should
;; then be associated with rules mode automatically.
;; Revision History
;; v1.0: July 5, 2012: First release
;; v1.0.1: July 11, 2012: switch case bug fix
;; v1.0.2: July 11, 2012: switch case bug fix for Horstmann indent style
;; v1.0.3: July 11, 2012: bug fix for nested switch cases
;; v1.0.4: July 11, 2012: bug fix for case statement at the start of the include file
;; v1.0.5: July 12, 2012: bug fix for nested switch cases (again)
;; v1.0.6: July 17, 2012: bug fix for: } else if ... {
(defconst rules-functions
(defconst rules-font-lock-keywords
(,(regexp-opt '("if" "else" "foreach" "break" "switch" "case" "default" "include") 'words) . font-lock-keyword-face)
(,(regexp-opt rules-functions 'words) . font-lock-function-name-face)
("\\(@[\-a-zA-Z0-9_]*\\)" 1 font-lock-warning-face)
("\\($[\-*a-zA-Z0-9_]*\\)" 1 font-lock-type-face)
"Minimal highlighting expressions for Netcool Probe Rules mode")
(defvar rules-mode-syntax-table
(let ((rules-mode-syntax-table (make-syntax-table)))
;; This is added so entity names with underscores can be more easily parsed
(modify-syntax-entry ?_ "w" rules-mode-syntax-table)
(modify-syntax-entry ?# "<" rules-mode-syntax-table) ; start comment
(modify-syntax-entry ?\n ">" rules-mode-syntax-table) ; end comment
;; (modify-syntax-entry ?{ "(}" rules-mode-syntax-table)
;; (modify-syntax-entry ?} "){" rules-mode-syntax-table)
"Syntax table for rules-mode")
;; Inspired and modified from
(defun rules-indent-line ()
"Indent the rules lines"
(if (bobp)
(indent-line-to 0)
(let ((not-indented t) cur-indent)
(if (looking-at "^[ \t]*\\(}\\)[ \t]*\\(else[ \t]*if\\)?.*\\(#.*\\)*$")
;; this is for the clean }
;; other cases will fall into the backward iteration below
(goto-char (match-end 1)) ; goto the end of the } matching
(backward-list) ; move backward over a parenthetical group
(setq cur-indent (current-indentation)))
(if (< cur-indent 0) ; We can't indent past the left margin
(setq cur-indent 0)))
(if (looking-at "\\(^[ \t]*case[ \t]*\".*\".*:\\|[ \t]*default[ \t]*:\\)")
(let ((case-pos (point)))
(while not-indented
(forward-line -1)
(if (looking-at "^[ \t]*switch.*{?[ \t]*.*$")
(setq cur-indent (+ (current-indentation) default-tab-width))
(setq not-indented nil))
(if (looking-at "^[ \t]*case[ \t]*\".*\".*:.*$")
(setq cur-indent (current-indentation))
(setq not-indented nil))
(if (looking-at "^[ \t]*default[ \t]*\\(:\\)[ \t]*.*$") ; line 1038 for testing in snmptrap.rules
; (debug)
(let ((default-pos (match-end 1))
(goto-char case-pos)
(if (setq pos-} (re-search-backward "}" default-pos t 1))
(goto-char (+ pos-} 1))
(setq cur-indent (- (current-indentation) default-tab-width))
(setq not-indented nil))
(goto-char default-pos)
(setq cur-indent (- (current-indentation) (* default-tab-width 2)))
(setq not-indented nil)))))
(if (bobp)
(setq cur-indent (current-indentation))
(setq not-indented nil)))))))))
(while not-indented ; Iterate backwards until we find an indentation hint
(forward-line -1)
(if (looking-at "^.*\\(}\\)[ \t]*\\(#.*\\)*$") ; any line ends with }
(goto-char (match-end 1))
(setq cur-indent (current-indentation))
(setq not-indented nil))
(if (looking-at ".*{[ \t]*\\(#.*\\)*$") ; This hint indicates that we need to indent an extra level
(setq cur-indent (+ (current-indentation) default-tab-width)) ; Do the actual indenting
(setq not-indented nil))
(if (looking-at "\\(^[ \t]*case[ \t]*\".*\".*:\\|[ \t]*default:\\)")
(setq cur-indent (+ (current-indentation) default-tab-width))
(setq not-indented nil))
(if (bobp)
(setq not-indented nil)))))))))
(if cur-indent
(indent-line-to cur-indent)
(indent-line-to 0))))) ; If we didn't see an indentation hint, then allow no indentation
(define-derived-mode rules-mode fundamental-mode "Netcool Probe Rules Mode"
"Major Mode for Netcool Probe Rules file Editing"
(set-syntax-table rules-mode-syntax-table)
(setq font-lock-defaults
nil ; CASE-FOLD: yes. Rules file is case-sensitive.
((?_ . "w")))) ; SYNTAX-ALIST
(set (make-local-variable 'indent-line-function) 'rules-indent-line))
(add-hook 'rules-mode-hook '(lambda ()
; (local-set-key (kbd "RET") 'newline-and-indent)
(local-set-key (kbd "}") '(lambda ()
(self-insert-command 1)
(provide 'rules-mode)
(setq auto-mode-alist (append '(("\\.rules$" . rules-mode))
(setq auto-mode-alist (append '(("\\.lookup$" . rules-mode))