1
0
mirror of https://github.com/golang/go synced 2024-11-18 13:44:48 -07:00
go/cmd/golsp/main.go
Rebecca Stambler d457fc8054 cmd/golsp: support formatting in golsp
This commit adds support for some basic commands necessary for
integration with VSCode. It also adds support for the
"textDocument/format" method.

Change-Id: I8fd0e33ca544ab65d3233efe2fef9716446ad4ff
Reviewed-on: https://go-review.googlesource.com/138135
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
2018-09-27 17:02:42 +00:00

105 lines
2.4 KiB
Go

// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// The golsp command is an LSP server for Go.
// The Language Server Protocol allows any text editor
// to be extended with IDE-like features;
// see https://langserver.org/ for details.
package main // import "golang.org/x/tools/cmd/golsp"
import (
"context"
"flag"
"fmt"
"io"
"log"
"os"
"runtime"
"runtime/pprof"
"runtime/trace"
"golang.org/x/tools/internal/jsonrpc2"
"golang.org/x/tools/internal/lsp"
)
var (
cpuprofile = flag.String("cpuprofile", "", "write CPU profile to this file")
memprofile = flag.String("memprofile", "", "write memory profile to this file")
traceFlag = flag.String("trace", "", "write trace log to this file")
// Flags for compatitibility with VSCode.
logfile = flag.String("logfile", "", "filename to log to")
mode = flag.String("mode", "", "no effect")
)
func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "usage: golsp [flags]\n")
flag.PrintDefaults()
}
flag.Parse()
if flag.NArg() > 0 {
flag.Usage()
os.Exit(2)
}
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal(err)
}
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal(err)
}
// NB: profile won't be written in case of error.
defer pprof.StopCPUProfile()
}
if *traceFlag != "" {
f, err := os.Create(*traceFlag)
if err != nil {
log.Fatal(err)
}
if err := trace.Start(f); err != nil {
log.Fatal(err)
}
// NB: trace log won't be written in case of error.
defer func() {
trace.Stop()
log.Printf("To view the trace, run:\n$ go tool trace view %s", *traceFlag)
}()
}
if *memprofile != "" {
f, err := os.Create(*memprofile)
if err != nil {
log.Fatal(err)
}
// NB: memprofile won't be written in case of error.
defer func() {
runtime.GC() // get up-to-date statistics
if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatalf("Writing memory profile: %v", err)
}
f.Close()
}()
}
if *logfile != "" {
f, err := os.Create(*logfile)
if err != nil {
log.Fatalf("Unable to create log file: %v", err)
}
defer f.Close()
log.SetOutput(io.MultiWriter(os.Stderr, f))
}
if err := run(context.Background()); err != nil {
log.Fatal(err)
}
}
func run(ctx context.Context) error {
return lsp.RunServer(ctx, jsonrpc2.NewHeaderStream(os.Stdin, os.Stdout), jsonrpc2.Log)
}