From ca68a22e6473d24f3aaca3d5ad26b78fad256560 Mon Sep 17 00:00:00 2001 From: Ted Zlatanov Date: Tue, 12 Mar 2013 11:49:26 -0400 Subject: [PATCH] * progmodes/cfengine.el: add CFEngine 3-specific indentation. --- lisp/ChangeLog | 7 +++ lisp/progmodes/cfengine.el | 90 +++++++++++++++++++++++++++++++++++--- 2 files changed, 92 insertions(+), 5 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index a1a75d2b5a..3b5051155e 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,10 @@ +2013-03-12 Teodor Zlatanov + + * progmodes/cfengine.el (cfengine-parameters-indent): New variable + for CFEngine 3-specific indentation. + (cfengine3-indent-line): Use it. Fix up category regex. + (cfengine3-font-lock-keywords): Add bundle and namespace characters. + 2013-03-12 Stefan Monnier * type-break.el (type-break-file-name): diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el index 3e022c01f4..74b81b0cd0 100644 --- a/lisp/progmodes/cfengine.el +++ b/lisp/progmodes/cfengine.el @@ -58,6 +58,70 @@ :group 'cfengine :type 'integer) +(defcustom cfengine-parameters-indent '(promise pname 0) + "*Indentation of CFEngine3 promise parameters (hanging indent). + +For example, say you have this code: + +bundle x y +{ + section: + class:: + promise ... + promiseparameter => ... +} + +You can choose to indent promiseparameter from the beginning of +the line (absolutely) or from the word \"promise\" (relatively). + +You can also choose to indent the start of the word +\"promiseparameter\" or the arrow that follows it. + +Finally, you can choose the amount of the indent. + +The default is to anchor at promise, indent parameter name, and offset 0: + +bundle agent rcfiles +{ + files: + any:: + \"/tmp/netrc\" + comment => \"my netrc\", + perms => mog(\"600\", \"tzz\", \"tzz\"); +} + +Here we anchor at beginning of line, indent arrow, and offset 10: + +bundle agent rcfiles +{ + files: + any:: + \"/tmp/netrc\" + comment => \"my netrc\", + perms => mog(\"600\", \"tzz\", \"tzz\"); +} + +Some, including cfengine_stdlib.cf, like to anchor at promise, indent +arrow, and offset 16 or so: + +bundle agent rcfiles +{ + files: + any:: + \"/tmp/netrc\" + comment => \"my netrc\", + perms => mog(\"600\", \"tzz\", \"tzz\"); +} +" + + :group 'cfengine + :type '(list + (choice (const :tag "Anchor at beginning of promise" promise) + (const :tag "Anchor at beginning of line" bol)) + (choice (const :tag "Indent parameter name" pname) + (const :tag "Indent arrow" arrow)) + (integer :tag "Indentation amount from anchor"))) + (defvar cfengine-mode-debug nil "Whether `cfengine-mode' should print debugging info.") @@ -126,8 +190,8 @@ This includes those for cfservd as well as cfagent.") ;; Defuns. This happens early so they don't get caught by looser ;; patterns. (,(concat "\\<" cfengine3-defuns-regex "\\>" - "[ \t]+\\<\\([[:alnum:]_]+\\)\\>" - "[ \t]+\\<\\([[:alnum:]_:]+\\)" + "[ \t]+\\<\\([[:alnum:]_.:]+\\)\\>" + "[ \t]+\\<\\([[:alnum:]_.:]+\\)" ;; Optional parentheses with variable names inside. "\\(?:(\\([^)]*\\))\\)?") (1 font-lock-builtin-face) @@ -305,10 +369,10 @@ Intended as the value of `indent-line-function'." ((looking-at (concat cfengine3-defuns-regex "\\>")) (indent-line-to 0)) ;; Categories are indented one step. - ((looking-at (concat cfengine3-category-regex "[ \t]*$")) + ((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]*$")) + ((looking-at (concat cfengine3-class-selector-regex "[ \t]*\\(#.*\\)*$")) (indent-line-to (* 2 cfengine-indent))) ;; Outdent leading close brackets one step. ((or (eq ?\} (char-after)) @@ -333,7 +397,23 @@ Intended as the value of `indent-line-function'." ;; plus 2. That way, promises indent deeper than class ;; selectors, which in turn are one deeper than categories. ((= 1 (nth 0 parse)) - (indent-line-to (* (+ 2 (nth 0 parse)) cfengine-indent))) + (let ((p-anchor (nth 0 cfengine-parameters-indent)) + (p-what (nth 1 cfengine-parameters-indent)) + (p-indent (nth 2 cfengine-parameters-indent))) + ;; Do we have the parameter anchor and location and indent + ;; defined, and are we looking at a promise parameter? + (if (and p-anchor p-what p-indent + (looking-at "\\([[:alnum:]_]+[ \t]*\\)=>")) + (let* ((arrow-offset (* -1 (length (match-string 1)))) + (extra-offset (if (eq p-what 'arrow) arrow-offset 0)) + (base-offset (if (eq p-anchor 'promise) + (* (+ 2 (nth 0 parse)) cfengine-indent) + 0))) + (indent-line-to (max 0 (+ p-indent base-offset extra-offset)))) + ;; Else, indent to cfengine-indent times the nested depth + ;; plus 2. That way, promises indent deeper than class + ;; selectors, which in turn are one deeper than categories. + (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. -- 2.20.1