Режим C ++, путаница с отступами

Aug 16 2020

Сегодня я понял кое-что странное, что меня беспокоит. Вот небольшой пример написанной мной функции. Я использую броненосцев, но это неважно. Здесь отступ выглядит просто отлично.

float GetE0()
{
    // Calculate E0 according to Kurfess et. al, 2000
    arma::fvec
        E2 {vertex2X - vertex1X, vertex2Y - vertex1Y, vertex2Z - vertex1Z}, E3 {vertex3X - vertex2X, vertex3Y - vertex2Y, vertex3Z - vertex2Z};
    
    float cosPhi2 = norm_dot(E2,E3);
    
    return Kurfess_Eq5(cosPhi2);
}

Теперь я считаю, что длительная инициализация E2и E3раздражает, поэтому я делаю разрыв строки между ними для лучшей читаемости. Я также делаю отступ для всего буфера.

float GetE0()
{
    // Calculate E0 according to Kurfess et. al, 2000
    arma::fvec
        E2 {vertex2X - vertex1X, vertex2Y - vertex1Y, vertex2Z - vertex1Z},
        E3 {vertex3X - vertex2X, vertex3Y - vertex2Y, vertex3Z - vertex2Z};

        float cosPhi2 = norm_dot(E2,E3);

        return Kurfess_Eq5(cosPhi2);
}

Теперь Emacs помещает оператор float [...] и return в тот же столбец, что E2и E3,. В первом примере это было не так. На мой взгляд, последние два утверждения относятся к тому же столбцу, что и arma::fvecутверждение, как и в первом примере.

Есть способ исправить это?

Ничего особенного в инете пока не нашел. Обычно я использую stroustrup в стиле c. Я пробовал другие стили, но безуспешно.

Изменить: извините, я совсем забыл. Я использую emacs 25.2.2, я использую helm и компанию с clang, но ни один пакет, о котором я могу думать, не изменяет отступы.

Edit2: я также наблюдал такое же поведение с параметром -Q (emacs -Q), поэтому я предполагаю, что могу исключить, что мои пакеты являются причиной.

Edit3: установка emacs 27.1 устранила проблему, но это привело меня к следующему вопросу, касающемуся выделения и отступов.

Пример 3: Теперь отступы кажутся правильными, но выделение отключено (было раньше, но проблема с отступом была приоритетной).

float GetE0()
{
    // Calculate E0 according to Kurfess et. al, 2000
    arma::fvec
        E2 {vertex2X - vertex1X, vertex2Y - vertex1Y, vertex2Z - vertex1Z},
        E3 {vertex3X - vertex2X, vertex3Y - vertex2Y, vertex3Z - vertex2Z};

    float cosPhi2 = norm_dot(E2,E3);
    return Kurfess_Eq5(cosPhi2);
}

В приведенном выше примере Emacs выделяется E2как переменная, но E3имеет стандартный цвет текста. Когда я теперь меняю отступ на Example4:

float GetE0()
{
    // Calculate E0 according to Kurfess et. al, 2000
    arma::fvec

         E2 {vertex2X - vertex1X,
         vertex2Y - vertex1Y,
         vertex2Z - vertex1Z},

         E3 {vertex3X - vertex2X,
             vertex3Y - vertex2Y,
             vertex3Z - vertex2Z};

    float cosPhi2 = norm_dot(E2,E3);
    return Kurfess_Eq5(cosPhi2);
}

Вы можете видеть, что отступ E2отличается от E3. Я считаю, что другой отступ является результатом того, что emacs не распознается E3как переменная. Кто-нибудь тоже это заметил?

Вот скриншот для иллюстрации

Ответы

Andi Aug 31 2020 at 01:08

Хорошо, я связался с сопровождающими / разработчиками CC-Mode, и оказалось, что это ошибка. Об этом тоже позаботились:https://sourceforge.net/p/cc-mode/mailman/message/37097087/

В переписке найдете патч в текстовом виде. Чтобы применить патч, скопируйте текст в файл, например patchfile.txt

$ mv patchfile.txt path/to/emacs/share/../lisp/progmodes $ cd path/to/emacs/share/../lisp/progmodes

Если у вас есть только cc - *. El.gz и .elc, но нет файлов cc- .el в папке progmodes, вам сначала нужно извлечь их

$ gunzip cc-*.el

Перед применением патча проверьте, нет ли ошибок

$ patch --dry-run < patchfile.txt

Если результат выглядит примерно так:

Hunk #1 succeeded at 9091 (offset -22 lines).
Hunk #2 succeeded at 9144 (offset -22 lines).
Hunk #3 succeeded at 11731 (offset -29 lines).
checking file cc-langs.el
Hunk #1 succeeded at 3684 (offset -9 lines).

Теперь вы можете применить патч

$ patch < patchfile.txt
[same output as dry-run]

Во время исправления файлы .orig создаются в качестве резервной копии на случай, если вам когда-нибудь понадобится вернуться.

В качестве последнего шага вам нужно будет скомпилировать файлы .el в .elc.

$ emacs -Q -batch -f batch-byte-compile cc-*.el

Мой вывод:

Source file ‘/opt/emacs/emacs-27.1-install/share/emacs/27.1/lisp/progmodes/cc-langs.el’ newer than byte-compiled file; using older file

In end of data:
cc-styles.el:687:1:Warning: the function ‘c-guess-basic-syntax’ might not be
    defined at runtime.

Теперь перезапустите emacs.

Из-за вывода ([...] новее, чем байт-скомпилированный [...]). Меня попросили открыть буфер в emacs в режиме cc, введите

M-: c-recognize-bare-brace-inits
<Return>

Если в эхо-области отображается «t», все должно быть в порядке. Если нет, вы можете использовать резервную копию и вернуться в исходное состояние.

Тем не менее, в моем случае ошибка была решена таким образом. Я могу представить, что это не займет много времени, пока исправление также официально появится в sourceforge, что сделает это описание исправления устаревшим.