Getting Started

Generate a working server, run its tests, and connect it to an editor.

Generate a Server

go run github.com/owenrumney/go-lsp/cmd/scaffold@latest \
  --name mylang \
  --module github.com/you/mylang-lsp \
  --lang mylang \
  --features hover,completion,diagnostics

The scaffold creates a server entrypoint, a handler package, starter tests using servertest, and a go.mod.

Build and Test

cd mylang-lsp
go test ./...
go build -o mylang-lsp .

Core Handler Shape

type Handler struct {
    documents *document.Store
    client    *server.Client
}

func New() *Handler {
    return &Handler{documents: document.NewStore()}
}

func (h *Handler) SetClient(client *server.Client) {
    h.client = client
}

func (h *Handler) Initialize(context.Context, *lsp.InitializeParams) (*lsp.InitializeResult, error) {
    return &lsp.InitializeResult{
        ServerInfo: &lsp.ServerInfo{Name: "mylang", Version: "0.1.0"},
    }, nil
}

func (h *Handler) Shutdown(context.Context) error { return nil }

Connect Your Editor

Neovim

vim.lsp.start({
  name = "mylang-lsp",
  cmd = { "./mylang-lsp" },
})

Helix

[[language]]
name = "my-language"
language-servers = ["mylang-lsp"]

[language-server.mylang-lsp]
command = "./mylang-lsp"

Next

Read Core Concepts for handler interfaces and auto-registration, then Documents for maintaining open file state.