Sorry, I'm new to emacs and I'm sure this is a very basic question.

For my personal projects I prefer spaces for indentation, whereas work requires smart-tabs (tabs for indentation, spaces for alignment).

I would like to create a .dir-locals.el file in my work project root, so that whenever I open a C++ file it automatically switches to indent-tabs-mode and turns on smart-tabs.

This is what I have in my .dir-locals.el file, but it is not working.

(defun my-c++-mode-setup()
  (use-package smart-tabs
    (smart-tabs-default-insinuations '(c c++)))
  (setq indent-tabs-mode . t)
(add-hook 'c++-mode-hook 'my-c++-mode-setup)

2 Answers 2


.dir-locals.el is not loaded like the init files .emacs and .emacs.d/init.el. Its structure is different from that of the init files.

I cite here the the relevant text from "Directory Variables" of the Emacs manual:

The .dir-locals.el file should hold a specially-constructed list, which maps major mode names (symbols) to alists (see Association Lists). Each alist entry consists of a variable name and the directory-local value to assign to that variable, when the specified major mode is enabled. Instead of a mode name, you can specify ‘nil’, which means that the alist applies to any mode; or you can specify a subdirectory (a string), in which case the alist applies to all files in that subdirectory.


You can specify the variables mode, eval, and unibyte in your .dir-locals.el, and they have the same meanings as they would have in file local variables. coding cannot be specified as a directory local variable. See File Variables.

You use case:

 ((c++-mode . ((indent-tabs-mode . t)
               (eval . (use-package smart-tabs
                        (smart-tabs-default-insinuations '(c c++)))))))

You should test the code yourself since I have neither use-package nor smart-tabs. Comment on this answer if you encounter difficulties.

  • After editing a file in a work directory, all C and C++ files will forevermore be operating in smart tabs mode, with this configuration. Aug 21, 2018 at 0:24

I would like to create a .dir-locals.el file in my work project root

This is not the tool you are looking for, or at the very least, not in the way you are trying to use it. The problem is that...

(add-hook 'c++-mode-hook 'my-c++-mode-setup)

...once this runs, all C++ code will run that hook, forever, and will get smart-tabs results.

Instead, you want to put this code into your ~/.emacs.d/init.el file, and make the code in the hook unconditional, but smarter, akin to this:

(use-package smart-tabs)
;; note, no '.' because this isn't a cons, it is a setq.
;; also, pick your default as you prefer
(setq indent-tabs-mode t)

(defvar my-use-smart-tabs nil
  "If set true, C++ will use smart tabs...")

(defun my-c++-mode-setup()
  (if my-use-smart-tabs 
        (setq indent-tabs-mode t))
   (setq indent-tabs-mode nil)))
(add-hook 'c++-mode-hook 'my-c++-mode-setup)

Now you can use your .dir-locals.el to set that variable, and it will cause the hook to turn on smart tabs. If it is not set, it'll turn them off.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.