Skip to content

Commit b30c074

Browse files
committed
Factored initializeWorkbench function
1 parent f0a3a30 commit b30c074

File tree

2 files changed

+86
-92
lines changed

2 files changed

+86
-92
lines changed

Diff for: ls/builder.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ func (handler *INOLanguageServer) rebuildEnvironmentLoop() {
7979
}
8080
}()
8181

82-
handler.writeLock(logger, false)
83-
handler.initializeWorkbench(logger, nil)
82+
handler.writeLock(logger, true)
83+
handler.initializeWorkbench(logger)
8484
handler.writeUnlock(logger)
8585
done <- true
8686
close(done)

Diff for: ls/ls.go

+84-90
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ type INOLanguageServer struct {
5050
closing chan bool
5151
clangdStarted *sync.Cond
5252
dataMux sync.RWMutex
53-
lspInitializeParams *lsp.InitializeParams
5453
buildPath *paths.Path
5554
buildSketchRoot *paths.Path
5655
buildSketchCpp *paths.Path
@@ -245,21 +244,70 @@ func (handler *INOLanguageServer) CheckCppDocumentSymbols() error {
245244
return nil
246245
}
247246

248-
func (handler *INOLanguageServer) startClangd(inoParams *lsp.InitializeParams) {
247+
func (ls *INOLanguageServer) startClangd(inoParams *lsp.InitializeParams) error {
249248
logger := NewLSPFunctionLogger(color.HiCyanString, "INIT --- ")
250-
logger.Logf("initializing workbench")
249+
logger.Logf("initializing workbench: %s", inoParams.RootURI)
251250

252251
// Start clangd asynchronously
253-
handler.writeLock(logger, false) // do not wait for clangd... we are starting it :-)
254-
defer handler.writeUnlock(logger)
252+
ls.writeLock(logger, false) // do not wait for clangd... we are starting it :-)
253+
defer ls.writeUnlock(logger)
254+
255+
ls.sketchRoot = inoParams.RootURI.AsPath()
256+
ls.sketchName = ls.sketchRoot.Base()
257+
ls.buildSketchCpp = ls.buildSketchRoot.Join(ls.sketchName + ".ino.cpp")
258+
259+
if err := ls.generateBuildEnvironment(logger); err != nil {
260+
return err
261+
}
262+
263+
if cppContent, err := ls.buildSketchCpp.ReadFile(); err == nil {
264+
ls.sketchMapper = sourcemapper.CreateInoMapper(cppContent)
265+
ls.sketchMapper.CppText.Version = 1
266+
} else {
267+
return errors.WithMessage(err, "reading generated cpp file from sketch")
268+
}
255269

256-
// TODO: Inline this function
257-
handler.initializeWorkbench(logger, inoParams)
270+
// Let's start clangd!
271+
dataFolder, err := extractDataFolderFromArduinoCLI(logger)
272+
if err != nil {
273+
logger.Logf("error: %s", err)
274+
}
275+
276+
// Start clangd
277+
ls.Clangd = NewClangdLSPClient(logger, ls.buildPath, ls.buildSketchCpp, dataFolder, ls)
278+
go func() {
279+
defer streams.CatchAndLogPanic()
280+
ls.Clangd.Run()
281+
logger.Logf("Lost connection with clangd!")
282+
ls.Close()
283+
}()
284+
285+
// Send initialization command to clangd (1 sec. timeout)
286+
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
287+
defer cancel()
288+
cppInitializeParams := *inoParams
289+
cppInitializeParams.RootPath = ls.buildSketchRoot.String()
290+
cppInitializeParams.RootURI = lsp.NewDocumentURIFromPath(ls.buildSketchRoot)
291+
if initRes, clangErr, err := ls.Clangd.conn.Initialize(ctx, &cppInitializeParams); err != nil {
292+
logger.Logf("error initilizing clangd: %v", err)
293+
return err
294+
} else if clangErr != nil {
295+
logger.Logf("error initilizing clangd: %v", clangErr.AsError())
296+
return clangErr.AsError()
297+
} else {
298+
logger.Logf("clangd successfully started: %s", string(lsp.EncodeMessage(initRes)))
299+
}
300+
301+
if err := ls.Clangd.conn.Initialized(&lsp.InitializedParams{}); err != nil {
302+
logger.Logf("error sending initialized notification to clangd: %v", err)
303+
return err
304+
}
258305

259306
// signal that clangd is running now...
260-
handler.clangdStarted.Broadcast()
307+
ls.clangdStarted.Broadcast()
261308

262309
logger.Logf("Done initializing workbench")
310+
return nil
263311
}
264312

265313
func (handler *INOLanguageServer) InitializeReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, inoParams *lsp.InitializeParams) (*lsp.InitializeResult, *jsonrpc.ResponseError) {
@@ -1051,26 +1099,9 @@ func (ls *INOLanguageServer) CleanUp() {
10511099
}
10521100
}
10531101

1054-
func (ls *INOLanguageServer) initializeWorkbench(logger jsonrpc.FunctionLogger, params *lsp.InitializeParams) error {
1055-
// TODO: This function must be split into two
1056-
// -> start clang (when params != nil)
1057-
// -> reser clang status (when params == nil)
1058-
// the two flows shares very little
1059-
1060-
currCppTextVersion := 0
1061-
if params != nil {
1062-
logger.Logf(" --> initialize(%s)", params.RootURI)
1063-
ls.sketchRoot = params.RootURI.AsPath()
1064-
ls.sketchName = ls.sketchRoot.Base()
1065-
ls.buildSketchCpp = ls.buildSketchRoot.Join(ls.sketchName + ".ino.cpp")
1066-
1067-
ls.lspInitializeParams = params
1068-
ls.lspInitializeParams.RootPath = ls.buildSketchRoot.String()
1069-
ls.lspInitializeParams.RootURI = lsp.NewDocumentURIFromPath(ls.buildSketchRoot)
1070-
} else {
1071-
logger.Logf(" --> RE-initialize()")
1072-
currCppTextVersion = ls.sketchMapper.CppText.Version
1073-
}
1102+
func (ls *INOLanguageServer) initializeWorkbench(logger jsonrpc.FunctionLogger) error {
1103+
logger.Logf("--> RE-initialize()")
1104+
currCppTextVersion := ls.sketchMapper.CppText.Version
10741105

10751106
if err := ls.generateBuildEnvironment(logger); err != nil {
10761107
return err
@@ -1083,69 +1114,31 @@ func (ls *INOLanguageServer) initializeWorkbench(logger jsonrpc.FunctionLogger,
10831114
return errors.WithMessage(err, "reading generated cpp file from sketch")
10841115
}
10851116

1086-
if params == nil {
1087-
// If we are restarting re-synchronize clangd
1088-
cppURI := lsp.NewDocumentURIFromPath(ls.buildSketchCpp)
1089-
1090-
logger.Logf("Sending 'didSave' notification to Clangd")
1091-
1092-
didSaveParams := &lsp.DidSaveTextDocumentParams{
1093-
TextDocument: lsp.TextDocumentIdentifier{URI: cppURI},
1094-
}
1095-
if err := ls.Clangd.conn.TextDocumentDidSave(didSaveParams); err != nil {
1096-
logger.Logf(" error reinitilizing clangd:", err)
1097-
return err
1098-
}
1099-
1100-
logger.Logf("Sending 'didChange' notification to Clangd")
1101-
didChangeParams := &lsp.DidChangeTextDocumentParams{
1102-
TextDocument: lsp.VersionedTextDocumentIdentifier{
1103-
TextDocumentIdentifier: lsp.TextDocumentIdentifier{URI: cppURI},
1104-
Version: ls.sketchMapper.CppText.Version,
1105-
},
1106-
ContentChanges: []lsp.TextDocumentContentChangeEvent{
1107-
{Text: ls.sketchMapper.CppText.Text},
1108-
},
1109-
}
1110-
if err := ls.Clangd.conn.TextDocumentDidChange(didChangeParams); err != nil {
1111-
logger.Logf(" error reinitilizing clangd:", err)
1112-
return err
1113-
}
1114-
} else {
1115-
// Otherwise start clangd!
1116-
dataFolder, err := extractDataFolderFromArduinoCLI(logger)
1117-
if err != nil {
1118-
logger.Logf(" error: %s", err)
1119-
}
1120-
1121-
// Start clangd
1122-
ls.Clangd = NewClangdLSPClient(logger, ls.buildPath, ls.buildSketchCpp, dataFolder, ls)
1123-
go func() {
1124-
defer streams.CatchAndLogPanic()
1125-
ls.Clangd.Run()
1126-
logger.Logf("Lost connection with clangd!")
1127-
ls.Close()
1128-
}()
1129-
1130-
// Send initialization command to clangd
1131-
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
1132-
defer cancel()
1133-
initRes, clangErr, err := ls.Clangd.conn.Initialize(ctx, ls.lspInitializeParams)
1134-
if err != nil {
1135-
logger.Logf(" error initilizing clangd: %v", err)
1136-
return err
1137-
}
1138-
if clangErr != nil {
1139-
logger.Logf(" error initilizing clangd: %v", clangErr.AsError())
1140-
return clangErr.AsError()
1141-
} else {
1142-
logger.Logf("clangd successfully started: %s", string(lsp.EncodeMessage(initRes)))
1143-
}
1117+
// Send didSave to notify clang that the source cpp is changed
1118+
logger.Logf("Sending 'didSave' notification to Clangd")
1119+
cppURI := lsp.NewDocumentURIFromPath(ls.buildSketchCpp)
1120+
didSaveParams := &lsp.DidSaveTextDocumentParams{
1121+
TextDocument: lsp.TextDocumentIdentifier{URI: cppURI},
1122+
}
1123+
if err := ls.Clangd.conn.TextDocumentDidSave(didSaveParams); err != nil {
1124+
logger.Logf("error reinitilizing clangd:", err)
1125+
return err
1126+
}
11441127

1145-
if err := ls.Clangd.conn.Initialized(&lsp.InitializedParams{}); err != nil {
1146-
logger.Logf(" error sending initialized notification to clangd: %v", err)
1147-
return err
1148-
}
1128+
// Send the full text to clang
1129+
logger.Logf("Sending full-text 'didChange' notification to Clangd")
1130+
didChangeParams := &lsp.DidChangeTextDocumentParams{
1131+
TextDocument: lsp.VersionedTextDocumentIdentifier{
1132+
TextDocumentIdentifier: lsp.TextDocumentIdentifier{URI: cppURI},
1133+
Version: ls.sketchMapper.CppText.Version,
1134+
},
1135+
ContentChanges: []lsp.TextDocumentContentChangeEvent{
1136+
{Text: ls.sketchMapper.CppText.Text},
1137+
},
1138+
}
1139+
if err := ls.Clangd.conn.TextDocumentDidChange(didChangeParams); err != nil {
1140+
logger.Logf("error reinitilizing clangd:", err)
1141+
return err
11491142
}
11501143

11511144
return nil
@@ -1359,6 +1352,7 @@ func (ls *INOLanguageServer) didChange(logger jsonrpc.FunctionLogger, inoDidChan
13591352
if dirty {
13601353
ls.scheduleRebuildEnvironment()
13611354
}
1355+
ls.sketchMapper.DebugLogAll()
13621356

13631357
logger.Logf("New version:----------+\n" + ls.sketchMapper.CppText.Text + "\n----------------------")
13641358

0 commit comments

Comments
 (0)