diff options
author | Karl Fogel <kfogel@red-bean.com> | 2008-01-19 10:25:14 -0500 |
---|---|---|
committer | Luke Kanies <luke@madstop.com> | 2008-03-20 11:45:55 -0500 |
commit | 751405733c19236d279e778ac467d8b265697128 (patch) | |
tree | 46a1b5ef20e9708a94a68889ac84299848dc4e63 /ext | |
parent | 40a389ab0fe7f954edd6adb5c1bbfa477ef5ef5c (diff) | |
download | puppet-751405733c19236d279e778ac467d8b265697128.tar.gz puppet-751405733c19236d279e778ac467d8b265697128.tar.xz puppet-751405733c19236d279e778ac467d8b265697128.zip |
* ext/emacs/puppet-mode.el (puppet-comment-line-p, puppet-in-array): New helper functions. (puppet-indent-line): Rewrite to handle three more situations: indent elements in an array, indent single-line blocks, and ignore previous comment content when indenting non-comment lines.
Suggested by: Micah Anderson
(He also provided the test data.)
Notes: Michah points out that this change may have introduced an
infinite loop (he can cause Emacs to hang now). Will investigate and
fix in a separate change.
Diffstat (limited to 'ext')
-rw-r--r-- | ext/emacs/puppet-mode.el | 117 |
1 files changed, 88 insertions, 29 deletions
diff --git a/ext/emacs/puppet-mode.el b/ext/emacs/puppet-mode.el index 978b98002..42b13f4f2 100644 --- a/ext/emacs/puppet-mode.el +++ b/ext/emacs/puppet-mode.el @@ -89,43 +89,102 @@ (make-local-variable 'paragraph-ignore-fill-prefix) (setq paragraph-ignore-fill-prefix t)) +(defun puppet-comment-line-p () + "Return non-nil iff this line is a comment." + (save-excursion + (beginning-of-line) + (looking-at (format "\\s-*%s" comment-start)))) + +(defun puppet-in-array () + "If point is in an array, return the position of the opening '[' of +that array, else return nil." + (save-excursion + (save-match-data + (let ((opoint (point)) + (apoint (search-backward "[" nil t))) + (when apoint + ;; An array opens before point. If it doesn't close before + ;; point, then point must be in it. + ;; ### TODO: of course, the '[' could be in a string literal, + ;; ### in which case this whole idea is bogus. But baby + ;; ### steps, baby steps. A more robust strategy might be + ;; ### to walk backwards by sexps, until hit a wall, then + ;; ### inspect the nature of that wall. + (if (= (count-matches "\\]" apoint opoint) 0) + apoint)))))) + (defun puppet-indent-line () "Indent current line as puppet code." (interactive) (beginning-of-line) (if (bobp) (indent-line-to 0) ; First line is always non-indented - (let ((not-indented t) cur-indent) - (if (looking-at "^.*}") ; If the line we are looking at is the end of - ; a block, then decrease the indentation - (progn - (save-excursion - (forward-line -1) - - (if (looking-at "^.*}") - (progn - (setq cur-indent (- (current-indentation) 2)) - (setq not-indented nil)) - (setq cur-indent (- (current-indentation) 2)))) - (if (< cur-indent 0) ; We can't indent past the left margin - (setq cur-indent 0))) + (let ((not-indented t) + (array-start (puppet-in-array)) + cur-indent) + (cond + (array-start + ;; This line probably starts with an element from an array. + ;; Indent the line to the same indentation as the first + ;; element in that array. That is, this... + ;; + ;; exec { + ;; "add_puppetmaster_mongrel_startup_links": + ;; command => "string1", + ;; creates => [ "string2", "string3", + ;; "string4", "string5", + ;; "string6", "string7", + ;; "string3" ], + ;; refreshonly => true, + ;; } + ;; + ;; ...should instead look like this: + ;; + ;; exec { + ;; "add_puppetmaster_mongrel_startup_links": + ;; command => "string1", + ;; creates => [ "string2", "string3", + ;; "string4", "string5", + ;; "string6", "string7", + ;; "string8" ], + ;; refreshonly => true, + ;; } + (save-excursion + (goto-char array-start) + (forward-char 1) + (re-search-forward "\\S-") + (forward-char -1) + (setq cur-indent (current-column)))) + ((looking-at "^[^{\n]*}") + ;; This line contains the end of a block, but the block does + ;; not also begin on this line, so decrease the indentation. + (save-excursion + (forward-line -1) + (if (looking-at "^.*}") + (progn + (setq cur-indent (- (current-indentation) 2)) + (setq not-indented nil)) + (setq cur-indent (- (current-indentation) 2)))) + (if (< cur-indent 0) ; We can't indent past the left margin + (setq cur-indent 0))) + (t + ;; Otherwise, we did not start on a block-ending-only line. (save-excursion - (while not-indented ; Iterate backwards until we find an - ; indentation hint + ;; Iterate backwards until we find an indentation hint + (while not-indented (forward-line -1) - (if (looking-at "^.*}") ; This hint indicates that we need to - ; indent at the level of the END_ token - (progn - (setq cur-indent (current-indentation)) - (setq not-indented nil)) - (if (looking-at "^.*{") ; This hint indicates that we need to - ; indent an extra level - (progn - ; Do the actual indenting - (setq cur-indent (+ (current-indentation) 2)) - (setq not-indented nil)) - (if (bobp) - (setq not-indented nil))))))) + (cond + ((puppet-comment-line-p) + ;; ignore it and continue iterating backwards + ) + ((looking-at "^.*}") ; indent at the level of the END_ token + (setq cur-indent (current-indentation)) + (setq not-indented nil)) + ((looking-at "^.*{") ; indent an extra level + (setq cur-indent (+ (current-indentation) 2)) + (setq not-indented nil)) + ((bobp) + (setq not-indented nil))))))) (if cur-indent (indent-line-to cur-indent) (indent-line-to 0))))) |