I tried to create a snippet in VSCode to quickly include C++ header guards. For example with a file path is C:\workspace\src\chrome\browser\ui\webui\settings\about_handler.h
The snippet is expected to generate like this:
#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_
From VScode snippet syntax guide, I tried to use TM_FILEPATH variable but cannot find a solution to transform the filepath into the macros above. I tried some way below:
${TM_FILEPATH/([^a-zA-Z0-9])|([a-zA-Z0-9])/${1:+_}${2:/upcase}/g}_ I can generate the filepath into C__WORKSPACE_SRC_CHROME_BROWSER_UI_WEBUI_SETTINGS_ABOUT_HANDLER_H_. This regex will convert all non-digit and non-alphabetic characters to _ and change all alphabetic characters to upper case.${TM_FILEPATH/.*src[\\\\\\/](.*)/${1:/upcase}/} I can generate into CHROME\BROWSER\UI\WEBUI\SETTINGS\ABOUT_HANDLER.H. This regex remove the path from begining to src since my current workspace is in src folder so I want my header macro to be related to that.The problem is I cannot combine these two transform to get the macro I want. Is there any ideas to make it works?
You can use
"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}"
]
}
The command is
${TM_FILEPATH/(?:^.*\\\\src\\\\)?(\\w+)(?!\\w*$)|(\\W)|(\\w+)$/${1:/upcase}${2:+_}${3:/upcase}${3:+_}/g}"
See the regex demo.
Details
(?:^.*\\src\\)?(\w+)(?!\w*$) - an optional occurrence of any zero or more chars other than line break chars as many as possible from the start of string (^.*), up to the \src\ substring (\\src\\), then one or more word chars captured into Group 1 ((\w+)), that are not followed with end of string ((?!\w*$))| - or(\W) - Group 2: any non-word char| - or(\w+)$ - Group 3: one or more word chars at the end of string.The replacement means:
${1:/upcase} - inserts Group 1 value turned to uppercase${2:+_} - if Group 2 was matched, insert a _${3:/upcase} - inserts Group 3 value in upper case${3:+_} - if Group 3 matched, inserts a _.Try this:
"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}"
]
}

The trick is to get everything you are interested in, the text between the path separators and the final ., into one capture group if you can. That is pretty easy in your case using a non-capturing group and a final bit that isn't captured:
(?:^.*\\\\src\\\\)?(\\w+)\\W?
But you do want all that matched so that vscode's snippet engine will replace it. In this case, the replacement is dead simple:
${1:/upcase}_
Every full match, like chrome\ will be replaced by capture group 1, e.g., chrome, capitalized and an underscore.
Since you actually want an underscore at the end that makes it easy too - you don't need any conditional logic to determine whether there is a capture group at the very end that shouldn't be followed by an underscore.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With