24

I am using emacs 23.1.1 on Ubuntu 10.04. I wish to program in Python with a 2-space indent. emacs looks to have a default mode for python (python.el?).

I put the following in my .emacs:

    ;; Only spaces, no tabs
    (setq indent-tabs-mode nil)

    ;; Always end a file with a newline
    (setq require-final-newline nil)

    ;; Don't know which of these might work
    (setq-default tab-width 2)
    (setq-default python-indent 2)
    (setq-default py-indent-offset 2)

When I edit a Python file, it uses a 4-space indent. When I try C-h v python-indent it says:

    python-indent's value is 4
    Local in buffer webpage_cache.py; global value is 2

        This variable is safe as a file local variable if its value
        satisfies the predicate `integerp'.

    Documentation:
    Number of columns for a unit of indentation in Python mode.
    See also `M-x python-guess-indent'

    You can customize this variable.

That is, it is 4, not 2. Grr. I tried customizing the variable and saving, still 4. I tried customize-group indent, still 4.

How do I get emacs to pay attention?

dfrankow
  • 20,191
  • 41
  • 152
  • 214

3 Answers3

23

You can put this into your .emacs file:

(add-hook 'python-mode-hook '(lambda () 
 (setq python-indent 2)))

The reason why

    (setq-default python-indent 2)

does not work may because this variable does not exit when .emacs is loaded. (But I am an emacs newbie. I am not sure about my explanation.)

However, PEP 8 -- Style Guide for Python Code recommends "4 spaces per indentation level" and I find 4 spaces more readable. I actually use this piece of code to force a 4 spaces indentation.

Vulpecula
  • 388
  • 1
  • 7
19

Either in you .emacs file or in a file referenced by your .emacs add:

(setq-default indent-tabs-mode nil)
(setq-default tab-width 2)

You can put in a hook if you want to localize

;; Python Hook
(add-hook 'python-mode-hook
          (function (lambda ()
                      (setq indent-tabs-mode nil
                            tab-width 2))))

EDIT: I have found the following the following issues can mess with my settings:

  • setting the variable before the library is loaded
  • other packages/configs resetting the global variables

For both those issues I have found creating hooks and localizing the variables can help.

dietbuddha
  • 8,556
  • 1
  • 30
  • 34
  • This answer ignores the fact that I already had tab-width 2 in my .emacs, and doesn't explain any of what I was seeing. Still, my setup works now (don't know why), so I'll accept. – dfrankow Nov 23 '10 at 17:49
  • Just out of curiosity, why wrap (lambda ...) in (function ...)? I hadn't seen (function ...) before, and the manual suggests it's not necessary. – Tyler Dec 13 '10 at 04:21
  • 1
    Tyler: Historically, it made a difference. It's no longer necessary, but still a habit for many people. See http://stackoverflow.com/questions/1852844/emacs-lisp-difference-between-function-lambda-and-lambda for details. – phils Dec 13 '10 at 09:16
  • I have python-indent at 2 and tab-indent at two and I still get an actual indent of 1. That stuff like this is this finicky in emacs is not at all good. – Samantha Atkins Feb 14 '18 at 19:58
15

I just ran into this problem myself, and I think the help for python-indent contains a big clue that no one else mentioned:

See also `M-x python-guess-indent'

If you don't customize python-guess-indent by setting it to nil, then python.el will automatically set python-indent for each Python buffer (that contains indented text), making your python-indent customization ineffective. (On the other hand, when in Rome...)

In the end, this is what went into my .emacs file (ignoring all other custom variables):

(custom-set-variables
 '(python-guess-indent nil)
 '(python-indent 2))
bk1e
  • 23,871
  • 6
  • 54
  • 65
  • For working with existing Python code I needed to set python-guess-indent to nil for things to work the way I wanted it to. For new Python code it wasn't required though. This was a bit confusing until I tried this fix. – andybauer Nov 25 '13 at 16:00
  • 2
    Now in Emacs v26 the python-mode variables have longer names. I ended up with this added to my custom-set-variables. I'm just trying to make it quit guessing and force it to 4. '(python-indent-guess-indent-offset nil) '(python-indent-offset 4) – IcarusNM May 11 '19 at 16:51