Skip to content

Improve highlighting for Godot shaders#86

Open
YuriSizov wants to merge 1 commit into
GDQuest:mainfrom
YuriSizov:better-gdshader
Open

Improve highlighting for Godot shaders#86
YuriSizov wants to merge 1 commit into
GDQuest:mainfrom
YuriSizov:better-gdshader

Conversation

@YuriSizov
Copy link
Copy Markdown
Contributor

@YuriSizov YuriSizov commented May 10, 2026

Please check if the PR fulfills these requirements:

  • The commit message follows our guidelines.
  • For bug fixes and features:
    • You tested the changes.

What kind of change does this PR introduce?

General improvements to the syntax highlighting for Godot shader files.

Does this PR introduce a breaking change?

No

New feature or change

What is the new behavior?

This changeset aims to provide better markup for highlighting Godot shaders, add some of the missing rules and make some others use more appropriate capture names (according to existing grammars and colors available in GUI themes for Zed. Alongside these changes the test shader file has been expanded to provide reference for many of the covered cases.

Here are some of the key changes:

  • Keywords are split into more groups, putting modifiers and control flow keywords into their own capture groups.
  • Preprocessor directives have been split from keywords and generally improved. However, there are numerous issues with parsing of these directives in the tree sitter for GDShader, so it's far from perfect still.
  • Properties and variables are now highlighted using their appropriate capture groups, whereas previously they were not highlighted at all.
  • Various capture groups that can have a built-in variation now use it appropriately, such as constants and functions.
  • Function parameters are highlighted as parameters, not as "special".
  • Type constructors/literals are highlighted as types (e.g. vec3(1.0)), not as method calls.

The highlights.scm file has also been slightly restructured.

Other information

The tree-sitter that we use for Godot shaders is not so great at this time. There are several problems with it, to name a few:

  • Preprocessor directives are not parsed consistently. #define (and its related control flow), #pragma, and #error are not parsed correctly and cannot be highlighted at all. Paradoxically, #endif is also not available for highlighting, despite other control flow being available (perhaps unintentionally). Understandably, supporting #define might be pretty hard. Should be possible to compare notes with the C/C++ grammar.

  • Since defines are not parsed at all, it seems that it doesn't know what to do with defined flags and macros in following code either.

  • Out of 4 possible ways to initialize arrays, only the third one listed in the docs is parsed correctly.

void fragment() {
	float float_arr[3] = float[3] (1.0, 0.5, 0.0); // ERROR
	int int_arr[3] = int[] (2, 1, 0); // ERROR
	vec2 vec2_arr[3] = { vec2(1.0, 1.0), vec2(0.5, 0.5), vec2(0.0, 0.0) }; // Ok.
	bool bool_arr[] = { true, true, false }; // ERROR
}
  • COLOR is not identified as a built-in, or special in any way, but SCREEN_TEXTURE is, which is not available in Godot 4. If the tree sitter should support Godot 3 and 4 at the same time, this might be an issue. In the same vein, filter_linear_mipmap is not recognized as a valid hint name; perhaps none of this family of hints are.

  • Using call_exp for cases like vec3(1.0) might be wrong? It's all internal markup, of course, and it is targettable through queries, but can be confusing.

  • Multiplicating assignement (blurred *= intensity;) throws an error between two parts of the operator.

And perhaps there is more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant