X-Git-Url: http://gitweb.michael.orlitzky.com/?p=nagios-mode.git;a=blobdiff_plain;f=nagios-mode.el;h=22535b548e35f702ff835440fb144949ac53eed6;hp=b9c5faaba8054a478f8418388a4e00acc6954250;hb=f999f09ae6e3ce6ff8bce49cd40cab6248ca0360;hpb=c6ae78ead8bae7b798c843ed0cffd466e69060e4 diff --git a/nagios-mode.el b/nagios-mode.el index b9c5faa..22535b5 100644 --- a/nagios-mode.el +++ b/nagios-mode.el @@ -36,99 +36,182 @@ (defun nagios-indent-line(&optional flag) "Indents a line, taking nesting into account." + (interactive) (nagios-indent-to (nagios-calculate-indent)) ) +(defun beginning-of-line-pos() + ;; Return the point position corresponding to the beginning + ;; of the current line. + (save-excursion + (beginning-of-line) + (point) + ) +) + +(defun end-of-line-pos() + ;; Return the point position corresponding to the end + ;; of the current line. + (save-excursion + (end-of-line) + (point) + ) +) + +(defun point-offset() + ;; How far are we from the beginning of the line? + (- (point) (beginning-of-line-pos)) +) + +(defun first-char-offset() + ;; How far is the first character on this line + ;; from the beginning of the line? + (save-excursion + (beginning-of-line) + (skip-chars-forward " \t") + ) +) + +(defun first-char-pos() + ;; What's the position of the first character on this line? + (+ (beginning-of-line-pos) (first-char-offset)) +) (defun nagios-indent-to(indent-column) "Indent the current line to column indent-column." - (setq pos (point)) - (beginning-of-line) - (setq bol (point)) - (setq pos-offset (- pos bol)) + ;; Store the point in orig-pos. + (let ((orig-point (point))) + + ;; And store the offset of the first character (with respect to the + ;; beginning of the line) in orig-first-char-offset. + (let ((orig-first-char-offset (first-char-offset))) + + ;; Delete any leading whitespace, and move the point to the + ;; beginning of the line. + (delete-region (beginning-of-line-pos) (first-char-pos)) + (beginning-of-line) + + ;; Now insert indent-column spaces. + (let ((indent-remaining indent-column)) + (while (< 0 indent-remaining) + (insert " ") + (setq indent-remaining (- indent-remaining 1))) + ) + + ;; The text on the current line just moved left/right some amount; + ;; call it text-delta. We want to move the point that same distance. + (let ((text-delta (- (first-char-offset) orig-first-char-offset))) + (goto-char (+ orig-point text-delta)) + ) + + ;; The point should never wind up to the left of indent-column, so + ;; if it's there, move it over to indent-column. + (if (< (point-offset) indent-column) + (goto-char (+ (beginning-of-line-pos) indent-column)) + ) + ) + ) +) - (setq first-char-offset - (skip-chars-forward " \t")) - (setq first-char-pos - (+ bol first-char-offset)) - - (delete-region bol first-char-pos) - - (beginning-of-line) +(defun char-is-commented(pos) + "True if the character at position pos is commented, nil otherwise." + (save-excursion + (goto-char pos) + (re-search-backward "#" (beginning-of-line-pos) t) + ) +) + +(defun char-is-commented-and-valid(pos) + "True if the character at position pos is commented and non-nil. + Nil otherwise." + (if (eq nil pos) + nil + (char-is-commented pos) + ) +) - (setq pos-change (- indent-column first-char-offset)) - (setq pos-offset (+ pos-offset pos-change)) - (if (<= pos-offset indent-column) - (setq pos-offset indent-column)) - - (while (< 0 indent-column) - (insert " ") - (setq indent-column (- indent-column 1))) +(defun last-opening-brace() + "Returns the position of the last opening brace, with + respect to the current point. Ignores braces which + are commented out." + (save-excursion + (let ((lob (re-search-backward "{" nil t))) - (goto-char (+ bol pos-offset)) + (while (char-is-commented-and-valid lob) + (goto-char lob) + (setq lob (re-search-backward "{" nil t)) + ) + (if lob + lob + -1) + ) ) +) +(defun last-closing-brace() + "Get the position of the last closing brace, with + respect to the current point. Ignores braces which + are commented out." + (save-excursion + (let ((lcb (re-search-backward "}" nil t))) -(defun nagios-in-block() - "Determine if the point is inside of a {} block." + (while (char-is-commented-and-valid lcb) + (goto-char lcb) + (setq lcb (re-search-backward "}" nil t)) + ) - (setq pos (point)) - - ;; Get the position of the last opening and closing braces, with - ;; respect to the current point - (setq last-opening-brace (re-search-backward "{" nil t)) - (goto-char pos) - - (setq last-closing-brace (re-search-backward "}" nil t)) - (goto-char pos) + (if lcb + lcb + -1) + ) + ) +) - ;; If either is nil (not found) just set it to -1, so the comparison - ;; doesn't die. - (if (not last-opening-brace) - (setq last-opening-brace -1)) - - (if (not last-closing-brace) - (setq last-closing-brace -1)) +(defun nagios-in-block() + "Determine if the point is inside of a {} block." ;; If the last brace seen in the buffer is an opening brace, we're ;; in a block. Otherwise, we aren't. - (if (>= last-closing-brace last-opening-brace) + (if (>= (last-closing-brace) (last-opening-brace)) nil - t) - ) + t) +) +(defun brace-on-line() + ;; Is there a curly brace on this line? + (save-excursion + (beginning-of-line) + (re-search-forward "[{}]" (end-of-line-pos) t) + ) +) + (defun nagios-calculate-indent() "Calculate the level of indentation." - ;; We're either inside a block, or we aren't. - (setq indent 0) - - (if (nagios-in-block) - (setq indent nagios-indent-level)) - - (setq pos (point)) - (end-of-line) - (setq eol (point)) - (beginning-of-line) - (setq bol (point)) - - ;; Set the indentation level to 0 if we find either brace on this - ;; line. - (if (re-search-forward "[{}]" eol t) - (setq indent 0)) - - (goto-char pos) + ;; We're either inside a block, or we aren't. + ;; Initialize the indent variable to either nagios-indent-level + ;; or 0 depending on whether or not we're in a block. + (let ((indent (if (nagios-in-block) + nagios-indent-level + 0) + ) + ) - indent + ;; Set the indentation level to 0 if we find either brace on this + ;; line and. + (if (and (brace-on-line) (not (char-is-commented (brace-on-line)))) + 0 + indent + ) ) - +) ;; Keymaps @@ -153,26 +236,6 @@ -;; Regular Expression Transformations - -(defun regexp-alt-raw(element-list) - "Takes a list of elements, and returns the string '\\(element1\\|element2...\\)'" - - ;; This is necessary since regexp-opt does not accept regular - ;; expressions as arguments. We use regexp-opt when we can, of - ;; course. - - (let ((regexp "\\(")) - (mapcar (lambda(elem) - (setq regexp (concat regexp "\\(" elem "\\)" "\\|"))) - element-list) - (concat (substring regexp 0 -2) ; Cut the last "\\|" - "\\)") - ) - ) - - - (defconst nagios-directives (eval-when-compile (concat "^[ \t\r\n]*" @@ -663,27 +726,32 @@ (concat "^[ \t\r\n]*" - (regexp-alt-raw - '("define command" - "define contact" - "define contactgroup" - "define host" - "define hostdependency" - "define hostescalation" - "define hostextinfo" - "define hostgroup" - "define hostgroupescalation" - "define null" - "define service" - "define servicedependency" - "define serviceescalation" - "define serviceextinfo" - "define servicegroup" - "define timeperiod")) - - ;; These can be "terminated" by either an opening curly - ;; brace, or a space. - "\\({\\| \\)") + "\\(" ;; Stick parenthesis around whatever comes out + ;; of regexp-opt. We use this to match a + ;; subexpression during font-lock. + (regexp-opt + '("define command" + "define contact" + "define contactgroup" + "define host" + "define hostdependency" + "define hostescalation" + "define hostextinfo" + "define hostgroup" + "define hostgroupescalation" + "define null" + "define service" + "define servicedependency" + "define serviceescalation" + "define serviceextinfo" + "define servicegroup" + "define timeperiod")) + ;; This closes the parentheses that we opened + "\\)" ;; before regexp-opt. + + ;; These can be "terminated" by either an opening curly + ;; brace, or a space. + "\\({\\| \\)") ) )