I'm trying to make a snippet for sublime text 3, I want to transform the filename variable (TM_FILENAME) to uppercase and replace ".c" by "_H". I have the expressions to do it, but not at the same time.
I have tried to put them next to each other, but it didn't work.
The content of the snippet file I have:
#ifndef ${1:${TM_FILENAME/\..+$/_H/}}
# define ${1:${TM_FILENAME}}
${1/(.*)/\U$1/\E}
$0
#endif
With the file name being test.c, this is the result:
#ifndef test_H
# define test_H
TEST_H
#endif
The third line IS what I want, but I want it after ifndef and define.
So I need to combine the third line's regex to the first one.
As was mentioned by @keith-hall in the comment on your question, this is possible by taking advantage of the fact that Sublime uses the boost regex syntax for matching and boost format strings to create the replacement text.
One of the features that this exposes is the idea of a conditional expression in the replacement text:
The character '?' begins a conditional expression, the general form is:
?Ntrue-expression:false-expression
where N is decimal digit.
If sub-expression N was matched, then true-expression is evaluated and sent to output, otherwise false-expression is evaluated and sent to output.
What this means is that for every capture group you include in your regular expression, you can specify what should be replaced as two separate text items; replacement text when the group captured some text and replacement text for when it does not.
An example of that based on your question above is this:
${1:${TM_FILENAME/(\.c)|(.)/(?1_H:)(?2\u$2:)/g}}
The regex portion here is (\.c)|(.)
, which matches either the literal text .c
(group 1) or alternately any single character (group 2).
In the replacement text, (?1_H:)
says that if the first capture group captured any text, the replacement for it should be the literal text _H
; otherwise the replacement text should be an empty string.
Following that, (?2\u$2:)
says that if capture group 2 captured anything, the replacement text should be an uppercase version of the character; otherwise the replacement should be an empty string.
Since the input regex has an alternation (|
character) the regex matches either one or the other; so in the replacement text only one group or the other has any text in it, and the output acts accordingly.
The options in the regex specify g
to ensure that the regex is applied to everything; otherwise it will only match once, which in this case would have the effect of upper-casing the first character in the filename and then stopping.