emacs:类和结构的不同缩进

Aur*_*ien 10 c++ emacs indentation

我正在尝试在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
};
Run Code Online (Sandbox Code Playgroud)

但是使用以下配置文件...

(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))
Run Code Online (Sandbox Code Playgroud)

......我只做到了:

class A
{
    public: // access-label
        int member; // inclass
};

struct B
{
        // this indentation is too long
        int member; // inclass
};
Run Code Online (Sandbox Code Playgroud)

当然那是因为:

  • 对于缩进,"class"和"struct"之间显然没有区别(它都是"inclass"),
  • "inclass"内容的缩进不依赖于访问标签的存在.

任何想法我如何使inclass东西的缩进依赖于类/结构或访问标签的存在?

Pra*_*mar 8

新答案

我遇到了你在问题中提到的确切要求.我必须根据我的新项目的编码风格设置缩进.经过一些研究,我使用Custom Line-up Functions实现了这一目标.

修改你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++")
)
Run Code Online (Sandbox Code Playgroud)

如果这个答案是可以接受的,我会继续删除旧答案.

老答案

根据您想要实现的目标,我可以建议采用不同的方法吗?您似乎希望访问标签处于与类和类成员不同的缩进级别.使用以下方法来实现这一目标.

(access-label . /)
Run Code Online (Sandbox Code Playgroud)

从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 . ++)
                       ))))
Run Code Online (Sandbox Code Playgroud)

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
};
Run Code Online (Sandbox Code Playgroud)

我推荐这种模式,因为成员变量/ struct成员的缩进级别是一致的.FWIW,Google C Style遵循相同的方法.

据我所知,无法区分类成员或结构成员(inclasssytax元素).您可以使用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))
Run Code Online (Sandbox Code Playgroud)