EditorSyntaxHighlighter in Godot – Complete Guide

Welcome to this comprehensive tutorial on the EditorSyntaxHighlighter class in Godot 4, where we delve into the art of customization and enhancement of your coding experience within the Godot Engine’s script editor. As you embark on this coding adventure, you’ll find that the ins and outs of syntax highlighting not only make your script more readable but also infinitely more manageable. This tutorial is perfect for both beginners wanting to understand the basics of Godot’s editor scripting capabilities and for experienced programmers looking to refine their skills.

What is EditorSyntaxHighlighter?

The EditorSyntaxHighlighter is a class provided by the Godot game engine—an open-source, multi-platform game engine beloved by indie developers and hobbyists alike. In essence, the EditorSyntaxHighlighter is the backbone of visual aids that make coding less of a chore and more of a seamless process.

What is it for?

Syntax highlighting illuminates patterns in your code, transforms the monochrome text into a canvas of color-coded cues, and organizes your code into a more readable format. This purpose-built tool helps you quickly identify elements within your scripts, such as variables, functions, and control structures, greatly reducing the cognitive load when writing or reviewing code.

Why Should I Learn About it?

Learning about the EditorSyntaxHighlighter not only enhances your coding efficiency but also opens up the possibility to tailor your scripting environment to your liking. Understanding and using this class can improve your scripting workflow, cut down on errors, and make your foray into Godot game development that much more enjoyable.

Stay tuned as we unfold how to utilize the EditorSyntaxHighlighter in Godot 4 with engaging examples, practical applications, and a sprinkle of game development magic to keep things interesting!

CTA Small Image
FREE COURSES AT ZENVA
LEARN GAME DEVELOPMENT, PYTHON AND MORE
ACCESS FOR FREE
AVAILABLE FOR A LIMITED TIME ONLY

Implementing a Custom Syntax Highlighter

Let’s dive right into enhancing our script editing experience by implementing a custom syntax highlighter. We start by creating a class that extends the EditorSyntaxHighlighter. This class can interact with the Godot editor, allowing us to define stylistic rules for different syntactic elements of our scripting language.

class MySyntaxHighlighter extends EditorSyntaxHighlighter:
    func _get_name() -> String:
        return "MyCustomHighlighter"

    func _supports(gdscript: bool) -> bool:
        return true

In the snippet above, we define the _get_name function to identify our syntax highlighter and the _supports function to specify that it supports GDScript (Godot’s default scripting language). Next, let’s add rules to highlight keywords and datatypes.

var _keywords = ["if", "else", "while", "for", "break", "continue", "return"]
var _datatypes = ["int", "String", "Array", "Dictionary"]

func _highlight(parsing_result: Dictionary) -> Array:
    var color_regions: Array = []
    for token in parsing_result["tokens"]:
        if token["type"] == GDScriptTokenizer.TOKEN_IDENTIFIER:
            if token["text"] in _keywords:
                color_regions.append(
                    _make_color_region(token["column"], token["end_column"], keyword_color)
                )
            elif token["text"] in _datatypes:
                color_regions.append(
                    _make_color_region(token["column"], token["end_column"], datatype_color)
                )
    return color_regions

By iterating through all tokens provided by the parsing_result and checking their type and text, we can selectively apply colors. We introduced two arrays—_keywords and _datatypes, to define our custom groups, and _highlight method to apply the highlighting.

We use the _make_color_region helper function to create color regions for our highlighter. This function will take the start column, end column, and a color to create a segment of text to be highlighted.

func _make_color_region(start_col: int, end_col: int, color: Color) -> Array:
    return [start_col, end_col, color, false]

This function constructs an array containing the starting column, ending column, the color for the segment, and a boolean indicating whether this segment can be merged with others.

Customizating the Color Scheme

A critical aspect of syntax highlighting is the color scheme. It needs to be accessible and provide enough contrast for different syntax elements. Here’s how to define custom colors for our highlighter.

var keyword_color = Color(0.8, 0.5, 0.2)  # An orange shade for keywords
var datatype_color = Color(0.2, 0.5, 0.8)  # A bluish shade for data types

These are color definitions for our keywords and datatypes. Of course, these colors are just examples—you could customize these to suit whatever color scheme you find most appealing.

Finally, let’s integrate our custom syntax highlighter into the Godot Editor so that it’s used in the script editor. We do this by using the add_script_editor_highlighter() function provided by Godot.

func _enter_tree():
    add_script_editor_highlighter(MySyntaxHighlighter.new())

With the _enter_tree method, we ensure that our syntax highlighter is added when our plugin/script is enabled or loaded in the editor.

In the next part, we’ll continue to enrich our syntax highlighter with additional features like highlighting strings and comments, and deal with error handling. Stay with us as we build upon our knowledge to elevate our code editor to the next level with Godot!Enhancing our syntax highlighter further requires that we distinguish between strings, comments, and other code elements. For that, we need to define additional rules and colors. Let’s continue by highlighting strings and comments, which are common elements in any programming language.

To identify strings and comments, we look again at the `type` of each `token`. Godot’s tokenizer class, `GDScriptTokenizer`, has specific types for strings, comments, and other syntactic elements. We’ll define colors for these types and include them in our `_highlight` method:

var string_color = Color(0.2, 0.8, 0.2)  # A green shade for strings
var comment_color = Color(0.5, 0.5, 0.5)   # A grey shade for comments

func _highlight(parsing_result: Dictionary) -> Array:
    var color_regions: Array = []
    for token in parsing_result["tokens"]:
        match token["type"]:
            GDScriptTokenizer.TOKEN_IDENTIFIER:
                if token["text"] in _keywords:
                    color_regions.append(
                        _make_color_region(token["column"], token["end_column"], keyword_color)
                    )
                elif token["text"] in _datatypes:
                    color_regions.append(
                        _make_color_region(token["column"], token["end_column"], datatype_color)
                    )
            GDScriptTokenizer.TOKEN_STRING:
                color_regions.append(
                    _make_color_region(token["column"], token["end_column"], string_color)
                )
            GDScriptTokenizer.TOKEN_COMMENT:
                color_regions.append(
                    _make_color_region(token["column"], token["end_column"], comment_color)
                )
    return color_regions

With these additions, our custom syntax highlighter will now colorize strings and comments as well. We’ve used the `match` statement to replace our `if-elif` chains for clarity and better organization within the code.

As we progress, we may want to add additional complexity, like highlighting class names or recognizing built-in Godot functions. Let’s define a color for Godot’s built-in functions and then update our `_highlight` method to apply it:

var function_color = Color(0.8, 0.2, 0.5)  # A purple shade for functions

# Assuming we have a list of builtin functions
var _builtin_funcs = ["print", "randf", "lerp", "clamp"]

func _highlight(parsing_result: Dictionary) -> Array:
    var color_regions: Array = []
    # ... other token processing ...

            GDScriptTokenizer.TOKEN_IDENTIFIER:
                if token["text"] in _builtin_funcs:
                    color_regions.append(
                        _make_color_region(token["column"], token["end_column"], function_color)
                    )
    # ... other token processing ...
    return color_regions

Now, let’s talk about error handling in our code. Syntax errors can occur, and we might want to highlight these to grab the user’s attention quickly. For demonstration, let’s simply define a bold red color for syntax errors and update our method to include error highlighting:

var error_color = Color(1.0, 0.0, 0.0)  # A bold red for errors

func _highlight(parsing_result: Dictionary) -> Array:
    var color_regions: Array = []
    # ... existing token processing ...

    for error in parsing_result["errors"]:
        color_regions.append(
            _make_color_region(error["column"], error["end_column"], error_color)
        )

    return color_regions

This example assumes that the parsing result contains a list of errors with the appropriate ‘column’ and ‘end_column’ indices to highlight. We’ve now covered the basics of enhancing the Godot script editor with custom syntax highlighting. These features can be further expanded to suit the specific needs of your project or to highlight custom scripting elements you’ve used in your game.

Remember, with great power comes great responsibility. While it’s tempting to add many colors and rules, always aim for a color scheme that’s easy on the eyes and adds clarity to your code base. Happy coding and game creating with Godot!Alright, diving deeper into the realm of EditorSyntaxHighlighter customization in Godot, let’s expand our toolkit by recognizing advanced patterns such as constants and class names. Additionally, we may want to style different elements further or introduce some interactivity by adding mouse-over text hints. Handling complex language features may seem daunting, but with Godot’s robust API, we have the tools at our fingertips.

Highlighting Constants

Constants in code are typically written in ALL_CAPS and serve as a key part of code readability. Let’s define a style for constants in our highlighter. We’ll use a bold font color to make them stand out.

var constant_color = Color(0.6, 0.6, 0.1, 1.0)  # A gold shade for constants

func _highlight(parsing_result: Dictionary) -> Array:
    var color_regions: Array = []
    # ... existing token processing ...

    for token in parsing_result["tokens"]:
        match token["type"]:
            GDScriptTokenizer.TOKEN_CONSTANT:
                color_regions.append(
                    _make_color_region(token["column"], token["end_column"], constant_color)
                )
    # ... remainder of token processing ...
    return color_regions

In this code example, we have added a new case to our match statement to check for `TOKEN_CONSTANT`. When detecting a constant, we apply our predefined `constant_color`.

Differentiating Class Names

Class names are generally important to highlight as they represent the blueprints of objects in your code. We’ll check if an identifier is a class name and highlight it using a distinct color.

var class_name_color = Color(0.5, 0.1, 0.5, 1.0)  # A purple shade for class names

func _highlight(parsing_result: Dictionary) -> Array:
    var color_regions: Array = []
    # ... existing token processing ...

    for token in parsing_result["tokens"]:
        match token["type"]:
            GDScriptTokenizer.TOKEN_IDENTIFIER:
                if _is_class_name(token["text"]):
                    color_regions.append(
                        _make_color_region(token["column"], token["end_column"], class_name_color)
                    )
    # ... remainder of token processing ...
    return color_regions

func _is_class_name(identifier: String) -> bool:
    # A hypothetical method to determine if the identifier is a class name.
    # This might involve checking a list of known class names, etc.
    # For now, this is a placeholder for demonstration purposes.
    pass

In the above example, `_is_class_name` is a placeholder function that should contain logic for determining if an identifier is a class name. This could be based on a list of known class names or other application-specific logic.

Adding Mouse-over Text Hints

Moreover, it may be beneficial to show hints when the user hovers the mouse over certain elements in the script editor. To this end, we can leverage the `_get_tooltip` method of EditorSyntaxHighlighter.

func _get_tooltip(parsing_result: Dictionary, column: int) -> String:
    for token in parsing_result["tokens"]:
        if token["start_column"] = column:
            if token["type"] == GDScriptTokenizer.TOKEN_IDENTIFIER and _is_class_name(token["text"]):
                return "Class name: " + token["text"]
            elif token["type"] == GDScriptTokenizer.TOKEN_CONSTANT:
                return "Constant value: " + str(token["value"])
    return ""

This function iterates over our tokens and finds the one that contains the column we’re querying for. Depending on the type of token, it returns a relevant tooltip. If no tokens are found, it returns an empty string.

Error Handling and Feedback

Error handling is essential for a pleasant coding experience. We can adapt our highlighter to provide instantaneous feedback to developers, which is particularly useful for learners.

func _highlight(parsing_result: Dictionary) -> Array:
    var color_regions: Array = []
    # ... existing token processing ...

    for error in parsing_result["errors"]:
        color_regions.append(
            _make_color_region(error["column"], error["end_column"], error_color)
        )
        # Add a tooltip for the error
        add_tooltip_for_region(
            error["column"], error["end_column"], "Error: " + error["message"]
        )
    return color_regions

Here we add a tooltip for each detected syntax error, providing instant feedback on what the error is—this feature could be instrumental for users who are new to the language.

These are just a sample of further modifications and extensions you can make to the EditorSyntaxHighlighter class in Godot. The actual implementation of these features may vary depending on the specific requirements of your project and language. By exploring these examples, you’ll gain a deeper understanding of the potential of Godot’s script editor, enabling you to create a highly personalized and efficient coding environment.

Embark on Your Game Development Journey

Now that we’ve explored the possibilities of customizing syntax highlighting in Godot 4, it’s time to take your knowledge to new heights. The road to mastery is long, but incredibly rewarding, and we at Zenva are here to guide you every step of the way. To continue refining your skills and expanding your knowledge in game development with Godot, our Godot Game Development Mini-Degree is the perfect next step. This collection of courses is meticulously designed to broaden your understanding and help you create stunning cross-platform games from scratch, catering to both beginners and more seasoned developers.

Delving into the Godot Game Development Mini-Degree, you’ll tackle subjects ranging from the basics of 2D and 3D game creation to more complex concepts like gameplay control, enemy engagements, and RPG mechanics. Each course comes packed with real-world projects across diverse genres, flexible 24/7 access, engaging live coding sessions, and interactive quizzes to solidify your learning experience. At Zenva, we empower you to transition seamlessly from a beginner to a professional game developer, all while earning valuable certificates that showcase your accomplishments.

For those eager to explore a broader array of topics and tools within Godot, our comprehensive catalog of Godot courses can be found here. From tackling specific aspects of game design to scripting and asset integration, there’s a course tailored to every aspect of your creative journey. We’re excited to see where your passion for game development takes you, and we’re committed to supporting your growth with our wealth of educational resources. Challenge yourself, keep learning, and let’s build amazing games together!

Conclusion

We’ve journeyed through the intricate world of Godot’s EditorSyntaxHighlighter, and you’re now equipped with the knowledge to enhance your coding canvas. This is just the beginning, a single thread in the vast tapestry of game development skills you can acquire with us. Embrace this learning curve, watch your code transform into a vivid story, and remember, every line of code you highlight is a step closer to your masterpiece.

At Zenva, we’re passionate about helping you bring your game development dreams to life. Whether you’re refining the look of your code with EditorSyntaxHighlighter or building the next hit indie game, our Godot Game Development Mini-Degree is the companion you need. Every lesson is a new door opening to worlds of creativity and technical prowess—walk through with us, and let’s craft your future in game development, one skill at a time.

FREE COURSES
Python Blog Image

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.