0

I am new to emacs. I have been using this configuration for emacs:

(setq column-number-mode t) 
(setq c-default-style "linux"
          c-basic-offset 4)
(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(custom-enabled-themes (quote (wheatgrass))))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 )

Generally, the indentation is correctly handled by emacs automatically. For an if-statement, however, even if I could see the correct indentation in emacs then in an other editor the tab is not shown.

I have been editing a *.c file and the mode is "C/l mode defined in ‘cc-mode.el’. Major mode for editing C code".

Here an example: If I create an c file in emacs with the following code:

int main() {
    int x = 1;

    if (x > 0)
        x++;
    else
        x--;

    printf("Value of x: %d\n", x);

    return 0;
}

If I visualize this code in different editor or I copy it from an emacs into another editor the output is the following:

int main() {
    int x = 1;

    if (x > 0)
    x++;
    else
    x--;

    printf("Value of x: %d\n", x);

    return 0;
}

Basically, it seems that even if it looks like it is correctly indenting the if statement it has not added any tab character in the if statement.

What is the problem? How could I fix it?

gyro91
  • 35
  • 8
  • 1
    Which mode is the buffer in? What do you get in the help for e.g. the `Ret` key? `C-h k Ret` – tripleee Jul 06 '18 at 16:10
  • This is what I got:RET (translated from ) runs the command newline (found in global-map), which is an interactive compiled Lisp function in ‘simple.el’. – gyro91 Jul 06 '18 at 16:31
  • 2
    And the mode? This sounds like the buffer is simply in Fundamental mode. Please [edit] your question to clarify the file name, how you are visiting it, and which mode it's in (`C-h m`). – tripleee Jul 06 '18 at 17:03
  • ok, the mode is :"C/l mode defined in ‘cc-mode.el’. Major mode for editing C Code". The file that I have been editing is indeed a *.c file. – gyro91 Jul 07 '18 at 07:15
  • You probably need to separately enable `electric-indent-mode`. – tripleee Jul 07 '18 at 08:17
  • I inserted (electric-indent-mode 1) at the beginning of the .emacs file but it didn't work – gyro91 Jul 07 '18 at 09:11
  • I can't tell for certain what the problem is. Please provide a minimal example in the question text, demonstrating exactly what is happening. – phils Jul 07 '18 at 09:47
  • I have provided an example in the question text. – gyro91 Jul 07 '18 at 10:45

2 Answers2

3

Emacs is mixing tabs and spaces for indentation, and your other editor is using a different tab width.

Looking at your examples I can ascertain that in Emacs tab-width is 8, c-basic-offset is 4, and indent-tabs-mode is t.

If we prefix the number of spaces (s) and/or tabs (t) needed with that configuration:

0 |int main() {
4s|    int x = 1;
  |
4s|    if (x > 0)
1t|        x++;
4s|    else
1t|        x--;
  |
4s|    printf("Value of x: %d\n", x);
  |
4s|    return 0;
0 |}

In your other editor your tab width is obviously equivalent to only 4 spaces, and hence "4s" and "1t" are displayed as the same width.

If you M-x set-variable RET tab-width RET 4 RET in Emacs, you will see the same thing.

n.b. M-x whitespace-mode can visualise the indentation characters for you.

For best cross-editor compatibility, either use only spaces for indentation -- indent-tabs-mode set to nil -- or if you prefer tabs then you should ensure that tab-width and c-basic-offset are the same value, which means that every level of indentation will be a tab (at least in languages where indentation is by some specific amount, as opposed to aligning with arbitrary other code).

It seems that you do want tabs, so try this configuration:

(add-hook 'c-mode-hook 'my-c-mode-hook)
(defun my-c-mode-hook ()
  "Custom `c-mode' behaviours."
  (setq c-basic-offset 4)
  (setq tab-width c-basic-offset)
  (setq indent-tabs-mode t))

If you were going with spaces-only then you would just disable indent-tabs-mode:

(add-hook 'c-mode-hook 'my-c-mode-hook)
(defun my-c-mode-hook ()
  "Custom `c-mode' behaviours."
  (setq indent-tabs-mode nil))

Or you could disable it by default, rather than for a specific major mode. indent-tabs-mode is always a buffer-local value, but if you change its default value then that will affect all future buffers in which it isn't set explicitly:

(setq-default indent-tabs-mode nil)
phils
  • 71,335
  • 11
  • 153
  • 198
  • I visualized the indentation characters and it was exactly as you said. However, I would like to ask you why you said that the solution to use only spaces for indentation is the best for compatibility among editors. I preferred tabs for this reason because I think that using only tabs could be flexible. Of course, only for visualization, spaces could be the best choice. However, if for some reason the code should be edited from another guy in another editor, then is not better to use tabs? You should only set the correct width. – gyro91 Jul 07 '18 at 14:56
  • @gyro91: If you use tabs, the next person who edits your code may not have the same tab stops and may use spaces for indentation anyway, resulting a complete mess. In many facilities using tabs for indentation is prohibited for that reason. You'll make things easier for you and everyone else who touches your code in the future if you *always* use spaces for indentation. – varro Jul 07 '18 at 15:19
  • It makes sense. My assumption was that the next person should be aware of that, but of course, it is not always this case. May I ask you if you could suggest a configuration for emacs that uses only spaces? Like the one you wrote before for only tabs. Thanks so much for the advice! – gyro91 Jul 07 '18 at 15:40
  • @gyro91 I actually said that both the "spaces only" and "tabs only" approaches were fine for compatibility. It's having a *mixture* of tabs and spaces for indentation that causes problems, as the width of a tab then becomes critical. – phils Jul 07 '18 at 22:40
  • Personally I do like tabs, as in principle everyone can then configure the indentation tab width that they personally find to be the most readable, without changing the code. Tabs vs Spaces for indentation is something of a Holy War, though, so I wouldn't recommend getting into an argument about it :) If you're working with other people, the important thing is to be consistent with whichever coding standards are in place. – phils Jul 07 '18 at 22:41
  • @gyro91: Do yourself a favour and add the line `(setq-default indent-tabs-mode nil)` to your ~/.emacs (or ~.emacs.d/init.el) file. In the long run you'll be happier. – varro Jul 07 '18 at 23:43
  • @phils: You must have not encountered environments in which different people edit the same code (probably at different times). I have, the result of different people having different ideas of what a tab should be results in chaotically indented code. I know, because I've encountered this. I speak from the perspective of having over 30 years in professional software development. – varro Jul 07 '18 at 23:51
  • @varro: I've plenty of experience of collaborating on software development, and I've seen similar problems, but "only use spaces" doesn't solve everything. For starters you need everyone to use the same offset value as well (no use having one person indenting by 4 spaces and another person by 8 spaces); but this is really just a single factor amongst many -- most projects have a whole host of other coding standards to follow, and configuring an editor for a given project is not a matter of disabling `indent-tabs-mode` and being done. The solution is not "spaces" but "adhering to a standard". – phils Jul 08 '18 at 04:11
  • I think that as you both said "adhering to a standard" is the best solution. Using spaces could be the best solution in an environment where there is no standard. If unfortunately, someone ends up in a situation like this, using spaces could be the best solution (after running away) in order to avoid misunderstanding. – gyro91 Jul 08 '18 at 08:34
  • When I'm indenting with tabs, I like the smart-tabs package (https://www.emacswiki.org/emacs/SmartTabs); smart-tabs usually prevents this problem. – jpkotta Jul 08 '18 at 19:57
2

Note sure it is the right direction, however you can check if tabs are the origin of the problem. The command:

C-u M-x untabify

transforms all tabs into spaces.

I would suggest to try:

  1. apply this untabify command to your code buffer,
  2. save it,
  3. open the file with the other text editor,

if you get now the correct indentation, we have identified to origin of the problem: the tabs.

A possible fix is to systematically use spaces instead tabs. You can have a look at: How to force spaces instead of tabs regardless of major mode?

Picaud Vincent
  • 10,518
  • 5
  • 31
  • 70
  • I tried but it didn't work. However, I would like to indent with a tab in order have a better flexibility for visualization. – gyro91 Jul 07 '18 at 11:11
  • ok, thanks for the feedback. Sorry this was not the right direction. – Picaud Vincent Jul 07 '18 at 11:31
  • 1
    It's hard to imagine that this (mixing tabs and spaces) isn't the problem. `M-x untabify` acts on the marked region, though, which is surely why that didn't work out. You can either use `C-x h M-x untabify` or `C-u M-x untabify` to untabify the entire buffer. – phils Jul 07 '18 at 12:18
  • @phils thanks for this remark, I have included it to my answer – Picaud Vincent Jul 07 '18 at 12:25
  • My mistake! I tried again and indeed your suggestion worked. – gyro91 Jul 07 '18 at 14:58