SourceForge has been redesigned. Learn more.

#180 rst.el: self-modifying code

emacs mode (14)
Jakub Wilk

I'm forwarding a bug reported by Samuel Bronson, originally at <>:

This is the expression for the default value of the customization setting `rst-adornment-faces-alist':

| (let ((alist '((t . font-lock-keyword-face)
| (nil . font-lock-keyword-face)))
| (i 1))
| (while (<= i rst-level-face-max)
| (nconc alist (list (cons i (intern (format "rst-level-%d-face" i)))))
| (setq i (1+ i)))
| alist)

According to the elisp manual (which refers to this as "STANDARD"):

,----[ (elisp) Variable Definitions ]
| The expression STANDARD can be evaluated at various other times,
| too--whenever the customization facility needs to know OPTION's
| standard value. So be sure to use an expression which is harmless
| to evaluate at any time. We recommend avoiding backquotes in
| STANDARD, because they are not expanded when editing the value, so
| list values will appear to have the wrong structure.

Unfortunately, the expression above is not safe to evaluate more than once, because it has the side effect of modifying the very data structure representing the expression. This happens because of the way it passes the value of a list literal to `nconc', which destructively modifies its arguments.

You can see the problem by customizing the variable `rst-level-face-max' to a few different values, then asking customize to show the saved lisp expression for `rst-adornment-faces-alist' (without having customized that).

A quick fix would be to use a copy of the literal list, as in the patch below.


  • Stefan Merten

    Stefan Merten - 2012-01-25
    • priority: 5 --> 6
    • assigned_to: nobody --> smerten
  • Stefan Merten

    Stefan Merten - 2012-04-30

    Contained in the next release of rst.el. Thanks to Samuel Bronson for the patch.

  • Stefan Merten

    Stefan Merten - 2012-04-30
    • status: open --> closed-fixed

Log in to post a comment.