Иногда инициализация массива в 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 в этой конкретной ситуации?
ОБНОВЛЕНИЕ:
Ответ Герберта Ситца был действительно очень полезным (спасибо!).Я немного изменил его код, чтобы он выглядел так:
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
. - Проверяется только первая открывающая скобка (
{
), чтобы выражение также соответствовало одномерным массивам (или структурам). - Don '• соответствуют выражениям, которые содержат точку с запятой (
;
), поскольку это указывает на то, что объявление хранится в одной строке (т. е. следующая строка не должна быть выровнена под открывающей скобкой).Я думаю, что это более общий подход, чем поиск закрывающих скобок или запятых в конце строки.
Пожалуйста, дайте мне знать, если я пропустил что-то важное.