lsp.go 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. // Package lsp implements a language server for Elvish.
  2. package lsp
  3. import (
  4. "context"
  5. "os"
  6. "github.com/sourcegraph/jsonrpc2"
  7. "src.elv.sh/pkg/prog"
  8. )
  9. // Program is the LSP subprogram.
  10. type Program struct {
  11. run bool
  12. }
  13. func (p *Program) RegisterFlags(fs *prog.FlagSet) {
  14. fs.BoolVar(&p.run, "lsp", false, "run language server instead of shell")
  15. }
  16. func (p *Program) Run(fds [3]*os.File, _ []string) error {
  17. if !p.run {
  18. return prog.ErrNextProgram
  19. }
  20. ctx, cancel := context.WithCancel(context.Background())
  21. defer cancel()
  22. s := server{}
  23. conn := jsonrpc2.NewConn(ctx,
  24. jsonrpc2.NewBufferedStream(transport{fds[0], fds[1]}, jsonrpc2.VSCodeObjectCodec{}),
  25. s.handler())
  26. <-conn.DisconnectNotify()
  27. return nil
  28. }
  29. type transport struct{ in, out *os.File }
  30. func (c transport) Read(p []byte) (int, error) { return c.in.Read(p) }
  31. func (c transport) Write(p []byte) (int, error) { return c.out.Write(p) }
  32. func (c transport) Close() error {
  33. if err := c.in.Close(); err != nil {
  34. c.out.Close()
  35. return err
  36. }
  37. return c.out.Close()
  38. }