GALA ships with a GoLand/IntelliJ plugin and an LSP server that work together to provide a full development experience. The plugin handles local features instantly (syntax highlighting, code folding, live templates), while the LSP server (gala lsp) adds type-aware intelligence (diagnostics, completion, inlay hints, go-to-definition).
The plugin provides rich syntax highlighting for all GALA constructs — keywords, types, string interpolation expressions, comments, operators, and built-in functions. Methods with receivers, pattern matching, and sealed type destructuring are all highlighted with distinct colors.

The screenshot shows methods with receivers (func (p Person) FullInfo()), string interpolation (s"${p.name} (age ${p.age})"), and pattern matching on sealed types (case Circle(r) => ...) — all with distinct semantic coloring.
After typing a dot (.), the LSP server resolves the receiver’s type and offers context-aware completions — only the methods and fields that belong to that type. Each suggestion includes the full type signature.

Here the cursor is inside a .Map() lambda on an Order value. The completion popup shows Order’s methods (ApplyDiscount, ToSummary, Validate) with return types, and its fields (id, items, total) — all resolved from the transpiler’s type information.
Values whose type comes from a Go package used to be a dead end in the editor: no completion, nothing to click. That gap is closed — Go-backed code now behaves like GALA code.
val b = bytes.NewBufferString(...) then b.) lists the Go type’s method set and fields. Go-to-definition on a package name, a package function, or a method navigates into the Go SDK source tree.sha256.New() returns hash.Hash, defined in a package you never imported. The analyzer records the method set of named types reached through a function’s return values, so completion still works on the result.github.com/google/uuid resolve the same way the stdlib does: the LSP maps each module import path to its cached .go source directory using the same logic the compiler uses, so their types get completion and their symbols get go-to-definition.go_interop and Go-only packages are navigable — imports are resolved straight from the document, so both the package name and pkg.Symbol references land on their declaration..Size() / .ByteSize() magic methodsThe transpiler lowers .Size() / .ByteSize() on Go primitive receivers (string, slice, map) to len(...) / utf8.RuneCountInString(...). Those receivers carry no GALA type metadata, so the editor used to know nothing about them. The LSP now mirrors the transpiler’s rule: both resolve to int, Size() is offered on string/slice/map and ByteSize() on string, and neither raises a false diagnostic. Because these methods have no source definition, go-to-definition on them correctly resolves to nothing rather than jumping to an unrelated same-named method.
The LSP server displays inferred types as inline hints next to val and var declarations. These hints come directly from the transpiler’s type resolver — the same types used for code generation — so they are always accurate.

Inlay hints show Tuple[int, int] for pair declarations, int for simple values, and track types through function returns — all without explicit type annotations in the source code.

The transpiler tracks types through method chains: validated.Map(...) produces Option[Order], chaining .Map((o) => o.ToSummary()) produces Option[string], and .GetOrElse("No order") unwraps to string. Each step is visible in the editor.
The plugin provides a structure view panel showing the outline of your GALA file — types, sealed variants, methods, and fields at a glance.

The structure view displays sealed type Shape with its variants (Circle, Rectangle, Triangle), each variant’s fields, and the auto-generated Apply/Unapply companion methods.
use (scoped-resource binding) and bind / also (do-notation), with the bound name clickable, renameable, and find-usages-awarefunc, val, var, match, if, for, sealed, struct, lambda, main, println, sinterpgala lsp)defer (GALA-E0036)go_interop and other Go-only packagesuse/bind/also, and .Size()/.ByteSize() on Go primitiveslen, append, make, panic, …) are filtered out of completion against the transpiler’s own authoritative list, so the editor never suggests code the compiler rejectsval/var declarationsgala-intellij-plugin.zip from releases.gala fileAdd to .vscode/settings.json:
{
"lsp.servers": {
"gala": {
"command": "gala",
"args": ["lsp"],
"filetypes": ["gala"]
}
}
}
require('lspconfig.configs').gala = {
default_config = {
cmd = { 'gala', 'lsp' },
filetypes = { 'gala' },
root_dir = require('lspconfig.util').root_pattern('gala.mod', '.git'),
},
}
require('lspconfig').gala.setup({})
Run gala lsp in a terminal. It should start and wait for JSON-RPC messages on stdin/stdout. If you see no output and no errors, the server is running correctly.