1

I've been using vim for two years but there are many things I don't know very well. Today, I was coding in c++ and found that I wanted to type the snippet like this:

Horse(COLOR color, HANDS height, int age):
Animal(age),
itsColor(color),
itsHeight(height) {
    cout << "Horse constructor...\n";
}   

Instead I found:

Horse(COLOR color, HANDS height, int age):
Animal(age),
    itsColor(color),
    itsHeight(height) {
        cout << "Horse constructor...\n";
    } 

How can I make the closing curly brace to align with the constructor definition?

My vimrc settings are:

set secure
set showmode
set number
set relativenumber
set cursorline
set linebreak
set colorcolumn=81
set updatetime=1000
set conceallevel=0
set showbreak=↳
set wrap
set lcs=tab:>-,nbsp:%,trail:¬
set list
set cinoptions=g0,l1,i0
set smarttab
set tabstop=4
set softtabstop=4
set shiftwidth=4
set shiftround
set expandtab
autocmd FileType make setlocal noexpandtab
autocmd FileType markdown setlocal colorcolumn=0
6
+150

Indent methods

Vim has several indent methods, including

  • 'autoindent'
  • 'smartindent'
  • 'cindent'
  • 'indentexpr'

Each one is unique and differently powerful.

cindent

According to :help cino-i, you want to use 'cindent'. This is already set for cpp files in $VIMRUNTIME/indent/cpp.vim, as found by doing :verbose set cindent? from a cpp file.

Customizing cindent for this case

To change the indentation of "C++ base class declarations and constructor initializations," you then want to change 'cinoptions' to include i0.

The example in the help docs:

                                                *cino-i*
iN    Indent C++ base class declarations and constructor
      initializations, if they start in a new line (otherwise they
      are aligned at the right side of the ':').
      (default 'shiftwidth').

        cino=                     cino=i0 >
          class MyClass :           class MyClass :
              public BaseClass      public BaseClass
          {}                        {}
          MyClass::MyClass() :      MyClass::MyClass() :
              BaseClass(3)          BaseClass(3)
          {}                        {}

In order to accomplish that, I would do the following:

  1. Set up a C++ filetype plugin by creating the the file ~/.vim/ftplugin/cpp.vim (or wherever your vim directory is)
  2. Add the following line to it:

    setlocal cinoptions=i0

This works because 'cinoptions' defaults to an empty string, is not changed by a filetype plugin, and the values used when not provided include is (use a 'shiftwidth') as seen in the help:

cinoptions=>s,e0,n0,f0,{0,}0,^0,L-1,:s,=s,l0,b0,gs,hs,N0,E0,ps,ts,is,+s,
        c3,C0,/0,(2s,us,U0,w0,W0,k0,m0,j0,J0,)20,*70,#0

Caveat based on OP's vimrc (AKA How to enable filetype-settings)

The OP's post already has cinoptions with i0 in it (although it is set globally in all files). However, it does not appear to be working.

In order for this solution (and indeed cinoptions/cindent in general) to work, you need to enable filetype detection, plugins, and indenting (at the very least). To do this, add the following line to your vimrc:

filetype plugin indent on

You can find some more similar information on this vi.stackexchange post and this one and this one.They're all mine, because they were easy to find and I have written extensively on the topic.


Further notes

Some testing related the unfortunate experience that the precise snippet in the OP then becomes

Horse(Color color, HANDS height, int age):
Animal(age),
    itsColor(color),
    itsHeight(height) {
        cout << "text" ;
    }

which is only a small step towards the solution requested by the OP. This can be corrected by not indenting continuation lines (+0 for 'cinoptions'). However, then continuation lines won't be indented (see :help cino-+). I suppose these are technically continuations (hence the commas, hence the indent).

The results:

class MyClass :
itsColors(color),
Animal(age),
itsHeight(height) {
    cout << "text" ;
}

A better solution remains to write and use indentexpr (possibly falling back on cindent() except in this case). I am not currently up to the task.

  • > you need to enable filetype detection, plugins, and indenting – klaus Jun 5 '18 at 14:52
  • Yes, as I noted in my answer you need filetype plugin indent on – D. Ben Knoble Jun 5 '18 at 14:54
  • 1
    Sorry, man, I didn't know comments don't format markdown blockquote. I wanted to tell you that I just didn't put all my vimrc in the post. I did have filetype plugin indent on in the top. Also, neovim does that by default. – klaus Jun 5 '18 at 15:00
  • Oh ok alright np – D. Ben Knoble Jun 5 '18 at 15:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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