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
  " 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)
  " 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)
  " Otherwise we adjust so the beginning of the declaration is one
  " shiftwidth in
  return &shiftwidth
set indentexpr=QtCppIndent()



  • 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.

Community content is available under CC-BY-SA unless otherwise noted.