Have .sublime-build config files been packed into another file/package
Technically speaking, the answer to your question is no; the Python.sublime-build
file is still in the same Python.sublime-package
it always was, but unlike ST2, ST3 can read the contents of sublime-package
files without extracting them first.
In ST2, Sublime performs a step called "Package Setup" whenever it starts, whereby it extracts the contents of sublime-package
files into the Packages
folder (when the package file has changed or when the folder version does not exist). If you check the top of the ST2 console, you can see messages regarding whether it thought it needed to do setup or not.
In ST3, Sublime can read package resources directly out of the sublime-package
files, and so it no longer performs the package extraction step that it used to.
So, whereasin ST2 you could go to the Packages
folder to look at the contents of a package, now you need to either peek inside of the sublime-package
file yourself (it's just a zip file with a different extension) or use the View Package File
command from the command palette, which will allow you to see and open any package resource from any package.
why, since it makes the editing much less handy?
One of the main reasons for this change is to make editing package resources safer. Previously if you were to edit the extracted contents of a package, if that package ever got updated Sublime would re-extract the new package file, which could clobber your changes away.
In order to allow for packages to update without this happening, ST3 supports the idea of overrides
for packages and resources; essentially the idea that you provide an external file and tell Sublime "Use this file instead of that one"; that way even if the sublime-package
file changes, your changes are left intact.
This can occur in two different ways:
If you place a sublime-package
file in the Installed Packages
folder and a similarly named package appears in the Packages
folder in the Sublime installation directory, then the version in Installed Packages
is used and the one that Sublime shipped with is ignored. This allows you to replace packages that ship with Sublime.
If there is a folder in the Packages
folder in your user configuration area that mimics the name of a sublime-package
file (e.g. Python.sublime-package
and Python/
), then the contents of the folder are considered to be part of the sublime-package
file, allowing you to augment the package.
Additionally, if any files appear with the same name and relative path in the folder version, they will be used in place of the one in the sublime-package
file (the case of the file name and path can matter in some cases, so it's best to mimic it exactly). This allows you to modify the contents of packages safely.
In both cases what this gives you is free reign to modify packages to your liking while being ensured that no matter what updates happen, your changes will remain in place. Thus it is important to note that you should never modify a sublime-package
file (unless you're the one that made it) because when updates happen, the package file will be replaced and your updates will be lost.
The caveat here is that when overrides
are in place, Sublime always uses them without question. So in the case that you're overriding a package file and the author also updates the package, your changed file will still be used.
The OverrideAudit package (disclaimer: I am the author) monitors when a sublime-package
file is updated in a way that could cause your local change to be masked and warns you about it. It also contains a command for easily being able to create overrides and see how they're different from the files that they're overriding as well.
More information on how packages work in ST3 (including the various places that package files can exist) can be found in the Demystifying Packages in Sublime Text video.
Examples of Overrides
For clarity, here are some examples of overrides using the above mechanism. In all cases we're going to use the following terms:
$DATA
: The location where Sublime is keeping your user specific configuration. For portable builds, this is the Data
directory that you get when you unpack the build; in all other cases it's in a folder somewhere in your home directory. Use Preferences > Browse Packages
and go up one folder level to find this location regardless of your OS or installation method.
Shipped Packages
: this is the folder named Packages
that exists inside of the installation directory of Sublime itself (i.e. where the binary sits). This contains all of the sublime-package
files that Sublime ships with by default.
Installed Packages
: This is a folder in $DATA
. Package Control installs sublime-package
files here and you can also place package files here manually as well. Packages contained anywhere in this folder (including subfolders) will be seen by Sublime.
Unpacked Packages
: This is the Packages
folder in $DATA
where unpacked packages are stored. Preferences > Browse Packages
always brings you here, and it's where your User
package is stored.
Package load order dictates that Sublime loads all of the Shipped
packages first, then all of the Installed
packages, and finally the Unpacked
packages. While loading a sublime-package
file, overrides in the Unpacked Packages
folder are loaded as part of that phase and any remaining files are loaded later.
Within the defined order, packages are sorted lexically so that they load in order, except that Default
is always loaded first and User
is always loaded last. Overrides take effect at the point where Sublime would try to load a particular package or resource from that package.
Complete Overrides
Overrides of this type cause Sublime to wholly ignore one sublime-package
file in favor of another; you can use this to affect changes to a package as a whole, including being able to remove files from a package which is otherwise not possible. This mechanism only applies to Shipped
packages and is not used very often.
Adding an empty Python.sublime-package
(a zip file containing no files) to the Installed Packages
folder will cause the package to appear empty, so Python support would be removed.
Adding a version of Python.sublime-package
to the Installed Packages
folder that has all of the sublime-snippet
files removed would leave Python support intact while removing all snippets.
Adding Sample.sublime-package
to the Installed Packages
folder is nor an override because the Shipped Packages
folder does not contain a package with this name. Thus this isjust a normal package installation.
Resource Overrides
Overrides of this type cause Sublime to favor a loose package resource file in the Unpacked Packages
folder over a similarly named file in a sublime-package
file (regardless of how that package is installed). This is a more common mechanism that you would use in order to adjust the content of a package file without directly modifying the sublime-package
file itself.
Creating a file named $DATA/Packages/Python/Python.sublime-build
would override the same named file in Python.sublime-package
so that as far as Sublime is concerned, that file is a part of the sublime-package
file.
Creating a file named $DATA/Packages/Python/Snippets/if.sublime-snippet
would do the same thing; the name of the file in the Python
folder has the same relative path and name as the version in the sublime-package
file, so Sublime uses it instead.
Creating a file named $DATA/Packages/python/python.sublime-build
will be treated as the first example if you're on Windows or MacOS with a case-insensitive file system, but will be treated as a new package containing a new build system on Linux because the case of the file names and/or the folder don't match the sublime-package
file name.
The determination of whether a resource is an override or not directly correlates with whether or not there is an identically named file at the correct location; anything that doesn't match that is considered as a new package or new package resource.
So for example creating $DATA/Packages/User/Python.sublime-build
does not override the default Python build system because the default build is in the Python
package and not the User
package. In this case this would add a second (identically named) build system.
Since the case of the files and folders matters, it's generally best to use a package of some sort (like PackageResourceViewer or OverrideAudit) to create the override for you to ensure that the case of everything is correct.
Although I'm biased I generally recommend OverrideAudit for this use because PackageResourceViewer has a command to extract an entire package into the Packages
folder. If you were to accidentally trigger that command you would effectively override the entire content of a whole package at once, which blocks it from ever updating and has the ability to cause otherwise hard to track down issues.