aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/cfengine.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes/cfengine.el')
-rw-r--r--lisp/progmodes/cfengine.el106
1 files changed, 94 insertions, 12 deletions
diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el
index 6fb9caa1a42..74b81b0cd01 100644
--- a/lisp/progmodes/cfengine.el
+++ b/lisp/progmodes/cfengine.el
@@ -5,7 +5,7 @@
5;; Author: Dave Love <fx@gnu.org> 5;; Author: Dave Love <fx@gnu.org>
6;; Maintainer: Ted Zlatanov <tzz@lifelogs.com> 6;; Maintainer: Ted Zlatanov <tzz@lifelogs.com>
7;; Keywords: languages 7;; Keywords: languages
8;; Version: 1.1 8;; Version: 1.2
9 9
10;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
11 11
@@ -58,6 +58,70 @@
58 :group 'cfengine 58 :group 'cfengine
59 :type 'integer) 59 :type 'integer)
60 60
61(defcustom cfengine-parameters-indent '(promise pname 0)
62 "*Indentation of CFEngine3 promise parameters (hanging indent).
63
64For example, say you have this code:
65
66bundle x y
67{
68 section:
69 class::
70 promise ...
71 promiseparameter => ...
72}
73
74You can choose to indent promiseparameter from the beginning of
75the line (absolutely) or from the word \"promise\" (relatively).
76
77You can also choose to indent the start of the word
78\"promiseparameter\" or the arrow that follows it.
79
80Finally, you can choose the amount of the indent.
81
82The default is to anchor at promise, indent parameter name, and offset 0:
83
84bundle agent rcfiles
85{
86 files:
87 any::
88 \"/tmp/netrc\"
89 comment => \"my netrc\",
90 perms => mog(\"600\", \"tzz\", \"tzz\");
91}
92
93Here we anchor at beginning of line, indent arrow, and offset 10:
94
95bundle agent rcfiles
96{
97 files:
98 any::
99 \"/tmp/netrc\"
100 comment => \"my netrc\",
101 perms => mog(\"600\", \"tzz\", \"tzz\");
102}
103
104Some, including cfengine_stdlib.cf, like to anchor at promise, indent
105arrow, and offset 16 or so:
106
107bundle agent rcfiles
108{
109 files:
110 any::
111 \"/tmp/netrc\"
112 comment => \"my netrc\",
113 perms => mog(\"600\", \"tzz\", \"tzz\");
114}
115"
116
117 :group 'cfengine
118 :type '(list
119 (choice (const :tag "Anchor at beginning of promise" promise)
120 (const :tag "Anchor at beginning of line" bol))
121 (choice (const :tag "Indent parameter name" pname)
122 (const :tag "Indent arrow" arrow))
123 (integer :tag "Indentation amount from anchor")))
124
61(defvar cfengine-mode-debug nil 125(defvar cfengine-mode-debug nil
62 "Whether `cfengine-mode' should print debugging info.") 126 "Whether `cfengine-mode' should print debugging info.")
63 127
@@ -94,7 +158,7 @@ This includes those for cfservd as well as cfagent.")
94 (regexp-opt cfengine3-defuns t) 158 (regexp-opt cfengine3-defuns t)
95 "Regex to match the CFEngine 3.x defuns.") 159 "Regex to match the CFEngine 3.x defuns.")
96 160
97 (defconst cfengine3-class-selector-regex "\\([[:alnum:]_().&|!]+\\)::") 161 (defconst cfengine3-class-selector-regex "\\([[:alnum:]_().&|!:]+\\)::")
98 162
99 (defconst cfengine3-category-regex "\\([[:alnum:]_]+\\):") 163 (defconst cfengine3-category-regex "\\([[:alnum:]_]+\\):")
100 164
@@ -126,8 +190,8 @@ This includes those for cfservd as well as cfagent.")
126 ;; Defuns. This happens early so they don't get caught by looser 190 ;; Defuns. This happens early so they don't get caught by looser
127 ;; patterns. 191 ;; patterns.
128 (,(concat "\\<" cfengine3-defuns-regex "\\>" 192 (,(concat "\\<" cfengine3-defuns-regex "\\>"
129 "[ \t]+\\<\\([[:alnum:]_]+\\)\\>" 193 "[ \t]+\\<\\([[:alnum:]_.:]+\\)\\>"
130 "[ \t]+\\<\\([[:alnum:]_]+\\)" 194 "[ \t]+\\<\\([[:alnum:]_.:]+\\)"
131 ;; Optional parentheses with variable names inside. 195 ;; Optional parentheses with variable names inside.
132 "\\(?:(\\([^)]*\\))\\)?") 196 "\\(?:(\\([^)]*\\))\\)?")
133 (1 font-lock-builtin-face) 197 (1 font-lock-builtin-face)
@@ -144,8 +208,8 @@ This includes those for cfservd as well as cfagent.")
144 1 font-lock-builtin-face) 208 1 font-lock-builtin-face)
145 209
146 ;; Variables, including scope, e.g. module.var 210 ;; Variables, including scope, e.g. module.var
147 ("[@$](\\([[:alnum:]_.]+\\))" 1 font-lock-variable-name-face) 211 ("[@$](\\([[:alnum:]_.:]+\\))" 1 font-lock-variable-name-face)
148 ("[@$]{\\([[:alnum:]_.]+\\)}" 1 font-lock-variable-name-face) 212 ("[@$]{\\([[:alnum:]_.:]+\\)}" 1 font-lock-variable-name-face)
149 213
150 ;; Variable definitions. 214 ;; Variable definitions.
151 ("\\<\\([[:alnum:]_]+\\)[ \t]*=[ \t]*(" 1 font-lock-variable-name-face) 215 ("\\<\\([[:alnum:]_]+\\)[ \t]*=[ \t]*(" 1 font-lock-variable-name-face)
@@ -305,10 +369,10 @@ Intended as the value of `indent-line-function'."
305 ((looking-at (concat cfengine3-defuns-regex "\\>")) 369 ((looking-at (concat cfengine3-defuns-regex "\\>"))
306 (indent-line-to 0)) 370 (indent-line-to 0))
307 ;; Categories are indented one step. 371 ;; Categories are indented one step.
308 ((looking-at (concat cfengine3-category-regex "[ \t]*$")) 372 ((looking-at (concat cfengine3-category-regex "[ \t]*\\(#.*\\)*$"))
309 (indent-line-to cfengine-indent)) 373 (indent-line-to cfengine-indent))
310 ;; Class selectors are indented two steps. 374 ;; Class selectors are indented two steps.
311 ((looking-at (concat cfengine3-class-selector-regex "[ \t]*$")) 375 ((looking-at (concat cfengine3-class-selector-regex "[ \t]*\\(#.*\\)*$"))
312 (indent-line-to (* 2 cfengine-indent))) 376 (indent-line-to (* 2 cfengine-indent)))
313 ;; Outdent leading close brackets one step. 377 ;; Outdent leading close brackets one step.
314 ((or (eq ?\} (char-after)) 378 ((or (eq ?\} (char-after))
@@ -317,6 +381,8 @@ Intended as the value of `indent-line-function'."
317 (indent-line-to (save-excursion 381 (indent-line-to (save-excursion
318 (forward-char) 382 (forward-char)
319 (backward-sexp) 383 (backward-sexp)
384 (move-beginning-of-line nil)
385 (skip-chars-forward " \t")
320 (current-column))) 386 (current-column)))
321 (error nil))) 387 (error nil)))
322 ;; Inside a string and it starts before this line. 388 ;; Inside a string and it starts before this line.
@@ -331,7 +397,23 @@ Intended as the value of `indent-line-function'."
331 ;; plus 2. That way, promises indent deeper than class 397 ;; plus 2. That way, promises indent deeper than class
332 ;; selectors, which in turn are one deeper than categories. 398 ;; selectors, which in turn are one deeper than categories.
333 ((= 1 (nth 0 parse)) 399 ((= 1 (nth 0 parse))
334 (indent-line-to (* (+ 2 (nth 0 parse)) cfengine-indent))) 400 (let ((p-anchor (nth 0 cfengine-parameters-indent))
401 (p-what (nth 1 cfengine-parameters-indent))
402 (p-indent (nth 2 cfengine-parameters-indent)))
403 ;; Do we have the parameter anchor and location and indent
404 ;; defined, and are we looking at a promise parameter?
405 (if (and p-anchor p-what p-indent
406 (looking-at "\\([[:alnum:]_]+[ \t]*\\)=>"))
407 (let* ((arrow-offset (* -1 (length (match-string 1))))
408 (extra-offset (if (eq p-what 'arrow) arrow-offset 0))
409 (base-offset (if (eq p-anchor 'promise)
410 (* (+ 2 (nth 0 parse)) cfengine-indent)
411 0)))
412 (indent-line-to (max 0 (+ p-indent base-offset extra-offset))))
413 ;; Else, indent to cfengine-indent times the nested depth
414 ;; plus 2. That way, promises indent deeper than class
415 ;; selectors, which in turn are one deeper than categories.
416 (indent-line-to (* (+ 2 (nth 0 parse)) cfengine-indent)))))
335 ;; Inside brackets/parens: indent to start column of non-comment 417 ;; Inside brackets/parens: indent to start column of non-comment
336 ;; token on line following open bracket or by one step from open 418 ;; token on line following open bracket or by one step from open
337 ;; bracket's column. 419 ;; bracket's column.
@@ -436,7 +518,8 @@ Intended as the value of `indent-line-function'."
436 ;; The syntax defaults seem OK to give reasonable word movement. 518 ;; The syntax defaults seem OK to give reasonable word movement.
437 (modify-syntax-entry ?# "<" table) 519 (modify-syntax-entry ?# "<" table)
438 (modify-syntax-entry ?\n ">#" table) 520 (modify-syntax-entry ?\n ">#" table)
439 (modify-syntax-entry ?\" "\"" table) 521 (modify-syntax-entry ?\" "\"" table) ; "string"
522 (modify-syntax-entry ?\' "\"" table) ; 'string'
440 ;; Variable substitution. 523 ;; Variable substitution.
441 (modify-syntax-entry ?$ "." table) 524 (modify-syntax-entry ?$ "." table)
442 ;; Doze path separators. 525 ;; Doze path separators.
@@ -475,7 +558,6 @@ to the action header."
475 ;; Shell commands can be quoted by single, double or back quotes. 558 ;; Shell commands can be quoted by single, double or back quotes.
476 ;; It's debatable whether we should define string syntax, but it 559 ;; It's debatable whether we should define string syntax, but it
477 ;; should avoid potential confusion in some cases. 560 ;; should avoid potential confusion in some cases.
478 (modify-syntax-entry ?\' "\"" cfengine2-mode-syntax-table)
479 (modify-syntax-entry ?\` "\"" cfengine2-mode-syntax-table) 561 (modify-syntax-entry ?\` "\"" cfengine2-mode-syntax-table)
480 562
481 (set (make-local-variable 'indent-line-function) #'cfengine2-indent-line) 563 (set (make-local-variable 'indent-line-function) #'cfengine2-indent-line)
@@ -505,7 +587,7 @@ on the buffer contents"
505 (forward-line))) 587 (forward-line)))
506 (if v3 (cfengine3-mode) (cfengine2-mode)))) 588 (if v3 (cfengine3-mode) (cfengine2-mode))))
507 589
508(defalias 'cfengine-mode 'cfengine-auto-mode) 590(defalias 'cfengine-mode 'cfengine3-mode)
509 591
510(provide 'cfengine3) 592(provide 'cfengine3)
511(provide 'cfengine) 593(provide 'cfengine)