Joe
Joe

Reputation: 3620

Emacs Per File Customization

I have an Emacs Lisp file with custom macros I want fontified and indented differently. The code looks like:

(defmacro* when-let ((var value) &rest body)
  `(let ((,var ,value))
     (when ,var ,@body)))

(defun func ()
  (when-let (a 1)
    a))

I want when-let fontified as a font-lock-keyword and indented as above. I know I can do this in my .emacs file but I'd prefer to make it a directory local or file local customization. The problem is that directory local and file local customizations seem to be limited to setting variables. In my .emacs file I have the following.

(add-hook 'emacs-lisp-mode-hook
   (lambda ()
             (put 'when-let 'lisp-indent-function 1)
             (font-lock-add-keywords nil
                                     '(("(\\(when-let\\)\\>" 1
                                        font-lock-keyword-face)))))

I want this in .dir-locals.el because it applies only to one file.

Upvotes: 5

Views: 2021

Answers (2)

phils
phils

Reputation: 73274

You can specify elisp for evaluation in file local variables1 by specifying an eval: value (the documentation says 'Eval:' but only lower-case 'eval:' seems to work). e.g.:

;;; Local Variables:
;;; mode: outline-minor
;;; eval: (hide-body)
;;; End:

As a security measure, Emacs will ask you for confirmation whenever it sees a value it does not already recognise as safe. If you tell it to remember it permanently, it writes the value to safe-local-variable-values in the (custom-set-variables) section of your init file.

Note that the above example of enabling a minor mode is deprecated (the mode local variable is for major modes only), so we need to re-write it as another evaluated form, in which we call the minor mode function.

If you need to evaluate multiple forms, you can either specify multiple eval values, which will be evaluated in order:

;;; Local Variables:
;;; eval: (outline-minor-mode 1)
;;; eval: (hide-body)
;;; End:

Or alternatively, just use progn:

;;; Local Variables:
;;; eval: (progn (outline-minor-mode 1) (hide-body))
;;; End:

The difference is that the latter would be considered a single value for the purposes of safe-local-variable-values, whereas with multiple eval values each one is considered independently.

1 C-hig (elisp) File Local Variables RET

Upvotes: 9

Rémi
Rémi

Reputation: 8342

For identing your when-let macro, you could use the indent declaration:

(defmacro* when-let ((var value) &rest body)
  (declare (indent 1))
  `(let ((,var ,value))
     (when ,var ,@body)))

look at the info node (elisp)Indenting Macros for more information about this. I don't know about a similar things for fontification.

Upvotes: 3

Related Questions