We can have multiple file patterns match the path for which we ask for settings, so the order of sections does matter, as we’ll use the setting from the last section with a match.
The order enforced is based on length though with a leading asterisk subtracted from the length, that way ‘*.txt’ will be placed before ‘CMakeLists.txt’ and ‘*.rb’ will go before ‘*_spec.rb’.
Incase of same length, we use regular string compare which would normally put the wildcard match first, e.g. ‘*.config’ goes before ‘.config’.
That way, if we have a setting for [ templates/** ] and create a new file in the templates folder (via the file browser) these settings will apply.
Previously we used the folder without trailing slash which required making the file pattern something like [ templates{/**,} ].
Settings are now ranked by locality first, and only if multiple settings from the same .tm_properties file apply, we rank them further using the following order (from lowest to highest): untargeted, scoped (ranked by scope selector), and finally file pattern match (glob).
A file setting like “src/*.cc” is arguably more specific (and thus more local) than targeting the scope “source.c++”, so it makes sense that the file settings rank higher than scope settings.
Some users also find it natural to target file extensions over scopes, but as TM will store some learned settings with a scope selector, it would previously lead to confusion, when a user was unable to e.g. change tab size for “*.php” (because TM had a learned setting for “source.php”).
This was previously public so that we could write tests for it, but since the test runner is linked with the object files, it can access symbols that has visibility set to hidden.
We generally lookup include/exclude patterns for a folder rather than a file, and here it makes sense to allow the bracketed sections of the property files to target the folder.
Since the sections are not ranked based on how good a match they are, targeting a subfolder, and then a subfolder of this subfolder, does not have which settings take precedence defined.
This is so that a global setting for ‘source.ruby’ takes precedence over a local ‘source’ setting.
A minor downside is that a local properties file cannot use scoped settings outside a scope selector section.