Question

I've recently been creating quite a few Sublime Text 3 plugins/snippets/etc. to automate repetitive tasks. The current one I am stuck on uses regex in a snippet to get my default skeleton for a new function.

Ideally, I would like the snippet would generate something similar to:

// Multiple Args (one arg would obviously look like (..." + "a: " + a + ")");)
function Foo(a, b, c)
{
    Log.AppendFolder("Foo(" + "a: " + a + ", b: " + b + ", c: " + c + ")");
        //body
    Log.PopLogFolder();
}
// Zero Args
function Foo()
{
    Log.AppendFolder("Foo()");
        //body
    Log.PopLogFolder();
}    

So far, I can get it formatted with 1 argument or many arguments, not all possible combos (zero, one, many).

The outline is current this, I just need to figure out the second ${2} with regex:

<snippet>
<content><![CDATA[
function ${1:function_name}(${2:arguments})
{
    Log.AppendFolder("$1(" + ${2/(?#stuck here)//} + ")");
        ${3://body}
    Log.PopLogFolder();
}$0]]></content>
    <tabTrigger>fun</tabTrigger>
    <scope>source.js</scope>
    <description>Function Template</description>
</snippet>

One Arg:

"$1(" + ${2/^([A-z0-9_-]*),?.*/"\1\: " + \1 + /}");"

Many Args (with 1 arg, this shows "a: " + a + a):

"$1(" + ${2/^([A-z0-9_-]*),?(.*)/"\1\: " + \1 + /}${2/([A-z0-9_-]*)(?:, *([A-z0-9_-]*))/"$2\: " + $2 + /g}");"

One method worked by had an extra + "" + in there, which I'd like to avoid:

${2/([A-z_0-9]+)((?:, ?)?)/"\1\: " + \1 + "\2" + /g}

I've tried a conditional look-ahead based on commas, but that gets messed up >1 arg, probably due to my lack of understanding of them:

${2/(?(?!,)^([A-z0-9_-]*)$|([A-z0-9_-]*), *)/"\1\: " + \1/g}

I could easily do this via a normal plugin (this is easy programmatically), but ideally this can remain a snippet/code-completion since I can just override the JS "fun" code-completion.

What am I missing to accomplish this (or is it simply the wrong avenue - if that's the case, I'd still like to know to learn more about regex)?

Was it helpful?

Solution

Finally figured this out, there is a conditional replacement option:

?n:then:else

So the final format looks like:

<snippet>
    <content><![CDATA[
function ${1:function_name}(${2:args})
{
    Log.AppendFolder("$1(${2/.+/" + /}${2/([A-z_0-9-]+) *(,)? */"$1\: " + $1 ?2: + "$2 " + :+ /g}${2/.+/"/})");
       ${3:// body...}
    Log.PopLogFolder();
}$0]]></content>
    <tabTrigger>fun</tabTrigger>
    <scope>source.js</scope>
    <description>Function</description>
</snippet>

Which will give the desired result:

function function_name()
{
    Log.AppendFolder("function_name()");
       // body...
    Log.PopLogFolder();
}

function function_name(a)
{
    Log.AppendFolder("function_name(" + "a: " + a + ")");
       // body...
    Log.PopLogFolder();
}

function function_name(a, b)
{
    Log.AppendFolder("function_name(" + "a: " + a  + ", " + "b: " + b + ")");
       // body...
    Log.PopLogFolder();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top