From 4af1dfcbd881d231e628fd12b42330ff8a24bf60 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Tue, 11 Aug 2020 18:13:16 -0400 Subject: [PATCH] Handle initialization and didOpen properly --- internal/buffer/buffer.go | 49 +++++++++++++++++++++++-------- internal/buffer/save.go | 4 ++- internal/config/runtime.go | 2 +- internal/lsp/server.go | 15 ++++++---- runtime/plugins/status/status.lua | 8 +++++ 5 files changed, 58 insertions(+), 20 deletions(-) diff --git a/internal/buffer/buffer.go b/internal/buffer/buffer.go index f06b4ed1..98349afb 100644 --- a/internal/buffer/buffer.go +++ b/internal/buffer/buffer.go @@ -166,7 +166,14 @@ func (b *SharedBuffer) lspDidChange(start, end Loc, text string) { Text: text, } - b.server.DidChange(b.AbsPath, b.version, []lspt.TextDocumentContentChangeEvent{change}) + if b.HasLSP() { + b.server.DidChange(b.AbsPath, b.version, []lspt.TextDocumentContentChangeEvent{change}) + } +} + +// HasLSP returns whether this buffer is communicating with an LSP server +func (b *SharedBuffer) HasLSP() bool { + return b.server != nil && b.server.Active } // MarkModified marks the buffer as modified for this frame @@ -400,23 +407,37 @@ func NewBuffer(r io.Reader, size int64, path string, startcursor Loc, btype BufT if !found { if btype == BTDefault { - ft := b.Settings["filetype"].(string) - l, ok := lsp.GetLanguage(ft) - if ok && l.Installed() { - b.server, _ = lsp.StartServer(l) - b.server.Initialize(gopath.Dir(b.AbsPath)) - bytes := b.Bytes() - if len(bytes) == 0 { - bytes = []byte{'\n'} - } - b.server.DidOpen(b.AbsPath, ft, string(bytes), b.version) - } + b.lspInit() } } return b } +// initializes an LSP server if possible, or calls didOpen on an existing +// LSP server in this workspace +func (b *Buffer) lspInit() { + ft := b.Settings["filetype"].(string) + l, ok := lsp.GetLanguage(ft) + if ok && l.Installed() { + b.server = lsp.GetServer(l, gopath.Dir(b.AbsPath)) + if b.server == nil { + var err error + b.server, err = lsp.StartServer(l) + if err == nil { + b.server.Initialize(gopath.Dir(b.AbsPath)) + } + } + if b.HasLSP() { + bytes := b.Bytes() + if len(bytes) == 0 { + bytes = []byte{'\n'} + } + b.server.DidOpen(b.AbsPath, ft, string(bytes), b.version) + } + } +} + // Close removes this buffer from the list of open buffers func (b *Buffer) Close() { for i, buf := range OpenBuffers { @@ -442,7 +463,9 @@ func (b *Buffer) Fini() { fmt.Fprint(util.Stdout, string(b.Bytes())) } - b.server.DidClose(b.AbsPath) + if b.HasLSP() { + b.server.DidClose(b.AbsPath) + } } // GetName returns the name that should be displayed in the statusline diff --git a/internal/buffer/save.go b/internal/buffer/save.go index f2fa0a13..e742bd1d 100644 --- a/internal/buffer/save.go +++ b/internal/buffer/save.go @@ -196,7 +196,9 @@ func (b *Buffer) saveToFile(filename string, withSudo bool) error { b.isModified = false b.UpdateRules() - b.server.DidSave(b.AbsPath) + if b.HasLSP() { + b.server.DidSave(b.AbsPath) + } return err } diff --git a/internal/config/runtime.go b/internal/config/runtime.go index 716ef76a..167347cb 100644 --- a/internal/config/runtime.go +++ b/internal/config/runtime.go @@ -1265,7 +1265,7 @@ func runtimePluginsStatusHelpStatusMd() (*asset, error) { return a, nil } -var _runtimePluginsStatusStatusLua = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x94\xc1\x6b\xdb\x30\x14\xc6\xef\xfe\x2b\x84\x4e\x32\x24\x6a\x77\xd8\x65\x90\x43\xda\xa5\x69\xd9\x68\x47\x1c\xca\xae\xb2\xfd\x1c\x3f\x90\x25\x23\xc9\x61\xed\x61\x7f\xfb\x90\x64\xb7\x76\x42\xc0\x1b\xa3\xb9\xe9\xbd\xdf\xfb\xf2\xf9\xb3\x9e\x9f\x37\xbb\xec\xe1\xe9\x91\xac\x08\xfd\xc4\xaf\xf9\x35\x4d\x12\xa9\x0b\x21\x49\x83\x85\xd1\x64\x45\xb0\x69\xb5\x71\x8c\x86\x33\x4d\xfb\x6e\xde\x55\x15\x98\xd3\xf6\x55\x2c\xbf\x51\x85\x56\x15\x1e\xce\xa8\x58\x7e\xa3\xea\xae\x11\x0a\x5f\x61\xc4\x0d\x25\x9a\x26\x49\xd5\xa9\xc2\xa1\x56\x04\x15\x3a\x96\x26\x84\x90\x68\x8e\x67\xe0\x32\x27\x5c\x67\x1f\x54\xa5\xef\x14\xa3\x36\x9c\x78\x6e\x84\x2a\x6a\x3a\x07\xad\x85\x9d\x07\xb6\xc2\x3a\x98\x45\x1e\x0b\x2d\x67\x81\x12\x15\xd8\x59\x64\xfe\xe2\x66\x92\x36\x86\xe6\xc1\x98\x32\x5f\x97\xe5\xae\x53\x0e\x1b\xb8\x43\x09\x03\x48\x17\x43\x7f\xb7\xbf\x07\xd9\x2e\x08\xad\x41\xb6\x57\xbd\x4c\x53\xd2\x34\x01\x55\x8e\xd2\x0f\x6e\x59\x1e\xb5\x0d\xb8\xce\x28\xe2\xb4\x75\x06\xd5\x81\xe5\x5f\xbe\xfb\xf6\x63\xd7\xb0\xf4\x74\xd0\xe7\x71\x79\x6e\x0b\x6e\x5d\x38\x3c\xc2\x6d\x67\xac\x36\x2c\xf5\x95\x67\xb4\x9d\x90\x3f\xcf\xb5\x42\x10\x97\xc5\x32\x7c\x85\xf3\x21\x9f\xc9\xc9\xcc\x70\xbf\xf8\x4d\x14\xbc\x30\x19\x2f\xd2\x30\x8b\x15\xc9\xf9\xfe\xa5\x05\xfe\x0d\x55\x49\x7e\xaf\xfa\x2d\xe0\x37\x7b\xff\x16\x88\xab\x41\x05\xd0\xff\xe2\xd5\xb6\x35\x48\x79\x76\xff\x43\xb5\x7f\x4b\x23\x36\x3c\x85\x1d\xd1\x7d\xc5\x2f\xc1\x14\x8d\xbe\x16\x04\x8c\x5f\xc1\x20\xc7\x37\xbf\xa0\xb8\xd5\x4d\x23\x54\xc9\xe8\x01\x1d\x5d\x10\x6a\xe0\xb8\x6c\x85\xb1\xe0\x0f\xcb\xa5\xc8\x73\x5f\x31\x50\xf9\xf3\xfd\x66\xfd\x75\x64\x02\xab\x28\xb7\x22\x0a\xe5\xf4\x59\x46\xc1\xf5\x96\xf8\xde\x60\x93\xb5\xa2\x00\x16\xbd\xbc\xeb\xf8\x04\x4f\x86\x28\x4d\x86\xce\x34\x5f\xbf\x7d\x97\xd3\xfd\xfc\x81\x89\x7a\x27\x7f\x9d\xa7\xad\xb5\x71\xff\x31\x4a\x6f\xe2\xdf\x82\x0c\x5f\xa7\x51\x92\xfd\x6e\x6f\xc1\x6d\xa5\xce\x85\x7c\x6a\x3d\xc6\x68\xff\x15\x9b\x7a\x1a\xc4\x7f\xac\xb3\xfd\x86\xbc\xff\xc5\xf4\x8f\x7d\xe5\x4f\x00\x00\x00\xff\xff\xdc\xdb\xdf\x2a\x2d\x06\x00\x00" +var _runtimePluginsStatusStatusLua = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x94\xc1\x6f\xdb\x20\x14\xc6\xef\xfe\x2b\x10\x27\x2c\xa5\xb4\x3b\xec\x52\x29\x87\xb4\x4b\x93\x6a\x55\x5b\xc5\x51\xb5\x2b\xb6\x9f\xe3\x27\x61\xb0\x00\x47\x6b\x0f\xfb\xdb\x27\xc0\x6e\x9d\xa4\x91\xbc\x69\xda\x91\x8f\xef\x7d\x7e\xfc\xf0\xe3\x65\xb9\xc9\xee\x9f\x1e\xc9\x9c\xd0\x2f\xfc\x8a\x5f\xd1\x24\x91\xba\x10\x92\x34\x58\x18\x4d\xe6\x04\x9b\x56\x1b\xc7\x68\x58\xd3\xb4\xdf\xcd\xbb\xaa\x02\x73\xbc\x7d\x19\xe5\x77\x57\xa1\x55\x85\xbb\x13\x57\x94\xdf\x5d\x75\xd7\x08\x85\x6f\x30\xf2\x0d\x12\x4d\x93\xa4\xea\x54\xe1\x50\x2b\x82\x0a\x1d\x4b\x13\x42\x48\x6c\x8e\x67\xe0\x32\x27\x5c\x67\xef\x55\xa5\xef\x14\xa3\x36\xac\x78\x6e\x84\x2a\x6a\x3a\xc5\x5a\x0b\x3b\xcd\xd8\x0a\xeb\x60\x92\x73\x5f\x68\x39\xc9\x28\x51\x81\x9d\xe4\xcc\x5f\xdd\x44\xa7\x8d\xd0\x26\x7c\xdc\xb6\xbd\x2f\xde\x06\x5f\x94\xe5\xa6\x53\x0e\x1b\xb8\x43\x09\x83\x8f\xce\x86\xfd\xcd\x76\x0d\xb2\x9d\x11\x5a\x83\x6c\x2f\xfb\x94\xa6\xa4\x69\x02\xaa\x1c\xdd\x52\x38\x15\xcb\x63\xb6\x01\xd7\x19\x45\x9c\xb6\xce\xa0\xda\xb1\xfc\xfa\xc1\x6f\x3f\x76\x0d\x4b\x8f\x0b\x3d\xb7\xf3\x75\x2b\x70\x8b\xc2\xe1\x1e\x6e\x3b\x63\xb5\x61\xa9\x57\x5e\xd0\x76\x42\xfe\x38\xcd\x0a\xc0\xce\x87\x65\xf8\x06\xa7\x45\x9e\xdd\x51\xcd\xf0\x1f\xf2\x9b\x18\x78\xa6\x52\xda\x76\x28\xc4\x8a\xe4\xd7\x6b\x61\x1f\xb2\x67\x96\x12\x57\x83\x0a\xf2\x28\x93\x6a\x45\x83\xe6\x33\x0e\xf4\xaa\xa2\xc7\xe7\x08\x7f\xf2\x38\x9b\x6f\x5f\x5b\xe0\xdf\x51\x95\xe4\xd7\xbc\x1f\x43\x7e\xb3\xf5\xb7\x7b\xf8\xb5\x38\x5b\xb6\x06\x29\x4f\x06\x30\xa8\xfd\xf5\x8f\xbc\x01\x8f\x1d\xb9\x7b\xc5\x4f\xe1\xa1\x35\xf6\x35\x23\x60\xfc\x1b\x10\xe2\xf8\xf2\x27\x14\xb7\xba\x69\x84\x2a\x19\xdd\xa1\xa3\x33\x42\x0d\xec\x2f\x5a\x61\x2c\xf8\xc5\xc5\x85\xc8\x73\xaf\x18\xa8\xfc\x7a\xbd\x5c\x7c\x1b\x35\x81\x55\x8c\x9b\x13\x85\xf2\xf0\x2c\x23\x4a\x7d\x4b\x7c\x6b\xb0\xc9\x5a\x51\x00\x8b\xbd\x7c\xe4\x0c\x58\xc7\x68\x3f\x80\x1f\xf2\xf5\xe3\x7f\x9e\xee\xd7\xff\x48\xd4\x77\xf2\xc7\x3c\x6d\xad\x8d\xfb\x87\x28\x7d\x13\x7f\x07\x32\x3c\x8f\x23\x92\xfd\xa3\xb1\x02\xb7\x92\x3a\x17\xf2\xa9\xf5\x36\x46\xfb\x67\xf4\xf3\xc1\x78\x5e\x64\xdb\x25\xf9\x7c\x38\xe2\x64\xfc\x0e\x00\x00\xff\xff\x54\x1d\xb1\xf6\xae\x06\x00\x00" func runtimePluginsStatusStatusLuaBytes() ([]byte, error) { return bindataRead( diff --git a/internal/lsp/server.go b/internal/lsp/server.go index efc1303f..82c57503 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -22,6 +22,10 @@ func init() { activeServers = make(map[string]*Server) } +func GetServer(l Language, dir string) *Server { + return activeServers[l.Command+"-"+dir] +} + type Server struct { cmd *exec.Cmd stdin io.WriteCloser @@ -30,7 +34,7 @@ type Server struct { capabilities lsp.ServerCapabilities root string lock sync.Mutex - active bool + Active bool requestID int responses map[int]chan ([]byte) } @@ -61,6 +65,8 @@ type RPCResult struct { } func StartServer(l Language) (*Server, error) { + s := new(Server) + c := exec.Command(l.Command, l.Args...) c.Stderr = log.Writer() @@ -83,7 +89,6 @@ func StartServer(l Language) (*Server, error) { return nil, err } - s := new(Server) s.cmd = c s.stdin = stdin s.stdout = bufio.NewReader(stdout) @@ -151,7 +156,7 @@ func (s *Server) Initialize(directory string) { } activeServers[s.language.Command+"-"+directory] = s - s.active = true + s.Active = true s.root = directory go s.receive() @@ -161,7 +166,7 @@ func (s *Server) Initialize(directory string) { resp, err := s.sendRequest("initialize", params) if err != nil { log.Println("[micro-lsp]", err) - s.active = false + s.Active = false s.lock.Unlock() return } @@ -183,7 +188,7 @@ func (s *Server) Initialize(directory string) { } func (s *Server) receive() { - for s.active { + for s.Active { resp, err := s.receiveMessage() if err != nil { log.Println("[micro-lsp]", err) diff --git a/runtime/plugins/status/status.lua b/runtime/plugins/status/status.lua index 4942d396..49447e78 100644 --- a/runtime/plugins/status/status.lua +++ b/runtime/plugins/status/status.lua @@ -13,6 +13,7 @@ function init() micro.SetStatusInfoFn("status.lines") micro.SetStatusInfoFn("status.bytes") micro.SetStatusInfoFn("status.size") + micro.SetStatusInfoFn("status.lsp") config.AddRuntimeFile("status", config.RTHelp, "help/status.md") end @@ -32,6 +33,13 @@ function size(b) return humanize.Bytes(b:Size()) end +function lsp(b) + if b:HasLSP() then + return "on" + end + return "off" +end + function branch(b) if b.Type.Kind ~= buffer.BTInfo then local shell = import("micro/shell")