Subject: bug#7025: Viper's `viper-deflocalvar' macro doesn't indent properly

From: Vegard Øye <[email-masked]>
Date: Sun, 12 Sep 2010 15:46:46 +0200

The `viper-deflocalvar' macro in viper-init.el is used for defining
buffer-local variables. However, it doesn't indent properly:

    (viper-deflocalvar foo nil
                       "Docstring")

The following patch adds a `declare' statement to fix the indentation:

    (viper-deflocalvar foo nil
      "Docstring")

`viper-loop' suffers from the same problem, and is also fixed by the
patch. Furthermore, the patch adds syntax highlighting for
`viper-deflocalvar' and `viper-loop', so that they blend in with
`defvar' and `loop'.

Vegard

--- viper-init.el         2010-09-12 15:22:42.000000000 +0200
+++ viper-init-patched.el 2010-09-12 15:32:35.000000000 +0200
@@ -95,6 +95,10 @@
 ;;; Macros
 
 (defmacro viper-deflocalvar (var default-value &optional documentation)
+  "Define VAR as a buffer-local variable.
+DEFAULT-VALUE is the default value and DOCUMENTATION is the
+docstring. The variable becomes buffer-local whenever set."
+  (declare (indent defun))
   `(progn
     (defvar ,var ,default-value
       ,(format "%s\n\(buffer local\)" documentation))
@@ -102,11 +106,20 @@
 
 ;; (viper-loop COUNT BODY) Execute BODY COUNT times.
 (defmacro viper-loop (count &rest body)
+  (declare (indent defun))
   `(let ((count ,count))
     (while (> count 0)
       ,@body
       (setq count (1- count)))))
 
+(when (fboundp 'font-lock-add-keywords)
+  (font-lock-add-keywords
+   'emacs-lisp-mode
+   '(("(\\(viper-deflocalvar\\)\\>[ \f\t\n\r\v]*\\(\\sw+\\)?"
+      (1 font-lock-keyword-face)
+      (2 font-lock-variable-name-face nil t))
+     ("(\\(viper-loop\\)\\>" 1 font-lock-keyword-face))))
+
 (defmacro viper-buffer-live-p (buf)
   `(and ,buf (get-buffer ,buf) (buffer-name (get-buffer ,buf))))