1

Today I realized something odd that bothers me. Here is a little example of a function I wrote. I am using armadillo, but that is is unimportant. Here, the indentation looks just fine.

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

Now, I find the long initialization of E2 and E3 annoying, so I make a line break between the two for better readibility. I also indent my whole buffer.

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

Now, Emacs indents the float [...] and return statement to the same column as E2, E3. This was not the case in the first example. In my layman's mind the last two statements belong to the same colum as the arma::fvec statement, like it was in the first example.

Is there a way to fix this?

I couldn't find anything specific in the internet yet. Usually, I am using c-style 'stroustrup'. I tried other styles with no succes.

Edit: Sorry, I completely forgot. I am using emacs 25.2.2, I use helm, and a company complete with clang but no package that I can think of modifies the indentations.

Edit2: I also observed the same behavior with the -Q option (emacs -Q), therefore I guess I can rule out that my packages are the causation.

Edit3: Installing emacs 27.1 fixed the issue but this lead me to a follow up question concerning highlighting and indentation.

Example 3: Now, indentation seems to be correct but the highlighting is off (it was before, but the indentation issue was priority).

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

In the above example, Emacs highlights E2 as a variable but E3 is standard text color. When I now change the indentation to 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);
}

You can see, that the indentation of E2 differs from E3. I believe the different indentation is a result of emacs not recognizing E3 as a variable. Did anyone also observe this?

Here a screenshot for illustration enter image description here

6
  • 1
    You might give Emacs 27.1 a try on the change that someone has fixed the problem in the last two or three years.
    – db48x
    Aug 16 '20 at 11:10
  • Im using emacs 27.0.91 and the gnu c style, for me it indents correctly, also I'm using the function c-indent-defun. Good luck!
    – f-sasa
    Aug 16 '20 at 11:34
  • Thanks for your comments. Installing Emacs 27.1 fixed the issue with the indentation.
    – Andi
    Aug 16 '20 at 12:25
  • Fixing the issue led to a follow up question. I edited the original post and hope it is still in the boundaries of the topic.
    – Andi
    Aug 16 '20 at 13:06
  • It may be an emacs bug, the variable font-lock-keywords contains the regex/patterns for every highlight keyword, I cannot spot the error, sorry. Recently I found a package for syntax highlight very interesting emacs-tree-sitter, which highlight the buffer correctly. Good luck!
    – f-sasa
    Aug 17 '20 at 5:21
0

Okay, so I got in contact with the maintainers/developers of CC-Mode and it turns out that this is bug. They also took care of it: https://sourceforge.net/p/cc-mode/mailman/message/37097087/

In the correspondence you find a patch in text form. To apply the patch, copy the text to a file e.g. patchfile.txt

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

If you only have cc-*.el.gz and .elc but no cc-.el files in the progmodes folder, you'll first have to extract them

$ gunzip cc-*.el

Before applying the patch, check if there would be any errors

$ patch --dry-run < patchfile.txt

If the output looks similar to this:

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).

You can now apply the patch

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

While patching, .orig files are created as a backup, in case you ever need to go back.

As a last step, you will have to compile the .el-files to .elc

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

My output:

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.

Now restart emacs.

Because of the output ([...] newer than byte-compiled [...]). I was asked to open a buffer in emacs in cc-mode, type

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

If the echo area displays "t" everything should be alright. If not, you might consider using the backup and returning to the initial state.

Nonetheless, in my case the bug was solved this way. I could imagine that it won't take long until the fix is also officially on sourceforge which will make this fix-description obsolete.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.