1 ;;; vcl-mode.el - Syntax highlighting for Varnish Command Language
3 ;;; Copyright (c) 2008-2009 Linpro AS
4 ;;; All rights reserved.
6 ;;; Author: Stig Sandbeck Mathisen <ssm@linpro.no>
8 ;;; Redistribution and use in source and binary forms, with or without
9 ;;; modification, are permitted provided that the following conditions
11 ;;; 1. Redistributions of source code must retain the above copyright
12 ;;; notice, this list of conditions and the following disclaimer.
13 ;;; 2. Redistributions in binary form must reproduce the above
14 ;;; copyright notice, this list of conditions and the following
15 ;;; disclaimer in the documentation and/or other materials provided
16 ;;; with the distribution.
18 ;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
19 ;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 ;;; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21 ;;; PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR
22 ;;; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 ;;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 ;;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 ;;; USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 ;;; AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 ;;; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 ;;; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 ;;; POSSIBILITY OF SUCH DAMAGE.
35 "Customizations for vcl-mode")
37 (defcustom vcl-indent-level 8
38 "*The level of indentation (number of space characters) in VCL-mode."
39 :type 'integer :group 'vcl)
41 (defcustom vcl-indent-tabs-mode nil
42 "*Allow tabs when indentation in vcl-mode if non-nil"
43 :type 'boolean :group 'vcl)
45 ;; I just love standards, there are so many to choose from
46 (if (string-match "XEmacs\\|Lucid" emacs-version)
47 (require 'generic-mode)
50 ;; Add a VCL major mode called "vcl-mode", based on generic-mode
52 (define-generic-mode 'vcl-mode
53 ;; comments (defined in "vcl-mode-setup-function"
55 ;; keywords (defined under "others" instead)
60 (generic-make-keywords-list
68 'font-lock-keyword-face)
71 (generic-make-keywords-list
76 'font-lock-builtin-face)
79 (generic-make-keywords-list
95 'font-lock-function-name-face)
98 (generic-make-keywords-list
110 'font-lock-function-name-face)
113 (generic-make-keywords-list
139 'font-lock-variable-name-face)
142 '("\\(\\(be\\)?req\\|resp\\|obj\\)\.http\.[A-Za-z-]+" .
143 font-lock-variable-name-face))
145 ;; Filenames to highlight
147 (list 'vcl-mode-setup-function)
148 "Mode for Varnish Command Language")
151 ;; A function to modify syntax, add a hook if needed, and setup
154 (defun vcl-mode-setup-function ()
155 ;; These are "part of words"
156 (modify-syntax-entry ?_ "w")
157 (modify-syntax-entry ?. "w")
159 ;; C++-style comments
160 (modify-syntax-entry ?/ ". 124")
161 (modify-syntax-entry ?* ". 23b")
163 ;; Perl-style comments
164 (modify-syntax-entry ?# "<")
165 (modify-syntax-entry ?\n ">")
167 (run-hooks 'vcl-mode-hook)
168 (set (make-local-variable 'indent-line-function) 'vcl-indent-line)
169 (setq indent-tabs-mode vcl-indent-tabs-mode)
172 (defvar vcl-mode-hook nil)
174 (defun vcl-indent-line ()
175 "Indent the current VCL line according to syntax."
178 (max (vcl-calculate-indentation) 0)))
181 ;; The function to calculate indentation level. This is a really
182 ;; simple and naive function, and does not perform anything like a
184 (defun vcl-calculate-indentation ()
185 "Return the column to which the current line should be indented."
188 ; Do not indent the first line.
189 (if (vcl-first-line-p) 0
190 ; Reduce indent level if we
191 ; close a block on this line
192 (if (vcl-closing-tag-on-this-line-p)
193 (- (vcl-previous-line-indentation)
195 ; Increase indent level if a
196 ; block opened on the previous
198 (if (vcl-opening-tag-on-previous-line-p)
199 (+ (vcl-previous-line-indentation)
201 ; By default, indent to the
202 ; level of the previous
204 (vcl-previous-line-indentation))))))
206 (defun vcl-opening-tag-on-previous-line-p ()
207 "Checks if we have an opening tag on the previous line."
211 (skip-chars-backward " \t\n")
213 (if (and (looking-at ".*{[ \t]*$")
214 (not (vcl-comment-p)))
217 (defun vcl-closing-tag-on-this-line-p ()
218 "Checks if we have a closing tag on this line."
221 (back-to-indentation)
224 (defun vcl-previous-line-indentation ()
225 "Return the indent level of the previous line."
229 (skip-chars-backward " \t\n")
230 (back-to-indentation)
233 (defun vcl-comment-p ()
234 "Checks if we have a commented line."
238 (looking-at "^[ \t]*#")))
240 (defun vcl-first-line-p ()
241 "Checks if we are on the first line."