1
0
Fork 0
mirror of https://github.com/laravel-ls/protocol.git synced 2026-06-16 03:54:56 +02:00
No description
Find a file
2026-03-01 23:08:21 +01:00
.github/workflows add .github/workflows/test.yml 2026-03-01 23:08:21 +01:00
base.go add more LanguageID constants 2026-02-02 19:11:13 +01:00
base_test.go add tests 2026-03-01 22:57:28 +01:00
capabilities_client.go add window features structs and types 2026-03-01 22:40:10 +01:00
capabilities_client_test.go add tests 2026-03-01 22:57:28 +01:00
capabilities_server.go Initial commit 2025-11-01 10:20:54 +01:00
capabilities_server_test.go add tests 2026-03-01 22:57:28 +01:00
client.go Initial commit 2025-11-01 10:20:54 +01:00
client_test.go add tests 2026-03-01 22:57:28 +01:00
completion.go Initial commit 2025-11-01 10:20:54 +01:00
completion_test.go add tests 2026-03-01 22:57:28 +01:00
diagnostics.go Initial commit 2025-11-01 10:20:54 +01:00
diagnostics_test.go add tests 2026-03-01 22:57:28 +01:00
document.go Initial commit 2025-11-01 10:20:54 +01:00
document_change_operation.go Initial commit 2025-11-01 10:20:54 +01:00
document_change_operation_test.go add tests 2026-03-01 22:57:28 +01:00
document_code_action.go Initial commit 2025-11-01 10:20:54 +01:00
document_code_action_test.go add tests 2026-03-01 22:57:28 +01:00
document_completion.go Initial commit 2025-11-01 10:20:54 +01:00
document_completion_test.go add tests 2026-03-01 22:57:28 +01:00
document_definition.go Initial commit 2025-11-01 10:20:54 +01:00
document_definition_test.go add tests 2026-03-01 22:57:28 +01:00
document_diagnostic.go Initial commit 2025-11-01 10:20:54 +01:00
document_diagnostic_test.go add tests 2026-03-01 22:57:28 +01:00
document_hover.go Initial commit 2025-11-01 10:20:54 +01:00
document_hover_test.go add tests 2026-03-01 22:57:28 +01:00
document_sync.go Initial commit 2025-11-01 10:20:54 +01:00
document_sync_test.go add tests 2026-03-01 22:57:28 +01:00
document_test.go add tests 2026-03-01 22:57:28 +01:00
go.mod Initial commit 2025-11-01 10:20:54 +01:00
go.sum Initial commit 2025-11-01 10:20:54 +01:00
LICENSE Adding LICENSE 2026-02-02 19:10:27 +01:00
lifecycle.go Change CancelParams.Id's type to json.Number 2026-02-09 00:22:19 +01:00
lifecycle_test.go add tests 2026-03-01 22:57:28 +01:00
progress.go add window features structs and types 2026-03-01 22:40:10 +01:00
progress_test.go add tests 2026-03-01 22:57:28 +01:00
README.md README.md: fix the code example 2026-02-18 15:28:58 +01:00
rpc.go rpc.go: in IsLspRPCErrorCode: simplify if statement. 2026-03-01 22:59:40 +01:00
rpc_test.go add tests 2026-03-01 22:57:28 +01:00
server.go Initial commit 2025-11-01 10:20:54 +01:00
server_test.go add tests 2026-03-01 22:57:28 +01:00
window.go add window features structs and types 2026-03-01 22:40:10 +01:00
window_test.go add tests 2026-03-01 22:57:28 +01:00
workspace.go Initial commit 2025-11-01 10:20:54 +01:00
workspace_test.go add tests 2026-03-01 22:57:28 +01:00

Language Server Protocol for golang

Language Server Protocol implementation in Go.

Design notes

The package does not include JSON RPC handling as that is better left to other packages.

Example

Example code using github.com/sourcegraph/jsonrpc2

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net"
	"os"

	"github.com/laravel-ls/protocol"
	"github.com/sourcegraph/jsonrpc2"
)

func handleInitialize(params protocol.InitializeParams) (protocol.InitializeResult, error) {
	// Initialization logic
	// Read more at: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initialize
	return protocol.InitializeResult{
		Capabilities: protocol.ServerCapabilities{
			TextDocumentSync: protocol.TextDocumentSyncKindFull,
		},
		ServerInfo: &protocol.ServerInfo{
			Name:    "My LSP Server",
			Version: "1.0.0",
		},
	}, nil
}

func handler(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) (any, error) {
	switch req.Method {
	case protocol.MethodInitialize:
		var params protocol.InitializeParams
		if err := json.Unmarshal(*req.Params, &params); err != nil {
			return nil, err
		}
		return handleInitialize(params)
	// ... add more methods
	default:
		// Respond with a method not found error
		return nil, &jsonrpc2.Error{
			Code:    jsonrpc2.CodeMethodNotFound,
			Message: fmt.Sprintf("Method %s not found", req.Method),
		}
	}
}

func handleConn(ctx context.Context, conn io.ReadWriteCloser) error {
	stream := jsonrpc2.NewBufferedStream(conn, jsonrpc2.VSCodeObjectCodec{})
	rpc := jsonrpc2.NewConn(ctx, stream, jsonrpc2.HandlerWithError(handler))

	select {
	case <-ctx.Done():
		return fmt.Errorf("context closed")
	case <-rpc.DisconnectNotify():
		return nil
	}
}

func main() {
	// example TCP server.
	ctx := context.Background()
	logger := log.New(os.Stderr, "[tcp-lsp] ", log.LstdFlags|log.Lmicroseconds)

	addr := "127.0.0.1:4389"
	l, err := net.Listen("tcp", addr)
	if err != nil {
		log.Fatal(err)
	}
	logger.Println("Listening on", addr)

	for {
		conn, err := l.Accept()
		if err != nil {
			logger.Println("accept error:", err)
			continue
		}

		logger.Println("Client connected:", conn.RemoteAddr())

		go func(c net.Conn) {
			defer c.Close()
			handleConn(ctx, c)
		}(conn)
	}
}

You can test your server with the following command on linux:

printf 'Content-Length: 58\r\n\r\n{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | nc 127.0.0.1 4389

Author

Henrik Hautakoski henrik@shufflingpixels.com