This commit is contained in:
Martino Ferrari
2026-01-19 23:10:09 +01:00
parent c4c29a640d
commit 69d3360289
12 changed files with 1122 additions and 0 deletions

109
internal/lsp/server.go Normal file
View File

@@ -0,0 +1,109 @@
package lsp
import (
"bufio"
"encoding/json"
"fmt"
"io"
"os"
)
type JsonRpcMessage struct {
Jsonrpc string `json:"jsonrpc"`
Method string `json:"method,omitempty"`
Params json.RawMessage `json:"params,omitempty"`
ID interface{} `json:"id,omitempty"`
Result interface{} `json:"result,omitempty"`
Error *JsonRpcError `json:"error,omitempty"`
}
type JsonRpcError struct {
Code int `json:"code"`
Message string `json:"message"`
}
func RunServer() {
reader := bufio.NewReader(os.Stdin)
for {
msg, err := readMessage(reader)
if err != nil {
if err == io.EOF {
break
}
fmt.Fprintf(os.Stderr, "Error reading message: %v\n", err)
continue
}
handleMessage(msg)
}
}
func readMessage(reader *bufio.Reader) (*JsonRpcMessage, error) {
// LSP uses Content-Length header
var contentLength int
for {
line, err := reader.ReadString('\n')
if err != nil {
return nil, err
}
if line == "\r\n" {
break
}
if _, err := fmt.Sscanf(line, "Content-Length: %d", &contentLength); err == nil {
continue
}
}
body := make([]byte, contentLength)
_, err := io.ReadFull(reader, body)
if err != nil {
return nil, err
}
var msg JsonRpcMessage
err = json.Unmarshal(body, &msg)
return &msg, err
}
func handleMessage(msg *JsonRpcMessage) {
switch msg.Method {
case "initialize":
respond(msg.ID, map[string]interface{}{
"capabilities": map[string]interface{}{
"textDocumentSync": 1, // Full sync
"hoverProvider": true,
"definitionProvider": true,
"referencesProvider": true,
"completionProvider": map[string]interface{}{
"triggerCharacters": []string{"=", ".", "{", "+", "$"},
},
},
})
case "initialized":
// Do nothing
case "shutdown":
respond(msg.ID, nil)
case "exit":
os.Exit(0)
case "textDocument/didOpen":
// Handle file open
case "textDocument/didChange":
// Handle file change
case "textDocument/hover":
// Handle hover
}
}
func respond(id interface{}, result interface{}) {
msg := JsonRpcMessage{
Jsonrpc: "2.0",
ID: id,
Result: result,
}
send(msg)
}
func send(msg interface{}) {
body, _ := json.Marshal(msg)
fmt.Printf("Content-Length: %d\r\n\r\n%s", len(body), body)
}