Regex – JavaScript , match the regex for the 2nd argument of a function

I have a function with the name waitForCompletion(arg1,value,waitTime);

I want to find out a way to know that I am on the second argument of the function i.e. waitForCompletion(arg1,

Use case:- When a user starts typing the function name and is on the second argument, I have to trigger some intellisense for showing the intellisense on what values the second argument can accept.

I currently have the following, but it only matches the function name and triggers my intellisense for all the arguments but it has to only do that for the 2nd argument.

let completionMatch = textUntilPosition.trim().match(/(^waitForCompletion)|(swaitForCompletion)/);

if(completionMatch){  //trigger intellisense }

I believe we would have to match the ( after the function name but somehow ignore the first argument and match then match the , after the first argument , that is when I can make sure that my pattern matches.

Note:- textUntilPosition gets me the text until the position where my cursor is at i.e. if my cursor is in the second argument waitForCompletion(arg1, , if my cursor is on the first argument it is waitForCompletion(arg1

Answer

When a user starts typing the function name and is on the second argument, I have to trigger some intellisense for showing the intellisense on what values the second argument can accept.

You can’t do this with a simple regular expression, you need a JavaScript parser. There are several open source ones available, such as Espree (the parser used by ESLint) and Acorn.

The reason for that is that JavaScript syntax is not regular in the sense of “regular” in “regular expression.” For instance, consider:

waitForCompletion(x ? example(1, 2) : y, 

Your regex would have to understand the conditional operator (? :) in order to know that you were in the second argument to waitForCompletion at that point rather than earlier when providing the second argument to example. That’s just one of the many, many ways that an argument can be more complex than just a single identifier or literal.


I don’t want to seem to be stonewalling this or seem to be unhelpful about it. Here’s an example that will work in many cases with the simple kind of argument you’ve described, but as I’ve said above (and in a comment below), it will fail with lots of other inputs:

"use strict";
const rex = /(^|s)waitForCompletions*((?:[^,]+|(["'])[^1]*?1),s*$/;
// true:
console.log(rex.test("waitForCompletion(arg1,"));
// false, wrong function:
console.log(rex.test("blahwaitForCompletion(arg1,"));
// false, second arg present
console.log(rex.test("waitForCompletion(arg1, arg2"));
// true:
console.log(rex.test("twaitForCompletion("hi","));
// true, there's a comma, but it's in a string (1):
console.log(rex.test("waitForCompletion("h,i","));
// true, there's a comma, but it's in a string (2):
console.log(rex.test("waitForCompletion('h,i',"));