Six open issues close with this one, and so does the thing people have asked for
most: your comments now reach the generated .gd.
Your comments survive
# and ## alike. Rename a file and its class reference comes with it, and a ##
block written above a function now shows up in the call hint. Before this, that text
lived in the .gate and reached nothing Godot or an editor could read.
Comments written inside brackets come through too: array literals, dictionary
literals, enum bodies and a call's argument list. A construct carrying a comment
takes its one-per-line form so each comment has a line of its own. One carrying none
is emitted exactly as it was before, so nothing in your project gets reformatted for
a feature you are not using.
Two places still lose one. A comment inside a lambda body belongs to the statements
in that body rather than to the argument list holding it, and one inside grouping
parentheses has nothing to attach to, since GATE drops the parentheses and writes the
expression out again.
Your editor is your own
GATE speaks LSP over a loopback socket from inside the Godot editor, the way Godot's
own GDScript server does, so you can edit a .gate in Neovim, Helix, Zed or VS Code
with completion, diagnostics, go to definition, hover and an outline.
Diagnostics come in two tiers. As you type, you get the errors and warnings Godot's
own script editor shows on the same file, because both come out of one pass over one
set of tokens. When you save, you get the errors a compile finds as well: unknown
types, the null analysis, the superset checks. Those used to reach you only through
Godot's Output panel, where an external editor cannot see them.
It is off by default. Turn on gate/lsp/enabled. It binds 127.0.0.1 and nothing
else, gate/lsp/port is 6100, and a port already taken is reported rather than
quietly swapped for another.
From the issue tracker
- Generic functions, #8, @SlashScreen.
func first<T>(xs: T[]) -> Tis a
template, and one copy is emitted per set of type arguments you use. Another file's
is called through its class name or a preloaded const. - Conditional compilation, #2, @ateo-jan.
@if,@elif,@elseand@endif,
with the symbols read from Godot and from your export preset. A define can carry a
value, not just a name. @globalclasses, #6, @squidt.@global class Foo extends Node2D:gets its own
script with a realclass_name, so you can attach it to a node.- Typed destructuring, #9, @Dead-Optimist.
var [Move[] moves, Mark[] marks] = componentsgives each name its type. - Multidimensional arrays, #3, @penggrin12.
int[,]is another spelling of
int[][], off by default behindgate/features/multidim_arrays. - The editor answers, #11, @Cloneian28. Completion offers the names the caret can
actually see and the base's virtuals. A call shows the signature of what you are
calling and its documentation. Private functions are back in the script editor's
method list. Dragging a node from the Scene dock into a.gateworks. Ctrl-click
and F1 place an enum's members. And choosing GATE in Attach Script writes the
.gateand hands Godot the.gd.
Arrow lambdas are in too, nums.map((x: int) => x + 1), and a pipe operator,
x |> f(), which is experimental and off by default.
Five settings
Type First, Shorthand Types, Type Names As Values, Multidim Arrays and Pipe Operator,
under Project Settings > Gate. Two are on by default and three are off. Write
something a switch is off for and you get an error naming the setting and the spelling
to use instead. A default is never written into your project.godot, so a project
that leaves them alone carries nothing.
It converts faster
Each file compiles once now instead of three times, and opening a converted project
again compiles nothing. A file GATE could not verify on the first pass is saved as
built but unchecked, so the next session checks it instead of building it all over
again.
Thanks to NekkoKan on the Discord, who has been supportive throughout and found
bugs I had missed.
Requires Godot 4.7+.