I am the author and maintainer of WoW Bundle for Visual Studio Code.
In Blizzard's World of Warcraft API, many constants like events names, widgets scripts handlers or certain function parameters are strings. Those strings can be single- or double-quoted and some (not all) of them are case-insensitive. For example:
local myFrame = CreateFrame('Button', nil, UIParent)
myFrame:SetPoint('CENTER', 0, 0)
MyFrame:RegisterEvent('PLAYER_ENTERING_WORLD')
myFrame:SetScript('OnEvent', myEventHandler)
To scope those special strings in my tmLanguage file, I declare them in a repository:
<!-- This is only an excerpt, there are many more of these :) -->
<key>repository</key>
<dict>
<key>string-parameters</key>
<dict>
<key>match</key>
<string>(?i)(Button|Frame|Slider|StatusBar|TOP|LEFT|BOTTOM|RIGHT|BACKGROUND|ARTWORK|LOW|MEDIUM|HIGH)</string>
<key>name</key>
<string>support.constant.wow.parameter.lua</string>
</dict>
<key>event-names</key>
<dict>
<key>match</key>
<string>(PLAYER_ENTERING_WORLD|ADDON_LOADED)</string>
<key>name</key>
<string>support.constant.wow.event.lua</string>
</dict>
<key>script-handlers</key>
<dict>
<key>match</key>
<string>(OnLoad|OnShow|OnEvent)</string>
<key>name</key>
<string>support.constant.wow.hander.lua</string>
</dict>
</dict>
and I include them inside a surrounding scope:
<dict>
<key>name</key>
<string>support.constant.wow.quoted.single.lua</string>
<key>begin</key>
<string>'</string>
<key>beginCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.constant.begin.lua</string>
</dict>
</dict>
<key>end</key>
<string>'</string>
<key>endCaptures</key>
<dict>
<key>0</key>
<dict>
<key>name</key>
<string>punctuation.definition.constant.end.lua</string>
</dict>
</dict>
<key>patterns</key>
<array>
<dict>
<key>include</key>
<string>#string-parameters</string>
</dict>
<dict>
<key>include</key>
<string>#event-names</string>
</dict>
<dict>
<key>include</key>
<string>#script-handlers</string>
</dict>
</array>
</dict>
Of course, I have two of these blocks (one for single quotes, one for double quotes) and they are declared before the regular strings blocks to make sure they take precedence.
So, this works... almost.
In declarations like:
local myFrame = CreateFrame(' Frame ', nil, UIParent) -- Notice the spaces around Frame
or, worse:
local myFrame = CreateFrame('Frame Type That Does Not Exist', nil, UIParent)
the whole string is still parsed as valid (as it contains the word Frame
from the #string-parameters
repo) when it should obviously not.
How do I make sure that only one word, without spaces around, from the repositories is matched? I tried modifying the regexes in many ways but to no avail.