Configurations¶
Settings¶
Sometimes, a good way to learn about settings is reading an existing one.
AutoSetSyntax.sublime-settings
{
//////////////////////////////////////////////////////////
// Online Document //
// https://jfcherng-sublime.github.io/ST-AutoSetSyntax/ //
//////////////////////////////////////////////////////////
///////////////////
// User Settings //
///////////////////
// The time (in secondes) to wait for the next event to be triggered.
"debounce": 0.3,
// Enable plugin log (in a dedicated panel)
"enable_log": true,
// Set default syntax for build outputs.
// Can be one of following formats:
// - Syntax top scope: "scope:text.html.markdown"
// - Partial/full syntax file path: "Markdown/Markdown."
// - The name of the syntax: "Markdown" (which is shown in the bottom-right corner of ST)
// - An empty string, which does nothing
"exec_file_syntax": "Packages/AutoSetSyntax/syntaxes/ExecOutput.sublime-syntax",
// Set default syntax for new files. You can use multiple formats as described above.
"new_file_syntax": "",
// Run "auto_set_syntax" command on views which exist before the plugin is loaded?
"run_on_startup_views": false,
// The max lookup size for the file.
// A negative number means no limit, which may have performance issue on large files.
"trim_file_size": 20000, // about 20KB
// The max lookup length for the first line.
// A negative number means no limit, which may have performance issue on a long first line.
"trim_first_line_length": 500,
// Apart from "trim_suffixes", also try to remove every sub-extensions when finding a syntax match.
"trim_suffixes_auto": false,
// Syntax rules that will be checked one by one.
// This plugin will assign the syntax in the first satisfied rule to the view.
// You may want to see "default_syntax_rules" for some examples.
"user_syntax_rules": [],
// Suffixes that will be used to right trim the filename.
// By doing that, the file may be then auto set syntax with a trimmed filename.
"user_trim_suffixes": [],
//////////////////////
// Project Settings //
////////////////////////////////////////////////////////////////////////////
// You shouldn't change these settings here but in your project settings. //
////////////////////////////////////////////////////////////////////////////
// Syntax rules that will be checked one by one.
// This plugin will assign the syntax in the first satisfied rule to the view.
// You may want to see "default_syntax_rules" for some examples.
"project_syntax_rules": [],
// Suffixes that will be used to right trim the filename.
// By doing that, the file may be then auto set syntax with a trimmed filename.
"project_trim_suffixes": [],
//////////////////////
// Default Settings //
////////////////////////////////////////////////////////////////////////////
// If you override default rules, they will not be updated in the future. //
// If you want to add new rules, add them in user settings. //
////////////////////////////////////////////////////////////////////////////
// Syntax rules that will be checked one by one.
// This plugin will assign the syntax in the first satisfied rule to the view.
"default_syntax_rules": [
// syntax rule
{
"syntaxes": "scope:source.python",
"selector": "text.plain",
// match rule
"match": "all", // "any" by default
"rules": [
// constraint rule
{
"constraint": "contains_regex",
"args": ["^(?:def|class)\\s"]
},
{
"constraint": "contains_regex",
"args": ["^import(?!\\s+groovy)(?:$|[\\s(])", "^from\\s+[a-zA-Z.]+\\s+import(?:$|[\\s(])"]
}
]
},
{
"comment": "Basic INI files",
"syntaxes": "scope:source.ini",
"selector": "text.plain",
"rules": [
{
"constraint": "is_name",
"args": [".minttyrc", ".wslconfig"]
}
]
},
{
"comment": "Basic JSON files",
"syntaxes": "scope:source.json",
"selector": "text.plain",
"rules": [
{
"constraint": "is_extension",
"args": [".css.map", ".geojson", ".js.map", ".jsonc", ".webmanifest"]
},
{
"constraint": "is_name",
"args": [
".babelrc",
".bowerrc",
".csslintrc",
".eslintrc",
".jscsrc",
".jshintrc",
".markdownlintrc",
".stylelintrc"
]
}
]
},
{
"comment": "Basic YAML files",
"syntaxes": "scope:source.yaml",
"selector": "text.plain",
"rules": [
{
"constraint": "is_name",
"args": [".clang-format", ".clang-tidy", ".clangd"]
}
]
},
{
"syntaxes": ["scope:source.shell.bash"],
"selector": "text.plain",
"rules": [
{
"constraint": "is_name",
"args": ["profile", ".bash_history"]
},
{
"constraint": "name_contains_regex",
"args": ["\\.(?:bash|z(?:shrc|shenv|profile|login|logout))(?:\\.[^/]*)?$"]
},
{
"constraint": "first_line_contains_regex",
"args": [
// @see https://www.shellcheck.net/wiki/SC2148
"^\\s*#\\s+shellcheck\\s+shell=(?:bash|sh|zsh)"
]
}
]
},
{
"comment": "Linux .env files",
"syntaxes": [
"/DotENV.", // https://packagecontrol.io/packages/DotENV
"scope:source.shell.bash"
],
"selector": "",
"match": "all",
"rules": [
{
"rules": [
{ "constraint": "selector_matches", "args": ["text.plain"] },
{ "constraint": "is_hidden_syntax" }
]
},
{
"rules": [
{
"constraint": "is_name",
"args": [".envrc"]
},
{
"constraint": "name_contains_regex",
"args": ["\\.(?:env)(?:\\.[^/]*)?$"]
}
]
}
]
},
{
"syntaxes": "scope:text.git.config",
"selector": "- text.git.config",
"rules": [
{
"constraint": "path_contains_regex",
"args": ["/\\.?git/config$"]
}
]
},
{
// at least, C++ is a super set of C in ST's syntax aspect
"syntaxes": "scope:source.c++",
"selector": "text.plain",
"rules": [
{
"constraint": "contains_regex",
"args": [
"(?:^|\\s)#include\\s*[<\"]",
"(?:^|\\s)#pragma\\s+(?:once|pack|(?:pop|push)_macro|warning)(?=$|\\s)",
"(?:^|\\s)template\\s*<\\s*(?:class|typename)(?=$|\\s)",
// some strong characteristics of keywords
"\\b(?:const(?:eval|expr|init)|decltype|nullptr|(?:const|dynamic|reinterpret|static)_cast)(?=$|\\s)"
]
}
]
},
{
"syntaxes": "scope:source.cs",
"selector": "text.plain",
"match": "all",
"rules": [
{
"constraint": "contains_regex",
"args": ["^using\\s"]
},
{
"constraint": "contains_regex",
"args": ["^namespace\\s"]
}
]
},
{
"syntaxes": "scope:source.diff",
"selector": "text.plain",
"rules": [
// path headers
{
"match": "all",
"rules": [
{
"constraint": "contains_regex",
"args": ["^\\+{3} "]
},
{
"constraint": "contains_regex",
"args": ["^-{3} "]
}
]
},
// context line numbers
{
"constraint": "contains_regex",
"args": ["^@@ -\\d+,\\d+ \\+\\d+,\\d+ @@"]
}
]
},
{
"syntaxes": "scope:source.go",
"selector": "text.plain",
"match": "all",
"rules": [
{
"constraint": "contains_regex",
"args": ["^(?:package)\\s"]
},
{
"constraint": "contains_regex",
"args": ["^(?:import|func|type)\\s"]
}
]
},
{
"syntaxes": ["Jenkinsfile", "scope:source.groovy"],
"selector": "text.plain",
"rules": [
{
"constraint": "name_contains_regex",
"args": ["^Jenkinsfile(?=\\b|_)"]
}
]
},
{
"syntaxes": "scope:source.java",
"selector": "text.plain",
"rules": [
{
"constraint": "first_line_contains_regex",
"args": ["^\\s*import\\s+java\\."]
},
{
"constraint": "contains_regex",
"args": ["\\bimport\\s+java\\.", "\\bSystem\\.out\\.println\\s*\\("],
"kwargs": { "threshold": 2 }
}
]
},
{
"syntaxes": "scope:source.ts",
"selector": "text.plain",
"match": "all",
"rules": [
{
"constraint": "is_extension",
"args": [".cts", ".mts"]
}
]
},
{
"syntaxes": "scope:source.tsx",
"selector": "text.plain",
"match": "all",
"rules": [
{
"constraint": "is_extension",
"args": [".ctsx", ".mtsx"]
}
]
},
{
"syntaxes": "scope:source.js",
"selector": "text.plain",
"match": "all",
"rules": [
{
"constraint": "is_magika_enabled",
"inverted": true
},
{
"constraint": "contains_regex",
"args": [
"\\bconsole\\.(?:assert|debug|error|info|log|trace|warn)\\s*\\(",
"(?:^|\\s)export\\s+default\\s"
]
}
]
},
{
"syntaxes": "scope:source.jsx",
"selector": "text.plain",
"match": "all",
"rules": [
{
"constraint": "is_extension",
"args": [".cjsx", ".mjsx"]
}
]
},
{
"syntaxes": "scope:source.lua",
"selector": "text.plain",
"rules": [
{
"constraint": "is_name",
"args": [".conkyrc"]
},
{
"constraint": "is_interpreter",
"args": ["lua"]
}
]
},
{
"comment": "Makefile",
"syntaxes": ["scope:source.makefile"],
"selector": "text.plain",
"rules": [
{
"constraint": "name_contains_regex",
"args": ["^Makefile\\."],
"kwargs": { "regex_flags": ["IGNORECASE"] }
},
{
"constraint": "contains_regex",
"args": ["^.PHONY\\s*:"]
}
]
},
{
// use the % regex to detect Matlab files
"syntaxes": "scope:source.matlab",
"selector": "text.plain | source.objc",
"match": "all",
"rules": [
{
"constraint": "is_extension",
"args": [".m"]
},
{
"constraint": "contains_regex",
"args": ["^\\s*%"],
"kwargs": { "threshold": 2 }
}
]
},
{
// .m files could be Objective-C or Matlab files
// We first use a rather reliable regex from GitHub
// https://github.com/github/linguist/blob/master/lib/linguist/heuristics.rb#L69
// to apply syntax for Objective-C files
"syntaxes": "scope:source.objc",
"selector": "text.plain | source.matlab",
"match": "all",
"rules": [
{
"constraint": "is_extension",
"args": [".m"]
},
{
"constraint": "contains_regex",
"args": [
"^\\s*(?:@(?:interface|class|protocol|property|end|synchronised|selector|implementation)\\b|#import\\s+.+\\.h[\">])"
]
}
]
},
{
"comment": "Python requirements.txt from https://packagecontrol.io/packages/requirementstxt",
"syntaxes": ["scope:source.requirementstxt", "scope:source.pip-requirements"],
"selector": "text.plain",
"rules": [
{
"constraint": "name_contains_regex",
"args": ["^requirements([-_.].+)?\\.(in|txt)$"]
}
]
},
{
"comment": "\"Ruby on Rails\" project",
"syntaxes": "scope:source.ruby.rails",
"selector": "source.ruby",
"match": "all",
"rules": [
{
"constraint": "is_extension",
"args": [".rb", ".rake"]
},
{
"constraint": "is_in_ruby_on_rails_project"
}
]
},
{
"syntaxes": "scope:source.ruby",
"selector": "text.plain",
"rules": [
{
"constraint": "is_extension",
"args": [".simplecov"]
},
{
"constraint": "is_name",
"args": ["Cartfile", "Cartfile.private", "Cartfile.resolved", "config.ru", "Dangerfile"],
"kwargs": { "case_insensitive": true }
},
{
"constraint": "is_interpreter",
"args": ["ruby"]
}
]
},
{
"comment": "SSH config from https://packagecontrol.io/packages/SSH%20Config",
"syntaxes": ["scope:source.ssh_config", "scope:source.ssh-config"],
// some syntaxes just aggresively set "config" filename as XML file
"selector": "text.plain | text.xml.config",
"rules": [
{
"constraint": "path_contains_regex",
"args": ["/\\.ssh/config$"]
}
]
},
{
// Meteor templates follow Handlebars syntax, but must end in .html;
// but they also always begin with `<template name=`
"syntaxes": "scope:text.html.handlebars",
"selector": "text.plain | text.html",
"match": "all",
"rules": [
{
"constraint": "is_extension",
"args": [".html"]
},
{
"constraint": "first_line_contains_regex",
"args": ["^<template name="]
}
]
},
{
"syntaxes": "scope:source.toml",
"selector": "text.plain",
"rules": [
{
"constraint": "is_name",
"args": ["uv.lock"]
}
]
},
{
"comment": "Django templates",
"syntaxes": ["scope:text.jinja", "scope:text.html.jinja"],
"selector": "text.html.basic",
"match": "all",
"rules": [
{
"constraint": "path_contains",
"args": ["/templates/"]
},
{
"constraint": "is_in_python_django_project"
}
]
},
{
"comment": "Jinja2/Twig HTML files",
"syntaxes": ["scope:text.jinja", "scope:text.html.jinja", "scope:text.html.twig"],
"selector": "text.html.basic",
"rules": [
{
"constraint": "contains_regex",
"args": [
"{{",
// https://jinja.palletsprojects.com/en/latest/templates/
"{%\\s*(?:autoescape|call|elif|else|extends|filter|for|from|if|import|include|macro|set|trans|with)\\b"
],
"kwargs": { "threshold": 4 }
}
]
},
{
"syntaxes": "scope:source.sql",
"selector": "text.plain",
"rules": [
{
"constraint": "first_line_contains",
"args": ["-- phpMyAdmin SQL Dump"]
},
{
"constraint": "contains_regex",
"args": ["\\bCREATE\\s+TABLE\\s+IF\\s+NOT\\s+EXISTS\\b"],
"kwargs": { "regex_flags": ["MULTILINE", "IGNORECASE"] }
}
]
},
{
"syntaxes": "scope:source.typoscript",
"selector": "text.plain",
"rules": [
{
"constraint": "is_name",
"args": ["ext_conf_template.txt", "ext_typoscript_constants.txt", "ext_typoscript_setup.txt"]
},
{
"constraint": "path_contains_regex",
"args": ["^.*/(?:fileadmin|typo3|TypoScript).*/(?:setup|constants)\\.txt$"]
}
]
},
{
"comment": "Apache config",
"syntaxes": "scope:source.apacheconf",
"selector": "text.plain | source.nginx",
"rules": [
{
"constraint": "path_contains_regex",
"args": ["\\b(?i:apache|httpd)(?:\\b|_).*/conf/.*\\.conf$"]
},
{
"constraint": "contains_regex",
"args": ["<(?:VirtualHost|Directory|Macro)(?:$|\\s)"]
}
]
},
{
"comment": "NGINX config",
"syntaxes": "scope:source.nginx",
"selector": "text.plain | source.apacheconf",
"rules": [
{
"constraint": "path_contains_regex",
"args": ["\\b(?i:nginx)(?:\\b|_).*/conf/.*\\.conf$"]
},
{
"constraint": "contains_regex",
"args": ["^\\s*(?:location\\s+(?:[~=/a-zA-Z])|(?:fastcgi_param|charset_map)\\s)"]
}
]
},
{
// @see https://doc.qt.io/qt-5/qt-conf.html
"comment": "Qt's config file",
"syntaxes": "scope:source.ini",
"selector": "- source.ini",
"rules": [
{
"constraint": "is_name",
"args": ["qt.conf"]
}
]
},
{
// @see https://doc.qt.io/qtvstools/qtvstools-translation-files.html
"comment": "Qt's translation file",
"syntaxes": "scope:text.xml",
"selector": "source.ts",
"match": "all",
"rules": [
{
"constraint": "is_extension",
"args": [".ts"]
},
{
"constraint": "first_line_contains_regex",
"args": ["^\\s*<\\?xml(?:$|\\s)"]
}
]
},
{
"comment": "Sublime Text/Merge changelog",
"syntaxes": "scope:text.html.basic",
"selector": "text.plain",
"match": "all",
"rules": [
{
"constraint": "is_name",
"args": ["changelog.txt"]
},
{
"constraint": "relative_exists",
"args": ["sublime_text", "sublime_text.exe", "sublime_merge", "sublime_merge.exe"]
}
]
},
{
"comment": "Package Control: Package installation/update messages",
"syntaxes": "scope:text.html.markdown",
"selector": "text.plain",
"rules": [
{
"constraint": "first_line_contains_regex",
"args": ["^Package Control Messages(?:$|\\s)"]
}
]
}
],
// Suffixes that will be used to right trim the filename.
// By doing that, the file may be then auto set syntax with a trimmed filename.
"default_trim_suffixes": [
"-dev",
"-development",
"-dist",
"-optional",
"-prod",
"-production",
"-qa",
"-test",
".backup",
".bak",
".common",
".default",
".dev",
".dist",
".example",
".in",
".inc",
".include",
".local",
".orig",
".out",
".qa",
".sample",
".shared",
".temp",
".test",
".tmp",
".tpl"
],
///////////////////
// Core Settings //
//////////////////////////////////////////////////////////////////////////////////
// These settings make this plugin function normally. You shouldn't touch them. //
//////////////////////////////////////////////////////////////////////////////////
"core_syntax_rules": [
{
"comment": "AutoSetSyntax Debug Information",
"syntaxes": "scope:source.python",
"selector": "text.plain",
"rules": [
{
"constraint": "first_line_contains_regex",
"args": ["^# === [AutoSetSyntax] "]
}
]
}
],
/////////////////////
// Magika settings //
/////////////////////
// To use this feature, you have to install the "magika" library.
// @see https://jfcherng-sublime.github.io/ST-AutoSetSyntax/experimental/dl-based-syntax-detection/#prerequisites
"magika.enabled": false,
"magika.min_confidence": 0.85,
// To list supported file types, run shell command: `$ magika --list-output-content-types`
// @see https://github.com/google/magika/blob/main/docs/supported_content_types_list.md
"magika.syntax_map.appleplist": ["scope:text.xml.plist", "=xml"],
"magika.syntax_map.asm": [
// no good way to do this?
"scope:source.asm.x86_64",
"scope:source.asm.arm",
"scope:source.rvasm",
"scope:source.assembly"
],
"magika.syntax_map.asp": ["scope:source.asp"],
"magika.syntax_map.batch": ["scope:source.dosbatch"],
"magika.syntax_map.c": ["scope:source.c++" /* magika can't distinguish between C and C++ */],
"magika.syntax_map.cs": ["scope:source.cs"],
"magika.syntax_map.css": ["scope:source.scss", "scope:source.css"],
"magika.syntax_map.csv": ["scope:text.advanced_csv", "scope:text.csv"],
"magika.syntax_map.go": ["scope:source.go"],
"magika.syntax_map.html": ["scope:text.html.basic"],
"magika.syntax_map.ini": ["scope:source.ini"],
"magika.syntax_map.java": ["scope:source.java"],
"magika.syntax_map.javascript": ["scope:source.ts" /* magika can't distinguish between TypeScript and JavaScript */],
"magika.syntax_map.json": ["scope:source.json"],
"magika.syntax_map.latex": ["scope:text.tex.latex"],
"magika.syntax_map.lisp": ["scope:source.lisp"],
"magika.syntax_map.m3u": ["scope:text.m3u"],
"magika.syntax_map.makefile": ["scope:source.makefile"],
"magika.syntax_map.markdown": ["scope:text.html.markdown"],
"magika.syntax_map.mum": ["=xml"],
"magika.syntax_map.pem": ["scope:text.pem"],
"magika.syntax_map.perl": ["scope:source.perl"],
"magika.syntax_map.php": ["scope:embedding.php", "scope:text.html.php"],
"magika.syntax_map.postscript": ["scope:source.postscript"],
"magika.syntax_map.powershell": ["scope:source.powershell"],
"magika.syntax_map.python": ["scope:source.python"],
"magika.syntax_map.rdf": ["=xml"],
"magika.syntax_map.rst": ["scope:text.restructuredtext"],
"magika.syntax_map.rtf": ["scope:text.rtf"],
"magika.syntax_map.ruby": ["scope:source.ruby"],
"magika.syntax_map.rust": ["scope:source.rust"],
"magika.syntax_map.scala": ["scope:source.scala"],
"magika.syntax_map.shell": ["scope:source.shell.bash"],
"magika.syntax_map.smali": ["scope:source.smali"],
"magika.syntax_map.sql": ["scope:source.sql"],
"magika.syntax_map.svg": ["=xml"],
"magika.syntax_map.txt": ["scope:text.plain"],
"magika.syntax_map.vba": ["scope:source.vbs"],
"magika.syntax_map.winregistry": ["scope:source.reg"],
"magika.syntax_map.xml": ["scope:text.xml"],
"magika.syntax_map.yaml": ["scope:source.yaml"]
}
enable_log
¶
Type | Default |
---|---|
boolean | true |
This setting control whether this plugin creates a dedicated log message panel. Since the panel won't affect other plugins, the default value is true
.
exec_file_syntax
¶
Type | Default |
---|---|
string | "Packages/AutoSetSyntax/syntaxes/ExecOutput.sublime-syntax" |
This setting controls what syntax a build output should use. The value can be any of the followings:
- An empty string, which does nothing.
- A syntax representation.
new_file_syntax
¶
Type | Default |
---|---|
string | "" |
This setting controls what syntax a new file should use. The value can be any of the followings:
- An empty string, which does nothing.
- A syntax representation.
run_on_startup_views
¶
Type | Default |
---|---|
boolean | false |
This setting controls whether you want to run the auto_set_syntax
command on views which exist before the plugin is loaded. If ST starts from cold start, this settings is necessary to set syntax for the just opened file.
Info
When ST starts up, there may be views that exists before plugins are loaded. Those views won't trigger on_load
or on_load_async
event listener in plugins. But those views will be put as an argument for the on_init
event.
For some people, they may even have hundreds of tabs opened. They may not want a plugin to run on all those views when ST starts up.
trim_file_size
¶
Type | Default |
---|---|
integer | 20000 (about 20KB) |
Detecting the syntax for the whole file can be resource-consuming if the file is large. This setting approximately controls how many bytes should be used to represent a file.
trim_first_line_length
¶
Type | Default |
---|---|
integer | 500 |
Detecting the syntax for the whole first line can be resource-consuming if it's a super long one-line file. This setting controls how many characters should be used to represent the first line.
trim_suffixes_auto
¶
Type | Default |
---|---|
boolean | false |
Apart from trim_suffixes
, also try to remove every sub-extensions when finding a syntax match. For example, for the file foo.json.ext1.ext2.ext3
, this setting enables trying the following file names as well.
foo.json.ext1.ext2
(no matching syntax)foo.json.ext1
(no matching syntax)foo.json
(matchesJSON
syntax)- If there is no
JSON
syntax, thenfoo
will be tried.
default_syntax_rules
¶
Syntax rules are the key part of AutoSetSyntax.
Structure of syntax rules
"default_syntax_rules": [
// syntax rule
{
"comment": "...",
"syntaxes": "...",
"selector": "...",
"on_events": null,
// match rule
"match": "...",
"rules": [
// constraint rule
{
"constraint": "...",
"args": ["..."],
},
// match rule
{
"match": "...",
"rules": [
// can be recursive...
],
},
],
},
// more syntax rules...
],
A syntax rule contains comment
, syntaxes
, selector
, on_events
and an expanded top-level match rule.
Arguments
This is just a optional string which explains what this syntax rule is for. It may make your debugging easier.
syntaxes
is a list of syntax representation. If there is only one syntax, you can simply un-list it into a string. If the top-level match
is satisfied by rules
, the first usable syntax in syntaxes
will be assigned to the view.
Limit this syntax rule only works when the selector
matches the top scope. Learn more about selectors from ST official docs.
on_events
is a list of event names or (by default) null
. It's used to restrict this syntax rule only works if this run is triggered by some certain events. If it's null
, then there is no restriction.
Failure
If you use an empty list, then this syntax rule will never be evaluated.
Available Events
Event Name | Meaning |
---|---|
"command" | This run is triggered by the auto_set_syntax command. |
"init" | This run is triggered by startup views. |
"load" | This run is triggered because a file gets loaded. |
"modify" | This run is triggered because of a buffer modification. |
"new" | This run is triggered because of a newly created window. |
"reload" | This run is triggered because a file has been reloaded. |
"revert" | This run is triggered because of the revert command. |
"save" | This run is triggered because of the buffer gets saved. |
"untransientize" | This run is triggered because a transient view becomes a normal view. |
A match rule may recursively contain any amount of match rule and constraint rule so you can build complex rules basing on your needs.
Arguments
The default value of the match
is "any"
, which tests whether there is any rules
satisfied.
Tip
You may learn more about built-in match
es here.
A constraint rule is the lowest-level rule, which tests an actual constraint.
Tip
You may learn more about built-in constraint
s here.
Warning
It's not recommended to directly override default_syntax_rules
because that stops you from possible future updates for default_syntax_rules
. The recommended way is putting your syntax rules in user_syntax_rules
. And put project-specific syntax rules in project_syntax_rules
in project settings.
default_trim_suffixes
¶
Type | Default |
---|---|
string[] | [ ".dist", ".local", /* many other suffixes */ ] |
These suffixes are considered unimportant in a file name. AutoSetSyntax will try to remove them from the file name and maybe a syntax will be found for a trimmed file name.
Warning
It's not recommended to directly override default_trim_suffixes
because that stops you from possible future updates for default_trim_suffixes
. The recommended way is putting your suffixes in user_trim_suffixes
. And put project-specific suffixes in project_trim_suffixes
in project settings.
Terms and Explanations¶
Syntax Representations¶
When we talk about setting "syntax" in plugin settings, there are three ways you can use.
Example
Let's take the built-in JavaScript
syntax as an example.
You can use "scope:TOP_SCOPE"
to represents a syntax.
For example, the top scope of JavaScript
is source.js
. Thus, you can use "scope:source.js"
.
Tip
To show the scope at the caret position, press Ctrl+Alt+Shift+P.
You can use the syntax name to represent a syntax.
For example, it's JavaScript
for the JavaScript
syntax. Thus, you can use "JavaScript"
.
Info
The syntax name is shown in the bottom-right corner of ST.
Warning
If you manually type a syntax name, note that it's case-sensitive.
You can use a partial path (or a full one if you prefer) of a syntax to represent it.
For example, the full path for the JavaScript
syntax is Packages/JavaScript/JavaScript.sublime-syntax
. Theoretically, you may use any substring of the full path to represent it. But if your partial path is not unique, it may represent other syntaxes as well and causes unwanted behavior. Thus, if you want to go the "by path" way, I recommend using "/JavaScript/JavaScript."
.
All of followings represent the same syntax, JavaScript
.
- Top scope:
"scope:source.js"
- Name:
"JavaScript"
- Partial path:
"/JavaScript/JavaScript."
- Full path:
"Packages/JavaScript/JavaScript.sublime-syntax"
Project Settings¶
To edit project settings, go to Project
ยป Edit Project
.
Example
{
"folders": [
// ...
],
"settings": {
"AutoSetSyntax": {
// use JavaScript as the new file syntax
"new_file_syntax": "scope:source.js",
"project_syntax_rules": [
// specific rules only for this project
],
"project_trim_suffixes": [
// specific trimmed suffixes only for this project
],
// maybe other plugin settings...
},
},
}
You can override any plugin setting in project settings. But most likely, you are just interested in new_file_syntax
, project_syntax_rules
and probably project_trim_suffixes
.
Appendix¶
Built-in Match
es¶
all
¶
Example
{
"match": "all",
"rules": [ /* some match rules or constraint rules */ ],
}
Test whether all rules in rules
are satisfied.
any
¶
Example
{
"match": "any",
"rules": [ /* some match rules or constraint rules */ ],
}
Test whether there is any rule in rules
satisfied.
ratio
¶
Example
{
"match": "ratio",
"rules": [ /* some match rules or constraint rules */ ],
"args": [2, 3],
}
Test whether at least \(\frac{2}{3}\) of rules in rules
are satisfied.
some
¶
Example
{
"match": "some",
"rules": [ /* some match rules or constraint rules */ ],
"args": [4],
}
Test whether at least 4 rules in rules
are satisfied.
Built-in Constraint
s¶
Tip: Directory Separator
For path-related constraints, the directory separator is always /
no matter what OS you are on. This should simplify the rule definitions.
Tip: Inverted Result
For all constraint rules, you may set inverted
to true
to invert the test result.
{
// This means testing the file does NOT contains `string_a` or `string_b`.
"constraint": "contains",
"args": ["string_a", "string_b"],
"inverted": true,
}
Warning
Under certain circumstances, the test result will not be inverted. For example, if the is_size
constraint tests a unsaved buffer, the result will always be false
no matter inverted
is true
or false
, because a unsaved buffer has no file size.
contains
¶
Example
{
"constraint": "contains",
"args": ["string_a", "string_b"],
"kwargs": { "threshold": 2 },
}
Test whether the file contains string literals string_a
or string_b
. At least 2
occurrences should be found.
contains_regex
¶
Example
{
"constraint": "contains_regex",
"args": ["string_[ab]", "^import\\s"],
"kwargs": {
"regex_flags": ["MULTILINE"],
"threshold": 2,
},
}
Test whether the file contains regexes string_[ab]
or ^import\s
. At least 2
occurrences should be found.
first_line_contains
¶
Example
{
"constraint": "first_line_contains",
"args": ["string_a", "string_b"],
}
Test whether the first line contains string literals string_a
or string_b
.
first_line_contains_regex
¶
Example
{
"constraint": "first_line_contains_regex",
"args": ["string_[ab]", "^import\\s"],
"kwargs": { "regex_flags": ["MULTILINE"] },
}
Test whether the first line contains regexes string_[ab]
or ^import\s
.
relative_exists
¶
Example
{
"constraint": "relative_exists",
"args": ["foo", "bar/"],
"kwargs": {"match": "all"},
}
Test whether both file foo
and directory bar/
exist relatively to the file.
is_arch
¶
Example
{
"constraint": "is_arch",
"args": ["x32", "arm64"],
}
Test whether the system arch is x32
or arm64
.
Info
Available platforms are: x32
, x64
, and arm64
.
is_extension
¶
Example
{
"constraint": "is_extension",
"args": [".rb", ".rake"],
"kwargs": {"case_insensitive": false},
}
Test whether the file extension is .rb
or .rake
.
Info
If case_insensitive
is not provided, it will be true
on Windows but false
on other OSes.
is_hidden_syntax
¶
Example
{
"constraint": "is_hidden_syntax",
}
Test whether the current syntax is hidden.
Info
A hidden syntax is usually not for providing syntax highlighting. For example, the "A File Icon" plugin uses hidden syntaxes just to show dedicated icons.
is_in_git_repo
¶
Example
{
"constraint": "is_in_git_repo",
}
Test whether the file is in a git repository.
is_in_hg_repo
¶
Example
{
"constraint": "is_in_hg_repo",
}
Test whether the file is in a Mercurial repository.
is_in_python_django_project
¶
Example
{
"constraint": "is_in_python_django_project",
}
Test whether the file is in a (Python) Django project.
is_in_ruby_on_rails_project
¶
Example
{
"constraint": "is_in_ruby_on_rails_project",
}
Test whether the file is in a Ruby on Rails project.
is_in_svn_repo
¶
Example
{
"constraint": "is_in_svn_repo",
}
Test whether the file is in a SVN repository.
is_interpreter
¶
Example
{
"constraint": "is_interpreter",
"args": ["python", "cpython"],
"kwargs": {"loosy_version": true},
}
Test any of the followings
- the interpreter in shebang
- the
syntax
in the VIM's syntax line
is python
, pypy
, python3
, python3.8
, etc.
is_line_count
¶
Example
{
"constraint": "is_line_count",
"args": [">", 500],
}
Test whether the file has more than 500 lines.
Info
Available comparators are: <
, <=
, ==
, >=
, >
and !=
.
is_magika_enabled
¶
Example
{
"constraint": "is_magika_enabled",
}
Test whether the magika
is enabled.
is_name
¶
Example
{
"constraint": "is_name",
"args": ["foo", "bar"],
"kwargs": {"case_insensitive": false},
}
Test whether the file name is foo
or bar
.
Info
If case_insensitive
is not provided, it will be true
on Windows but false
on other OSes.
is_platform
¶
Example
{
"constraint": "is_platform",
"args": ["linux", "windows"],
}
Test whether the system platform is Linux
or Windows
.
Info
Available platforms are: linux
, osx
, and windows
.
is_platform_arch
¶
Example
{
"constraint": "is_platform_arch",
"args": ["linux_x64", "windows_x32", "osx_arm64"],
}
Test whether the system platform and arch is Linux 64-bit
, Windows 32-bit
or Apple M1
.
Info
Available platform_arch
are combinations of (linux
, osx
, windows
) and (x32
, x64
, arm64
) using a _
as the delimiter.
is_rails_file
¶
Example
{
"constraint": "is_rails_file",
}
Test whether the file is a Ruby on Rails
file.
is_size
¶
Example
{
"constraint": "is_size",
"args": [">", 5000],
}
Test whether the file size is greater than 5000
bytes (about 5
KB).
Info
Available comparators are: <
, <=
, ==
, >=
, >
and !=
.
is_syntax
¶
Example
{
"constraint": "is_syntax",
"args": ["scope:source.python", "JavaScript", "/JSON."]
}
Test whether the current syntax is in the given syntax list. See syntax representation for more informations.
name_contains
¶
Example
{
"constraint": "name_contains",
"args": ["foo", "bar"],
}
Test whether the file name contains foo
or bar
.
name_contains_regex
¶
Example
{
"constraint": "name_contains_regex",
"args": ["^foo", "bar$"],
"kwargs": { "regex_flags": ["MULTILINE"] },
}
Test whether the file name contains regexes ^foo
or bar$
.
path_contains
¶
Example
{
"constraint": "path_contains",
"args": ["foo", "bar"],
}
Test whether the file path contains foo
or bar
.
path_contains_regex
¶
Example
{
"constraint": "path_contains_regex",
"args": ["/conf/.*\\.conf$", "/assets/.*\\.js$"],
"kwargs": { "regex_flags": ["MULTILINE"] },
}
Test whether the file path contains regexes /conf/.*\.conf$
or /assets/.*\.js$
.
selector_matches
¶
Example
{
"constraint": "selector_matches",
"args": ["text.plain | source.env"],
}
Test whether the any of selectors matches the base scope of the current syntax.
Regular Expression Flags¶
Some constraint
s allow you to use (Python) regexes in args
. There are two ways to use regex flags on those regexes.
Example
{
"constraint": "contains_regex",
"args": ["(?i:foo)_bar"],
}
This will matches FoO_bar
.
Info
If you want to learn more, you may read inline regex flags.
By default, ["MULTILINE"]
is used for convenience.
Warning
Note that those regex_flags
will be applied to ALL regexes.
Example
{
"constraint": "contains_regex",
"args": ["string_[ab]", "^import\\s"],
"kwargs": { "regex_flags": ["IGNORECASE", "MULTILINE"] },
}
This will make string_[ab]
and ^import\s
matching case-insensitive.
Common Flags
Flag | Meaning |
---|---|
"IGNORECASE" | Ignore case (case-insensitive). |
"I" | An alias of "IGNORECASE" . |
"MULTILINE" | Make ^ matches at line beginnings and $ matches at line endings. |
"M" | An alias of "MULTILINE" . |
"DOTALL" | Make . matches any character, including a newline. |
"S" | An alias of "DOTALL" . |
If you want to learn more, you may read Python's docs about the re
module.