Skip to content

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.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.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="]
                }
            ]
        },
        {
            "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 Debug Information === #"]
                }
            ]
        }
    ],

    /////////////////////
    // 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:

new_file_syntax

Type Default
string ""

This setting controls what syntax a new file should use. The value can be any of the followings:

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.

  1. foo.json.ext1.ext2 (no matching syntax)
  2. foo.json.ext1 (no matching syntax)
  3. foo.json (matches JSON syntax)
  4. If there is no JSON syntax, then foo 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 matches here.

A constraint rule is the lowest-level rule, which tests an actual constraint.

Tip

You may learn more about built-in constraints 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 Matches

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 Constraints

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 constraints 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.