Omni Align
C/C++ 宏定义与注释对齐工具,VSCode 扩展。
一键将散乱的 #define 宏排列成整齐的列结构——名称、值、注释各居其列,位域组合 A | B | C 中的运算符垂直对齐。专为嵌入式 SDK 头文件场景设计。
效果演示
简单三列对齐
选中一段宏定义,按 Ctrl+=:
对齐前
#define DDL_GPIO_MODE_ANALOG (0x00000000U) /*!< Select analog mode */
#define DDL_GPIO_MODE_INPUT GPIO_MDR_MD0_0 /*!< Select input mode */
#define DDL_GPIO_MODE_OUTPUT GPIO_MDR_MD0_1 /*!< Select output mode */
#define DDL_GPIO_MODE_ALTERNATE GPIO_MDR_MD0 /*!< Select alternate function mode */
对齐后
#define DDL_GPIO_MODE_ANALOG (0x00000000U) /*!< Select analog mode */
#define DDL_GPIO_MODE_INPUT GPIO_MDR_MD0_0 /*!< Select input mode */
#define DDL_GPIO_MODE_OUTPUT GPIO_MDR_MD0_1 /*!< Select output mode */
#define DDL_GPIO_MODE_ALTERNATE GPIO_MDR_MD0 /*!< Select alternate function mode */
多列位域对齐
当组内多个宏的值含 | 运算符时,自动识别位域组合模式,将每个 | 分隔的子表达式作为独立列对齐:
对齐前
#define DDL_ADC_REG_SEQ_SCAN_DISABLE (0x00000000UL) /*!< disable */
#define DDL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS ( ADC_SQ1_LT3_0) /*!< 2 ranks */
#define DDL_ADC_REG_SEQ_SCAN_ENABLE_8RANKS (ADC_SQ1_LT3_2 | ADC_SQ1_LT3_1 | ADC_SQ1_LT3_0) /*!< 8 ranks */
#define DDL_ADC_REG_SEQ_SCAN_ENABLE_9RANKS (ADC_SQ1_LT3_3 ) /*!< 9 ranks */
#define DDL_ADC_REG_SEQ_SCAN_ENABLE_10RANKS (ADC_SQ1_LT3_3 | ADC_SQ1_LT3_0) /*!< 10 ranks */
对齐后
#define DDL_ADC_REG_SEQ_SCAN_DISABLE (0x00000000UL) /*!< disable */
#define DDL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS ( ADC_SQ1_LT3_0) /*!< 2 ranks */
#define DDL_ADC_REG_SEQ_SCAN_ENABLE_8RANKS (ADC_SQ1_LT3_2 | ADC_SQ1_LT3_1 | ADC_SQ1_LT3_0) /*!< 8 ranks */
#define DDL_ADC_REG_SEQ_SCAN_ENABLE_9RANKS (ADC_SQ1_LT3_3 ) /*!< 9 ranks */
#define DDL_ADC_REG_SEQ_SCAN_ENABLE_10RANKS (ADC_SQ1_LT3_3 | ADC_SQ1_LT3_0) /*!< 10 ranks */
| 运算符和各子项在垂直方向上对齐,右括号 ) 也落在同一列。
跨组统一对齐
选中多组用空行分隔的宏块时,所有组的宏名统一对齐到最长的那个:
#define DDL_ADC_VREF_SEL_AVDD (0x00000000UL)
#define DDL_ADC_VREF_SEL_GPIO_INPUT (ADC_CR_VREFSEL)
#define DDL_ADC_VREFBUF_OUTPUT_SEL_2_0 ADC_CR_VREFBUF_VOUT_SEL_0
#define DDL_ADC_VREFBUF_OUTPUT_SEL_3_0 (ADC_CR_VREFBUF_VOUT_SEL_1 | ADC_CR_VREFBUF_VOUT_SEL_0)
#define DDL_ADC_VREFBUF_OUTPUT_SEL_3_5 ADC_CR_VREFBUF_VOUT_SEL_2
#define DDL_ADC_MODE_STANDARD_NORMAL (0x0UL)
#define DDL_ADC_MODE_ULTRA_LOW_NORMAL (ADC_CR_MODESEL_1 | ADC_CR_MODESEL_0)
三组宏的名列全部对齐到 DDL_ADC_VREFBUF_OUTPUT_SEL_3_5(33 字符)的宽度,组间空行保留。
快捷键
| 快捷键 |
Windows/Linux |
macOS |
功能 |
| 对齐选中区域 |
Ctrl+= |
Cmd+= |
选中一段宏后对齐;无选中时对齐光标所在组 |
| 对齐当前宏块 |
Ctrl+Shift+= |
Cmd+Shift+= |
对齐光标所在的连续宏块 |
| 对齐整个文件 |
Ctrl+Alt+= |
Cmd+Alt+= |
按组分别对齐文件中所有宏 |
快捷键仅在 C/C++ 文件中生效,不影响其他文件类型的缩放操作。也可通过右键菜单使用。
配置项
在 VSCode 设置中搜索 omniAlign 即可配置:
| 配置项 |
类型 |
默认值 |
说明 |
omniAlign.columnGap |
integer |
2 |
列与列之间的最小空格数 |
omniAlign.alignComments |
boolean |
true |
是否对齐尾注释列 |
omniAlign.multiColumnValue |
boolean |
true |
启用多列位域对齐(按 \| 拆分值,每段独立成列) |
omniAlign.commentStyle |
enum |
"auto" |
尾注释样式:auto//*!<//*/// |
omniAlign.languages |
array |
["c", "cpp"] |
生效的语言 ID |
omniAlign.groupByBlankLine |
boolean |
true |
空行作为组分隔;关闭后整段连续宏视为一组 |
omniAlign.onSave |
boolean |
false |
保存文件时自动对齐 |
omniAlign.maxColumnWidth |
integer |
120 |
单列最大宽度(字符),超出则不强对齐 |
omniAlign.unifyMultiGroup |
boolean |
true |
选中多组时跨组统一对齐宏名列 |
对齐规则
分组
连续的 #define 行构成一个"宏块"。空行、普通代码行、纯注释行会断开当前组。groupByBlankLine 设为 false 时,纯注释行不打断分组(适用于 Doxygen 段内说明紧贴宏的情况)。
列宽计算
- 名称列:取组内最长宏名的宽度 +
columnGap
- 值列:取组内最长值的宽度 +
columnGap(无注释时不填充,避免尾随空格)
- 注释列:取组内最长注释的宽度
跨组统一对齐时,名称列取所有组中最长的宏名,值列和注释列仍按各自组内计算。
多列位域模式
当组内至少 2 个带值宏含顶层 |,且组内有尾注释时,启用多列模式:
- 按
| 拆分值,每个子表达式作为独立列
- 单 token 行通过映射放入对应槽位(如
ADC_SQ1_LT3_0 落到最右槽)
| 运算符和 ) 在垂直方向对齐
无注释的组不启用多列模式,改用简单左对齐,避免产生前导空格。
尾随空格
无注释的行不会产生尾随空格。无注释的组不会填充值列宽度。
安装
从 VSIX 安装
code --install-extension omni-align-0.1.1.vsix
或直接在 VSCode 扩展面板中选择"从 VSIX 安装"。
从源码构建
git clone <repo-url>
cd omni-align
npm install
npm run compile
按 F5 启动扩展开发宿主进行调试。
项目结构
src/
aligner/
parser.ts # #define 行解析器
grouper.ts # 宏块分组逻辑
aligner.ts # 对齐主算法(三列 + 多列 + 跨组统一)
valueSplitter.ts # 多列位域拆分与渲染
config.ts # 配置读取
commands.ts # 命令实现
extension.ts # 插件入口
test/
fixtures.ts # 测试数据(取自真实 SDK)
runTest.ts # 测试运行器
开发
npm run compile # 编译
npm run watch # 监听模式
npm test # 运行测试
npx @vscode/vsce package # 打包 VSIX
许可证
MIT