Sometimes an array initialization in C extends over several lines, especially if the array is multidimensional. In Emacs the result of auto-indentation looks like this:
int a[N][N] = {{0, 0, 6, 7, 0, 4, 0, 2, 0},
{0, 5, 0, 6, 0, 0, 0, 0, 1},
{2, 0, 0, 0, 0, 8, 0, 0, 4},
{4, 0, 9, 5, 0, 7, 0, 0, 3},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{8, 0, 0, 2, 0, 1, 9, 0, 6},
{6, 0, 0, 1, 0, 0, 0, 0, 7},
{3, 0, 0, 0, 0, 5, 0, 6, 0},
{0, 2, 0, 3, 0, 6, 1, 0, 0}};
In Vim the auto-indentation feature enabled by :filetype indent on
merely indents the lines by the constant shiftwidth
which leads to the following:
int a[N][N] = {{0, 0, 6, 7, 0, 4, 0, 2, 0},
{0, 5, 0, 6, 0, 0, 0, 0, 1},
{2, 0, 0, 0, 0, 8, 0, 0, 4},
{4, 0, 9, 5, 0, 7, 0, 0, 3},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{8, 0, 0, 2, 0, 1, 9, 0, 6},
{6, 0, 0, 1, 0, 0, 0, 0, 7},
{3, 0, 0, 0, 0, 5, 0, 6, 0},
{0, 2, 0, 3, 0, 6, 1, 0, 0}};
Is there a way to make Vim behave like Emacs in this particular situation?
UPDATE:
Herbert Sitz's answer was indeed very helpful (thanks!). I have slightly modified his code to look like this:
setlocal indentexpr=GetMyCIndent()
function! GetMyCIndent()
let theIndent = cindent(v:lnum)
let m = matchstr(getline(v:lnum - 1),
\ '^\s*\w\+\s\+\S\+.*=\s*{\ze[^;]*$')
if !empty(m)
let theIndent = len(m)
endif
return theIndent
endfunction
Saving this to the file ~/.vim/after/ftplugin/c.vim
solves the problem, i.e. it makes Vim align the array declaration the same way Emacs does.
What I have changed:
- Use
matchstr()
instead ofmatchlist()
to make the code easier to understand (len(m)
in place oflen(m[0])
). - Allow white spaces at the beginning of the line so that the declaration can be nested (e.g. in a function).
- Allow more than just two words before the assignment operator. This takes care of
static
declarations. - Only check for the first opening bracket (
{
) so that the expression also matches one-dimensional arrays (or structures). - Don't match expressions which contain a semicolon (
;
) because this indicates that the declaration holds in one line (i.e. the next line should not be aligned under the opening bracket). I think this is a more general approach than looking for closing brackets or commas at the end of the line.
Please let me know if I have missed something important.