Each buffer can have a local binding for a variable. This means any variable lookup made while this buffer is current will reveal the buffer local value of that variable instead of the default one. Local variables are an important feature in Emacs, for example they are used by major modes to establish their buffer local behavior and settings. To avoid interfering with each other major modes also kill existing local variables when you enter them.

You have already seen a buffer local variable in this post: The special comment line for lexical-binding which binds it buffer locally to t . In Emacs such buffer local variables defined in special comment lines are also called file local variables.

Any global variable can be shadowed by a buffer local one. Take for example the my-var variable defined in a previous section of this post which you can set locally like this:

( setq-local my-var t ) ;; or (set (make-local-variable 'my-var) t)

my-var will be local to the buffer which is current when you evaluate the code above. If you call describe-variable on it, you will see that the documentation tells you the local value and the global one. Programmatically you can check the local value using buffer-local-value and the default one with default-value . To remove the local version you could invoke M-x kill-local-variable .

Another important property you need to be aware of is that once a variable is buffer local, any further uses of setq (while this buffer is current) will continue to set the local value. To set the default value you would need to use setq-default .

Because local variables are meant for buffer customization you will use them most often in mode hooks. A typical example would be something like:

( add-hook 'go-mode-hook ( defun go-setup+ () ( setq-local compile-command ( if ( string-suffix-p "_test.go" buffer-file-name ) "go test -v" ( format "go run %s" ( shell-quote-argument ( file-name-nondirectory buffer-file-name )))))))

This will set the compile command used by M-x compile for go mode buffers.

Another important aspect is that some variables are automatically buffer local. This means as soon as you setq such a variable this will establish a local binding for the current buffer. This feature shouldn’t be used often because this implicit behavior isn’t nice but if you want you can create such automatically local variables like this:

( defvar-local my-automatical-local-var t ) ;; or (make-variable-buffer-local 'my-automatical-local-var)