2 ;; nagios-mode, an Emacs mode for Nagios <http://www.nagios.org/>
3 ;; configuration files.
5 ;; Copyright Michael Orlitzky
7 ;; http://michael.orlitzky.com/
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.
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.
19 ;; http://www.fsf.org/licensing/licenses/gpl.html
28 (defcustom nagios-indent-level 2
29 "Number of spaces in one indentation (tab)."
30 :type 'integer :group 'nagios
37 (defun nagios-indent-line(&optional flag)
38 "Indents a line, taking nesting into account."
40 (nagios-indent-to (nagios-calculate-indent))
44 (defun nagios-beginning-of-line-pos()
45 ;; Return the point position corresponding to the beginning
46 ;; of the current line.
53 (defun nagios-end-of-line-pos()
54 ;; Return the point position corresponding to the end
55 ;; of the current line.
62 (defun nagios-point-offset()
63 ;; How far are we from the beginning of the line?
64 (- (point) (nagios-beginning-of-line-pos))
67 (defun nagios-first-char-offset()
68 ;; How far is the first character on this line
69 ;; from the beginning of the line?
72 (skip-chars-forward " \t")
76 (defun nagios-first-char-pos()
77 ;; What's the position of the first character on this line?
78 (+ (nagios-beginning-of-line-pos) (nagios-first-char-offset))
81 (defun nagios-indent-to(indent-column)
82 "Indent the current line to column indent-column."
83 ;; Store the point in orig-pos.
84 (let ((orig-point (point)))
86 ;; And store the offset of the first character (with respect to the
87 ;; beginning of the line) in orig-first-char-offset.
88 (let ((orig-first-char-offset (nagios-first-char-offset)))
90 ;; Delete any leading whitespace, and move the point to the
91 ;; beginning of the line.
92 (delete-region (nagios-beginning-of-line-pos) (nagios-first-char-pos))
95 ;; Now insert indent-column spaces.
96 (let ((indent-remaining indent-column))
97 (while (< 0 indent-remaining)
99 (setq indent-remaining (- indent-remaining 1)))
102 ;; The text on the current line just moved left/right some amount;
103 ;; call it text-delta. We want to move the point that same distance.
104 (let ((text-delta (- (nagios-first-char-offset) orig-first-char-offset)))
105 (goto-char (+ orig-point text-delta))
108 ;; The point should never wind up to the left of indent-column, so
109 ;; if it's there, move it over to indent-column.
110 (if (< (nagios-point-offset) indent-column)
111 (goto-char (+ (nagios-beginning-of-line-pos) indent-column))
118 (defun nagios-char-is-commented(pos)
119 "True if the character at position pos is commented, nil otherwise."
122 (re-search-backward "\\(#\\|;\\)" (nagios-beginning-of-line-pos) t)
126 (defun nagios-char-is-commented-and-valid(pos)
127 "True if the character at position pos is commented and non-nil.
131 (nagios-char-is-commented pos)
136 (defun nagios-last-opening-brace()
137 "Returns the position of the last opening brace, with
138 respect to the current point. Ignores braces which
141 (let ((lob (re-search-backward "{" nil t)))
143 (while (nagios-char-is-commented-and-valid lob)
145 (setq lob (re-search-backward "{" nil t))
156 (defun nagios-last-closing-brace()
157 "Get the position of the last closing brace, with
158 respect to the current point. Ignores braces which
161 (let ((lcb (re-search-backward "}" nil t)))
163 (while (nagios-char-is-commented-and-valid lcb)
165 (setq lcb (re-search-backward "}" nil t))
175 (defun nagios-in-block()
176 "Determine if the point is inside of a {} block."
178 ;; If the last brace seen in the buffer is an opening brace, we're
179 ;; in a block. Otherwise, we aren't.
180 (if (>= (nagios-last-closing-brace) (nagios-last-opening-brace))
186 (defun nagios-brace-on-line()
187 ;; Is there a curly brace on this line?
190 (re-search-forward "[{}]" (nagios-end-of-line-pos) t)
195 (defun nagios-calculate-indent()
196 "Calculate the level of indentation."
198 ;; We're either inside a block, or we aren't.
199 ;; Initialize the indent variable to either nagios-indent-level
200 ;; or 0 depending on whether or not we're in a block.
201 (let ((indent (if (nagios-in-block)
207 ;; Set the indentation level to 0 if we find either brace on this
209 (if (and (nagios-brace-on-line)
210 (not (nagios-char-is-commented (nagios-brace-on-line))))
220 (defun nagios-insert-right-brace-and-indent()
221 "Insert a '}' character, and indent the line."
228 (defvar nagios-mode-map()
229 "Keymap used in nagios mode.")
231 (when (not nagios-mode-map)
232 (setq nagios-mode-map (make-sparse-keymap))
233 (define-key nagios-mode-map
235 'nagios-insert-right-brace-and-indent)
240 (defconst nagios-directives
242 (concat "^[ \t\r\n]*"
246 "active_checks_enabled"
249 "can_submit_commands"
259 "contactgroup_members"
264 "dependent_description"
266 "dependent_host_name"
267 "dependent_hostgroup"
268 "dependent_hostgroup_name"
269 "dependent_hostgroups"
270 "dependent_service_description"
271 "dependent_servicegroup"
272 "dependent_servicegroup_name"
273 "dependent_servicegroups"
280 "event_handler_enabled"
282 "execution_failure_criteria"
283 "execution_failure_options"
284 "failure_prediction_enabled"
285 "failure_prediction_options"
287 "first_notification_delay"
288 "flap_detection_enabled"
289 "flap_detection_options"
290 "freshness_threshold"
292 "high_flap_threshold"
296 "host_notification_commands"
297 "host_notification_options"
298 "host_notification_period"
299 "host_notifications_enabled"
317 "master_service_description"
323 "normal_check_interval"
326 "notification_failure_criteria"
327 "notification_failure_options"
328 "notification_interval"
329 "notification_options"
330 "notification_period"
331 "notifications_enabled"
334 "obsess_over_service"
338 "passive_checks_enabled"
340 "retain_nonstatus_information"
341 "retain_status_information"
342 "retry_check_interval"
345 "service_description"
347 "service_notification_commands"
348 "service_notification_options"
349 "service_notification_period"
350 "service_notifications_enabled"
352 "servicegroup_members"
370 (defconst nagios-macros
410 "$CONTACTGROUPALIAS$"
411 "$CONTACTGROUPMEMBERS$"
413 "$CONTACTGROUPNAMES$"
419 "$HOSTACKAUTHORALIAS$"
420 "$HOSTACKAUTHORNAME$"
425 "$HOSTANDSERVICESIMPORTANCE$"
434 "$HOSTEXECUTIONTIME$"
435 "$HOSTGROUPACTIONURL$"
437 "$HOSTGROUPMEMBERADDRESSES$"
442 "$HOSTGROUPNOTESURL$"
449 "$HOSTNOTIFICATIONENABLED$"
450 "$HOSTNOTIFICATIONID$"
451 "$HOSTNOTIFICATIONNUMBER$"
452 "$HOSTNOTIFICATIONPERIOD$"
454 "$HOSTPERCENTCHANGE$"
465 "$LASTHOSTPROBLEMID$"
467 "$LASTHOSTSTATECHANGE$"
469 "$LASTHOSTUNREACHABLE$"
472 "$LASTSERVICECRITICAL$"
473 "$LASTSERVICEEVENTID$"
475 "$LASTSERVICEPROBLEMID$"
477 "$LASTSERVICESTATECHANGE$"
478 "$LASTSERVICESTATEID$"
479 "$LASTSERVICEUNKNOWN$"
480 "$LASTSERVICEWARNING$"
484 "$LONGSERVICEOUTPUT$"
487 "$MAXSERVICEATTEMPTS$"
489 "$NOTIFICATIONAUTHOR$"
490 "$NOTIFICATIONAUTHORALIAS$"
491 "$NOTIFICATIONAUTHORNAME$"
492 "$NOTIFICATIONCOMMENT$"
493 "$NOTIFICATIONISESCALATED$"
494 "$NOTIFICATIONNUMBER$"
495 "$NOTIFICATIONRECIPIENTS$"
500 "$RETENTIONDATAFILE$"
502 "$SERVICEACKAUTHORALIAS$"
503 "$SERVICEACKAUTHORNAME$"
504 "$SERVICEACKCOMMENT$"
507 "$SERVICECHECKCOMMAND$"
510 "$SERVICEDISPLAYNAME$"
513 "$SERVICEDURATIONSEC$"
515 "$SERVICEEXECUTIONTIME$"
516 "$SERVICEGROUPACTIONURL$"
517 "$SERVICEGROUPALIAS$"
518 "$SERVICEGROUPMEMBERS$"
520 "$SERVICEGROUPNAMES$"
521 "$SERVICEGROUPNOTES$"
522 "$SERVICEGROUPNOTESURL$"
523 "$SERVICEIMPORTANCE$"
525 "$SERVICEISVOLATILE$"
529 "$SERVICENOTIFICATIONENABLED$"
530 "$SERVICENOTIFICATIONID$"
531 "$SERVICENOTIFICATIONNUMBER$"
532 "$SERVICENOTIFICATIONPERIOD$"
534 "$SERVICEPERCENTCHANGE$"
536 "$SERVICEPERFDATAFILE$"
547 "$TOTALHOSTPROBLEMS$"
548 "$TOTALHOSTPROBLEMSUNHANDLED$"
550 "$TOTALHOSTSDOWNUNHANDLED$"
551 "$TOTALHOSTSERVICES$"
552 "$TOTALHOSTSERVICESCRITICAL$"
553 "$TOTALHOSTSERVICESOK$"
554 "$TOTALHOSTSERVICESUNKNOWN$"
555 "$TOTALHOSTSERVICESWARNING$"
556 "$TOTALHOSTSUNREACHABLE$"
557 "$TOTALHOSTSUNREACHABLEUNHANDLED$"
559 "$TOTALSERVICEPROBLEMS$"
560 "$TOTALSERVICEPROBLEMSUNHANDLED$"
561 "$TOTALSERVICESCRITICAL$"
562 "$TOTALSERVICESCRITICALUNHANDLED$"
564 "$TOTALSERVICESUNKNOWN$"
565 "$TOTALSERVICESUNKNOWNUNHANDLED$"
566 "$TOTALSERVICESWARNING$"
567 "$TOTALSERVICESWARNINGUNHANDLED$"
828 (defconst nagios-definitions
831 (concat "^[ \t\r\n]*"
833 "\\(" ;; Stick parenthesis around whatever comes out
834 ;; of regexp-opt. We use this to match a
835 ;; subexpression during font-lock.
839 "define contactgroup"
841 "define hostdependency"
842 "define hostescalation"
847 "define servicedependency"
848 "define serviceescalation"
849 "define serviceextinfo"
850 "define servicegroup"
851 "define timeperiod"))
852 ;; This closes the parentheses that we opened
853 "\\)" ;; before regexp-opt.
855 ;; These can be "terminated" by either an opening curly
856 ;; brace, or a space.
863 (defconst nagios-special
865 (concat "^[ \t\r\n]*"
868 '("name" "register" "use") t)
875 ;; The One True Font Locking Variable
877 (defvar nagios-font-lock-keywords
879 (cons nagios-special font-lock-keyword-face)
880 (cons nagios-directives font-lock-variable-name-face)
881 (cons nagios-macros font-lock-constant-face)
882 (cons nagios-definitions '(1 font-lock-function-name-face)))
884 "Rules for highlighting Nagios configuration files."
889 (defvar nagios-mode-syntax-table nil
890 "Syntax table used in nagios-mode buffers.")
891 (if nagios-mode-syntax-table
893 (setq nagios-mode-syntax-table (make-syntax-table))
894 (modify-syntax-entry ?# "< b" nagios-mode-syntax-table) ;; Comment style 1
895 (modify-syntax-entry ?\; "< b" nagios-mode-syntax-table) ;; Comment style 2
896 (modify-syntax-entry ?\n "> b" nagios-mode-syntax-table) ;; End comment
900 ;; Main Mode Function
903 "Major mode for editing Nagios configuration files."
906 (kill-all-local-variables)
907 (make-local-variable 'font-lock-defaults)
908 (make-local-variable 'comment-start)
909 (make-local-variable 'comment-start-skip)
910 (make-local-variable 'comment-end)
911 (make-local-variable 'indent-line-function)
913 (set-syntax-table nagios-mode-syntax-table)
915 (setq mode-name "nagios"
916 major-mode 'nagios-mode
917 indent-line-function 'nagios-indent-line
918 font-lock-defaults '(nagios-font-lock-keywords)
920 comment-start-skip "#\|; +"
925 (use-local-map nagios-mode-map)
927 ;; I don't /think/ I need to define this before attempting
928 ;; to run it. Users can define it if they want.
929 (run-hooks 'nagios-mode-hook)
933 (provide 'nagios-mode)