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({})
The GALA plugin connects Claude Code to gala lsp, so an AI agent editing .gala files uses the same analysis as your editor:
The plugin starts the gala binary but does not include it. Install the GALA CLI first (see Getting Started) and check that gala version works in the terminal you start Claude Code from. Then run in Claude Code:
/plugin marketplace add martianoff/gala
/plugin install gala@gala
Projects created with gala new include a .claude/settings.json that declares the marketplace, so Claude Code installs and enables the plugin once you trust the project folder.
If gala is not on the PATH, Claude’s LSP tool fails with Command 'gala' not found and no GALA diagnostics reach it. Diagnostics cover what the GALA transpiler checks; errors that only the Go compiler finds in the generated code still need gala build. Full instructions: ide/claude-code.
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.