Vim automatically removes indentation on Python comments [duplicate]
Asked Answered
E

5

78

I'm using Vim and editing Python scripts.

Autoindent works pretty well in general, but when I start a new line and type '#' to type a comment, Vim unindents that line for me.

For example, if have

def foo():

and I press enter, Vim will indent properly

def foo():
    pass

but, if instead of typing pass, I type #, it unindents automatically

def foo():
# comment

class Thing():
    def __init__(self):
         pass
# comment line gets unindented all the way

my .vimrc file follows. anyone know why this is happening?

set tabstop=4
set smartindent
set shiftwidth=4
set expandtab
set backspace=indent,eol,start
set scrolloff=3
set statusline=%f%m%r%h%w\ [%Y\ %{&ff}]\ [%l/%L\ (%p%%)]
set laststatus=2
Etan answered 2/3, 2010 at 1:1 Comment(1)
For teh search engine: dedent, outdent.Rodriques
G
63

Setting smartindent on makes Vim behave like you describe for me, whereas with nosmartindent (which is what I tend to use) it behaves like you'd prefer it to.

Update: From the docs on smartindent:

When typing '#' as the first character in a new line, the indent for that line is removed, the '#' is put in the first column. The indent is restored for the next line. If you don't want this, use this mapping: ":inoremap # X^H#", where ^H is entered with CTRL-V CTRL-H. When using the ">>" command, lines starting with '#' are not shifted right.

That seems to be it.


Update: Probably no need to bother with the following... I'll leave it here for the added informational value. ;-)

If setting nosmartindent doesn't help, perhaps you could use the :set command -- with no parameters -- to obtain the list of all settings in effect in your Vim session, then paste it somewhere (on Pastie perhaps). There's a few other options which affect automatic indentation, as far as I remember.

Grower answered 2/3, 2010 at 1:12 Comment(3)
I had difficulty getting the ^H suggested in this answer using CTRL-V CTRL-H, but I found that inoremap # X<BS># does the trick.Gagarin
You can also use inoremap # X<c-h># if you really want the CTRL-HLexis
I tried this and @Ola answer's but it doesn't fix it competently. If you already have an unidented #, the >> command won't change the indent.Cyrenaica
V
22

While Michał's post explains what smartindent does, you can do a lot better than just turning it off. You could configure it more to your liking, or better yet, let Vim pick better indentation for you. With the following in your vimrc instead of other indent settings:

filetype indent on

Vim will automatically use the proper indent plugin for python. This is way better than just not de-indenting a # line - pretty much everything should be properly indented.

Veg answered 2/3, 2010 at 1:28 Comment(12)
Jefromi, I don't understand your answer. vim is already selecting the python indentation plugin - the problem is that the plugin happens to indent illogically, removing indentation completely. So your proposed solution doesn't fix the problem as explained in the question.Underground
smartindent will cause line-initial # to unindent regardless of whether filetype indent is turned on or not. So, you have to set nosmartindent to fix things anyway.Kamenskuralski
Ah, right. I should clarify: I really meant using filetype indent instead of other indent settings.Veg
And Thomas, I was thrown off by you saying that autoindent was working well - that's an option setting, separate from the filetype indent plugins (though I believe the python indent plugin enables autoindent, because it gets half the job done).Veg
...and the fact that you didn't have any mention of filetype in your .vimrc.Veg
@Jefromi You should add more detail to this answer, it is far from being comprehensibleProchronism
@SaulloCastro You should add more detail to your comment: what is incomprehensible? Was it just that I hadn't incorporated the discussion from the comments? If you use filetype-based indentation (the vimrc line I gave) Vim will automatically indent Python correctly - seems simple enough.Veg
@Jefromi Probably due to my lack of experience in VIM I could not make it work only reading the answer. It would be nice to have some example, like .py ident on, or python ident one, or something similarProchronism
Yeah, this outright doesn't work for me. Either I am misunderstanding something, something is missing from this answer or there is something else wrong.Despain
@DavidYoung It definitely works if the filetype in question is supported, i.e. it's correctly detected and has indentation rules (so python should be fine!), and if there's nothing else in your vimrc to confound things. If you want to troubleshoot, I'd probably ask a new question on vi.stackexchange.comVeg
my problem is i like smartindent for if foo: and then getting an indent on the next line. I absolutely hate when I have a comment starting at beginning of line and I highlight code and comments and indent it and the commented lines don't indent. filetype indent on does not seem to indent after functions/ifs when I have nosmartindent, and nocindent also does nothing. :shrug:Twopenny
wow, ok, so use cindent and set indentkeys-=0# and you can indent things again!Twopenny
O
6

You can try an option only for python files:

autocmd BufRead *.py inoremap # X<c-h>#<space>
Ola answered 30/6, 2012 at 9:15 Comment(0)
R
4

For some unkown reason the above behavior was caused when i had cindent on. Turning it off fixed it for me. None of the other fixes above helped.

Reinert answered 15/4, 2013 at 13:3 Comment(1)
The reason is that the convention in C code (which is what cindent is for) is to unindent a proprocessor directive, which begins with #. So, this is helpful for C but a big problem for Python.Leu
D
-2

If you install this script, you will get proper python (pep8) indenting:

http://www.vim.org/scripts/script.php?script_id=974

Dipody answered 30/3, 2013 at 0:14 Comment(2)
This appears to be much worse.Consistent
Never mind. Even suggested answer seems to fail. Must be some plugin I haveConsistent

© 2022 - 2024 — McMap. All rights reserved.