3

I'm trying to create a VSCODE CODE SNIPPET for PHP that automatically put the namespace (based on folder path).

The idea is make a substitution on the directory of the current document, considering that all my class are located inside the MVC folder, and that this is located inside the src folder, examples:

  • /dev/project/src/MVC/Models/Access/Auth, or
  • /home/user/dev/project/src/MVC/Models/Access/Auth, or
  • /any_other_folder/src/MVC/Models/Access/Auth

I got the full folder name with VSCODE snippet variabe $TM_DIRECTORY.

Aparently hasn't error on REGEX, as you can see on: https://regex101.com/r/P8CpkX/1

My try of the snipped code:

"namep": {
        "prefix": [
            "namep"
        ],
        "body": [
            "",
            "// TM_DIRECTORY: $TM_DIRECTORY",

            "namespace ${TM_DIRECTORY/.*src\/(([^\/]*)(\/)?)|(\/)([^\/]*)/$2\\$5/g};"
        ],
        "scope": "php",
        "description": "Try to put namespace automatically"
    }

It results in:

// TM_DIRECTORY: /home/user/dev/project/src/MVC/Models/Access/Auth
namespace ${TM_DIRECTORY/.*src/(([^/]*)(/)?)|(/)([^/]*)/$5/g};

But the expected is (as demonstrated on REGEX):

// TM_DIRECTORY: /home/user/dev/project/src/MVC/Models/Access/Auth
namespace \MVC\Models\Access\Auth;

Could anyone helps to fix it?

Thanks a lot!!!

0

3 Answers 3

4

You can use

"namep": {
    "prefix": [
        "namep"
    ],
    "body": [
        "namespace \\\\${TM_DIRECTORY/(?:.*[\\/\\\\])?src[\\/\\\\]([^\\/\\\\]*)[\\/\\\\]?|[\\/\\\\]([^\\/\\\\]*)/$1\\$2/g}",
    ],
    "scope": "php",
    "description": "Try to put namespace automatically"
}

See the regex demo.

It matches

  • (?:.*[\/\\])? - an optional occurrence of any 0+ chars other than line break chars as many as possible and then either \ or /
  • src[\/\\] - an src string and then //\
  • ([^\/\\]*) - Group 1: any zero or more chars other than / and \
  • [\/\\]?- an optional //\ char
  • | - or
  • [\/\\] - a \ or / char
  • ([^\/\\]*) - Group 2: any zero or more chars other than / and \

Demo:

enter image description here

Sign up to request clarification or add additional context in comments.

5 Comments

Trying to understand: To "/any_other_folder/src/MVC/Models/Access/SubFolderEndssrc/Auth" the regex caputured "MVC" in group 1, and the array ["Access", "SubFolderEndssrc", "Auth"] in group 2. "Model" wasn't captured.... how this substitution works "$1\\$2", why it join group1 + 'Model' (not caputured) + group2.... and replaced '/' with '\' too? Thanks a lot!
@AllanAndrade When Group 1 does not match, $1 is empty, so the \ + Group 2 value is returned. As Models part is not matched, it is not replaced, and is kept in the resulting string.
@AllanAndrade I left out the initial \, I added it just now. So, use "namespace \\\\${TM_DIRECTORY/(?:.*[\\/\\\\])?src[\\/\\\\]([^\\/\\\\]*)[\\/\\\\]?|[\\/\\\\]([^\\/\\\\]*)/$1\\$2/g}",
Wiktor, Thank you again! I updated it with you comment above!
Magento 2 version (for classes under app/code): "namespace ${TM_DIRECTORY/(?:.*[\\/\\\\])?code[\\/\\\\]([^\\/\\\\]*)[\\/\\\\]?|[\\/\\\\]([^\\/\\\\]*)/$1\\$2/g};"
1

Using $1\$2 as replace string results in strange matches, the Models string is never matched.

An alternative is to not match an ending separator in group/alternative 1

  "namep": {
    "prefix": ["namep"],
    "body": ["namespace ${TM_DIRECTORY/.*[\\/\\\\]src[\\/\\\\]([^\\/\\\\]+)|[\\/\\\\]([^\\/\\\\]+)/\\${1}${2}/g}",],
    "scope": "php",
    "description": "Try to put namespace automatically"
  }
  • .*[/\\]src[/\\] : search for src as a directory name
  • ([^/\\]+) : Group 1: a directory name after the src directory
  • | : separating alternatives
  • [/\\] : a directory separator
  • ([^/\\]+) : Group 2: a directory name

You want each directory name in the result prepended with a \ and group 1 or group 2 is empty so we can use the replace string: \$1$2

Comments

0

I published a VS Code extension that addresses this issue without the need for regexes, even in projects with multiple namespaces.

The extension automatically determines the correct namespace by analyzing the file's path and PSR-4 definitions in the nearest composer.json file. It then populates the namespace dynamically based on the currently edited file.

You can check it out here: PHP Dynamic Snippets Extension.

I hope it helps!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.