From: Ted Zlatanov <tzz@lifelogs.com>
To: emacs-devel@gnu.org
Subject: Re: changes to cfengine-mode
Date: Wed, 07 Dec 2011 06:04:03 -0500 [thread overview]
Message-ID: <8739cwtzh8.fsf@lifelogs.com> (raw)
In-Reply-To: jwv39d290lz.fsf-monnier+emacs@gnu.org
[-- Attachment #1: Type: text/plain, Size: 2556 bytes --]
On Fri, 02 Dec 2011 15:32:25 -0500 Stefan Monnier <monnier@IRO.UMontreal.CA> wrote:
>> I'd like to rename `cfengine-mode' to `cfengine2-mode', and
>> `cfengine-auto-mode' to `cfengine-mode' (`cfengine-auto-mode' loads
>> `cfengine3-mode' if it thinks a cfengine v.3 file is edited).
SM> That sounds right.
Thanks for looking. Attached is a patch that will:
1) rename `cfengine-mode' to `cfengine2-mode' and defalias
'cfengine-mode to 'cfengine-auto-mode. Provide 'cfengine2.
2) rename all the "cfengine-*" variables used only by `cfengine2-mode'
to "cfengine2-*"
3) adjust the commentary to match
4) give a version and set it to 1.1 for this release
5) use "CFEngine" consistently, capitalized as the author, Mark Burgess,
does
6) add `cfengine3-mode-verbose' to control some debugging info
7) add `cfengine3-parameters-indent' to address some shortcomings in
indentation. This is a new feature but necessary to fix the lack of a
hanging indent in the current `cfengine3-mode'. It's very low-risk and
I hope it's acceptable.
8) improve and capitalize comments in many places, though that work is
not complete
9) change the "lighter" modeline indicators from "Cfengine[23]" to
"CFE[23]" to take less space
I also have a font-lock issue I can't figure out with the current
version. Given the following code (use `cfengine3-mode' to see the
problem):
#+begin_src cfengine3
body common control
{
bundlesequence => { "g", "cfrun", "rcfiles", "packages", "packages_push" };
inputs => { "cfengine_stdlib.cf" };
}
bundle common g
{
}
#+end_src
These are two defuns as far as `cfengine3-mode' is concerned.
The "bundle common g" line is supposed to be font-locked and it is,
sometimes. For instance it's not font-locked in a text buffer where
you've just run `cfengine3-mode', but if you remove the blank line
between the two defuns, it gets font-locked. Then if I do more editing
it keeps flip-flopping between font-locked and undecorated. I've spend
many hours looking for the cause of this issue and I hope you or someone
else will spot it more easily, or tell me how to debug it better. I
have a feeling it's due to the defun motion commands but I'm not sure.
>> Another approach is to rename `cfengine-mode' to `cfengine2-mode' and
>> `cfengine3-mode' to `cfengine-mode', effectively making v.2 support less
>> important. **I like this approach better** because cfengine v.2 is
>> disappearing quickly, but it would break backwards compatibility so I
>> proposed it second.
SM> We can consider it for 24.2,
OK.
Ted
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: cfengine23.patch --]
[-- Type: text/x-diff, Size: 12713 bytes --]
=== modified file 'lisp/progmodes/cfengine.el'
--- lisp/progmodes/cfengine.el 2011-11-20 03:48:53 +0000
+++ lisp/progmodes/cfengine.el 2011-12-07 10:48:58 +0000
@@ -5,6 +5,9 @@
;; Author: Dave Love <fx@gnu.org>
;; Maintainer: Ted Zlatanov <tzz@lifelogs.com>
;; Keywords: languages
+;; Version: 1.1
+(defvar cfengine-version nil)
+(setq cfengine-version "1.1")
;; This file is part of GNU Emacs.
@@ -29,18 +32,18 @@
;; The CFEngine 3.x support doesn't have Imenu support but patches are
;; welcome.
-;; You can set it up so either cfengine-mode (2.x and earlier) or
-;; cfengine3-mode (3.x) will be picked, depending on the buffer
+;; You can set it up so either `cfengine2-mode' (2.x and earlier) or
+;; `cfengine3-mode' (3.x) will be picked, depending on the buffer
;; contents:
-;; (add-to-list 'auto-mode-alist '("\\.cf\\'" . cfengine-auto-mode))
+;; (add-to-list 'auto-mode-alist '("\\.cf\\'" . cfengine-mode))
;; OR you can choose to always use a specific version, if you prefer
-;; it
+;; it:
;; (add-to-list 'auto-mode-alist '("\\.cf\\'" . cfengine3-mode))
-;; (add-to-list 'auto-mode-alist '("^cf\\." . cfengine-mode))
-;; (add-to-list 'auto-mode-alist '("^cfagent.conf\\'" . cfengine-mode))
+;; (add-to-list 'auto-mode-alist '("^cf\\." . cfengine2-mode))
+;; (add-to-list 'auto-mode-alist '("^cfagent.conf\\'" . cfengine2-mode))
;; This is not the same as the mode written by Rolf Ebert
;; <ebert@waporo.muc.de>, distributed with cfengine-2.0.5. It does
@@ -49,16 +52,32 @@
;;; Code:
(defgroup cfengine ()
- "Editing Cfengine files."
+ "Editing CFEngine files."
:group 'languages)
(defcustom cfengine-indent 2
- "*Size of a Cfengine indentation step in columns."
+ "*Size of a CFEngine indentation step in columns."
:group 'cfengine
:type 'integer)
-(defcustom cfengine-mode-abbrevs nil
- "Abbrevs for Cfengine mode."
+(defcustom cfengine3-parameters-indent '(promise pname 0)
+ "*Indentation of CFEngine3 promise parameters (hanging indent)."
+ :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")))
+
+(defcustom cfengine3-mode-verbose nil
+ "Whether `cfengine-mode' should be verbose
+ (only used by the cfengine3 support currently)"
+ :group 'cfengine
+ :type 'boolean)
+
+(defcustom cfengine2-mode-abbrevs nil
+ "Abbrevs for CFEngine2 mode."
:group 'cfengine
:type '(repeat (list (string :tag "Name")
(string :tag "Expansion")
@@ -66,7 +85,7 @@
;; Taken from the doc for pre-release 2.1.
(eval-and-compile
- (defconst cfengine-actions
+ (defconst cfengine2-actions
'("acl" "alerts" "binservers" "broadcast" "control" "classes" "copy"
"defaultroute" "disks" "directories" "disable" "editfiles" "files"
"filters" "groups" "homeservers" "ignore" "import" "interfaces"
@@ -102,7 +121,7 @@
`(;; Actions.
;; List the allowed actions explicitly, so that errors are more obvious.
(,(concat "^[ \t]*" (eval-when-compile
- (regexp-opt cfengine-actions t))
+ (regexp-opt cfengine2-actions t))
":")
1 font-lock-keyword-face)
;; Classes.
@@ -117,17 +136,6 @@
(defvar cfengine3-font-lock-keywords
`(
- (,(concat "^[ \t]*" cfengine3-class-selector-regex)
- 1 font-lock-keyword-face)
- (,(concat "^[ \t]*" cfengine3-category-regex)
- 1 font-lock-builtin-face)
- ;; Variables, including scope, e.g. module.var
- ("[@$](\\([[:alnum:]_.]+\\))" 1 font-lock-variable-name-face)
- ("[@$]{\\([[:alnum:]_.]+\\)}" 1 font-lock-variable-name-face)
- ;; Variable definitions.
- ("\\<\\([[:alnum:]_]+\\)[ \t]*=[ \t]*(" 1 font-lock-variable-name-face)
-
- ;; CFEngine 3.x faces
;; defuns
(,(concat "\\<" cfengine3-defuns-regex "\\>"
"[ \t]+\\<\\([[:alnum:]_]+\\)\\>"
@@ -136,27 +144,43 @@
(2 font-lock-constant-name-face)
(3 font-lock-function-name-face)
(5 font-lock-variable-name-face))
+
+ ;; class selector
+ (,(concat "^[ \t]*" cfengine3-class-selector-regex)
+ 1 font-lock-keyword-face)
+
+ ;; category
+ (,(concat "^[ \t]*" cfengine3-category-regex)
+ 1 font-lock-builtin-face)
+
+ ;; Variables, including scope, e.g. module.var
+ ("[@$](\\([[:alnum:]_.]+\\))" 1 font-lock-variable-name-face)
+ ("[@$]{\\([[:alnum:]_.]+\\)}" 1 font-lock-variable-name-face)
+
+ ;; Variable definitions.
+ ("\\<\\([[:alnum:]_]+\\)[ \t]*=[ \t]*(" 1 font-lock-variable-name-face)
+
;; variable types
(,(concat "\\<" (eval-when-compile (regexp-opt cfengine3-vartypes t)) "\\>")
1 font-lock-type-face)))
-(defvar cfengine-imenu-expression
+(defvar cfengine2-imenu-expression
`((nil ,(concat "^[ \t]*" (eval-when-compile
- (regexp-opt cfengine-actions t))
+ (regexp-opt cfengine2-actions t))
":[^:]")
1)
("Variables/classes" "\\<\\([[:alnum:]_]+\\)[ \t]*=[ \t]*(" 1)
("Variables/classes" "\\<define=\\([[:alnum:]_]+\\)" 1)
("Variables/classes" "\\<DefineClass\\>[ \t]+\\([[:alnum:]_]+\\)" 1))
- "`imenu-generic-expression' for Cfengine mode.")
+ "`imenu-generic-expression' for CFEngine mode.")
-(defun cfengine-outline-level ()
- "`outline-level' function for Cfengine mode."
+(defun cfengine2-outline-level ()
+ "`outline-level' function for CFEngine mode."
(if (looking-at "[^:]+\\(?:[:]+\\)$")
(length (match-string 1))))
-(defun cfengine-beginning-of-defun ()
- "`beginning-of-defun' function for Cfengine mode.
+(defun cfengine2-beginning-of-defun ()
+ "`beginning-of-defun' function for CFEngine mode.
Treats actions as defuns."
(unless (<= (current-column) (current-indentation))
(end-of-line))
@@ -165,8 +189,8 @@
(goto-char (point-min)))
t)
-(defun cfengine-end-of-defun ()
- "`end-of-defun' function for Cfengine mode.
+(defun cfengine2-end-of-defun ()
+ "`end-of-defun' function for CFEngine mode.
Treats actions as defuns."
(end-of-line)
(if (re-search-forward "^[[:alpha:]]+: *$" nil t)
@@ -176,7 +200,7 @@
;; Fixme: Should get an extra indent step in editfiles BeginGroup...s.
-(defun cfengine-indent-line ()
+(defun cfengine2-indent-line ()
"Indent a line in Cfengine mode.
Intended as the value of `indent-line-function'."
(let ((pos (- (point-max) (point))))
@@ -283,15 +307,17 @@
(narrow-to-defun)
(back-to-indentation)
(setq parse (parse-partial-sexp (point-min) (point)))
- (message "%S" parse)
+ (when cfengine3-mode-verbose
+ (message "%S" parse))
+
(cond
- ;; body/bundle blocks start at 0
+ ;; Body/bundle blocks start at 0.
((looking-at (concat cfengine3-defuns-regex "\\>"))
(indent-line-to 0))
- ;; categories are indented one step
+ ;; Categories are indented one step.
((looking-at (concat cfengine3-category-regex "[ \t]*$"))
(indent-line-to cfengine-indent))
- ;; class selectors are indented two steps
+ ;; 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.
@@ -303,13 +329,31 @@
(backward-sexp)
(current-column)))
(error nil)))
- ;; inside a string and it starts before this line
+ ;; Inside a string and it starts before this line.
((and (nth 3 parse)
(< (nth 8 parse) (save-excursion (beginning-of-line) (point))))
(indent-line-to 0))
- ;; inside a defun, but not a nested list (depth is 1)
+
+ ;; Inside a defun, but not a nested list (depth is 1). This is
+ ;; a promise, usually.
((= 1 (nth 0 parse))
- (indent-line-to (* (+ 2 (nth 0 parse)) cfengine-indent)))
+ (let ((p-anchor (nth 0 cfengine3-parameters-indent))
+ (p-what (nth 1 cfengine3-parameters-indent))
+ (p-indent (nth 2 cfengine3-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.
@@ -421,8 +465,8 @@
(modify-syntax-entry ?\\ "." table))
;;;###autoload
-(define-derived-mode cfengine3-mode prog-mode "CFEngine3"
- "Major mode for editing cfengine input.
+(define-derived-mode cfengine3-mode prog-mode "CFE3"
+ "Major mode for editing CFEngine3 input.
There are no special keybindings by default.
Action blocks are treated as defuns, i.e. \\[beginning-of-defun] moves
@@ -441,39 +485,39 @@
#'cfengine3-end-of-defun))
;;;###autoload
-(define-derived-mode cfengine-mode prog-mode "Cfengine"
- "Major mode for editing cfengine input.
+(define-derived-mode cfengine2-mode prog-mode "CFE2"
+ "Major mode for editing CFEngine2 input.
There are no special keybindings by default.
Action blocks are treated as defuns, i.e. \\[beginning-of-defun] moves
to the action header."
(cfengine-common-settings)
- (cfengine-common-syntax cfengine-mode-syntax-table)
+ (cfengine-common-syntax cfengine2-mode-syntax-table)
;; Shell commands can be quoted by single, double or back quotes.
;; It's debatable whether we should define string syntax, but it
;; should avoid potential confusion in some cases.
- (modify-syntax-entry ?\' "\"" cfengine-mode-syntax-table)
- (modify-syntax-entry ?\` "\"" cfengine-mode-syntax-table)
+ (modify-syntax-entry ?\' "\"" cfengine2-mode-syntax-table)
+ (modify-syntax-entry ?\` "\"" cfengine2-mode-syntax-table)
- (set (make-local-variable 'indent-line-function) #'cfengine-indent-line)
+ (set (make-local-variable 'indent-line-function) #'cfengine2-indent-line)
(set (make-local-variable 'outline-regexp) "[ \t]*\\(\\sw\\|\\s_\\)+:+")
- (set (make-local-variable 'outline-level) #'cfengine-outline-level)
+ (set (make-local-variable 'outline-level) #'cfengine2-outline-level)
(set (make-local-variable 'fill-paragraph-function)
#'cfengine-fill-paragraph)
- (define-abbrev-table 'cfengine-mode-abbrev-table cfengine-mode-abbrevs)
+ (define-abbrev-table 'cfengine2-mode-abbrev-table cfengine2-mode-abbrevs)
(setq font-lock-defaults
- '(cfengine-font-lock-keywords nil nil nil beginning-of-line))
+ '(cfengine-font-lock-keywords nil nil nil beginning-of-line))
;; Fixme: set the args of functions in evaluated classes to string
;; syntax, and then obey syntax properties.
- (setq imenu-generic-expression cfengine-imenu-expression)
+ (setq imenu-generic-expression cfengine2-imenu-expression)
(set (make-local-variable 'beginning-of-defun-function)
- #'cfengine-beginning-of-defun)
- (set (make-local-variable 'end-of-defun-function) #'cfengine-end-of-defun))
+ #'cfengine2-beginning-of-defun)
+ (set (make-local-variable 'end-of-defun-function) #'cfengine2-end-of-defun))
;;;###autoload
(defun cfengine-auto-mode ()
- "Choose between `cfengine-mode' and `cfengine3-mode' depending
+ "Choose between `cfengine2-mode' and `cfengine3-mode' depending
on the buffer contents"
(let ((v3 nil))
(save-restriction
@@ -481,9 +525,12 @@
(while (not (or (eobp) v3))
(setq v3 (looking-at (concat cfengine3-defuns-regex "\\>")))
(forward-line)))
- (if v3 (cfengine3-mode) (cfengine-mode))))
+ (if v3 (cfengine3-mode) (cfengine2-mode))))
+
+(defalias 'cfengine-mode 'cfengine-auto-mode)
(provide 'cfengine3)
+(provide 'cfengine2)
(provide 'cfengine)
;;; cfengine.el ends here
next prev parent reply other threads:[~2011-12-07 11:04 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-22 17:18 prog-mode not available in earlier Emacsen, need help with cfengine.el Ted Zlatanov
2011-11-22 18:05 ` Eli Zaretskii
2011-11-22 18:45 ` Ted Zlatanov
2011-11-22 22:30 ` Stefan Monnier
2011-11-23 2:09 ` Ted Zlatanov
2011-11-23 6:03 ` Chong Yidong
2011-11-23 13:35 ` Ted Zlatanov
2011-11-24 6:03 ` Chong Yidong
2011-11-25 13:17 ` Ted Zlatanov
2011-11-26 10:57 ` Reiner Steib
2011-11-27 2:06 ` Ted Zlatanov
2011-12-01 15:39 ` Ted Zlatanov
2011-12-02 16:12 ` changes to cfengine-mode (was: prog-mode not available in earlier Emacsen, need help with cfengine.el) Ted Zlatanov
2011-12-02 20:32 ` changes to cfengine-mode Stefan Monnier
2011-12-07 11:04 ` Ted Zlatanov [this message]
2011-12-07 16:10 ` Stefan Monnier
2011-12-08 9:52 ` Chong Yidong
2011-12-13 17:21 ` Ted Zlatanov
2011-12-13 19:51 ` Stefan Monnier
2011-12-13 21:46 ` Ted Zlatanov
2011-12-17 0:45 ` Stefan Monnier
2011-12-21 11:31 ` Ted Zlatanov
2011-12-13 17:23 ` Ted Zlatanov
2011-12-07 16:12 ` Stefan Monnier
2011-12-13 15:47 ` Ted Zlatanov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8739cwtzh8.fsf@lifelogs.com \
--to=tzz@lifelogs.com \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.