1

The byte compiler just gave me this message

1103:24:Warning: assignment to free variable `orig-win-config

on this bit of code:

 ;; create window config store and restore functions
 ;; credit to @lawlist on stackoverflow for this embedded setup
 (setq mysetup
       (lambda ()
         ;; store original window configuration
         (set (make-local-variable 'orig-win-config)
              (current-window-configuration))
         ;; bind q to the window restore function
         (local-set-key
          "q"
          (lambda ()
            (interactive)
            ;; q is shared by all Help-mode buffers
            ;; so guard those that did not set up orig-win-config
            (when (boundp 'orig-win-config)
              (set-window-configuration orig-win-config))
            (kill-buffer (current-buffer))))))

The code runs in a defmacro that displays a temporary buffer window in Help-mode. The code creates a local function variable mysetup that can be called in the Help mode hook, to remember the original window configuration so the original configuration can be restored when the temporary help buffer is dispatched with "q".

The byte compiler apparently thinks that the (make-local-variable 'orig-win-config) statement creates a free variable that should not be assigned to this way.

Is there a way to change my syntax to keep the byte compiler happy, and to create/assign to the variable in a more correct way?

This question seems similar, but is not quite the same because it works with a (defun argument in the argument list, not a new variable in a (defmacro. So I don't know what to make of the info in that question.

Kevin
  • 1,308
  • 8
  • 20

1 Answers1

2

As usual for this kind of thing, just put (defvar orig-win-config) near the beginning of the same file. That declares orig-win-config as a dynamic variable.

Otherwise, the byte-compiler thinks that (set-window-configuration orig-win-config) refers to an undefined variable. (It is not that the compiler thinks that (make-local-variable 'orig-win-config) "creates a free variable".

The point is that orig-win-config is not bound in yourcode. It really is a free variable. By providing a declaration that it is a global variable, you let the compiler (and Emacs generally) know that it is a dynamic variable: a symbol.

A symbol has a symbol-value property, whether or not it has a value when the file is compiled. A symbol can always be used as a variable, and only a runtime error can be raised if it does not have a value as a variable at a given time.

Drew
  • 75,699
  • 9
  • 109
  • 225
  • Thank you for your help. If I want to use my free variable in multiple files, should I be putting a `defvar` at the top of each file? Or is there some way to tell the byte compiler to "include" a list of known globals, so I can keep them all in one place? Maybe `(eval-when-compile (require 'my-defvars-file.el))` ? – Kevin Jun 24 '16 at 21:26