]> gitweb.michael.orlitzky.com - nagios-mode.git/blob - nagios-mode.el
Added the contactgroups and contactgroup_members directives.
[nagios-mode.git] / nagios-mode.el
1 ;;
2 ;; nagios-mode, an Emacs mode for Nagios <http://www.nagios.org/>
3 ;; configuration files.
4 ;;
5 ;; Copyright Michael Orlitzky
6 ;;
7 ;; http://michael.orlitzky.com/
8 ;;
9 ;; This program is free software: you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation, either version 3 of the License, or
12 ;; (at your option) any later version.
13 ;;
14 ;; This program is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18 ;;
19 ;; http://www.fsf.org/licensing/licenses/gpl.html
20 ;;
21
22 (require 'font-lock)
23 (require 'regexp-opt)
24
25
26 ;; Custom Variables
27
28 (defcustom nagios-indent-level 2
29 "Number of spaces in one indentation (tab)."
30 :type 'integer :group 'nagios
31 )
32
33
34
35 ;; Indentation Voodoo
36
37 (defun nagios-indent-line(&optional flag)
38 "Indents a line, taking nesting into account."
39 (nagios-indent-to (nagios-calculate-indent))
40 )
41
42
43
44 (defun nagios-indent-to(indent-column)
45 "Indent the current line to column indent-column."
46 (setq pos (point))
47 (beginning-of-line)
48 (setq bol (point))
49 (setq pos-offset (- pos bol))
50
51 (setq first-char-offset
52 (skip-chars-forward " \t"))
53
54 (setq first-char-pos
55 (+ bol first-char-offset))
56
57 (kill-region bol first-char-pos)
58
59 (beginning-of-line)
60
61 (setq pos-change (- indent-column first-char-offset))
62 (setq pos-offset (+ pos-offset pos-change))
63
64 (if (<= pos-offset indent-column)
65 (setq pos-offset indent-column))
66
67 (while (< 0 indent-column)
68 (insert " ")
69 (setq indent-column (- indent-column 1)))
70
71 (goto-char (+ bol pos-offset))
72
73 )
74
75
76
77 (defun nagios-in-block()
78 "Determine if the point is inside of a {} block."
79
80 (setq pos (point))
81
82 ;; Get the position of the last opening and closing braces, with
83 ;; respect to the current point
84 (setq last-opening-brace (re-search-backward "{" nil t))
85 (goto-char pos)
86
87 (setq last-closing-brace (re-search-backward "}" nil t))
88 (goto-char pos)
89
90 ;; If either is nil (not found) just set it to -1, so the comparison
91 ;; doesn't die.
92 (if (not last-opening-brace)
93 (setq last-opening-brace -1))
94
95 (if (not last-closing-brace)
96 (setq last-closing-brace -1))
97
98 ;; If the last brace seen in the buffer is an opening brace, we're
99 ;; in a block. Otherwise, we aren't.
100 (if (>= last-closing-brace last-opening-brace)
101 nil
102 t)
103 )
104
105
106
107 (defun nagios-calculate-indent()
108 "Calculate the level of indentation."
109 ;; We're either inside a block, or we aren't.
110
111 (setq indent 0)
112
113 (if (nagios-in-block)
114 (setq indent nagios-indent-level))
115
116 (setq pos (point))
117 (end-of-line)
118 (setq eol (point))
119 (beginning-of-line)
120 (setq bol (point))
121
122 ;; Set the indentation level to 0 if we find either brace on this
123 ;; line.
124 (if (re-search-forward "[{}]" eol t)
125 (setq indent 0))
126
127 (goto-char pos)
128
129 indent
130 )
131
132
133
134 ;; Keymaps
135
136 (defun nagios-insert-right-brace-and-indent()
137 "Insert a '}' character, and indent the line."
138 (interactive)
139 (insert "}")
140 (nagios-indent-line)
141 )
142
143
144 (defvar nagios-mode-map()
145 "Keymap used in nagios mode.")
146
147 (when (not nagios-mode-map)
148 (setq nagios-mode-map (make-sparse-keymap))
149 (define-key nagios-mode-map
150 (read-kbd-macro "}")
151 'nagios-insert-right-brace-and-indent)
152 )
153
154
155
156 ;; Regular Expression Transformations
157
158 (defun regexp-alt-raw(element-list)
159 "Takes a list of elements, and returns the string '\\(element1\\|element2...\\)'"
160
161 ;; This is necessary since regexp-opt does not accept regular
162 ;; expressions as arguments. We use regexp-opt when we can, of
163 ;; course.
164
165 (let ((regexp "\\("))
166 (mapcar (lambda(elem)
167 (setq regexp (concat regexp "\\(" elem "\\)" "\\|")))
168 element-list)
169 (concat (substring regexp 0 -2) ; Cut the last "\\|"
170 "\\)")
171 )
172 )
173
174
175
176 ;; Syntax Highlighting Patterns
177
178 (defconst nagios-comments
179 (eval-when-compile
180 (regexp-alt-raw
181 '("#+.*"
182 ";+.*")))
183 )
184
185
186 (defconst nagios-directives
187 (eval-when-compile
188 (concat "^[ \t\r\n]*"
189
190 (regexp-opt
191 '("active_checks_enabled" "address" "alias" "check_command"
192 "check_freshness" "check_interval" "check_period" "checks_enabled"
193 "command_line" "command_name" "contactgroups" "contact_groups"
194 "contactgroup_members" "contact_name" "contactgroup_name" "contacts"
195 "dependent_host_name" "dependent_service_description" "email"
196 "event_handler" "event_handler_enabled" "execution_failure_criteria"
197 "failure_prediction_enabled" "first_notification"
198 "first_notification_delay" "flap_detection_enabled" "freshness_threshold"
199 "friday" "high_flap_threshold" "host_name" "host_notification_commands"
200 "host_notification_options" "host_notification_period"
201 "host_notifications_enabled" "hostgroup_name" "hostgroups"
202 "is_volatile" "last_notification" "low_flap_threshold"
203 "max_check_attempts" "members" "monday" "normal_check_interval"
204 "notes" "notification_failure_criteria"
205 "notification_interval" "notification_options"
206 "notification_period" "notifications_enabled"
207 "obsess_over_service" "pager" "parallelize_check"
208 "parents" "passive_checks_enabled"
209 "process_perf_data" "retain_nonstatus_information"
210 "retain_status_information" "retry_check_interval"
211 "retry_interval" "saturday" "service_description"
212 "service_notification_commands" "service_notification_options"
213 "service_notification_period" "service_notifications_enabled"
214 "servicegroup_name" "stalking_options"
215 "sunday" "thursday" "timeperiod_name" "tuesday" "wednesday") t)
216
217 "[ \r\n\t]+")
218 )
219 )
220
221
222
223 (defconst nagios-macros
224 (eval-when-compile
225 (regexp-alt-raw
226 '("\\$CONTACT\\(NAME\\|ALIAS\\|EMAIL\\|PAGER\\)\\$"
227 "\\$HOST\\(NAME\\|ALIAS\\|ADDRESS\\|STATE\\)\\$"
228 "\\$\\(ARG\\|USER\\)\\([1-9]\\|[1-2][0-9]\\|3[0-2]\\)\\$"
229 "\\$SERVICE\\(DESC\\|STATE\\)\\$"
230 "\\$\\(OUTPUT\\|PERFDATA\\|EXECUTIONTIME\\|LATENCY\\)\\$"
231 "\\$NOTIFICATION\\(TYPE\\|NUMBER\\)\\$"
232 "\\$\\(\\(SHORT\\)?DATETIME\\|DATE\\|TIME\\|TIMET\\)\\$"
233 "\\$\\(LASTSTATECHANGE\\|STATETYPE\\)\\$"
234 "\\$ADMIN\\(EMAIL\\|PAGER\\)\\$"
235 "\\$\\(SERVICE\\|HOST\\)ATTEMPT\\$")))
236 )
237
238
239
240 (defconst nagios-definitions
241 (eval-when-compile
242
243 (concat "^[ \t\r\n]*"
244
245 (regexp-alt-raw
246 '("define +\\(host\\|service\\|timeperiod\\|contact\\|command\\)"
247 "define +\\(host\\|contact\\|service\\)group"
248 "define +\\(service\\|host\\)dependency"
249 "define +\\(service\\|host\\|hostgroup\\)escalation"))
250
251 ;; These can be "terminated" by either an opening curly
252 ;; brace, or a space.
253 "\\({\\| \\)")
254 )
255 )
256
257
258
259 (defconst nagios-special
260 (eval-when-compile
261 (concat "^[ \t\r\n]*"
262
263 (regexp-opt
264 '("name" "register" "use") t)
265
266 "[ \r\n\t]+"))
267 )
268
269
270
271 (defconst nagios-string
272 (eval-when-compile
273 "\\(\".*?\"\\)"))
274
275
276 ;; The One True Font Locking Variable
277
278 (defvar nagios-font-lock-keywords
279 (list
280
281 ;; Font lock the comments first.
282 (cons nagios-comments font-lock-comment-delimiter-face)
283
284 ;; Strings have the highest priority. For now, this is broken,
285 ;; but I guess I would rather have strings miscolored within
286 ;; comments than the other way around.
287 (cons nagios-string '(0 font-lock-string-face t))
288
289 (cons nagios-special font-lock-keyword-face)
290 (cons nagios-directives font-lock-variable-name-face)
291 (cons nagios-macros font-lock-constant-face)
292 (cons nagios-definitions '(1 font-lock-function-name-face)))
293
294 "Rules for highlighting Nagios configuration files."
295 )
296
297
298
299 ;; Main Mode Function
300
301 (defun nagios-mode()
302 "Major mode for editing Nagios configuration files."
303
304 (interactive)
305
306 ;; Initializing. This is actually important to cover
307 ;; up some Emacs stupidity. Font locking won't occur
308 ;; without it.
309 (kill-all-local-variables)
310
311 ;; Set up indentation handling using the functions
312 ;; defined earlier.
313 (make-local-variable 'indent-line-function)
314 (setq indent-line-function 'nagios-indent-line)
315
316 ;; Configure font locking. Set the defaults to something
317 ;; sensible, defined earlier.
318 (make-local-variable 'font-lock-defaults)
319 (setq font-lock-defaults '(nagios-font-lock-keywords t t))
320
321 ;; Keyboard Mapping
322 (use-local-map nagios-mode-map)
323
324 ;; Rock and roll.
325 (setq mode-name "nagios"
326 major-mode 'nagios-mode)
327
328 ;; I don't /think/ I need to define this before attempting
329 ;; to run it. Users can define it if they want.
330 (run-hooks 'nagios-mode-hook)
331 )
332
333
334 (provide 'nagios-mode)