I am trying to create a VS code snippet that scaffolds the namespace based on the current folder in a project.
The current path provied by the TM_DIRECTORY variable could be something like this.
/Users/bernhardrichter/GitHub/heatkeeper2000/src/HeatKeeper.Server/Mapping
What I would like to end up with is namespace HeatKeeper.Server.Mapping based upon my root source folder being src
So I need to strip away everything before and including src so that we are left with HeatKeeper.Server/Mapping. And then I need to replace(transform) the / into . so that the final result is HeatKeeper.Server.Mapping.
Is it possible to do this in a single transform? If not is it possible to have multiple transforms?
This is what I have so far
"namespace ${TM_DIRECTORY/(.*src.)(.*).*$/$2/}"
This outputs namespace HeatKeeper.Server/Mapping which is almost what I want. I just need to replace all / with .
The problem is that I don't know where to put this transform.
The transform looks like this.
"${TM_DIRECTORY/[\\/]/./g}"
which gives me
.Users.bernhardrichter.GitHub.heatkeeper2000.src.HeatKeeper.Server.Mapping
I just don't know how to combine these two?
See after the edit for a more general (not just the last two directories) answer.
Original answer:
Yes, you can do them in one snippet, you just need to separately capture the two directories after src. Try:
"namespace ${TM_DIRECTORY/.*src\\/(.*)\\/(.*)$/$1.$2/}",
Then put a period between the two capture groups. This regex assumes you always have a src directory preceding the two directories that you want. If that isn't the case, this will work capturing the last two directories:
"namespace ${TM_DIRECTORY/.*\\/(.*)\\/(.*)$/$1.$2/}",
Note that the path separators "/" must be double-escaped.
EDIT ------------------------ see below -----------------------------------------------
For the more general case of some unknown number of directories after a specific directory, try this form:
"body": "${TM_DIRECTORY/.*src\\/(([^\\/]*)(\\/)?)|(\\/)([^\\/]*)/$2${3:+.}${5:+.}$5/g}",
// here for easier testing using the clipboard
"body": "${CLIPBOARD/.*src\\/(([^\\/]*)(\\/)?)|(\\/)([^\\/]*)/$2${3:+.}${5:+.}$5/g}",
Where src appears, put the last directory you do not want. This works for 1 or more directories after src (in this case).
interestingly, it was the one folder case that was the trickiest. That was solved by the extra conditional ${3:+.} which means if there is a capture group 3, insert a ..
For the regex explanation, see reg101 demo. At that link you can see that a simpler substitution works except for the one folder case. If you don't mind just backspacing over the that last . you could use the substitution $2.$5 instead of $2${3:+.}${5:+.}$5 I used above.
Finally, note that the above were designed to work with forward slash / path separators. To modify it to use either back/forward slash separators, look at this (with USERS as the last unwanted directory):
"body": "${TM_DIRECTORY/.*Users[\\/\\\\](([^\\/\\\\]*)([\\/\\\\])?)|([\\/\\\\])([^\\/\\\\]*)/$2${3:+.}${5:+.}$5/g}",
All forward slashes \\/ get converted to the alternative forward and backslashes [\\/\\\\] where backslashes must appear as \\\\ if you want to test for a literal \. Yow.
[For the original question, just add namespace to the beginning.]
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