Sublime Forum

Bold/italic style in region API

#1

add_regions can be used to underline regions. And with a generated color scheme, it can also be tricked into changing foreground/background colors. However, when I try to add markup.bold or markup.italic scopes, the font style is not changed. I am sure that the scope is applied because if I add "foreground": "#ff0000" to the markup.bold definition, the text becomes red but not bold. So, does that look like a bug and is there a workaround?

0 Likes

#2

markup.bold is just the name of the scope. It doesn’t mean that adding that scope to a region will render it bold (same goes for italics).

I don’t think using the View.add_regions API, one can change the font style of the region(s) in question. You can only use the colors sourced from the color scheme file or the pseudo scopes (Glad to be proven wrong on this).

0 Likes

#3

I know, I have added "font_style": "bold" to the color scheme file already.

What are the pseudo scopes?

0 Likes

#4

Have a look at the View.add_regions documentation here.
https://www.sublimetext.com/docs/api_reference.html

It explains about the pseudo scopes you can use.

0 Likes

#5

Wow, I was using https://www.sublimetext.com/docs/3/api_reference.html all the time and thought it was the latest version. I believe Sublime docs don’t have easy to follow structure.

0 Likes

#6

Yes. Via a color scheme, you can apply any font style (as per what is in the docs) to any scope you desire. I just don’t think it is possible programmtically to change it, though(programmatic -> View.add_regions)

0 Likes

#7

Does that mean the scope one assigns via syntax definitions are treated differently from the ones added with add_regions? For instance, adding markup.bold to some text via syntax files works while add_regions keeps the font regular.

0 Likes

#8

Not sure what do you mean by this. Syntax definitions applies scopes to a body of text based on RegEx. The scopes are later used by color scheme to apply color to the said body of text. You can then target those scopes in View.add_regions to apply some color (based on what color has been assigned to that scope in the color scheme).

For example, in my color scheme, let’s say I have assigned the color green to the scope selector string.
So doing View.add_regions("test", [sublime.Region(0, 5)], "string") will apply that green color to the first 5 words in the currently open document. It just picks up the color and not the font style.

Similarly, doing something like View.add_regions("test", [sublime.Region(0, 5)], "region.redish") will apply a redish color (based on what is the nearest color that is “red”).

0 Likes

#9

InteractiveRun.sublime-color-scheme:

{
    "name": "Interactive shell",
    "globals": {
        "background": "#000000",
        "foreground": "#ffffff",
        "caret": "#d3d7cf",
        "block_caret": "#d3d7cf",
        "selection": "#303030",
        "selection_foreground": "#ffffff",
        "selection_border": "#ffffff",
        "selection_border_width": "0",
        "inactive_selection": "#202020",
        "inactive_selection_foreground": "#ffffff",
        "selection_corner_style": "square"
    },
    "rules": [
        {
            "scope": "markup.bold",
            "font_style": "bold"
        }
    ]
}

Case 1

InteractiveRun.sublime-syntax:

%YAML 1.2
---
name: Interactive
scope: source.interactive

contexts:
  main:
    - match: \b(hello)\b
      scope: markup.bold

Test file:

hello

Result:

The text is bold.

Case 2

Plain text syntax.

Test file:

hello

Run in console:

view.add_regions("helloregion", [sublime.Region(0, 5)], "markup.bold", flags=sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE)

Result:

The text is regular.


Notice that if I use "foreground": "#ff0000" (or background) style instead of "font_style": "bold" and remove DRAW_NO_FILL flag, the text is highlighted in red correctly in both cases.

0 Likes

#10

Yes. Everything you presented is correct. Your hello would get the markup.bold scope but you haven’t provided any foreground or background to it in the color scheme which can be leveraged by add_regions to provide the color. So it just applies white. (Again the presence or absence of font_style for that scope doesn’t matter)

0 Likes

#11

Okay, I expected add_regions to behave the same way as syntax definitions with some set of flags, but it looks like they are inherently different and using the same set of scopes for them is meaningless. Thanks for the response.

0 Likes

#12

I think you are confusing on what purpose each of them serve.

A syntax definition provides scopes. Without the color scheme to target those scopes and provide color, a syntax definition is pretty much useless. The vice versa is also true. Without knowing what scopes to target, a color scheme can’t do it’s job.

The job of add_regions is to add a “visual marker” to a certain region of the buffer. This “visual marker” can be squiggles, underlines, adding a box around the text, color etc. Note that add_regions doesn’t assign scopes. That’s the syntax definition’s job.

0 Likes

#13

The problem is that often the syntax is too complex to be handled with the syntax definitions Sublime supports, so one has to make a plugin that does the parsing and assigns the scopes. Sadly, one can only simulate that by adding simple control sequences like [[push:comment]] to the text which would then be parsed by sublime-syntax, and hiding the controls with add_regions (hopefully at least that’s supported).

0 Likes

#14

What a joy. You can’t hide text via plugin API. The best method you have is fold, but it leaves a giant distracting yellow rectangle, and there is no way to remove it.

0 Likes

#15

Yes, as I understand it, the View.add_regions method is not meant to alter the foreground color of text, but the colors from the given scope are only used for the underline/outline and the optional gutter icon. In particular, the corresponding foreground color from the color scheme is used to tint the icon, and background is used for the underline/outline color, which falls back to foreground if background isn’t specified in the color scheme rule.

There is a workaround to change the foreground color from add_regions via setting a slightly different background color in the color scheme rule, described in https://github.com/sublimehq/sublime_text/issues/817#issuecomment-95211154, but I wouldn’t recommend it, as it is not intended to arbitrarily change the text foreground color from plugins. And it doesn’t seem to work with the font style (bold/italic).

There might be other valid use cases to adjust font styles or text color, for example from language servers (VS Code refers to this as “semantic highlighting”), and you can read more about it in the linked GitHub issue.

0 Likes