Indenting for Qt C++

From Vim Tips Wiki

Jump to: navigation, search
Tip 1604 Printable Monobook Previous Next

created 2008 · complexity basic · author Davidmaxwaterman · version 7.0


Qt has some extensions to C++ that break the built-in C/C++ formatting functions. Notably, the additional keywords "signals", "slots", and "Q_OBJECT" used in class declarations.

Here is a function that can be put in your vimrc, that makes the '=' indent operation work correctly.

function! QtCppIndent()
  " Patterns used to recognise labels and search for the start
  " of declarations
  let labelpat='signals:\|slots:\|public:\|protected:\|private:\|Q_OBJECT'
  let declpat='\(;\|{\|}\)\_s*.'
  " If the line is a label, it's a no brainer
  if match(getline(v:lnum),labelpat) != -1
    return 0
  endif
  " If the line starts with a closing brace, it's also easy: use cindent
  if match(getline(v:lnum),'^\s*}') != -1
    return cindent(v:lnum)
  endif
  " Save cursor position and move to the line we're indenting
  let pos=getpos('.')
  call setpos('.',[0,v:lnum,1,0])
  " Find the beginning of the previous declaration (this is what
  " cindent will mimic)
  call search(declpat,'beW',v:lnum>10?v:lnum-10:0)
  let prevlnum = line('.')
  " Find the beginning of the next declaration after that (this may
  " just get us back where we started)
  call search(declpat,'eW',v:lnum<=line('$')-10?v:lnum+10:0)
  let nextlnum = line('.')
  " Restore the cursor position
  call setpos('.',pos)
  " If we're not after a label, cindent will do the right thing
  if match(getline(prevlnum),labelpat)==-1
    return cindent(v:lnum)
  " It will also do the right thing if we're in the middle of a
  " declaration; this occurs when we are neither at the beginning of
  " the next declaration after the label, nor on the (non-blank) line
  " directly following the label
  elseif nextlnum != v:lnum && prevlnum != prevnonblank(v:lnum-1)
    return cindent(v:lnum)
  endif
  " Otherwise we adjust so the beginning of the declaration is one
  " shiftwidth in
  return &shiftwidth
endfunc
set indentexpr=QtCppIndent()

[edit] Comments

 TO DO 

  • I suspect this code should be in something like after/ftplugin/cpp.vim (not vimrc).
  • And/or, remove the set indentexpr=QtCppIndent() and have a mapping to apply that when wanted (setlocal?).
  • Need to clarify what settings are required in vimrc to get everything working.
  • Further work may be needed because the tip author said:
This tip doesn't work very well. It seems to work on some code, but doesn't on other code. IMO, it clearly needs more work to become publishable.

Personal tools