Sublime Forum

Hidden Syntax in Package to Highlight Build Results — Is it OK?

#1

Ciao.

I would like an opinion on how I’ve been handling a problem in a package I’m creating; ie., if I’ve taken the correct approach to solve it.

The solution I came up with works, but I was wondering wether it is elegant or not, if I could have taken a better approach, or if indeed it might pose a problem if I were to decide to publish the package for general use.

Link to the project mentioned here:

The Problem

Basically, I’m working on a language syntax, but I also want to the compiler errors report from Build operations to be syntax highlighted in order to use colors to make the log more readable in ST console.

Here is the achieved result:

… I’m just wondering if the end justifies the means! ie: if in my attempt to achieve this I’ve “bent the rules” to the point of making the package unfit for distribution.

Adopted Solution

In short:

  1. I’ve created an hidden syntax definition to highlight the Build log from STDIN
  2. I’ve set the Build System to use this hidden syntax to highlight results
  3. I’ve hidden in the default color scheme of my package an extra section targetting the scopes of the hidden syntax
  4. I’ve added in the hidden syntax settings to always use that color scheme

Hidden Syntax Definition

I’ve decided to take advantage of the Build Systems syntax option, so I’ve added to my package an extra syntax called Alan Compiler Output.sublime-syntax which is inteded solely for highlighting the compiler output from Build operations.

In fact, I’ve declared it as hidden:

name:    Alan Compiler Output
comment: Colors Alan build sytems error report
hidden:  true
scope:   text.alancompiler

And I didn’t asociated any file extensions with it either, since it will only be used to highlight text coming from STDIN.

I’ve then added to my package’s Build system settings to use this syntax to highlight the compiler’s output:

// "Alan.sublime-build"
{
  "shell_cmd": "alan -cc \"$file\"",
  "working_dir": "$file_path",
  "selector": "source.alan",
  "file_patterns": [ "*.alan" ],
  // ===========================================================================
  // Capture Errors and Warnings from Compiler Output for Results Navigation
  // ===========================================================================
  // Whith `-cc` option, Alan reports have this form:
  //    "sourcefile.alan", line 5(24): 101 E : Error message.
  //    "sourcefile.alan", line 8(13): 200 W : Warning message.
  // ---------------------------------------------------------------------------
  "file_regex":  "^\"([^\"]+)\", line (\\d+)\\((\\d+)\\): (.*)$",
  // ===========================================================================
  // Syntax Highlight the Compiler Log (WIP experimental feature):
  "syntax": "Packages/Alan/Alan Compiler Output.sublime-syntax",
}

Color Scheme Problem and Solution

The real problem was (is) the color scheme for highlighting the results in ST console.

The syntax I’ve created for the purpose uses highly arbitrary scopes (I have no idea how a log file should be scoped), after all its only intended for “internal use”.

Which means that a dedicated color scheme is required to cover these scopes and achieve the desired coloring results.

Hijacking the Package’s Scheme

So, what I did, was to take advantage of the color scheme that I’ve created for this package, and add at its end a block of settings targetting specifically the scopes of the highlighted log.

In the Alan DarkFluo.sublime-color-scheme file, I’ve added at the end:

        },
        // \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
        //                     Alan Compiler Output Syntax
        // /////////////////////////////////////////////////////////////////////
        // The following colors are used to syntax highlight Alan compiler's
        // output during Build operatrions. The output is captured through the
        // "Alan Compiler Output" syntax definition, which is hidden to the user
        // and used only in build systems. Regardless of which color scheme the
        // users assigns to Alan syntax, the settings for "Alan Compiler Output"
        // will always refer to this color scheme in order to ensure that the
        // compiler output is colored as expected. The scopes for this syntax
        // are rather arbitrarily chosen, as there is no real use for them beside
        // coloring the error messages.
        {
            // Base Text Color
            "name": "Base Color",
            "scope": "text.alancompiler",
            "foreground": "var(grey)",
            "background": "#000000", // transparent
            "font_style": "",
        },
        {
            // Strings
            "name": "Strings",
            "scope": "string.quoted.double.alancompiler",
            "foreground": "var(tint3)",
            "background": "#000000", // transparent
        },

… where all the rules are targetting specifically the text.alancompiler scope, and should therefore not interfere with other languages using this color scheme. Also, I’m using text scopes here, instead of code.

The idea is that although the user might not be actually using the color scheme supplied with the package for any syntax, the hidden syntax used to highlight the compiler output can rely on it being present in the package, and thus use is to color the log syntax.

Enforcing the Scheme on the Hidden Syntax

I then added to the package a Alan Compiler Output.sublime-settings file, which enforces the color scheme on the ``Alan Compiler Output` syntax:

{
    "color_scheme": "Alan DarkFluo.sublime-color-scheme",
}

Whilst I know that packages should not usually fiddle with settings, I’ve reasoned that:

  1. This being a hidden syntax not intended for end-user direct use, it’s ok to enforce some settings on it.
  2. Since there seems to be no way to create a hidden color scheme, the only viable approach was to take advantage of the scheme that ships with the package.

Conclusion

As mentioned, this works, and actually looks nice since the output is nicely colored: each error type receives a specific colors combination, making it easy to read through long error reports.

Since I’ve only published one package so far, and I even with that one I had to fix some settings before it was accepted on Package.io, I wanted to know if this approach I’ve taken is OK.

Also, I didn’t know how to scope the error log from the compiler; so, right now I’ve used arbitrary scope, and even went as far as using meta scopes in the color scheme rules (but only for the hidden syntax!).

Where can I find references or examples on how to scope log files and the like?

Thanks,

Tristano (Italy)

0 Likes

#2

Although not mentioned at https://www.sublimetext.com/docs/3/color_schemes.html, I believe that files with the extension .hidden-tmTheme or .hidden-sublime-color-scheme .hidden-color-scheme will be hidden. You can always check Packages/Default/ui.py with PackageResourceViewer to be sure.

0 Likes

#3

Thanks @kingkeith !

You’re right, the .hidden-tmTheme syntax works greatly (I’ve tested it).

But the .hidden-sublime-color-scheme seems unsopported — ie, when I try to use it I get an error saying that the scheme has an invalid PList syntax, which makes me believe it’s being treated as a tmTheme regardless of the new scheme extension.

Definitely, using a separate hidden color scheme for the purpose is much cleaner, even if I have to use the old tmTheme format.

I’ve tried looking (quickly) into Default/ui.py but couldn’t find any obvious references to hidden files there.

0 Likes

#4

I’d generally try to avoid hard-coding (or soft-forcing) color schemes or modifying existing ones, even through overrides, at all costs, unless it can’t be avoided.

For log output, the proposed markup styles in the following RFC issue seem like perfect candidates:

Beause these scopes haven’t been standardized yet, you can make use of fallback scopes in your syntax definition and rely on region.yellowish and similar to be present (in dev builds). You would then use those like so:

- scope: region.yellowish markup.warning.alancompiler

Color schemes with settings for markup.warning will have those settings take precedence, while those without it can still benefit from the yellow fallback scope, which is generated by ST based on the colors used in the scheme.

2 Likes

#5

Thanks @kingkeith and @FichteFoll, your advise has helped me out a lot. I’ve mentioned you in the Acknowledgements section of my project:

I’ve started out by creating a hidden color scheme for the log syntax, so now I’ve detached it from the main syntax scheme.

I’d generally try to avoid hard-coding (or soft-forcing) color schemes or modifying existing ones, even through overrides, at all costs, unless it can’t be avoided.

I have opted for «soft-forcing» the color scheme on the hidden syntax because I’d like it to work as intended. My reasoning is that the end user will also like it to be colored as intended, without having to manually configure it; and that, at end of the day, it’s always possible to override the package defaults via User settings, but I’m convinced that the package should work out of box as expected/intended. Why would this be harmful or in violation of ST guidelines?

I’m sincerely asking you, because often I see mentioned this or that as being best practice, or that shouldn’t be done, but can’t find in-depth guidelines for them.

I haven’t yet found the time to change the scope names, but the link provided by @FichteFoll has clarified which scopes I should use, and that will be my next step.

0 Likes