@@ -51,6 +51,7 @@ type InoHandler struct {
51
51
clangdNotificationCount int64
52
52
progressHandler * ProgressProxyHandler
53
53
54
+ closing chan bool
54
55
clangdStarted * sync.Cond
55
56
dataMux sync.RWMutex
56
57
lspInitializeParams * lsp.InitializeParams
@@ -119,6 +120,7 @@ func NewInoHandler(stdio io.ReadWriteCloser, board lsp.Board) *InoHandler {
119
120
handler := & InoHandler {
120
121
docs : map [string ]* lsp.TextDocumentItem {},
121
122
inoDocsWithDiagnostics : map [lsp.DocumentURI ]bool {},
123
+ closing : make (chan bool ),
122
124
config : lsp.BoardConfig {
123
125
SelectedBoard : board ,
124
126
},
@@ -131,10 +133,18 @@ func NewInoHandler(stdio io.ReadWriteCloser, board lsp.Board) *InoHandler {
131
133
jsonrpc2 .OnSend (streams .JSONRPCConnLogOnSend ("IDE <-- LS CL:" )),
132
134
)
133
135
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
+
134
143
handler .progressHandler = NewProgressProxy (handler .StdioConn )
135
144
136
145
if enableLogging {
137
146
log .Println ("Initial board configuration:" , board )
147
+ log .Println ("Language server build path:" , handler .buildPath )
138
148
}
139
149
140
150
go handler .rebuildEnvironmentLoop ()
@@ -150,10 +160,30 @@ type FileData struct {
150
160
version int
151
161
}
152
162
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
+ }
157
187
}
158
188
159
189
// HandleMessageFromIDE handles a message received from the IDE client (via stdio).
@@ -473,12 +503,14 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
473
503
// Exit the process and trigger a restart by the client in case of a severe error
474
504
if err .Error () == "context deadline exceeded" {
475
505
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 ()
477
508
}
478
509
if strings .Contains (err .Error (), "non-added document" ) || strings .Contains (err .Error (), "non-added file" ) {
479
510
log .Printf (prefix + "The clangd process has lost track of the open document." )
480
511
log .Printf (prefix + " %s" , err )
481
- handler .exit ()
512
+ log .Println (prefix + "Please restart the language server." )
513
+ handler .Close ()
482
514
}
483
515
}
484
516
@@ -489,12 +521,6 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
489
521
return result , err
490
522
}
491
523
492
- func (handler * InoHandler ) exit () {
493
- log .Println ("Please restart the language server." )
494
- handler .StopClangd ()
495
- os .Exit (1 )
496
- }
497
-
498
524
func (handler * InoHandler ) initializeWorkbench (ctx context.Context , params * lsp.InitializeParams ) error {
499
525
currCppTextVersion := 0
500
526
if params != nil {
@@ -507,10 +533,7 @@ func (handler *InoHandler) initializeWorkbench(ctx context.Context, params *lsp.
507
533
currCppTextVersion = handler .sketchMapper .CppText .Version
508
534
}
509
535
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 {
514
537
return err
515
538
}
516
539
handler .buildSketchCpp = handler .buildSketchRoot .Join (handler .sketchName + ".ino.cpp" )
@@ -566,6 +589,11 @@ func (handler *InoHandler) initializeWorkbench(ctx context.Context, params *lsp.
566
589
handler .ClangdConn = jsonrpc2 .NewConn (context .Background (), clangdStream , clangdHandler ,
567
590
jsonrpc2 .OnRecv (streams .JSONRPCConnLogOnRecv ("IDE LS <-- CL:" )),
568
591
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
+ }()
569
597
570
598
// Send initialization command to clangd
571
599
ctx , cancel := context .WithTimeout (context .Background (), time .Second )
0 commit comments