clang-format 中有很多 AlignXxx,可自行查看官网说明

1. 声明

AlignConsecutiveDeclarations,垂直对齐连续的声明。支持两种写法:简洁枚举形式、嵌套对象形式

# 写法一:枚举形式(快捷)
AlignConsecutiveDeclarations: None                            # 不对齐
AlignConsecutiveDeclarations: Consecutive                     # 只对相邻且无空行/注释隔离的声明对齐
AlignConsecutiveDeclarations: AcrossEmptyLines                # 允许跨空行对齐
AlignConsecutiveDeclarations: AcrossComments                  # 允许跨注释对齐
AlignConsecutiveDeclarations: AcrossEmptyLinesAndComments     # 既跨空行又跨注释对齐

# 写法二:嵌套对象形式(更灵活)
AlignConsecutiveDeclarations:
  Enabled: true|false                        # 是否启用(等同于枚举中的 None / 非 None)
  AcrossEmptyLines: true|false               # 是否在遇到空行时继续对齐
  AcrossComments: true|false                 # 是否在遇到注释时继续对齐
  AlignFunctionDeclarations: true|false      # 是否对函数声明(返回类型/名字)进行对齐
  AlignFunctionPointers: true|false          # 是否对函数指针声明(例如 int (*f)())进行对齐
  • 未格式化
int a = 1;

int somelongname = 2;
/* a comment */
double c = 3;

unsigned int f1(void);
void f2(void);
size_t f3(void);

unsigned i;
int &r;
int *p;
int (*f)();
  • 格式化(使能所有选项)
int          a = 1;

int          somelongname = 2;
/* a comment */
double       c = 3;

unsigned int f1(void);
void         f2(void);
size_t       f3(void);

unsigned     i;
int         &r;
int         *p;
int          (*f)();

2. 赋值

AlignConsecutiveAssignments,对 “连续的赋值语句” 做列对齐(把=或赋值运算符对齐到同一列)

支持两种写法:简洁枚举形式、嵌套对象形式

# 写法一:枚举形式(快捷)
AlignConsecutiveAssignments: None                            # 不对齐
AlignConsecutiveAssignments: Consecutive                     # 只对相邻且无空行/注释隔离的声明对齐
AlignConsecutiveAssignments: AcrossEmptyLines                # 允许跨空行对齐    
AlignConsecutiveAssignments: AcrossComments                  # 允许跨注释对齐
AlignConsecutiveAssignments: AcrossEmptyLinesAndComments     # 既跨空行又跨注释对齐

# 写法二:嵌套对象形式(更灵活)
AlignConsecutiveAssignments:
  Enabled: true|false              # 开启/关闭对齐
  AcrossEmptyLines: true|false     # 是否跨空行也继续对齐
  AcrossComments: true|false       # 是否跨注释行也对齐
  AlignCompound: true|false        # 是否包括复合赋值(+=, &=, >>= 等)
  PadOperators: true|false         # 是否左侧填充短赋值运算符以对齐(见示例)
  • 未格式化
int main() {
  int a = 1;
  float somelongname = 2;
  int x = 3;
  int y = 4;

  a &= 2;
  somelongname = 2;
  x >>= 2;
  y = 2;

  // 注释会中断对齐
  int d = 4;
  /* comment */
  int e = 5;
}
  • 格式化(使能所有选项,并且上一步的声明对齐都使能了)
int main() {
  int   a              = 1;
  float somelongname   = 2;
  int   x              = 3;
  int   y              = 4;

  a                   &= 2;
  somelongname         = 2;
  x                  >>= 2;
  y                    = 2;

  // 注释不会中断对齐
  int d                = 4;
  /* comment */
  int e                = 5;
}

3. 宏定义

AlignConsecutiveMacros,对连续的 #define 宏定义做列对齐

支持两种写法:简洁枚举形式、嵌套对象形式

# 写法一:枚举形式(快捷)
AlignConsecutiveMacros: None                            # 不对齐
AlignConsecutiveMacros: Consecutive                     # 只对相邻且无空行/注释隔离的声明对齐
AlignConsecutiveMacros: AcrossEmptyLines                # 允许跨空行对齐    
AlignConsecutiveMacros: AcrossComments                  # 允许跨注释对齐
AlignConsecutiveMacros: AcrossEmptyLinesAndComments     # 既跨空行又跨注释对齐

# 写法二:嵌套对象形式(更灵活)
AlignConsecutiveMacros:
  Enabled: true|false              # 开启/关闭对齐
  AcrossEmptyLines: true|false     # 是否跨空行也继续对齐
  AcrossComments: true|false       # 是否跨注释行也对齐
  • 未格式化
#define SHORT_NAME 42
#define LONGER_NAME 0x007f
#define EVEN_LONGER_NAME (2)
#define foo(x) (x * x)
#define bar(y, z) (y + z)

#define A 1

/* comment */
#define AFTER_COMMENT 100

#define ALONE 5
  • 格式化(使能所有选项)
#define SHORT_NAME       42
#define LONGER_NAME      0x007f
#define EVEN_LONGER_NAME (2)
#define foo(x)           (x * x)
#define bar(y, z)        (y + z)

#define A                1

/* comment */
#define AFTER_COMMENT    100

#define ALONE            5

4. 单行注释

AlignTrailingComments,尾随注释(行尾 ///* ... */)的对齐方式

支持两种写法:传统方式、嵌套对象形式

# 写法一:传统方式(不推荐)
AlignTrailingComments: true|false    # 开启/关闭对齐

# 写法二:嵌套对象形式(更灵活)
AlignTrailingComments:
  # Leave:保持原样,不强制对齐(保留输入的注释位置) 
  # Always:始终对齐(把行末注释对齐到同一列) 
  # Never:不要对齐,但其它 formatter 仍可能调整注释
  Kind: Leave | Always | Never
  OverEmptyLines: <unsigned>      # 在对齐时跨过多少个空行仍继续对齐(整数)
  • 未格式化
int a = 1; // small
int abc = 2; // longer name

#define FOO 1 // macro comment

int x = 3; // trailing
// blank line breaks group

int y = 4; // next group
  • 格式化(kind=Always OverEmptyLines=1 )
int a   = 1;   // small
int abc = 2;   // longer name

#define FOO 1  // macro comment

int x = 3;     // trailing
// blank line breaks group

int y = 4;  // next group

5. 指针和引用

用来控制指针的 * 和引用的 &,如何对齐。

# Left:把 * / & 贴紧类型(例:int* a;)
# Right:把 * / & 贴近变量名(例:int *a;)
# Middle:将 * / & 独立为中间 token,两侧留空格(例:int * a;)
PointerAlignment: Left|Right|Middle

# true: clang-format 会扫描文件,依据文件里最常见的指针/引用对齐风格自动调整
# false: 使用 .clang-format 中明确指定的 PointerAlignment
DerivePointerAlignment: true|false

# 控制引用 & 的对齐方式;
# Pointer 表示按 PointerAlignment 的规则对齐引用
# Left/Right/Middle: 单独指定引用的表现
ReferenceAlignment: Pointer|Left|Right|Middle

# 控制在包含指针限定符(如 const)的情形是否在限定符前/后留空格。
# Default 表示不强制改变(以 PointerAlignment 规则为主)
# Before/After/Both: 可强制加空格,影响可读性样式,例如 void * const * x vs void *const *x
SpaceAroundPointerQualifiers: Default|Before|After|Both
  • 效果一
// PointerAlignment=Right 
// DerivePointerAlignment=false 
// ReferenceAlignment=Pointer
// SpaceAroundPointerQualifiers=Default

int       *a;
int       *b;
int       *c;
int *const p1;
int *const p2;
int       &r1;
int       &r2;
int       &r3;
  • 效果二
// PointerAlignment=Left
// DerivePointerAlignment=false 
// ReferenceAlignment=Pointer
// SpaceAroundPointerQualifiers=Default

int*       a;
int*       b;
int*       c;
int* const p1;
int* const p2;
int&       r1;
int&       r2;
int&       r3;

6. AlignAfterOpenBracket

控制当括号/尖括号/方括号内的内容被折行时,后续行是否水平对齐到第一个元素

  • 效果一
// AlignAfterOpenBracket: false

#include <tuple>

// 3) 尖括号(模板参数)演示
using MyTuple = std::tuple<int, long,
    double, char>;

void someLongFunction (int a, int b, int c, int d) {}

int main () {
    // 1) 圆括号(函数调用)演示
    int arg1 = 1, arg2 = 2, arg3 = 3, arg4 = 4;
    someLongFunction(arg1, arg2,
        arg3, arg4);

    // 2) 方括号(索引表达式)演示
    int arr[] = {1, 2,
        3, 4, 5};

    MyTuple t{1, 2, 3.0, 'a'};

    return 0;
}
  • 效果二
// AlignAfterOpenBracket: true

#include <tuple>

// 3) 尖括号(模板参数)演示
using MyTuple = std::tuple<int, long,
                           double, char>;

void someLongFunction (int a, int b, int c, int d) {}

int main () {
    // 1) 圆括号(函数调用)演示
    int arg1 = 1, arg2 = 2, arg3 = 3, arg4 = 4;
    someLongFunction(arg1, arg2,
                     arg3, arg4);    // 格式化时 AlignAfterOpenBracket 决定第二行起始列

    // 2) 方括号(索引表达式)演示
    int arr[] = {1, 2,
                 3, 4, 5};

    MyTuple t{1, 2, 3.0, 'a'};

    return 0;
}

7. AlignConsecutiveShortCaseStatements

垂直对齐连续的声明。支持两种写法:简洁枚举形式、嵌套对象形式

AlignConsecutiveShortCaseStatements:
  Enabled: true|false                        # 是否启用对齐行为(true/false)
  AcrossEmptyLines: true|false               # 是否跨空行对齐(true:跨空行也对齐;false:空行会中断对齐块)
  AcrossComments: true|false                 # 是否跨注释行对齐(true:注释不会中断对齐;false:注释中断对齐)
  AlignCaseColons: true|false                # 控制对齐是以 : 为对齐锚点,还是以 : 后的 token 对齐
  • 效果一
// AlignConsecutiveShortCaseStatements: 
//  Enabled: false
//  AcrossEmptyLines: true
//  AcrossComments: true
//  AlignCaseColons: true
  
#include <iostream>
#include <string>

const char* level_name (int level) {
    switch ( level ) {
        case 1: return "debug";
        case 10: return "info";

        case 100: return "warning";
        // more levels could be here
        default: return "unknown";
    }
}

int main () {
    std::cout << level_name(100) << std::endl;
    return 0;
}
  • 效果二
// AlignConsecutiveShortCaseStatements: 
//  Enabled: true
//  AcrossEmptyLines: true
//  AcrossComments: true
//  AlignCaseColons: true

#include <iostream>
#include <string>

const char* level_name (int level) {
    switch ( level ) {
        case 1  : return "debug";
        case 10 : return "info";

        case 100: return "warning";
        // more levels could be here
        default : return "unknown";
    }
}

int main () {
    std::cout << level_name(100) << std::endl;
    return 0;
}
  • 效果三
// AlignConsecutiveShortCaseStatements: 
//  Enabled: true
//  AcrossEmptyLines: true
//  AcrossComments: true
//  AlignCaseColons: false

#include <iostream>
#include <string>

const char* level_name (int level) {
    switch ( level ) {
        case 1:   return "debug";
        case 10:  return "info";

        case 100: return "warning";
        // more levels could be here
        default:  return "unknown";
    }
}

int main () {
    std::cout << level_name(100) << std::endl;
    return 0;
}