Иногда инициализация массива в 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 функция автоиндексации, разрешенная :filetype indent on
, просто отбрасывает строки константой 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 в этой конкретной ситуации?
UPDATE:
Ответ Герберта Ситца действительно был очень полезен (спасибо!). Я немного изменил его код, чтобы выглядеть так:
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])
). - Разрешить пробелы в начале строки, чтобы объявление могло быть вложенным (например, в функцию).
- До выполнения оператора присваивания допускается не более двух слов. Это касается объявлений
static
. - Проверить только первую открывающую скобку (
{
), чтобы выражение также соответствовало одномерным массивам (или структурам). - Не совпадают выражения, содержащие точку с запятой (
;
), поскольку это указывает на то, что объявление выполняется в одной строке (т.е. следующая строка не должна выравниваться под открытой скобкой). Я думаю, что это более общий подход, чем поиск закрывающих скобок или запятых в конце строки.
Пожалуйста, дайте мне знать, если я пропустил что-то важное.