为 C++ header 守卫实施 VSCode 片段

Implement VSCode snippet for C++ header guard

我试图在 VSCode 中创建一个片段以快速包含 C++ header 守卫。例如,文件路径为 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_

VScode snippet syntax guide 开始,我尝试使用 TM_FILEPATH 变量但找不到将文件路径转换为上述宏的解决方案。我在下面尝试了一些方法:

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

你可以使用

"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}"
        ]
      }

命令是

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

参见 regex demo.

详情

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

替换的意思是:

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

试试这个:

"cppHeaderGuard": {
  "prefix": "g1",
  "body": [
    "#ifndef ${TM_FILEPATH/(?:^.*\\src\\)?(\w+)\W?/${1:/upcase}_/g}",
    "#define ${TM_FILEPATH/(?:^.*\\src\\)?(\w+)\W?/${1:/upcase}_/g}",
    "",
    "#endif // ${TM_FILEPATH/(?:^.*\\src\\)?(\w+)\W?/${1:/upcase}_/g}"
  ]
}

诀窍是尽可能将您感兴趣的所有内容(路径分隔符和最后的 . 之间的文本)放入一个捕获组中。在您的情况下,使用非捕获组和未捕获的最后一位非常容易:

(?:^.*\\src\\)?(\w+)\W?

但您确实需要所有 匹配的 以便 vscode 的代码段引擎将替换它。在这种情况下,替换非常简单:

${1:/upcase}_

每个完整匹配项,如 chrome\ 将被替换为捕获组 1,例如 chrome,大写和下划线。

由于您实际上想要在末尾添加下划线,这也使它变得简单 - 您不需要任何条件逻辑来确定最后是否存在不应跟随下划线的捕获组。