From eee8207a7ea34e54577219c3a6b7b5395540382d Mon Sep 17 00:00:00 2001 From: Ted Zlatanov Date: Fri, 1 Jul 2011 05:09:52 -0500 Subject: [PATCH] Moved `cfengine3-mode' to cfengine.el. Removed cfengine3.el. * progmodes/cfengine.el: Moved all cfengine3.el functionality here. Noted Ted Zlatanov as the maintainer. (cfengine-common-settings, cfengine-common-syntax): New functions to set up common things between `cfengine-mode' and `cfengine3-mode'. (cfengine3-mode): New mode. (cfengine3-defuns cfengine3-defuns-regex (cfengine3-class-selector-regex cfengine3-category-regex) (cfengine3-vartypes cfengine3-font-lock-keywords) (cfengine3-beginning-of-defun, cfengine3-end-of-defun) (cfengine3-indent-line): Added from cfengine3.el. --- lisp/ChangeLog | 14 ++ lisp/progmodes/cfengine.el | 262 +++++++++++++++++++++++++++++++---- lisp/progmodes/cfengine3.el | 331 -------------------------------------------- 3 files changed, 252 insertions(+), 355 deletions(-) delete mode 100644 lisp/progmodes/cfengine3.el diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 4740b9ff3dc..bb1c85891a6 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,17 @@ +2011-07-01 Teodor Zlatanov + + * progmodes/cfengine.el: Moved all cfengine3.el functionality + here. Noted Ted Zlatanov as the maintainer. + (cfengine-common-settings, cfengine-common-syntax): New functions + to set up common things between `cfengine-mode' and + `cfengine3-mode'. + (cfengine3-mode): New mode. + (cfengine3-defuns cfengine3-defuns-regex + (cfengine3-class-selector-regex cfengine3-category-regex) + (cfengine3-vartypes cfengine3-font-lock-keywords) + (cfengine3-beginning-of-defun, cfengine3-end-of-defun) + (cfengine3-indent-line): Added from cfengine3.el. + 2011-07-01 Michael Albinus * net/tramp.el (tramp-encoding-command-interactive): New defcustom. diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el index 22ece17cb28..c436d2ff06e 100644 --- a/lisp/progmodes/cfengine.el +++ b/lisp/progmodes/cfengine.el @@ -3,6 +3,7 @@ ;; Copyright (C) 2001-2011 Free Software Foundation, Inc. ;; Author: Dave Love +;; Maintainer: Ted Zlatanov ;; Keywords: languages ;; This file is part of GNU Emacs. @@ -28,6 +29,7 @@ ;; Possible customization for auto-mode selection: ;; (push '(("^cfagent.conf\\'" . cfengine-mode)) auto-mode-alist) ;; (push '(("^cf\\." . cfengine-mode)) auto-mode-alist) +;; (push '(("\\.cf\\'" . cfengine3-mode)) auto-mode-alist) ;; This is not the same as the mode written by Rolf Ebert ;; , distributed with cfengine-2.0.5. It does @@ -63,7 +65,27 @@ ;; cfservd "admit" "grant" "deny") "List of the action keywords supported by Cfengine. -This includes those for cfservd as well as cfagent.")) +This includes those for cfservd as well as cfagent.") + + (defconst cfengine3-defuns + (mapcar + 'symbol-name + '(bundle body)) + "List of the CFEngine 3.x defun headings.") + + (defconst cfengine3-defuns-regex + (regexp-opt cfengine3-defuns t) + "Regex to match the CFEngine 3.x defuns.") + + (defconst cfengine3-class-selector-regex "\\([[:alnum:]_().&|!]+\\)::") + + (defconst cfengine3-category-regex "\\([[:alnum:]_]+\\):") + + (defconst cfengine3-vartypes + (mapcar + 'symbol-name + '(string int real slist ilist rlist irange rrange counter)) + "List of the CFEngine 3.x variable types.")) (defvar cfengine-font-lock-keywords `(;; Actions. @@ -82,6 +104,31 @@ This includes those for cfservd as well as cfagent.")) ;; File, acl &c in group: { token ... } ("{[ \t]*\\([^ \t\n]+\\)" 1 font-lock-constant-face))) +(defvar cfengine3-font-lock-keywords + `( + (,(concat "^[ \t]*" cfengine3-class-selector-regex) + 1 font-lock-keyword-face) + (,(concat "^[ \t]*" cfengine3-category-regex) + 1 font-lock-builtin-face) + ;; Variables, including scope, e.g. module.var + ("[@$](\\([[:alnum:]_.]+\\))" 1 font-lock-variable-name-face) + ("[@$]{\\([[:alnum:]_.]+\\)}" 1 font-lock-variable-name-face) + ;; Variable definitions. + ("\\<\\([[:alnum:]_]+\\)[ \t]*=[ \t]*(" 1 font-lock-variable-name-face) + + ;; CFEngine 3.x faces + ;; defuns + (,(concat "\\<" cfengine3-defuns-regex "\\>" + "[ \t]+\\<\\([[:alnum:]_]+\\)\\>" + "[ \t]+\\<\\([[:alnum:]_]+\\)\\((\\([^)]*\\))\\)?") + (1 font-lock-builtin-face) + (2 font-lock-constant-name-face) + (3 font-lock-function-name-face) + (5 font-lock-variable-name-face)) + ;; variable types + (,(concat "\\<" (eval-when-compile (regexp-opt cfengine3-vartypes t)) "\\>") + 1 font-lock-type-face))) + (defvar cfengine-imenu-expression `((nil ,(concat "^[ \t]*" (eval-when-compile (regexp-opt cfengine-actions t)) @@ -197,6 +244,191 @@ Intended as the value of `indent-line-function'." (fill-paragraph justify)) t)) +(defun cfengine3-beginning-of-defun () + "`beginning-of-defun' function for Cfengine 3 mode. +Treats body/bundle blocks as defuns." + (unless (<= (current-column) (current-indentation)) + (end-of-line)) + (if (re-search-backward (concat "^[ \t]*" cfengine3-defuns-regex "\\>") nil t) + (beginning-of-line) + (goto-char (point-min))) + t) + +(defun cfengine3-end-of-defun () + "`end-of-defun' function for Cfengine 3 mode. +Treats body/bundle blocks as defuns." + (end-of-line) + (if (re-search-forward (concat "^[ \t]*" cfengine3-defuns-regex "\\>") nil t) + (beginning-of-line) + (goto-char (point-max))) + t) + +(defun cfengine3-indent-line () + "Indent a line in Cfengine 3 mode. +Intended as the value of `indent-line-function'." + (let ((pos (- (point-max) (point))) + parse) + (save-restriction + (narrow-to-defun) + (back-to-indentation) + (setq parse (parse-partial-sexp (point-min) (point))) + (message "%S" parse) + (cond + ;; body/bundle blocks start at 0 + ((looking-at (concat cfengine3-defuns-regex "\\>")) + (indent-line-to 0)) + ;; categories are indented one step + ((looking-at (concat cfengine3-category-regex "[ \t]*$")) + (indent-line-to cfengine-indent)) + ;; class selectors are indented two steps + ((looking-at (concat cfengine3-class-selector-regex "[ \t]*$")) + (indent-line-to (* 2 cfengine-indent))) + ;; Outdent leading close brackets one step. + ((or (eq ?\} (char-after)) + (eq ?\) (char-after))) + (condition-case () + (indent-line-to (save-excursion + (forward-char) + (backward-sexp) + (current-column))) + (error nil))) + ;; inside a string and it starts before this line + ((and (nth 3 parse) + (< (nth 8 parse) (save-excursion (beginning-of-line) (point)))) + (indent-line-to 0)) + ;; inside a defun, but not a nested list (depth is 1) + ((= 1 (nth 0 parse)) + (indent-line-to (* (+ 2 (nth 0 parse)) cfengine-indent))) + ;; Inside brackets/parens: indent to start column of non-comment + ;; token on line following open bracket or by one step from open + ;; bracket's column. + ((condition-case () + (progn (indent-line-to (save-excursion + (backward-up-list) + (forward-char) + (skip-chars-forward " \t") + (cond + ((looking-at "[^\n#]") + (current-column)) + ((looking-at "[^\n#]") + (current-column)) + (t + (skip-chars-backward " \t") + (+ (current-column) -1 + cfengine-indent))))) + t) + (error nil))) + ;; Else don't indent. + (t (indent-line-to 0)))) + ;; If initial point was within line's indentation, + ;; position after the indentation. Else stay at same point in text. + (if (> (- (point-max) pos) (point)) + (goto-char (- (point-max) pos))))) + +;; CFEngine 3.x grammar + +;; specification: blocks +;; blocks: block | blocks block; +;; block: bundle typeid blockid bundlebody +;; | bundle typeid blockid usearglist bundlebody +;; | body typeid blockid bodybody +;; | body typeid blockid usearglist bodybody; + +;; typeid: id +;; blockid: id +;; usearglist: '(' aitems ')'; +;; aitems: aitem | aitem ',' aitems |; +;; aitem: id + +;; bundlebody: '{' statements '}' +;; statements: statement | statements statement; +;; statement: category | classpromises; + +;; bodybody: '{' bodyattribs '}' +;; bodyattribs: bodyattrib | bodyattribs bodyattrib; +;; bodyattrib: class | selections; +;; selections: selection | selections selection; +;; selection: id ASSIGN rval ';' ; + +;; classpromises: classpromise | classpromises classpromise; +;; classpromise: class | promises; +;; promises: promise | promises promise; +;; category: CATEGORY +;; promise: promiser ARROW rval constraints ';' | promiser constraints ';'; +;; constraints: constraint | constraints ',' constraint |; +;; constraint: id ASSIGN rval; +;; class: CLASS +;; id: ID +;; rval: ID | QSTRING | NAKEDVAR | list | usefunction +;; list: '{' litems '}' ; +;; litems: litem | litem ',' litems |; +;; litem: ID | QSTRING | NAKEDVAR | list | usefunction + +;; functionid: ID | NAKEDVAR +;; promiser: QSTRING +;; usefunction: functionid givearglist +;; givearglist: '(' gaitems ')' +;; gaitems: gaitem | gaitems ',' gaitem |; +;; gaitem: ID | QSTRING | NAKEDVAR | list | usefunction + +;; # from lexer: + +;; bundle: "bundle" +;; body: "body" +;; COMMENT #[^\n]* +;; NAKEDVAR [$@][(][a-zA-Z0-9_\200-\377.]+[)]|[$@][{][a-zA-Z0-9_\200-\377.]+[}] +;; ID: [a-zA-Z0-9_\200-\377]+ +;; ASSIGN: "=>" +;; ARROW: "->" +;; QSTRING: \"((\\\")|[^"])*\"|\'((\\\')|[^'])*\'|`[^`]*` +;; CLASS: [.|&!()a-zA-Z0-9_\200-\377]+:: +;; CATEGORY: [a-zA-Z_]+: + +(defun cfengine-common-settings () + (set (make-local-variable 'syntax-propertize-function) + ;; In the main syntax-table, \ is marked as a punctuation, because + ;; of its use in DOS-style directory separators. Here we try to + ;; recognize the cases where \ is used as an escape inside strings. + (syntax-propertize-rules ("\\(\\(?:\\\\\\)+\\)\"" (1 "\\")))) + (set (make-local-variable 'parens-require-spaces) nil) + (set (make-local-variable 'comment-start) "# ") + (set (make-local-variable 'comment-start-skip) + "\\(\\(?:^\\|[^\\\\\n]\\)\\(?:\\\\\\\\\\)*\\)#+[ \t]*") + ;; Like Lisp mode. Without this, we lose with, say, + ;; `backward-up-list' when there's an unbalanced quote in a + ;; preceding comment. + (set (make-local-variable 'parse-sexp-ignore-comments) t)) + +(defun cfengine-common-syntax (table) + ;; the syntax defaults seem OK to give reasonable word movement + (modify-syntax-entry ?# "<" table) + (modify-syntax-entry ?\n ">#" table) + (modify-syntax-entry ?\" "\"" table) + ;; variable substitution: + (modify-syntax-entry ?$ "." table) + ;; Doze path separators: + (modify-syntax-entry ?\\ "." table)) + +;;;###autoload +(define-derived-mode cfengine3-mode prog-mode "CFEngine3" + "Major mode for editing cfengine input. +There are no special keybindings by default. + +Action blocks are treated as defuns, i.e. \\[beginning-of-defun] moves +to the action header." + (cfengine-common-settings) + (cfengine-common-syntax cfengine3-mode-syntax-table) + + (set (make-local-variable 'indent-line-function) #'cfengine3-indent-line) + (setq font-lock-defaults + '(cfengine3-font-lock-keywords nil nil nil beginning-of-defun)) + + ;; use defuns as the essential syntax block + (set (make-local-variable 'beginning-of-defun-function) + #'cfengine3-beginning-of-defun) + (set (make-local-variable 'end-of-defun-function) + #'cfengine3-end-of-defun)) + ;;;###autoload (define-derived-mode cfengine-mode prog-mode "Cfengine" "Major mode for editing cfengine input. @@ -204,25 +436,15 @@ There are no special keybindings by default. Action blocks are treated as defuns, i.e. \\[beginning-of-defun] moves to the action header." - (modify-syntax-entry ?# "<" cfengine-mode-syntax-table) - (modify-syntax-entry ?\n ">#" cfengine-mode-syntax-table) + (cfengine-common-settings) + (cfengine-common-syntax cfengine-mode-syntax-table) + ;; Shell commands can be quoted by single, double or back quotes. ;; It's debatable whether we should define string syntax, but it ;; should avoid potential confusion in some cases. - (modify-syntax-entry ?\" "\"" cfengine-mode-syntax-table) (modify-syntax-entry ?\' "\"" cfengine-mode-syntax-table) (modify-syntax-entry ?\` "\"" cfengine-mode-syntax-table) - ;; variable substitution: - (modify-syntax-entry ?$ "." cfengine-mode-syntax-table) - ;; Doze path separators: - (modify-syntax-entry ?\\ "." cfengine-mode-syntax-table) - ;; Otherwise, syntax defaults seem OK to give reasonable word - ;; movement. - (set (make-local-variable 'parens-require-spaces) nil) - (set (make-local-variable 'comment-start) "# ") - (set (make-local-variable 'comment-start-skip) - "\\(\\(?:^\\|[^\\\\\n]\\)\\(?:\\\\\\\\\\)*\\)#+[ \t]*") (set (make-local-variable 'indent-line-function) #'cfengine-indent-line) (set (make-local-variable 'outline-regexp) "[ \t]*\\(\\sw\\|\\s_\\)+:+") (set (make-local-variable 'outline-level) #'cfengine-outline-level) @@ -233,20 +455,12 @@ to the action header." '(cfengine-font-lock-keywords nil nil nil beginning-of-line)) ;; Fixme: set the args of functions in evaluated classes to string ;; syntax, and then obey syntax properties. - (set (make-local-variable 'syntax-propertize-function) - ;; In the main syntax-table, \ is marked as a punctuation, because - ;; of its use in DOS-style directory separators. Here we try to - ;; recognize the cases where \ is used as an escape inside strings. - (syntax-propertize-rules ("\\(\\(?:\\\\\\)+\\)\"" (1 "\\")))) (setq imenu-generic-expression cfengine-imenu-expression) (set (make-local-variable 'beginning-of-defun-function) #'cfengine-beginning-of-defun) - (set (make-local-variable 'end-of-defun-function) #'cfengine-end-of-defun) - ;; Like Lisp mode. Without this, we lose with, say, - ;; `backward-up-list' when there's an unbalanced quote in a - ;; preceding comment. - (set (make-local-variable 'parse-sexp-ignore-comments) t)) + (set (make-local-variable 'end-of-defun-function) #'cfengine-end-of-defun)) +(provide 'cfengine3) (provide 'cfengine) ;;; cfengine.el ends here diff --git a/lisp/progmodes/cfengine3.el b/lisp/progmodes/cfengine3.el deleted file mode 100644 index 68a4286657c..00000000000 --- a/lisp/progmodes/cfengine3.el +++ /dev/null @@ -1,331 +0,0 @@ -;;; cfengine3.el --- mode for editing Cfengine 3 files - -;; Copyright (C) 2001-2011 Free Software Foundation, Inc. - -;; Author: Ted Zlatanov -;; Keywords: languages - -;; This file is part of GNU Emacs. - -;; GNU Emacs 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 3 of the License, or -;; (at your option) any later version. - -;; GNU Emacs 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. If not, see . - -;;; Commentary: - -;; Supports only cfengine 3, unlike the older cfengine.el which -;; supports 1.x and 2.x. - -;; Possible customization for auto-mode selection: - -;; (push '(("^cfagent.conf\\'" . cfengine3-mode)) auto-mode-alist) -;; (push '(("^cf\\." . cfengine3-mode)) auto-mode-alist) -;; (push '(("\\.cf\\'" . cfengine3-mode)) auto-mode-alist) - -;;; Code: - -(defgroup cfengine3 () - "Editing CFEngine 3 files." - :group 'languages) - -(defcustom cfengine3-indent 2 - "*Size of a CFEngine 3 indentation step in columns." - :group 'cfengine3 - :type 'integer) - -(eval-and-compile - (defconst cfengine3-defuns - (mapcar - 'symbol-name - '(bundle body)) - "List of the CFEngine 3.x defun headings.") - - (defconst cfengine3-defuns-regex - (regexp-opt cfengine3-defuns t) - "Regex to match the CFEngine 3.x defuns.") - - (defconst cfengine3-class-selector-regex "\\([[:alnum:]_().&|!]+\\)::") - - (defconst cfengine3-category-regex "\\([[:alnum:]_]+\\):") - - (defconst cfengine3-vartypes - (mapcar - 'symbol-name - '(string int real slist ilist rlist irange rrange counter)) - "List of the CFEngine 3.x variable types.")) - -(defvar cfengine3-font-lock-keywords - `( - (,(concat "^[ \t]*" cfengine3-class-selector-regex) - 1 font-lock-keyword-face) - (,(concat "^[ \t]*" cfengine3-category-regex) - 1 font-lock-builtin-face) - ;; Variables, including scope, e.g. module.var - ("[@$](\\([[:alnum:]_.]+\\))" 1 font-lock-variable-name-face) - ("[@$]{\\([[:alnum:]_.]+\\)}" 1 font-lock-variable-name-face) - ;; Variable definitions. - ("\\<\\([[:alnum:]_]+\\)[ \t]*=[ \t]*(" 1 font-lock-variable-name-face) - - ;; CFEngine 3.x faces - ;; defuns - (,(concat "\\<" cfengine3-defuns-regex "\\>" - "[ \t]+\\<\\([[:alnum:]_]+\\)\\>" - "[ \t]+\\<\\([[:alnum:]_]+\\)\\((\\([^)]*\\))\\)?") - (1 font-lock-builtin-face) - (2 font-lock-constant-name-face) - (3 font-lock-function-name-face) - (5 font-lock-variable-name-face)) - ;; variable types - (,(concat "\\<" (eval-when-compile (regexp-opt cfengine3-vartypes t)) "\\>") - 1 font-lock-type-face))) - -(defun cfengine3-beginning-of-defun () - "`beginning-of-defun' function for Cfengine 3 mode. -Treats body/bundle blocks as defuns." - (unless (<= (current-column) (current-indentation)) - (end-of-line)) - (if (re-search-backward (concat "^[ \t]*" cfengine3-defuns-regex "\\>") nil t) - (beginning-of-line) - (goto-char (point-min))) - t) - -(defun cfengine3-end-of-defun () - "`end-of-defun' function for Cfengine 3 mode. -Treats body/bundle blocks as defuns." - (end-of-line) - (if (re-search-forward (concat "^[ \t]*" cfengine3-defuns-regex "\\>") nil t) - (beginning-of-line) - (goto-char (point-max))) - t) - -(defun cfengine3-indent-line () - "Indent a line in Cfengine mode. -Intended as the value of `indent-line-function'." - (let ((pos (- (point-max) (point))) - parse) - (save-restriction - (narrow-to-defun) - (back-to-indentation) - (setq parse (parse-partial-sexp (point-min) (point))) - (message "%S" parse) - (cond - ;; body/bundle blocks start at 0 - ((looking-at (concat cfengine3-defuns-regex "\\>")) - (indent-line-to 0)) - ;; categories are indented one step - ((looking-at (concat cfengine3-category-regex "[ \t]*$")) - (indent-line-to cfengine3-indent)) - ;; class selectors are indented two steps - ((looking-at (concat cfengine3-class-selector-regex "[ \t]*$")) - (indent-line-to (* 2 cfengine3-indent))) - ;; Outdent leading close brackets one step. - ((or (eq ?\} (char-after)) - (eq ?\) (char-after))) - (condition-case () - (indent-line-to (save-excursion - (forward-char) - (backward-sexp) - (current-column))) - (error nil))) - ;; inside a string and it starts before this line - ((and (nth 3 parse) - (< (nth 8 parse) (save-excursion (beginning-of-line) (point)))) - (indent-line-to 0)) - ;; inside a defun, but not a nested list (depth is 1) - ((= 1 (nth 0 parse)) - (indent-line-to (* (+ 2 (nth 0 parse)) cfengine3-indent))) - ;; Inside brackets/parens: indent to start column of non-comment - ;; token on line following open bracket or by one step from open - ;; bracket's column. - ((condition-case () - (progn (indent-line-to (save-excursion - (backward-up-list) - (forward-char) - (skip-chars-forward " \t") - (cond - ((looking-at "[^\n#]") - (current-column)) - ((looking-at "[^\n#]") - (current-column)) - (t - (skip-chars-backward " \t") - (+ (current-column) -1 - cfengine3-indent))))) - t) - (error nil))) - ;; Else don't indent. - (t (indent-line-to 0)))) - ;; If initial point was within line's indentation, - ;; position after the indentation. Else stay at same point in text. - (if (> (- (point-max) pos) (point)) - (goto-char (- (point-max) pos))))) - -;; (defvar cfengine3-smie-grammar -;; (smie-prec2->grammar -;; (smie-merge-prec2s -;; (smie-bnf->prec2 -;; '((token) -;; (decls (decls "body" decls) -;; (decls "bundle" decls)) -;; (insts (token ":" insts))) -;; '((assoc "body" "bundle"))) -;; (smie-precs->prec2 -;; '((right ":") -;; (right "::") -;; (assoc ";") -;; (assoc ",") -;; (right "=>")))))) - -;; (defun cfengine3-smie-rules (kind token) -;; (pcase (cons kind token) -;; (`(:elem . basic) 2) -;; (`(:list-intro . ,(or `"body" `"bundle")) t) -;; (`(:after . ":") 2) -;; (`(:after . "::") 2))) - -;; (defun cfengine3-show-all-tokens () -;; (interactive) -;; (goto-char (point-min)) -;; (while (not (eobp)) -;; (let* ((p (point)) -;; (token (funcall smie-forward-token-function))) -;; (delete-region p (point)) -;; (insert-before-markers token) -;; (forward-char)))) - -;; (defun cfengine3-line-classes () -;; (interactive) -;; (save-excursion -;; (beginning-of-line) -;; (let* ((todo (buffer-substring (point) -;; (save-excursion (end-of-line) (point)))) -;; (original (concat (loop for c across todo -;; collect (char-syntax c))))) -;; (format "%s\n%s" original todo)))) - -;; (defun cfengine3-show-all-classes () -;; (interactive) -;; (goto-char (point-min)) -;; (while (not (eobp)) -;; (let ((repl (cfengine3-line-classes))) -;; (kill-line) -;; (insert repl) -;; (insert "\n")))) - -;; specification: blocks -;; blocks: block | blocks block; -;; block: bundle typeid blockid bundlebody -;; | bundle typeid blockid usearglist bundlebody -;; | body typeid blockid bodybody -;; | body typeid blockid usearglist bodybody; - -;; typeid: id -;; blockid: id -;; usearglist: '(' aitems ')'; -;; aitems: aitem | aitem ',' aitems |; -;; aitem: id - -;; bundlebody: '{' statements '}' -;; statements: statement | statements statement; -;; statement: category | classpromises; - -;; bodybody: '{' bodyattribs '}' -;; bodyattribs: bodyattrib | bodyattribs bodyattrib; -;; bodyattrib: class | selections; -;; selections: selection | selections selection; -;; selection: id ASSIGN rval ';' ; - -;; classpromises: classpromise | classpromises classpromise; -;; classpromise: class | promises; -;; promises: promise | promises promise; -;; category: CATEGORY -;; promise: promiser ARROW rval constraints ';' | promiser constraints ';'; -;; constraints: constraint | constraints ',' constraint |; -;; constraint: id ASSIGN rval; -;; class: CLASS -;; id: ID -;; rval: ID | QSTRING | NAKEDVAR | list | usefunction -;; list: '{' litems '}' ; -;; litems: litem | litem ',' litems |; -;; litem: ID | QSTRING | NAKEDVAR | list | usefunction - -;; functionid: ID | NAKEDVAR -;; promiser: QSTRING -;; usefunction: functionid givearglist -;; givearglist: '(' gaitems ')' -;; gaitems: gaitem | gaitems ',' gaitem |; -;; gaitem: ID | QSTRING | NAKEDVAR | list | usefunction - -;; # from lexer: - -;; bundle: "bundle" -;; body: "body" -;; COMMENT #[^\n]* -;; NAKEDVAR [$@][(][a-zA-Z0-9_\200-\377.]+[)]|[$@][{][a-zA-Z0-9_\200-\377.]+[}] -;; ID: [a-zA-Z0-9_\200-\377]+ -;; ASSIGN: "=>" -;; ARROW: "->" -;; QSTRING: \"((\\\")|[^"])*\"|\'((\\\')|[^'])*\'|`[^`]*` -;; CLASS: [.|&!()a-zA-Z0-9_\200-\377]+:: -;; CATEGORY: [a-zA-Z_]+: - -;;;###autoload -(define-derived-mode cfengine3-mode prog-mode "CFEngine3" - "Major mode for editing cfengine input. -There are no special keybindings by default. - -Action blocks are treated as defuns, i.e. \\[beginning-of-defun] moves -to the action header." - (modify-syntax-entry ?# "<" cfengine3-mode-syntax-table) - (modify-syntax-entry ?\n ">#" cfengine3-mode-syntax-table) - (modify-syntax-entry ?\" "\"" cfengine3-mode-syntax-table) - ;; variable substitution: - (modify-syntax-entry ?$ "." cfengine3-mode-syntax-table) - ;; Doze path separators: - (modify-syntax-entry ?\\ "." cfengine3-mode-syntax-table) - ;; Otherwise, syntax defaults seem OK to give reasonable word - ;; movement. - - ;; (smie-setup cfengine3-smie-grammar #'cfengine3-smie-rules) - ;; ;; :forward-token #'cfengine3-smie-forward-token - ;; ;; :backward-token #'cfengine3-smie-backward-token) - ;; (set (make-local-variable 'smie-indent-basic) 'cfengine3-indent) - - (set (make-local-variable 'parens-require-spaces) nil) - (set (make-local-variable 'comment-start) "# ") - (set (make-local-variable 'comment-start-skip) - "\\(\\(?:^\\|[^\\\\\n]\\)\\(?:\\\\\\\\\\)*\\)#+[ \t]*") - (set (make-local-variable 'indent-line-function) #'cfengine3-indent-line) - (setq font-lock-defaults - '(cfengine3-font-lock-keywords nil nil nil beginning-of-defun)) - ;; Fixme: set the args of functions in evaluated classes to string - ;; syntax, and then obey syntax properties. - (set (make-local-variable 'syntax-propertize-function) - ;; In the main syntax-table, \ is marked as a punctuation, because - ;; of its use in DOS-style directory separators. Here we try to - ;; recognize the cases where \ is used as an escape inside strings. - (syntax-propertize-rules ("\\(\\(?:\\\\\\)+\\)\"" (1 "\\")))) - - ;; use defuns as the essential syntax block - (set (make-local-variable 'beginning-of-defun-function) - #'cfengine3-beginning-of-defun) - (set (make-local-variable 'end-of-defun-function) - #'cfengine3-end-of-defun) - - ;; Like Lisp mode. Without this, we lose with, say, - ;; `backward-up-list' when there's an unbalanced quote in a - ;; preceding comment. - (set (make-local-variable 'parse-sexp-ignore-comments) t)) - -(provide 'cfengine3) - -;;; cfengine3.el ends here -- 2.11.4.GIT