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.
34 ;;; https://www.varnish-cache.org/trac/browser/fragmentation/varnish-tools/emacs/vcl-mode.el?rev=72322230cfe73244bcf31e008a05a9c2c3867816
35 ;;; Updated to work with varnish 3 a bit better; highlight more of the
36 ;;; variable names and functions
39 "Customizations for vcl-mode")
41 (defcustom vcl-indent-level 8
42 "*The level of indentation (number of space characters) in VCL-mode."
43 :type 'integer :group 'vcl)
45 (defcustom vcl-indent-tabs-mode nil
46 "*Allow tabs when indentation in vcl-mode if non-nil"
47 :type 'boolean :group 'vcl)
49 ;; I just love standards, there are so many to choose from
50 (if (string-match "XEmacs\\|Lucid" emacs-version)
51 (require 'generic-mode)
54 ;; Add a VCL major mode called "vcl-mode", based on generic-mode
56 (define-generic-mode 'vcl-mode
57 ;; comments (defined in "vcl-mode-setup-function"
59 ;; keywords (defined under "others" instead)
64 (generic-make-keywords-list
71 'font-lock-keyword-face)
74 (generic-make-keywords-list
87 'font-lock-builtin-face)
90 (generic-make-keywords-list
106 'font-lock-function-name-face)
109 (generic-make-keywords-list
122 'font-lock-function-name-face)
125 (generic-make-keywords-list
142 "req.backend.healthy"
143 "req.hash_always_miss"
144 "req.hash_ignore_busy"
156 "bereq.connect_timeout"
157 "bereq.first_byte_timeout"
158 "bereq.between_bytes_timeout"
171 "beresp.backend.name"
173 "beresp.backend.port"
193 'font-lock-variable-name-face)
196 '("\\(\\(be\\)?\\(req\\|resp\\|obj\\)\\)\.http\.[A-Za-z-]+" .
197 font-lock-variable-name-face))
199 ;; Filenames to highlight
201 (list 'vcl-mode-setup-function)
202 "Mode for Varnish Command Language")
205 ;; A function to modify syntax, add a hook if needed, and setup
208 (defun vcl-mode-setup-function ()
209 ;; These are "part of words"
210 (modify-syntax-entry ?_ "w")
211 (modify-syntax-entry ?. "w")
213 ;; C++-style comments
214 (modify-syntax-entry ?/ ". 124")
215 (modify-syntax-entry ?* ". 23b")
217 ;; Perl-style comments
218 (modify-syntax-entry ?# "<")
219 (modify-syntax-entry ?\n ">")
221 (run-hooks 'vcl-mode-hook)
222 (set (make-local-variable 'indent-line-function) 'vcl-indent-line)
223 (setq indent-tabs-mode vcl-indent-tabs-mode)
226 (defvar vcl-mode-hook nil)
228 (defun vcl-indent-line ()
229 "Indent the current VCL line according to syntax."
232 (max (vcl-calculate-indentation) 0)))
235 ;; The function to calculate indentation level. This is a really
236 ;; simple and naive function, and does not perform anything like a
238 (defun vcl-calculate-indentation ()
239 "Return the column to which the current line should be indented."
242 ; Do not indent the first line.
243 (if (vcl-first-line-p) 0
244 ; Reduce indent level if we
245 ; close a block on this line
246 (if (vcl-closing-tag-on-this-line-p)
247 (- (vcl-previous-line-indentation)
249 ; Increase indent level if a
250 ; block opened on the previous
252 (if (vcl-opening-tag-on-previous-line-p)
253 (+ (vcl-previous-line-indentation)
255 ; By default, indent to the
256 ; level of the previous
258 (vcl-previous-line-indentation))))))
260 (defun vcl-opening-tag-on-previous-line-p ()
261 "Checks if we have an opening tag on the previous line."
265 (skip-chars-backward " \t\n")
267 (if (and (looking-at ".*{[ \t]*$")
268 (not (vcl-comment-p)))
271 (defun vcl-closing-tag-on-this-line-p ()
272 "Checks if we have a closing tag on this line."
275 (back-to-indentation)
278 (defun vcl-previous-line-indentation ()
279 "Return the indent level of the previous line."
283 (skip-chars-backward " \t\n")
284 (back-to-indentation)
287 (defun vcl-comment-p ()
288 "Checks if we have a commented line."
292 (looking-at "^[ \t]*#")))
294 (defun vcl-first-line-p ()
295 "Checks if we are on the first line."