Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transform path to namespace in a VS Code Snippet

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?

like image 345
seesharper Avatar asked Apr 20 '26 23:04

seesharper


1 Answers

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.]

like image 156
Mark Avatar answered Apr 23 '26 16:04

Mark



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!