inoremap :call ReIndent(1) function! ReIndent(in_insert_mode) let l:col = col(".") let l:lnum = line(".") " set append = 1, if we're at the end of the line. let l:linelen = strlen(getline(l:lnum)) let l:append = (l:col >= l:linelen) let l:indent_ok = 0 if IndentToParen(l:lnum, 1) let l:indent_ok = 1 elseif IndentToParen(l:lnum, 0) let l:indent_ok = 1 endif " Move back to our original position let l:linedelta = strlen(getline(l:lnum)) - l:linelen call setpos('.', [0, l:lnum, l:col + l:linedelta, 0]) if l:indent_ok == 0 "Both indent attempts failed, try using == instead normal == endif if a:in_insert_mode if l:append == 1 startinsert! else normal l startinsert endif endif endfunction function! IndentToParen(lnum, assume_unclosed) " Search for '(' on the previous line let l:ret = 1 let l:lnum = a:lnum let l:prevlnum = prevnonblank(l:lnum - 1) let l:oldline = getline(l:lnum) if a:assume_unclosed " insert a ), find what it matches, indent to that open paren? call setline(l:lnum, ")") else call setpos('.', [0, l:prevlnum, 0, 0]) execute "normal $F)" endif let [l:slnum, l:scol] = searchpairpos('(', '', ')', 'nbW') if a:assume_unclosed call setline(l:lnum, l:oldline) endif if l:slnum[0] != 0 " Trim leading space/tabs call setpos('.', [0, l:lnum, 0, 0]) s/^[ >]*// " Set the line with new indentation if a:assume_unclosed == 0 let l:scol = indent(l:slnum) endif call setline(l:lnum, repeat(" ", l:scol) . getline(l:lnum)) " Turn spaces into tabs on this line, if necessary. .retab! else "echo "No match found on IndentToParen " . a:assume_unclosed let l:ret = 0 endif return l:ret endfunction