Неправильный отступ в режиме Emacs С++?

Я запускаю emacs 23 в режиме С++ и имею некоторые проблемы с отступами. Предположим, у меня есть этот код:

void foo()
{
   if (cond)
     { <---
        int i;
        ...
     } <---
}

Кажется, это поведение по умолчанию для автоматического отступа. Однако я хотел бы изменить его, чтобы он был таким:

void foo()
{
   if (cond)
   {
      int i;
      ...
   }
}

Есть ли способ сделать это легко, настроив режим С++ или мой файл .emacs?


person Idan K    schedule 19.03.2009    source источник
comment
Ознакомьтесь с ‹a href=emacswiki.org/emacs/IndentingC#toc2›Emacs вики по отступам C‹/a›   -  person crashmstr    schedule 19.03.2009
comment
Для справки, этот режим отступа является стилем GNU. Все программы GNU должны следовать этому стилю отступов.   -  person greyfade    schedule 19.03.2009
comment
да я где-то это читал, но терпеть не могу   -  person Idan K    schedule 19.03.2009
comment
Обычно рекомендуется писать код для пользователей, а не для себя. Большинство людей, не пишущих код GNU, используют другие стили.   -  person Daniel H    schedule 26.01.2012


Ответы (5)


В моем файле .emacs есть следующее:

(defun my-c++-mode-hook ()
  (setq c-basic-offset 4)
  (c-set-offset 'substatement-open 0))
(add-hook 'c++-mode-hook 'my-c++-mode-hook)

Вы можете определить, какое смещение редактировать, нажав [ctrl-c Ctrl-S] в любой строке. В первой строке с фигурной скобкой после if будет написано substatement-open.

person Alex B    schedule 19.03.2009

Это мое... это соответствует настройке по умолчанию для Visual Studio.

(defun my-c-mode-common-hook ()
 ;; my customizations for all of c-mode, c++-mode, objc-mode, java-mode
 (c-set-offset 'substatement-open 0)
 ;; other customizations can go here

 (setq c++-tab-always-indent t)
 (setq c-basic-offset 4)                  ;; Default is 2
 (setq c-indent-level 4)                  ;; Default is 2

 (setq tab-stop-list '(4 8 12 16 20 24 28 32 36 40 44 48 52 56 60))
 (setq tab-width 4)
 (setq indent-tabs-mode t)  ; use spaces only if nil
 )

(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)
person justinhj    schedule 19.03.2009
comment
Большое спасибо! Я искал это везде... Сколько себя помню. - person Nick Bolton; 13.08.2009
comment
(setq c-default-style bsd c-basic-offset 4) Выполняет многое из этого за меньшее количество строк. Хотя режимы indent-tab-modes должны оставаться. - person Jesus Ramos; 30.06.2011
comment
Я ничего не могу заставить работать - это сводит меня с ума - фигурные скобки все еще отступают внутри операторов if. - person wcochran; 03.04.2018
comment
Это странно. Когда вы находитесь в файле c, видите ли вы, что переменная c-mode-common-hook переопределена? - person justinhj; 09.04.2018

Краткий ответ: поместите эту строку в свой файл .emacs:

(c-set-offset 'substatement-open 0)

Длинный ответ: ...

Для тех из нас, кто плохо знаком с emacs-lisp, есть довольно простой метод по адресу http://www.cs.cmu.edu/cgi-bin/info2www?(efaq)Customizing%20C%20and%20C%2B%2B%20indentation:

  • Перейдите к строке, которую вы хотите сделать отступом

  • Введите C-C C-O (это буква "O", а не ноль)

  • Нажмите Ввод, чтобы принять предложение по умолчанию.

  • Введите "0" (это ноль) без дополнительных отступов, нажмите Enter

  • Нажмите Tab, чтобы изменить отступ строки.

  • Будущее "{" в этой ситуации будет иметь правильную настройку табуляции, пока вы не перезапустите emacs.

Преимущество этого метода в том, что вы действительно можете увидеть код lisp, который хотите изменить. Вы можете поместить в свой файл .emacs:

(c-set-offset 'SYNTACTIC-SYMBOL OFFSET)

Кроме того, вы можете попробовать программу AStyle для автоматического форматирования исходного кода C++ вне emacs.

person Paul    schedule 20.03.2009
comment
Это кажется наиболее удобным подходом, но есть ли способ определить стиль, включающий все ваши изменения? - person Mouse.The.Lucky.Dog; 27.04.2014
comment
Это немного поздно, но я должен сказать, что это самый аккуратный способ настроить отступ и очень простой. Мне нравится часть Длинный ответ. - person Dean Seo; 14.07.2021

Принятый ответ на самом деле неверен. Emacswiki не поможет.

Вставьте следующий код в ~/.emacs:

(defun fix-c-indent-offset-according-to-syntax-context (key val)
  ;; remove the old element
  (setq c-offsets-alist (delq (assoc key c-offsets-alist) c-offsets-alist))
  ;; new value
  (add-to-list 'c-offsets-alist (cons key val)))

(add-hook 'c-mode-common-hook
          (lambda ()
            (when (derived-mode-p 'c-mode 'c++-mode 'java-mode)
              ;; indent
              (fix-c-indent-offset-according-to-syntax-context 'substatement-open 0))
            ))

См. http://blog.binchen.org/posts/ccjava-code-indentation-in-emacs.html для технических подробностей.

Ключевая проблема заключается в том, что c-set-offset ненадежен для определения контекста синтаксиса (Emacs24.3.1). Так что единственный надежный способ — проанализировать исходный код emacs. Подробные шаги по взлому кода перечислены в моей статье, в основном вам нужно прочитать функцию c-indent-line, которая определена в /usr/share/emacs/24.3/lisp/progmodes/cc- cmds.el

Некоторые люди жаловались, что моя установка не работает. На самом деле это работает во всех стабильных версиях Emacs (23.4, 24.3, 24.4), если вы не меняете настройки по умолчанию (отступ имеет разные профили, мои настройки основаны на профиле по умолчанию).

Мой ключевой момент в том, что по этому конкретному вопросу вам нужно прочитать код.

person chen bin    schedule 26.09.2014

Перед настройкой отдельных смещений настройте предпочтительный стиль. Я использую строуструп, вы можете попробовать другие, см. http://www.emacswiki.org/emacs/IndentingC#toc1 для имен и http://en.wikipedia.org/wiki/Indent_style#Variant:_Stroustrup для примеров

M-x custom-variable c-default-style (и установите предпочтительный для C++_

person Mekk    schedule 03.02.2015