Автоотступ Vim: выравнивание инициализации массива, которая распространяется на несколько строк

Иногда инициализация массива в C занимает несколько строк, особенно если массив многомерный. В Emacs результат автоматического отступа выглядит следующим образом:

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}};

В Vim функция автоматического отступа, разрешенная : отступ типа файла на просто отступает строки на константу shiftwidth , что приводит к на следующее:

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}};

Есть ли способ заставить Vim вести себя как Emacs в этой конкретной ситуации?

ОБНОВЛЕНИЕ:

Herbert Sitz ' Ответ был действительно очень полезным (спасибо!). Я немного изменил его код, чтобы он выглядел так:

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

Сохранение этого в файле ~ / .vim / after / ftplugin / c.vim решает проблему, т.е. заставляет Vim выровнять объявление массива по так же, как и Emacs.

Что я изменил:

  • Используйте matchstr () вместо matchlist () , чтобы упростить понимание кода ( len ( m) вместо len (m [0]) ).
  • Разрешить пробелы в начале строки, чтобы объявление могло быть вложенным (например, в функцию).
  • Допускайте перед оператором присваивания более двух слов. Это касается статических объявлений.
  • Проверяйте только первую открывающую скобку ( {), чтобы выражение также соответствовало одномерным массивам (или структурам).
  • Не сравнивайте выражения, содержащие точку с запятой ( ; ), потому что это указывает на то, что объявление удерживается в одной строке (т.е. следующая строка не должна выравниваться по открывающей скобке). Я думаю, что это более общий подход, чем поиск закрывающих скобок или запятых в конце строки.

Пожалуйста, дайте мне знать, если я пропустил что-то важное.

11
задан qfab 6 October 2010 в 09:25
поделиться