summaryrefslogtreecommitdiff
path: root/lisp/progmodes/cfengine.el
diff options
context:
space:
mode:
authorTed Zlatanov <tzz@lifelogs.com>2013-03-12 11:49:26 -0400
committerTed Zlatanov <tzz@lifelogs.com>2013-03-12 11:49:26 -0400
commitca68a22e6473d24f3aaca3d5ad26b78fad256560 (patch)
treebf550e935897597d1e6d2b1e239615a019dbe981 /lisp/progmodes/cfengine.el
parent48b9bb83f2bec3692800cf007e85c284ba7b77e8 (diff)
downloademacs-ca68a22e6473d24f3aaca3d5ad26b78fad256560.tar.gz
* progmodes/cfengine.el: add CFEngine 3-specific indentation.
Diffstat (limited to 'lisp/progmodes/cfengine.el')
-rw-r--r--lisp/progmodes/cfengine.el90
1 files changed, 85 insertions, 5 deletions
diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el
index 3e022c01f4a..74b81b0cd01 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.