Vim Objective-C Colon Indentation

Vim’s objective-c mode has an annoying indentation issue. It tries to line colons up on subsequent lines, like so:

[self performSelectorOnMainThread:@selector(finishLoad) 
                       withObject:nil 
                    waitUntilDone:NO];

That’s nice, but it has an annoying bug that makes it try to align the colons with a previous line that is unrelated:

if ([someVariable isEqualToString:@"blah"]) {
[self performSelectorOnMainThread:@selector(finishLoad) 
                       withObject:nil 
                    waitUntilDone:NO];
}

This all takes place in indent/objc.vim (full path on a MacPorts installation is /opt/local/share/vim/vim72/indent/objc.vim, for MacVim it is /Applications/MacVim.app/Contents/Resources/vim/runtime/indent/objc.vim).

There is probably a way to fix this in a .vimrc file, but I just edited objc.vim. At the bottom of the file is a function GetObjCIndent. Change the second if statement to match the following:

function GetObjCIndent()
    let theIndent = cindent(v:lnum)

    let prev_line = getline(v:lnum - 1)
    let cur_line = getline(v:lnum)
        
    if prev_line !~# ":" || cur_line !~# ":"
        return theIndent
    endif
     
    if prev_line !~# ";" && prev_line !~# "{"
        let prev_colon_pos = s:GetWidth(prev_line, ":")
        let delta = s:GetWidth(cur_line, ":") - s:LeadingWhiteSpace(cur_line)
        let theIndent = prev_colon_pos - delta
    endif
        
    return theIndent
endfunction

There are some refinements that could be made to fix it for more cases, but this one fixes the one that was driving me crazy.


Related Posts

  1. iPhone/iPad UISearchBar and UISearchDisplayController Asynchronous Example
  2. My 5 Must-have vim Plugins
  3. Rails Fragment Caching With Multiple Accounts
  4. Vim ack plugin with MacVim and MacPorts
  5. Postgresql Primary Key Sequence Out Of Sync
You should follow me on Twitter: @patrickxb