Sublime Forum

File_regex for Visual Studio 2022 cl.exe

#1

Having followed @OdatNurd’s excellent SO post on the subject, the one thing it doesn’t include is the file_regex and regex is definitely one of my weaknesses. Here’s my build file so far and the file_regex:

{
    "shell_cmd": "cl /Wall /EHsc \"${file}\" /Fe\"${file_base_name}\"",
    "working_dir": "${file_path}",
    "selector": "source.c, source.c++",

// Can this regex be better, more concise, briefer etc?
    "file_regex": "^([^\\(]+)\\((\\d+)\\): error ([^:]+): (.*)$"
}

and here’s the error message style:

C:\Users\Lozminda\Just C++\test01.cpp(9): error C2275: 'std::vector<Bob,std::allocator<Bob>>': expected an expression instead of a type

It works OK with F4, but due to my lack of confidence with regex, could someone just run their eyes over it and suggest any improvements, if there are any improvements to be made please ?

:rabbit::hocho:

0 Likes

#2

Your regex doesn’t work if the filename (or path) contains a ( character.

Also I assume that C2275 is not the column number, but an error code. But since there is no column number given in the error message, there is nothing you can do about it, and apparently ST result navigation still works even if the provided column number is invalid.

I think this one should work even for paths including (

"file_regex": "^(.+?)\\((\\d+)\\): error ([^:]+): (.*)$"
1 Like

#3

You can use an empty capture () for parts of the regex that don’t match; in the case of there being no column, Sublime can direct you to the specific line but not the actual column of the error, which for most purposes is not that big of a deal.

1 Like

#4

In reply to @OdatNurd:
I tried

"file_regex": "^([^\\(]+)\\((\\d+)\\): error (): (.*)$"

Instead of

    "file_regex": "^([^\\(]+)\\((\\d+)\\): error ([^:]+): (.*)$"

and the first didn’t work. I guessing I’ve misunderstood you ?

0 Likes

#5

Thanks for the new improved regex.
Just as an aside there’s a really good computerphile episode on regex and NFA and DFAs (SE difference between NFA and DFA) which you probably already know about, but completely blew my mind. Cheers

:rabbit::hocho:

Ps

"file_regex": "^([^\\(]+)\\((\\d+)\\): error (): (.*)$"

doesn’t work either…

0 Likes

#6

Your new regex doesn’t work because the error : part of the regex doesn’t match the error output anymore. You still have to account for the error code in the output.

For example

"file_regex": "^(.+?)\\((\\d+)()\\): error [^:]+: (.*)$"

Where exactly you put the empty capture group () shouldn’t matter, as long as it is between the line number and the message (here in this example I have put it directly after the line number).


(Offtopic): I watched a bit of your linked Youtube video, but from what I’ve seen it seems to be quite abstract and it doesn’t really help much if you want to learn about regex from a user’s perspective. A good and concise tutorial explaining most basics about regex is for examle at https://github.com/ziishaned/learn-regex. In general I’m not the biggest fan of that Computerphile channel, but I’ve only ever seen a handful of videos from it, and of course it’s certainly a matter of taste. Also I must say that I have an engineering & maths background rather than programming or informatics. Therefore channels I rather prefer over Computerphile are for example “Veritasium”, “3Blue1Brown”, “Up and Atom”, “Stand-up Maths”, “Mathologer” (some videos of that last channel are very dry, but some others are excellent). Oh and a great Youtube channel about Python programming that I can recommend a lot is “mCoding” (offtopic end)

0 Likes

#7

Just to be more explicit, the file_regex should have 4 captures in it which capture, in order:

  1. filename
  2. line number
  3. column number
  4. message

The only one that’s strictly needed from a usefulness perspective is the first one, the filename. Without that, Sublime can’t at least navigate you to the file that had the problem.

If you also capture a line number, then when the file is opened, it can also open it to the line that had the problem, and by extension can potentially annotate the line with the failure reason.

If you ALSO capture the column number, then the cursor can be placed more directly at the error point in the line instead of just at the start of the line, and any annotation can potentially be targetted directly at the error location (e.g. in ST3 the error bubble can point directly at the error).

If you ALSO capture the error message, then the message is used in the annotation so that when you browse to the error you can see what the actual problem was.

All that said, the captures are always interpreted in the order that is outlined above, so if the error output doesn’t have all of the parts, you may need to inject an empty capture in to “skip” it.

For example, if the error output is:

my_filename:52  This was a really bad error

With no column number, your regex is:

([^:]+):(\d+)()\s*(.*)

To say:

  1. Everything that is not a colon, up until we see a colon, is the filename portion
  2. There must then be a literal colon in the output
  3. Following the literal colon, there must be a sequence of 1 or more digits, which will be the line number
  4. Since there is no column number, but there is an error message, an empty capture captures “nothing” to take up the capture slot for the column
  5. The remainder of the line is the message, after skipping an arbitrary and optional amount of whitespace

The above regex presumes a non-windows file system where colons aren’t allowed to be in files. For your particular output, I would probably use something like the following instead:

([^(]+)\((\d+)\)():\s*(.*)

This works the same way but treats everything up to but not including the first ( character as the filename instead, like in your output sample above.

This however presumes that you’re not the kind of person that includes ( characters in your filenames; otherwise it will go wrong.

Also, none of these regex examples are JSON quoted (but you could for example test them against the expected output by using the Find/Replace panel or via regex101.

0 Likes