Goose in other editors
The compiler is its own language server: goose lsp
speaks the Language Server Protocol on stdin and stdout, so any editor
with an LSP client can use it. VS Code has an extension that starts it for you. For
Neovim, Helix and Emacs, the configuration below is all it takes.
Every snippet starts goose lsp with the compiler on
PATH; where it is not, put the executable's full path in place of
goose. The server finds the standard library the way
goose check does (GOOSE_STDLIB, or the
stdlib/ directory near the executable). For a compiler away
from its checkout, add --stdlib and the directory to the
command: goose lsp --stdlib /path/to/goose/stdlib.
Each open file is analyzed as a program of its own, with the files it
imports. To have a module checked as part of the program that imports it
(and the errors of that program shown in it), name the program's entry
file in the client's initialization options, as an absolute path:
{ "entryFiles": ["/path/to/project/main.goose"] }. The
snippets show where these options go.
The server's semantic tokens color names by what they resolve to (functions, types, fields, variants, parameters, variables), not keywords, strings or comments; the TextMate grammar is VS Code's alone.
Neovim
Neovim 0.11 or later, in init.lua:
vim.filetype.add({ extension = { goose = 'goose' } })
vim.lsp.config('goose', {
cmd = { 'goose', 'lsp' },
filetypes = { 'goose' },
root_markers = { '.git' },
-- init_options = { entryFiles = { '/path/to/project/main.goose' } },
})
vim.lsp.enable('goose')On Neovim 0.10, start it from the filetype instead:
vim.filetype.add({ extension = { goose = 'goose' } })
vim.api.nvim_create_autocmd('FileType', {
pattern = 'goose',
callback = function(ev)
vim.lsp.start({ name = 'goose', cmd = { 'goose', 'lsp' }, root_dir = vim.fs.root(ev.buf, { '.git' }) })
end,
})What it shows: diagnostics, hover (K), go to definition
(CTRL-]), references (grr), rename
(grn), document symbols (gO), signature help
(CTRL-S in Insert mode), completion
(CTRL-X CTRL-O, or as you type with
vim.lsp.completion.enable) and semantic highlighting, by
default; inlay hints with vim.lsp.inlay_hint.enable(),
folding with foldmethod=expr and
foldexpr=v:lua.vim.lsp.foldexpr(), and code lenses with
vim.lsp.codelens.refresh() (on BufEnter and
InsertLeave, say). The lenses above generic functions count
their instantiations; to list them with
vim.lsp.codelens.run(), give Neovim the command and tell
the server it has it:
vim.lsp.commands['goose.showInstantiations'] = function(command)
vim.ui.select(command.arguments[2], { prompt = 'Instantiations of ' .. command.arguments[1] }, function() end)
end
-- and in vim.lsp.config('goose', ...):
-- init_options = { commands = { 'goose.showInstantiations' } },Helix
In languages.toml (in Helix's configuration directory,
or .helix/ in the project):
[language-server.goose]
command = "goose"
args = ["lsp"]
# config = { entryFiles = ["/path/to/project/main.goose"] }
[[language]]
name = "goose"
scope = "source.goose"
file-types = ["goose"]
roots = [".git"]
comment-token = "//"
indent = { tab-width = 4, unit = " " }
language-servers = ["goose"](config is what Helix sends as the initialization
options.)
What it shows: diagnostics, hover (space k), go to
definition (gd), references (gr), rename
(space r), document and workspace symbols
(space s, space S), signature help and
completion as you type, and inlay hints with
display-inlay-hints = true under [editor.lsp]
in config.toml. Helix highlights with tree-sitter grammars,
of which Goose has none, and has no semantic tokens, folding or code
lenses, so files show uncolored.
Emacs
With Eglot (built in since Emacs 29), in init.el:
(define-derived-mode goose-mode prog-mode "Goose"
(setq-local comment-start "// "))
(add-to-list 'auto-mode-alist '("\\.goose\\'" . goose-mode))
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs '(goose-mode "goose" "lsp")))
(add-hook 'goose-mode-hook #'eglot-ensure)
For entry files, the server program takes the options after the
command:
'(goose-mode "goose" "lsp" :initializationOptions (:entryFiles ["/path/to/project/main.goose"])).
What it shows: diagnostics through Flymake, hover and signature help
in ElDoc, go to definition (M-.), references
(M-?), rename (eglot-rename), document symbols
in Imenu, workspace symbols (xref-find-apropos), completion
(completion-at-point) and inlay hints; the newest Eglot,
from GNU ELPA, highlights with semantic tokens too
(eglot-semantic-tokens-mode). Eglot has no folding or code
lenses.
Goose