Function: cfengine3-indent-line

cfengine3-indent-line is a byte-compiled function defined in cfengine.el.gz.

Signature

(cfengine3-indent-line)

Documentation

Indent a line in CFEngine 3 mode.

Intended as the value of indent-line-function.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cfengine.el.gz
(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)))
      (when cfengine-mode-debug
        (message "%S" parse))

      (cond
       ;; Macros start at 0.  But make sure we're not inside a string.
       ((and (not (nth 3 parse))
             (looking-at (concat cfengine3-macro-regex)))
        (indent-line-to 0))
       ;; 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)
                              (move-beginning-of-line nil)
                              (skip-chars-forward " \t")
                              (current-column)))
          (error nil)))
       ;; Inside a string and it starts before this line: do nothing.
       ((and (nth 3 parse)
             (< (nth 8 parse) (save-excursion (beginning-of-line) (point))))
        )

       ;; Inside a defun, but not a nested list (depth is 1).  This is
       ;; a promise, usually.

       ;; 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.
       ((= 1 (nth 0 parse))
        (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.
       ((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)))))