Endless Parentheses

Concise ramblings on Emacs productivity.

validate.el: Schema validation for Emacs-Lisp

Emacs’ customizable variables (a.k.a., defcustom) are allowed to specify a :type parameter for setting its custom-type. The customize interface uses this information to produce a sophisticated menu for the user to customize that variable. However, a large fraction of users use setq to directly edit custom variables, and even some packages programmatically change the value of other package’s custom variables. Ultimately, there are no guarantees that the value in question matches the :type specified in the variable.

validate.el tries to address that by offering a small set of functions and macros to validate that a value matches a :type schema, throwing an error when it doesn’t. Most importantly, in case of error it provides very informative messages about what part of the value failed to validate. So, instead of getting some obscure wrong-type-argument error deep down in the code, you’ll get a message like the following as soon as the variable is used:

Looking for ‘(repeat (choice string number))’ in ‘("aa" 90 la)’ failed because:
Looking for ‘(choice string number)’ in ‘la’ failed because:
  all of the options failed
    Looking for ‘string’ in ‘la’ failed because:
      not a string
    Looking for ‘number’ in ‘la’ failed because:
      not a number

There are 3 main use-cases for this:

  1. As an end-user of a package, you can use validate-setq instead of setq for editing variables. This will ensure the configuration you provide matches the schema specified by the developer, and thus prevents you from misconfiguring stuff.

    Also note that this works on any defcustom defined with a :type. That is, it doesn’t matter if the package itself uses validate.el.

  2. As a developer, when using a variable, use (validate-variable 'var-name). This will be identical to just using var-name if the value passes validation, but will immediately throw an error if it doesn’t.
  3. Also as a developer, you can call (validate-mark-safe-local 'var-name) which will create a safe-local predicate for the variable whenever the local value satisfies its schema.

validate.el is available on GNU Elpa, so you can install it from the package-menu or add it as a dependency in your package.

;; Package-Requires: ((validate "0.3"))

Tags: package, elpa, emacs

Say thanks on Gratipay
comments powered by Disqus