Search code examples
phpregexvisual-studio-coderegex-groupvscode-snippets

How can I create a VSCode snippet to automatically insert namespace of files inside my src folder?


First off, I have the following psr-4 declaration for the src folder inside my composer.json file:

"autoload": {
        "psr-4": {
            "Src\\": "src/"
        }
    },

I would like to build a VSCode snippet that autogenerates the namespace of a new file that resides inside the src folder.

So far I have this inside php.json:

    "Namespace Src": {
        "prefix": "ns_src",
        "body": [
            "namespace ${RELATIVE_FILEPATH};",
        ],
        "description": "Namespace for file routes inside the src folder"
    },

Taking as an example the following file:

src/MyEntity/Application/MyUseCase.php

The desired result would be:

namespace Src\MyEntity\Application;

And right now this is what it returns to me:

namespace src/MyEntity/Application/MyUseCase.php;

So I need to tackle:

  • Upper case of src.
  • Replacement of forward slashes / into back slashes \.
  • Removal of everything that is after the last forward slash /.

I know there has to be a way to do this with regex. I have read this similar problem (VSCODE snippet PHP to fill namespace automatically) but I haven't quite got the hang of it after reading it. And I think the upper case problem could maybe be solved with \F as in here: https://www.regular-expressions.info/replacecase.html#:~:text=In%20the%20regex%20%5CU%5Cw,is%20not%20a%20word%20character.

Is this the right approach? Could you give me any tips on this problem?

Thank you so much.


Solution

  • You can use

    "Namespace Src": {
        "prefix": "ns_src",
        "body": [
            "namespace ${RELATIVE_FILEPATH/^(?:.*[\\\\\\/])?(src)(?=[\\\\\\/])|[\\\\\\/][^\\\\\\/]*$|([\\\\\\/])/${1:+Src}${2:+\\\\}/g};",
         ],
        "description": "Namespace for file routes inside the src folder"
    },
    

    See the regex demo. Details:

    • ^(?:.*[\\\/])?(src)(?=[\\\/]) - start of string (^), then an optional occurrence of any zero or more chars as many as possible (.*) and a \ or / char ([\\\/]), and then src captured into Group 1, that is immediately followed with / or \
    • | - or
    • [\\\/][^\\\/]*$ - a \ or / char and then zero or more chars other than / and \ till end of string
    • | - or
    • ([\\\/]) - Group 2: a \ or / char.

    The ${1:+Src}${2:+\\\\} replacement replaces in this way:

    • ${1:+Src} - if Group 1 matched, replace with Src
    • ${2:+\\\\} - if Group 2 matched, replace with \.