为 C++ 标头防护实现 VSCode 片段

Lon*_* Le 4 regex visual-studio-code vscode-snippets

我尝试在 VSCode 中创建一个片段以快速包含 C++ 标头防护。例如文件路径是C:\workspace\src\chrome\browser\ui\webui\settings\about_handler.h

该代码片段预计将生成如下:

#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_ABOUT_HANDLER_H_
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_ABOUT_HANDLER_H_

#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_ABOUT_HANDLER_H_
Run Code Online (Sandbox Code Playgroud)

VScode 片段语法指南中,我尝试使用TM_FILEPATH变量,但找不到将文件路径转换为上面的宏的解决方案。我尝试了以下一些方法:

  • 通过转换,${TM_FILEPATH/([^a-zA-Z0-9])|([a-zA-Z0-9])/${1:+_}${2:/upcase}/g}_我可以将文件路径生成为C__WORKSPACE_SRC_CHROME_BROWSER_UI_WEBUI_SETTINGS_ABOUT_HANDLER_H_. 此正则表达式会将所有非数字和非字母字符转换为大写_,并将所有字母字符更改为大写。
  • 通过转换${TM_FILEPATH/.*src[\\\\\\/](.*)/${1:/upcase}/}我可以生成CHROME\BROWSER\UI\WEBUI\SETTINGS\ABOUT_HANDLER.H. 这个正则表达式从头到尾删除了路径src,因为我当前的工作区位于src文件夹中,所以我希望我的标头宏与该路径相关。

问题是我无法结合这两个变换来获得我想要的宏。有什么想法可以让它发挥作用吗?

Wik*_*żew 9

您可以使用

"CppGuard": {
        "prefix": "cppgrd",
        "body": [
          "#ifndef ${TM_FILEPATH/(?:^.*\\\\src\\\\)?(\\w+)(?!\\w*$)|(\\W)|(\\w+)$/${1:/upcase}${2:+_}${3:/upcase}${3:+_}/g}",
          "#define ${TM_FILEPATH/(?:^.*\\\\src\\\\)?(\\w+)(?!\\w*$)|(\\W)|(\\w+)$/${1:/upcase}${2:+_}${3:/upcase}${3:+_}/g}",
          "\n#endif // ${TM_FILEPATH/(?:^.*\\\\src\\\\)?(\\w+)(?!\\w*$)|(\\W)|(\\w+)$/${1:/upcase}${2:+_}${3:/upcase}${3:+_}/g}"
        ]
      }
Run Code Online (Sandbox Code Playgroud)

命令是

${TM_FILEPATH/(?:^.*\\\\src\\\\)?(\\w+)(?!\\w*$)|(\\W)|(\\w+)$/${1:/upcase}${2:+_}${3:/upcase}${3:+_}/g}"
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述 请参阅正则表达式演示

细节

  • (?:^.*\\src\\)?(\w+)(?!\w*$)^.*- 从字符串 ( ) 的开头到子字符串 ( )尽可能多地出现除\src\换行符之外的任何零个或多个字符\\src\\,然后捕获到第 1 组 ( ) 中的一个或多个单词字符(\w+),这些字符不是后跟字符串结尾 ( (?!\w*$))
  • |- 或者
  • (\W)- 第 2 组:任何非单词字符
  • |- 或者
  • (\w+)$- 第 3 组:字符串末尾的一个或多个单词字符。

替换的意思是:

  • ${1:/upcase}- 插入组 1 值转为大写
  • ${2:+_}- 如果组 2 匹配,则插入_
  • ${3:/upcase} - 以大写形式插入第 3 组值
  • ${3:+_}- 如果组 3 匹配,则插入_.