Я пытаюсь добиться следующего отступа в Emacs:
class A
{
// I ALWAYS use access labels in classes
public: // access-label
int member; // inclass
};
struct B
{
// I NEVER use access labels in structs
int member; // inclass
};
Однако со следующим файлом конфигурации …
(defun my-cpp-mode ()
"My C++ mode"(c++-mode)
(c-set-style "K&R")
(setq c-basic-offset 4)
(c-set-offset 'access-label '-)
(c-set-offset 'inclass '++)
;; ...
(setq mode-name "My C++")
)
(add-to-list 'auto-mode-alist '("\\.[ch]p?p?\\'" . my-cpp-mode))
… Я достигаю только:
class A
{
public: // access-label
int member; // inclass
};
struct B
{
// this indentation is too long
int member; // inclass
};
Конечно это потому что:
Любая идея, как я могу сделать отступ в классе вещи зависит от класса / структуры или от наличия меток доступа?
Новый ответ
Я столкнулся с точным требованием, которое вы упомянули в своем вопросе.
Мне пришлось настроить отступ в соответствии со стилем кодирования моего нового проекта. После небольшого исследования я достиг этого, используя Пользовательские функции линейки.
Изменить ваш my-cpp-mode
выглядеть так:
(defun my-c-lineup-inclass (langelem)
(let ((inclass (assoc 'inclass c-syntactic-context)))
(save-excursion
(goto-char (c-langelem-pos inclass))
(if (or (looking-at "struct")
(looking-at "typedef struct"))
'+
'++))))
(defun my-cpp-mode ()
"My C++ mode"(c++-mode)
(c-set-style "K&R")
(setq c-basic-offset 4)
(c-set-offset 'access-label '-)
(c-set-offset 'inclass 'my-c-lineup-inclass)
;; ...
(setq mode-name "My C++")
)
Если этот ответ приемлем, я уберу старый ответ.
Старый ответ
Исходя из того, что вы пытаетесь достичь, могу ли я предложить другой подход? Кажется, вы хотите, чтобы метка доступа была на другом уровне отступа, чем класс и члены класса. Используйте следующее, чтобы достичь этого.
(access-label . /)
Из документации Emacs:
Если OFFSET является одним из символов
+',
-»,++',
-»,*', or
/»
затем положительный или отрицательный кратный `c-basic-offset ‘добавляется к
отступ в основании; 1, -1, 2, -2, 0,5 и -0,5 соответственно.
Вот фрагмент из одного из определенных мной стилей.
(c-add-style
"xyz-style"'((indent-tabs-mode . nil)
(fill-column . 75)
(c-basic-offset . 4)
(c-offsets-alist . (
(access-label . /)
(inextern-lang . 0)
(innamespace . 0)
(member-init-intro . ++)
))))
С c-basic-offset
установить на 4, (access-label . /)
добавляет отрицательный отступ в 2 пробела к меткам доступа. Вот фактический результат моего режима отступа на вашем примере кода.
class A
{
// I ALWAYS use access labels in classes
public: // access-label
int member; // inclass
};
struct B
{
// I NEVER use access labels in structs
int member; // inclass
};
Я рекомендую этот режим, потому что уровень отступа переменных-членов / членов структуры является согласованным. FWIW, Google C Style следует тому же подходу.
Насколько я могу судить, нельзя различать члена класса или члена структуры (inclass
элемент синтаксиса). Ты можешь использовать M-x c-syntactic-information-on-region
провести синтаксический анализ региона. Один такой анализ на вашем примере дает следующее. Исходя из результатов, нечего различать, если вы находитесь в классе или структуре.
class A // ((topmost-intro 1))
{ // ((class-open 1))
// ((inclass 64) (topmost-intro 64) (comment-intro))I ALWAYS use access labels in classes
// ((inclass 64) (topmost-intro 64))
public: // ((inclass 64) (access-label 64))access-label
int member; // ((inclass 64) (topmost-intro 64))inclass
}; // ((class-close 1))
// ((topmost-intro 503))
struct B // ((topmost-intro 503))
{ // ((class-open 629))
// ((inclass 694) (topmost-intro 694) (comment-intro))I NEVER use access labels in structs
// ((inclass 694) (topmost-intro 694))
int member; // ((inclass 694) (topmost-intro 694))inclass
}; // ((class-close 629))
Основываясь на ответе Правина Кумара выше, я реализовал немного другую версию пользовательской функции:
(defun my-c-lineup-inclass (langelem)
(let ((inclass (assoc 'inclass c-syntactic-context)))
(save-excursion
(c-beginning-of-defun) ; This sees the correct string.
(if (or (looking-at "struct")
(looking-at "typedef struct"))
'+
'++))))
; In particular, the following offsets need to be specified:
(c-set-offset 'access-label '-)
(c-set-offset 'inclass 'my-c-lineup-inclass)
; ...
Исходный код не работал в случае, если скобка была на следующей строке, т.е.
struct foo
{
int bar;
};
все равно отступ++
».
Отказ от ответственности: я не знаю Лисп. Я просто играл, и это работает для меня. Я не знаю, например, есть ли какие-либо проблемы с производительностью, связанные с этим.
Стандарты кодирования в моем проекте теперь требуют такого отступа. Как и Аркадий, я предпочитаю решение, которое учитывает метки доступа. Вот что я придумал:
(defun indent-after-access-label (langelem)
"Return the appropriate indent for a class or a struct."(save-excursion
(save-match-data
;; Optimization to avoid at least a few calls to re-search-backward.
(if (assoc 'access-label c-syntactic-context)
'++
(if (re-search-backward "\\(?:p\\(?:ublic\\|r\\(?:otected\\|ivate\\)\\)\\)" c-langelem-pos langelem) t)
'++
'+)))))
Как упоминалось ранее, indent-after-acess-label
Символ должен быть установлен в качестве отступа для inclass
(с помощью c-set-offset
или же c-offset-alist
, так далее.).
Это вряд ли идеально, из-за re-search-backward
, но это работает.