@@ -51,6 +51,7 @@ type InoHandler struct {
5151 clangdNotificationCount int64
5252 progressHandler * ProgressProxyHandler
5353
54+ closing chan bool
5455 clangdStarted * sync.Cond
5556 dataMux sync.RWMutex
5657 lspInitializeParams * lsp.InitializeParams
@@ -119,6 +120,7 @@ func NewInoHandler(stdio io.ReadWriteCloser, board lsp.Board) *InoHandler {
119120 handler := & InoHandler {
120121 docs : map [string ]* lsp.TextDocumentItem {},
121122 inoDocsWithDiagnostics : map [lsp.DocumentURI ]bool {},
123+ closing : make (chan bool ),
122124 config : lsp.BoardConfig {
123125 SelectedBoard : board ,
124126 },
@@ -131,10 +133,18 @@ func NewInoHandler(stdio io.ReadWriteCloser, board lsp.Board) *InoHandler {
131133 jsonrpc2 .OnSend (streams .JSONRPCConnLogOnSend ("IDE <-- LS CL:" )),
132134 )
133135
136+ if buildPath , err := paths .MkTempDir ("" , "arduino-language-server" ); err != nil {
137+ log .Fatalf ("Could not create temp folder: %s" , err )
138+ } else {
139+ handler .buildPath = buildPath .Canonical ()
140+ handler .buildSketchRoot = buildPath .Join ("sketch" ).Canonical ()
141+ }
142+
134143 handler .progressHandler = NewProgressProxy (handler .StdioConn )
135144
136145 if enableLogging {
137146 log .Println ("Initial board configuration:" , board )
147+ log .Println ("Language server build path:" , handler .buildPath )
138148 }
139149
140150 go handler .rebuildEnvironmentLoop ()
@@ -150,10 +160,30 @@ type FileData struct {
150160 version int
151161}
152162
153- // StopClangd closes the connection to the clangd process.
154- func (handler * InoHandler ) StopClangd () {
155- handler .ClangdConn .Close ()
156- handler .ClangdConn = nil
163+ // Close closes all the json-rpc connections.
164+ func (handler * InoHandler ) Close () {
165+ if handler .ClangdConn != nil {
166+ handler .ClangdConn .Close ()
167+ handler .ClangdConn = nil
168+ }
169+ if handler .closing != nil {
170+ close (handler .closing )
171+ handler .closing = nil
172+ }
173+ }
174+
175+ // CloseNotify returns a channel that is closed when the InoHandler is closed
176+ func (handler * InoHandler ) CloseNotify () <- chan bool {
177+ return handler .closing
178+ }
179+
180+ // CleanUp performs cleanup of the workspace and temp files create by the language server
181+ func (handler * InoHandler ) CleanUp () {
182+ if handler .buildPath != nil {
183+ log .Printf ("removing buildpath" )
184+ handler .buildPath .RemoveAll ()
185+ handler .buildPath = nil
186+ }
157187}
158188
159189// HandleMessageFromIDE handles a message received from the IDE client (via stdio).
@@ -473,12 +503,14 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
473503 // Exit the process and trigger a restart by the client in case of a severe error
474504 if err .Error () == "context deadline exceeded" {
475505 log .Println (prefix + "Timeout exceeded while waiting for a reply from clangd." )
476- handler .exit ()
506+ log .Println (prefix + "Please restart the language server." )
507+ handler .Close ()
477508 }
478509 if strings .Contains (err .Error (), "non-added document" ) || strings .Contains (err .Error (), "non-added file" ) {
479510 log .Printf (prefix + "The clangd process has lost track of the open document." )
480511 log .Printf (prefix + " %s" , err )
481- handler .exit ()
512+ log .Println (prefix + "Please restart the language server." )
513+ handler .Close ()
482514 }
483515 }
484516
@@ -489,12 +521,6 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
489521 return result , err
490522}
491523
492- func (handler * InoHandler ) exit () {
493- log .Println ("Please restart the language server." )
494- handler .StopClangd ()
495- os .Exit (1 )
496- }
497-
498524func (handler * InoHandler ) initializeWorkbench (ctx context.Context , params * lsp.InitializeParams ) error {
499525 currCppTextVersion := 0
500526 if params != nil {
@@ -507,10 +533,7 @@ func (handler *InoHandler) initializeWorkbench(ctx context.Context, params *lsp.
507533 currCppTextVersion = handler .sketchMapper .CppText .Version
508534 }
509535
510- if buildPath , err := handler .generateBuildEnvironment (); err == nil {
511- handler .buildPath = buildPath
512- handler .buildSketchRoot = buildPath .Join ("sketch" ).Canonical ()
513- } else {
536+ if err := handler .generateBuildEnvironment (handler .buildPath ); err != nil {
514537 return err
515538 }
516539 handler .buildSketchCpp = handler .buildSketchRoot .Join (handler .sketchName + ".ino.cpp" )
@@ -566,6 +589,11 @@ func (handler *InoHandler) initializeWorkbench(ctx context.Context, params *lsp.
566589 handler .ClangdConn = jsonrpc2 .NewConn (context .Background (), clangdStream , clangdHandler ,
567590 jsonrpc2 .OnRecv (streams .JSONRPCConnLogOnRecv ("IDE LS <-- CL:" )),
568591 jsonrpc2 .OnSend (streams .JSONRPCConnLogOnSend ("IDE LS --> CL:" )))
592+ go func () {
593+ <- handler .ClangdConn .DisconnectNotify ()
594+ log .Printf ("Lost connection with clangd!" )
595+ handler .Close ()
596+ }()
569597
570598 // Send initialization command to clangd
571599 ctx , cancel := context .WithTimeout (context .Background (), time .Second )
0 commit comments