Sublime Forum

Is it possible to change the theme for the build panel?

#1

In ST2, I was able to modify the build panel color theme. Its the only capability I really miss after upgrading to ST3. It was so nice to have a light color theme for my code and a build panel that looked like a real terminal window. I’m hoping someone might have found a way to do this in ST3 by now.

0 Likes

#2

The build output panel is a view, and the color_scheme setting of a view can be set differently than the global color_scheme if desired. So one way to do something like this would be to communicate to the build output panel that you want it to use a different color scheme than the default.

There’s not a direct way to apply the color_scheme setting to the build output panel, but there are a few ways to accomplish that aim depending on your use case and how much work you want to put into effecting the change.

Option 1: Simple plugin

Using the plugin below (see this video if you don’t know how to install a plugin) you can get most of the way there, which might be enough for most use cases. When the plugin loads it creates the build output panel in every window right away and assigns a color_scheme to it. It also watches for a new window being created and immediately applies the new color scheme to that window’s build output panel as well.

import sublime
import sublime_plugin


def plugin_loaded():
    for window in sublime.windows():
        window.run_command("apply_build_color")


class ApplyBuildColorCommand(sublime_plugin.WindowCommand):
    def run(self):
        panel = self.window.create_output_panel("exec")
        panel.settings().set("color_scheme", "Mariana.sublime-color-scheme")


class WindowEventListener(sublime_plugin.EventListener):
    def on_post_window_command(self, window, command, args):
        if command == "new_window":
            sublime.active_window().run_command("apply_build_color")

Potential downsides:

  • Every window will always have a Build Results panel in the panel chooser, even if no build has happened yet
  • Dragging a tab out to create a new window won’t trigger the plugin
  • On MacOS, if Sublime is running but there are no windows open, clicking the dock icon will create a window but it won’t trigger the plugin.

You could mitigate the last couple of these in the rare case that it happens by running the apply_build_color command manually (say by binding it to a key or adding it to the command palette) though.

Option 2: Custom Syntax

Although you can’t apply the color_scheme setting to the build output panel, a sublime-build file can include a syntax key to tell the build output how to syntax highlight the build results. It’s also possible for the syntax specific settings to include a color_scheme key to make anything using that syntax use that color scheme.

Using that, you could create a file named BuildOutput.sublime-syntax in your User package with content like this:

%YAML 1.2
---
# http://www.sublimetext.com/docs/3/syntax.html
name: Build Output
hidden: true
scope: text.plain.build
contexts:
  main: []

Additionally, create a file named BuildOutput.sublime-settings in the User package like so:

{
    "color_scheme": "Mariana.sublime-color-scheme",
}

Lastly, in any sublime-build file that you routinely use to build, you add a syntax line using the above syntax, such as in this example:

{
    "shell_cmd": "tcc -run \"$file\"",
    "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$",
    "working_dir": "${file_path}",
    "selector": "source.c",

    "syntax": "BuildOutput.sublime-syntax",
}

Now when that build executes, the syntax setting of the output panel is changed, which also carries with it the color scheme.

The downside here is that you have to manually edit the sublime-build files that you want this to apply to. If you only ever use a couple of different builds, that’s possibly less of an issue.

Option 3: Impose your will on the code

In this variation you make a modification directly to the code that’s responsible for executing the build to get it to apply the color scheme directly. To do that you would install PackageResourceViewer if you don’t already have it installed, and then use PackageResourceViewer: Open Resource (make sure you don’t pick one of the Extract options by accident) and choose Default, then exec.py to open the internal code that executes the build.

Scroll through the file until you find the part that applies settings to the build output panel, which looks like this:

        self.output_view.settings().set("result_file_regex", file_regex)
        self.output_view.settings().set("result_line_regex", line_regex)
        self.output_view.settings().set("result_base_dir", working_dir)
        self.output_view.settings().set("word_wrap", word_wrap)
        self.output_view.settings().set("line_numbers", False)
        self.output_view.settings().set("gutter", False)
        self.output_view.settings().set("scroll_past_end", False)
        self.output_view.assign_syntax(syntax)

And add in an extra setting line to apply the color scheme and save the file.

        self.output_view.settings().set("color_scheme", "Mariana.sublime-color-scheme")

This makes the code executing the build always apply the color scheme you want any time it executes any build in any window.

The downside here is that you lose the ability for option #2 to work in builds; they can still assign a syntax but since you explictely set a color scheme, the setting in the appropriate file won’t be honored.

Additionally, this creates an override; in your Packages folder (Preferences > Browse Packages) there is now a Default folder with a file named exec.py in it. Sublime will use that in place of the internal file forever, even in case of updates and bug fixes (without warning you). Removing that file and restarting Sublime will put you back to the default though.

You can use the OverrideAudit package to warn you if the plugin gets updated on a Sublime text update, though.

1 Like

#3

Option 4: use sublime_lib.OutputPanel.Create()

If you’re creating an output panel manually in a build command, you can use the sublime_lib.OutputPanel class:

from sublime_lib import OutputPanel

my_panel = OutputPanel.create(
    window,
    "My build system",
    scope="text.plain.build",
    settings={
        'result_file_regex': file_regex,
        ...
})

my_panel.show()
my_panel.write("Hello, World!")
0 Likes

#4

Wow, thank you so much for taking the time to provide extremely easy-to-follow and nicely formatted solutions! Option 2 and Option 3 were most attractive to me. Both solutions worked great.

I have to say, I’m pleasantly surprised how much this forum has improved in user-to-user support. Years ago on the old forum, I’d consider myself lucky to even get a response to a question like this. People here are extremely helpful. You are definitely a valuable resource to this community.

Anyway, I ended up using Option 3 since it’s a bit of a hassle to modify build files that are part of packages I’ve installed like such as, PowerShell.sublime-package.

Thanks again!

0 Likes

#5

ThomSmith, thank you for taking the time to provide a forth option. I’ll keep that in mind!

0 Likes

#6

PS: I don’t want to push my luck, but do you know what two colors I need to change in respective tmTheme file to affect the colors of my build panel? I’m poking around my tmTheme file, but can’t figure out which element changes the entire background and also text color of the build panel.

0 Likes

#7

The “default” color of the foreground and background of text (that is, before a syntax highlighting rule in the theme decides to change it’s color based on what it is) is controlled by the foreground and background properties in the globals section of the color scheme.

For a sublime-color-scheme file, that would look like this:

{
    "globals":
    {
        "foreground": "red",
        "background": "blue",
    }
}

For a tmTheme file in the older format, the snippet would look like:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>name</key>
    <string>Cobalt</string>
    <key>settings</key>
    <array>
        <dict>
            <key>settings</key>
            <dict>
                <key>foreground</key>
                <string>#FFFFFF</string>
                <key>background</key>
                <string>#002240</string>
            </dict>
        </dict>
    </array>
</dict>
</plist>

Color scheme files with the same base name combine together,so if you want to tweak the colors of the color scheme the easiest way to do that is create a sublime-color-scheme file in your User package with the same base name as the color scheme that you’re using and put just the content shown above in the file (but with less ugly colors :wink: ). As soon as you save the file, Sublime will load it and combine it with the existing color information.

This applies even if the color scheme you’re using is a tmTheme file; if you were using Example.tmTheme as your color scheme, you would create Example.sublime-color-scheme to augment it.

See also the color scheme docs for all of the myriad ways you can assign or tweak colors.

0 Likes

#8

I didn’t even realize that Sublime Text 3 has sublime-color-scheme files. I’m still using my old custom, MKANET.tmTheme file …located under my \Packages\Color Scheme folder; which was a PITA to make (even with the help of the https://tmtheme-editor.herokuapp.com online theme editor).

I was easily able to make my own custom Buildpane.sublime-color-scheme file in my User package.

Is there an easy way to convert my old MKANET.tmTheme to the new format? I imagine it would be very time consuming to do by hand.

0 Likes

#9

While you have your tmTheme file open, you can pick the Convert Color Scheme command from the command palette to perform this sort of conversion automatically. It provides you with some options on how you want to do the conversion, which controls what happens to the colors in the color scheme.

The options you get are:

  • HSL - use HSL variables for colors
  • Hex - use hex variables for colors
  • None - hardcode all colors

The first two options set up a variables section to define variables based on the colors in the color scheme, which generally makes it easier to make changes later because by changing the color of a variable you change it’s value everywhere instead of having to manually find and replace all of the places the color is defined. You also get the ability to easily create colors based on other colors.

The last option generates a straight conversion between the older format at the new, so all of the color rules and the globals will have their colors set directly as straight hex values with no variables at all (but you still get the benefit of the file not being in XML :wink:).

0 Likes