Sublime Text 3 - Detect syntax based on file header

How would I get Sublime Text 3 to recognize file type (i.e. set syntax and build system) based on a files header?

For example: If the first line of a file was <!DOCTYPE html>, it would be recognized as an HTML file or if the first line in a file was #!/usr/bin/env python3 it would know it is a Python 3 file.

I know normally file extensions would dictate this, but I am using Linux and a lot of these files don't have extensions because they are commands.


Solution 1:

Syntax definitions have a first_line_match rule, for example:

HTML: https://github.com/sublimehq/Packages/blob/master/HTML/HTML.sublime-syntax#L12

 first_line_match: (?i)<(!DOCTYPE\s*)?html

PHP: https://github.com/sublimehq/Packages/blob/master/PHP/PHP.sublime-syntax#L13

first_line_match: '^(#!.*[^-]php[0-9]?|<\?php)\b'

SHELL: https://github.com/sublimehq/Packages/blob/master/ShellScript/Shell-Unix-Generic.sublime-syntax#L18

first_line_match: '^#!.*\b(bash|zsh|sh|tcsh)|^#\s*-\*-[^*]*mode:\s*shell-script[^*]*-\*-'

See the syntax definitions documentation for more details.

Solution 2:

ApplySyntax plugin does handle cases, when you need different syntax for files with the same extension and many more.

Solution 3:

To expand on Gerard Roche's answer, if you're wondering how to find these syntax definition files in Sublime Text 3, I found this answer helpful.

To summarize: on MacOS X, the package files live at /Applications/Sublime Text.app/Contents/MacOS/Packages and are all zip files even if they don't show the extension. To change the syntax definitions,

  1. Create a new folder where you'll unzip to (if you unzip in place, it's harder to keep track of all the files).
  2. Copy the language file you wish to modify into this folder and unzip it. Then rename the previous language file as a backup.
  3. Open the <Language>.sublime-syntax file and change the first_line_match rule to whatever you need.
  4. Zip all of the files back together again using a no-compression zip, name the zip file the same as the original file and then move it back out to the Packages folder.

Thanks to xmnboy for pointing out that the zip files can't be compressed.