diff options
| author | Katsumi Yamaoka | 2015-06-30 03:47:18 +0000 |
|---|---|---|
| committer | Katsumi Yamaoka | 2015-06-30 03:47:18 +0000 |
| commit | f66d4e860ef45719628e3c2bab336f62fff38db2 (patch) | |
| tree | 2c568dcdb96adc1d69410d88c23a543b012f1ef7 /lisp/progmodes | |
| parent | 3fa319bd841dfd0451fcd0e937af9582bdb81ef7 (diff) | |
| parent | 1b3004cbf4de52261977d32a33b9a7e1ee630647 (diff) | |
| download | emacs-f66d4e860ef45719628e3c2bab336f62fff38db2.tar.gz emacs-f66d4e860ef45719628e3c2bab336f62fff38db2.zip | |
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
Diffstat (limited to 'lisp/progmodes')
| -rw-r--r-- | lisp/progmodes/cfengine.el | 62 |
1 files changed, 51 insertions, 11 deletions
diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el index aec7d208022..27784a503ba 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.3 | 8 | ;; Version: 1.4 |
| 9 | 9 | ||
| 10 | ;; This file is part of GNU Emacs. | 10 | ;; This file is part of GNU Emacs. |
| 11 | 11 | ||
| @@ -24,7 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | ;;; Commentary: | 25 | ;;; Commentary: |
| 26 | 26 | ||
| 27 | ;; Provides support for editing GNU Cfengine files, including | 27 | ;; Provides support for editing GNU CFEngine files, including |
| 28 | ;; font-locking, Imenu and indentation, but with no special keybindings. | 28 | ;; font-locking, Imenu and indentation, but with no special keybindings. |
| 29 | 29 | ||
| 30 | ;; By default, CFEngine 3.x syntax is used. | 30 | ;; By default, CFEngine 3.x syntax is used. |
| @@ -46,6 +46,14 @@ | |||
| 46 | 46 | ||
| 47 | ;; (add-hook 'cfengine3-mode-hook 'eldoc-mode) | 47 | ;; (add-hook 'cfengine3-mode-hook 'eldoc-mode) |
| 48 | 48 | ||
| 49 | ;; You may also find the command `cfengine3-reformat-json-string' | ||
| 50 | ;; useful, just bind it to a key you prefer. It will take the current | ||
| 51 | ;; string and reformat it as JSON. So if you're editing JSON inside | ||
| 52 | ;; the policy, it's a quick way to make it more legible without | ||
| 53 | ;; manually reindenting it. For instance: | ||
| 54 | |||
| 55 | ;; (global-set-key [(control f4)] 'cfengine3-reformat-json-string) | ||
| 56 | |||
| 49 | ;; This is not the same as the mode written by Rolf Ebert | 57 | ;; This is not the same as the mode written by Rolf Ebert |
| 50 | ;; <ebert@waporo.muc.de>, distributed with cfengine-2.0.5. It does | 58 | ;; <ebert@waporo.muc.de>, distributed with cfengine-2.0.5. It does |
| 51 | ;; better fontification and indentation, inter alia. | 59 | ;; better fontification and indentation, inter alia. |
| @@ -53,6 +61,7 @@ | |||
| 53 | ;;; Code: | 61 | ;;; Code: |
| 54 | 62 | ||
| 55 | (autoload 'json-read "json") | 63 | (autoload 'json-read "json") |
| 64 | (autoload 'json-pretty-print "json") | ||
| 56 | 65 | ||
| 57 | (defgroup cfengine () | 66 | (defgroup cfengine () |
| 58 | "Editing CFEngine files." | 67 | "Editing CFEngine files." |
| @@ -80,7 +89,7 @@ will use a fallback syntax definition." | |||
| 80 | :group 'cfengine | 89 | :group 'cfengine |
| 81 | :type '(choice file (const nil))) | 90 | :type '(choice file (const nil))) |
| 82 | 91 | ||
| 83 | (defcustom cfengine-parameters-indent '(promise pname 0) | 92 | (defcustom cfengine-parameters-indent '(promise pname 2) |
| 84 | "Indentation of CFEngine3 promise parameters (hanging indent). | 93 | "Indentation of CFEngine3 promise parameters (hanging indent). |
| 85 | 94 | ||
| 86 | For example, say you have this code: | 95 | For example, say you have this code: |
| @@ -101,15 +110,15 @@ You can also choose to indent the start of the word | |||
| 101 | 110 | ||
| 102 | Finally, you can choose the amount of the indent. | 111 | Finally, you can choose the amount of the indent. |
| 103 | 112 | ||
| 104 | The default is to anchor at promise, indent parameter name, and offset 0: | 113 | The default is to anchor at promise, indent parameter name, and offset 2: |
| 105 | 114 | ||
| 106 | bundle agent rcfiles | 115 | bundle agent rcfiles |
| 107 | { | 116 | { |
| 108 | files: | 117 | files: |
| 109 | any:: | 118 | any:: |
| 110 | \"/tmp/netrc\" | 119 | \"/tmp/netrc\" |
| 111 | comment => \"my netrc\", | 120 | comment => \"my netrc\", |
| 112 | perms => mog(\"600\", \"tzz\", \"tzz\"); | 121 | perms => mog(\"600\", \"tzz\", \"tzz\"); |
| 113 | } | 122 | } |
| 114 | 123 | ||
| 115 | Here we anchor at beginning of line, indent arrow, and offset 10: | 124 | Here we anchor at beginning of line, indent arrow, and offset 10: |
| @@ -823,7 +832,9 @@ This includes those for cfservd as well as cfagent.") | |||
| 823 | ) | 832 | ) |
| 824 | "Regexp matching full defun declaration (excluding argument list).") | 833 | "Regexp matching full defun declaration (excluding argument list).") |
| 825 | 834 | ||
| 826 | (defconst cfengine3-class-selector-regex "\\([[:alnum:]_().&|!:]+\\)::") | 835 | (defconst cfengine3-macro-regex "\\(@[a-zA-Z].+\\)") |
| 836 | |||
| 837 | (defconst cfengine3-class-selector-regex "\\([\"']?[[:alnum:]_().$&|!:]+[\"']?\\)::") | ||
| 827 | 838 | ||
| 828 | (defconst cfengine3-category-regex "\\([[:alnum:]_]+\\):") | 839 | (defconst cfengine3-category-regex "\\([[:alnum:]_]+\\):") |
| 829 | 840 | ||
| @@ -850,6 +861,14 @@ This includes those for cfservd as well as cfagent.") | |||
| 850 | 861 | ||
| 851 | (defvar cfengine3-font-lock-keywords | 862 | (defvar cfengine3-font-lock-keywords |
| 852 | `( | 863 | `( |
| 864 | ;; Macros | ||
| 865 | (,(concat "^" cfengine3-macro-regex) | ||
| 866 | 1 font-lock-error-face) | ||
| 867 | |||
| 868 | ;; invalid macros | ||
| 869 | (,(concat "^[ \t]*" cfengine3-macro-regex) | ||
| 870 | 1 font-lock-warning-face) | ||
| 871 | |||
| 853 | ;; Defuns. This happens early so they don't get caught by looser | 872 | ;; Defuns. This happens early so they don't get caught by looser |
| 854 | ;; patterns. | 873 | ;; patterns. |
| 855 | (,(concat "\\_<" cfengine3-defuns-regex "\\_>" | 874 | (,(concat "\\_<" cfengine3-defuns-regex "\\_>" |
| @@ -1016,7 +1035,7 @@ Treats body/bundle blocks as defuns." | |||
| 1016 | t) | 1035 | t) |
| 1017 | 1036 | ||
| 1018 | (defun cfengine3-indent-line () | 1037 | (defun cfengine3-indent-line () |
| 1019 | "Indent a line in Cfengine 3 mode. | 1038 | "Indent a line in CFEngine 3 mode. |
| 1020 | Intended as the value of `indent-line-function'." | 1039 | Intended as the value of `indent-line-function'." |
| 1021 | (let ((pos (- (point-max) (point))) | 1040 | (let ((pos (- (point-max) (point))) |
| 1022 | parse) | 1041 | parse) |
| @@ -1028,6 +1047,10 @@ Intended as the value of `indent-line-function'." | |||
| 1028 | (message "%S" parse)) | 1047 | (message "%S" parse)) |
| 1029 | 1048 | ||
| 1030 | (cond | 1049 | (cond |
| 1050 | ;; Macros start at 0. But make sure we're not inside a string. | ||
| 1051 | ((and (not (nth 3 parse)) | ||
| 1052 | (looking-at (concat cfengine3-macro-regex))) | ||
| 1053 | (indent-line-to 0)) | ||
| 1031 | ;; Body/bundle blocks start at 0. | 1054 | ;; Body/bundle blocks start at 0. |
| 1032 | ((looking-at (concat cfengine3-defuns-regex "\\_>")) | 1055 | ((looking-at (concat cfengine3-defuns-regex "\\_>")) |
| 1033 | (indent-line-to 0)) | 1056 | (indent-line-to 0)) |
| @@ -1103,6 +1126,19 @@ Intended as the value of `indent-line-function'." | |||
| 1103 | (if (> (- (point-max) pos) (point)) | 1126 | (if (> (- (point-max) pos) (point)) |
| 1104 | (goto-char (- (point-max) pos))))) | 1127 | (goto-char (- (point-max) pos))))) |
| 1105 | 1128 | ||
| 1129 | (defun cfengine3-reformat-json-string () | ||
| 1130 | "Reformat the current string as JSON using `json-pretty-print'." | ||
| 1131 | (interactive) | ||
| 1132 | (let ((ppss (syntax-ppss))) | ||
| 1133 | (when (nth 3 ppss) ;inside a string | ||
| 1134 | (save-excursion | ||
| 1135 | (goto-char (nth 8 ppss)) | ||
| 1136 | (forward-char 1) | ||
| 1137 | (let ((start (point))) | ||
| 1138 | (forward-sexp 1) | ||
| 1139 | (json-pretty-print start | ||
| 1140 | (point))))))) | ||
| 1141 | |||
| 1106 | ;; CFEngine 3.x grammar | 1142 | ;; CFEngine 3.x grammar |
| 1107 | 1143 | ||
| 1108 | ;; specification: blocks | 1144 | ;; specification: blocks |
| @@ -1199,18 +1235,22 @@ Intended as the value of `indent-line-function'." | |||
| 1199 | "???") | 1235 | "???") |
| 1200 | (propertize f 'face 'font-lock-function-name-face) | 1236 | (propertize f 'face 'font-lock-function-name-face) |
| 1201 | (mapconcat (lambda (p) | 1237 | (mapconcat (lambda (p) |
| 1202 | (let ((type (cdr (assq 'type p))) | 1238 | (let* ((type (cdr (assq 'type p))) |
| 1239 | (description (cdr (assq 'description p))) | ||
| 1240 | (desc-string (if (stringp description) | ||
| 1241 | (concat " /" description "/") | ||
| 1242 | "")) | ||
| 1203 | (range (cdr (assq 'range p)))) | 1243 | (range (cdr (assq 'range p)))) |
| 1204 | (cond | 1244 | (cond |
| 1205 | ((not (stringp type)) "???type???") | 1245 | ((not (stringp type)) "???type???") |
| 1206 | ((not (stringp range)) "???range???") | 1246 | ((not (stringp range)) "???range???") |
| 1207 | ;; options are lists of possible keywords | 1247 | ;; options are lists of possible keywords |
| 1208 | ((equal type "option") | 1248 | ((equal type "option") |
| 1209 | (propertize (concat "[" range "]") | 1249 | (propertize (concat "[" range "]" desc-string) |
| 1210 | 'face | 1250 | 'face |
| 1211 | 'font-lock-keyword-face)) | 1251 | 'font-lock-keyword-face)) |
| 1212 | ;; anything else is a type name as a variable | 1252 | ;; anything else is a type name as a variable |
| 1213 | (t (propertize type | 1253 | (t (propertize (concat type desc-string) |
| 1214 | 'face | 1254 | 'face |
| 1215 | 'font-lock-variable-name-face))))) | 1255 | 'font-lock-variable-name-face))))) |
| 1216 | plist | 1256 | plist |