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!!!

Allan Andrade
  • 670
  • 10
  • 26

2 Answers2

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

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • 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! – Allan Andrade Apr 23 '21 at 11:39
  • 1
    @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. – Wiktor Stribiżew Apr 23 '21 at 11:43
  • 2
    @AllanAndrade I left out the initial ``\``, I added it just now. So, use ``"namespace \\\\${TM_DIRECTORY/(?:.*[\\/\\\\])?src[\\/\\\\]([^\\/\\\\]*)[\\/\\\\]?|[\\/\\\\]([^\\/\\\\]*)/$1\\$2/g}",`` – Wiktor Stribiżew Apr 23 '21 at 11:54
  • Wiktor, Thank you again! I updated it with you comment above! – Allan Andrade Apr 24 '21 at 02:03
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

rioV8
  • 24,506
  • 3
  • 32
  • 49