Monday, February 21, 2011

Indenting comments to match code in vim

I do all my coding in vim and am quite happy with it (so, please, no "use a different editor" responses), but have an ongoing annoyance in that the smartindent feature wants to not indent comments beginning with # at all. e.g., I want

  # Do something
  $x = $x + 1;
  if ($y) {
    # Do something else
    $y = $y + $z;
  }

instead of vim's preferred

# Do something
  $x = $x + 1;
  if ($y) {
# Do something else
    $y = $y + $z;
  }

The only ways I have been able to prevent comments from being sent to the start of the line are to either insert and delete a character on the line before hitting # (a nuisance to have to remember to do every time) or turn off smartindent entirely (losing automatic indentation increase/decrease as I open/close braces).

How can I set vim to maintain my indentation for comments instead of sending them to the start of the line?

From stackoverflow
  • I think "smartindent" is designed for C, so it thinks "#" is the start of a pre-processor directive instead of a comment. I don't know a solution for it, except if you type a space, then a backspace, then the "#" it won't do that.

  • This problem can be solved by putting the following in your _vimrc file.

    set cindent
    set cinkeys=0{,0},!^F,o,O,e " default is: 0{,0},0),:,0#,!^F,o,O,e
    

    More info...

    Dave Sherohman : Works perfectly - thanks!
    Zathrus : Note that Richard Waite's response is far, far better. Vim knows how to properly indent most files, please let it do so.
    Ben Hoffstein : Yup, agreed. I was not aware of that functionality.
    Ben Hoffstein : I'll leave my answer here in case someone happens to be using an older version of Vim that doesn't support filetype plugins, but I recommend using Richard Waite's solution whenever possible.
  • It looks like you're coding in Perl. Ensure that the following are set in your .vimrc:

    filetype plugin indent on
    syntax enable
    

    These will tell Vim to set the filetype when opening a buffer and configure the indentation and syntax highlighting. No need to explicitly set smartindent since Vim's included Perl syntax file will set it (and any other Perl-specific customizations) automatically.

    Dave Sherohman : Strange... I didn't expect this to do anything, as I was already getting proper syntax highlighting, but this did indeed get the comments handled correctly as well. Presumably the indentation plugin wasn't being loaded by default, then?
    rmw1985 : To the best of my knowledge it is not configured to load according to filetype. Some distribution packagers will modify the system default to set the plugin to load by filetype, but that causes problems when moving to systems which have the "real" or a differently configured system default.
    Johan : This does not help at all! I'm still stuck with this indent problem on the windows computer at work. (I miss gg=G)
    Johan : But it do solve the problem when I am running under Ubuntu at home (vim/gvim both work), so there must be something funny in those scripts that gvim uses under Windows...
    Tomas Sedovic : Seems like having `smartindent` set overrides this. So deleting that from vimrc can help too.
  • If you are using the "smartindent" indenting option, a fix for your problem is explained in the ":help smartindent" VIM documentation:

    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.

    I use "smartindent" and can confirm that the fix described works for me. It tricks VIM by replacing the keystroke for "#" with typing "X", then hitting backspace, then typing "#" again. You can try this yourself manually and see that it does not trigger the auto-outdenting.

0 comments:

Post a Comment