0

After install of Sublime Text 2 and running a few .py files with CTRL+B, I can find this file in the filesystem:

C:\Users\User\AppData\Roaming\Sublime Text 2\Packages\Python\Python.sublime-build

However, after installing Sublime Text 3 (portable version from here) and running a few Python files, I still can't find Python.sublime-build related to Sublime Text 3 in the whole filesystem.

Have .sublime-build config files been packed into another file/package, and why, since it makes the editing much less handy?

Basj
  • 41,386
  • 99
  • 383
  • 673

2 Answers2

1

Packages that ship with Sublime Text 3 are stored in special ZIP files (*.sublime-package) which you can find in your Sublime Text program directory (e.g. %ProgramW6432%\Sublime Text 3\Packages).

Apart from any unzip tool you can use the Package Resource Viewer package to extract and edit them (see the override section in the Package Control documentation for details)

The separation allows for package developers to update their packages without overwriting your customizations.

idleberg
  • 12,634
  • 7
  • 43
  • 70
  • What is the benefit of having to unzip, modify, rezip, etc. (either manually or by a dedicated package/plugin) instead of just having the files normally, like in ST2? I guess it's not for the probably-500KB saved disk space. Do most users really find this handy? – Basj Feb 25 '18 at 18:51
  • I don't know, I don't care. Please do read the linked override section, there's no need to rezip. – idleberg Feb 25 '18 at 18:53
  • 2
    As an FYI, the Sublime updater can and will wholesale replace `sublime-package` files on update, and Package Control does the same. So modifying packages directly will blow away your changes. Presumably the new system is in place at least so that you can modify packaged files and still have the underlying package update. – OdatNurd Feb 25 '18 at 20:41
  • @OdatNurd Do you mean I should *not* modify content in `/Packages/thepackage.sublime-package` (which is a ZIP file)? How to override these default values then? Should I create a **new file** in `/Data/Packages/User/blahblah.sublime-build` that will override the one in the sublime-package? – Basj Nov 25 '19 at 18:05
  • @Basj When Sublime updates, it replaces package files with new ones, and Package Control does the same thing. So if you were to modify a file it would work, but at the next update your changes will go away unexpectedly. A new file named for example `Data/Packages/Python/Python.sublime-build` will override the file in the `Python.sublime-package` file; so even if the package updates, your change remains in place. For some things (like build systems) you can also create files in your `User` package as well; that doesn't override the default but it does provide a new choice to pick from. – OdatNurd Nov 25 '19 at 18:14
  • @OdatNurd Your last comment is a perfect answer for this question, could you please post it? – Basj Nov 25 '19 at 19:01
1

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.

OdatNurd
  • 21,371
  • 3
  • 50
  • 68
  • Thank you for the edit about overrides! So, conclusion (for portable version): 1) `/Data/Packages/User/Python.sublime-build` does *not* override the same file from inside `/Packages/Python.sublime-package`, but *adds* a new build system. 2) `/Data/Packages/Python/Python.sublime-build` does override the same file from inside `/Packages/Python.sublime-package`. Thanks for this clarification! – Basj Nov 26 '19 at 19:56