From f0b1158ab6092ae57bf31472f786ec34f60cfb1a Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Mon, 10 Aug 2020 22:49:29 -0400 Subject: [PATCH] Run notifications in background to hide latency --- internal/buffer/autocomplete.go | 2 +- internal/buffer/buffer.go | 2 ++ internal/buffer/save.go | 3 +++ internal/lsp/notifications.go | 8 +++---- internal/lsp/server.go | 42 +++++++++++++++++++-------------- 5 files changed, 34 insertions(+), 23 deletions(-) diff --git a/internal/buffer/autocomplete.go b/internal/buffer/autocomplete.go index f32dd337..c7d53c25 100644 --- a/internal/buffer/autocomplete.go +++ b/internal/buffer/autocomplete.go @@ -227,7 +227,7 @@ func LSPComplete(b *Buffer) ([]string, []string) { for i, item := range items { suggestions[i] = item.Label - if len(item.TextEdit.NewText) > 0 { + if item.TextEdit != nil && len(item.TextEdit.NewText) > 0 { completions[i] = util.SliceEndStr(item.TextEdit.NewText, c.X-argstart) } else if len(item.InsertText) > 0 { completions[i] = util.SliceEndStr(item.InsertText, c.X-argstart) diff --git a/internal/buffer/buffer.go b/internal/buffer/buffer.go index 3ffac2e5..8e338bfe 100644 --- a/internal/buffer/buffer.go +++ b/internal/buffer/buffer.go @@ -443,6 +443,8 @@ func (b *Buffer) Fini() { if b.Type == BTStdout { fmt.Fprint(util.Stdout, string(b.Bytes())) } + + 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 d037fb92..f2fa0a13 100644 --- a/internal/buffer/save.go +++ b/internal/buffer/save.go @@ -195,5 +195,8 @@ func (b *Buffer) saveToFile(filename string, withSudo bool) error { b.AbsPath = absPath b.isModified = false b.UpdateRules() + + b.server.DidSave(b.AbsPath) + return err } diff --git a/internal/lsp/notifications.go b/internal/lsp/notifications.go index f4005642..90f9c3a0 100644 --- a/internal/lsp/notifications.go +++ b/internal/lsp/notifications.go @@ -14,7 +14,7 @@ func (s *Server) DidOpen(filename, language, text string, version int) { TextDocument: doc, } - s.sendNotification("textDocument/didOpen", params) + go s.sendNotification("textDocument/didOpen", params) } func (s *Server) DidSave(filename string) { @@ -25,7 +25,7 @@ func (s *Server) DidSave(filename string) { params := lsp.DidSaveTextDocumentParams{ TextDocument: doc, } - s.sendNotification("textDocument/didSave", params) + go s.sendNotification("textDocument/didSave", params) } func (s *Server) DidChange(filename string, version int, changes []lsp.TextDocumentContentChangeEvent) { @@ -40,7 +40,7 @@ func (s *Server) DidChange(filename string, version int, changes []lsp.TextDocum TextDocument: doc, ContentChanges: changes, } - s.sendNotification("textDocument/didChange", params) + go s.sendNotification("textDocument/didChange", params) } func (s *Server) DidClose(filename string) { @@ -51,5 +51,5 @@ func (s *Server) DidClose(filename string) { params := lsp.DidCloseTextDocumentParams{ TextDocument: doc, } - s.sendNotification("textDocument/didClose", params) + go s.sendNotification("textDocument/didClose", params) } diff --git a/internal/lsp/server.go b/internal/lsp/server.go index 1f7ce92b..efc1303f 100644 --- a/internal/lsp/server.go +++ b/internal/lsp/server.go @@ -90,8 +90,6 @@ func StartServer(l Language) (*Server, error) { s.language = &l s.responses = make(map[int]chan []byte) - // activeServers[l.Command] = s - return s, nil } @@ -154,29 +152,34 @@ func (s *Server) Initialize(directory string) { activeServers[s.language.Command+"-"+directory] = s s.active = true + s.root = directory go s.receive() - resp, err := s.sendRequest("initialize", params) - if err != nil { - log.Println("[micro-lsp]", err) - return - } + s.lock.Lock() + go func() { + resp, err := s.sendRequest("initialize", params) + if err != nil { + log.Println("[micro-lsp]", err) + s.active = false + s.lock.Unlock() + return + } - // todo parse capabilities - log.Println("[micro-lsp] <<<", string(resp)) + // todo parse capabilities + log.Println("[micro-lsp] <<<", string(resp)) - var r RPCInit - json.Unmarshal(resp, &r) + var r RPCInit + json.Unmarshal(resp, &r) - err = s.sendNotification("initialized", struct{}{}) - if err != nil { - log.Println("[micro-lsp]", err) - return - } + s.lock.Unlock() + err = s.sendNotification("initialized", struct{}{}) + if err != nil { + log.Println("[micro-lsp]", err) + } - s.capabilities = r.Result.Capabilities - s.root = directory + s.capabilities = r.Result.Capabilities + }() } func (s *Server) receive() { @@ -203,6 +206,7 @@ func (s *Server) receive() { case "": // Response if _, ok := s.responses[r.ID]; ok { + log.Println("[micro-lsp] Got response for", r.ID) s.responses[r.ID] <- resp } } @@ -251,6 +255,8 @@ func (s *Server) sendNotification(method string, params interface{}) error { Params: params, } + s.lock.Lock() + defer s.lock.Unlock() return s.sendMessage(m) }