【问题标题】:Implement VSCode snippet for C++ header guard为 C++ 标头保护实现 VSCode 片段
【发布时间】:2020-12-05 10:44:57
【问题描述】:

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

sn-p 预计生成如下:

#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 变量,但找不到将文件路径转换为上述宏的解决方案。我尝试了以下方法:

  • 通过转换${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 文件夹中,所以我希望我的标题宏与之相关。

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

【问题讨论】:

  • @WiktorStribiżew 我之前已经对你的答案投了赞成票
  • 所以,它没有用,对吧?您还需要这方面的帮助吗?
  • @WiktorStribiżew 不,您的解决方案完美无缺

标签: regex visual-studio-code vscode-snippets


【解决方案1】:

你可以使用

"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 组匹配,则插入 _

【讨论】:

    【解决方案2】:

    试试这个:

    "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 的 sn-p 引擎将替换它。在这种情况下,替换非常简单:

    ${1:/upcase}_

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

    由于您实际上想要在末尾添加一个下划线,这也很容易 - 您不需要任何条件逻辑来确定最后是否有一个不应后跟下划线的捕获组。

    【讨论】:

    • 我没有故意使用(?:^.*\\src\\)?(\w+)\W? 模式(我当然也测试过)。这种模式假设没有连续的特殊字符,这对于这种输入通常是正确的,但我们仍然不能太确定。我决定让我的模式尽可能通用。
    • 啊,那么像往常一样,输入的性质,在这种情况下是文件路径,将决定需要考虑哪些特殊情况。
    猜你喜欢
    • 1970-01-01
    • 2011-06-13
    • 2020-04-30
    • 1970-01-01
    • 2013-11-13
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    • 2013-11-17
    相关资源
    最近更新 更多