Skip to content

Commit 3ba5af0

Browse files
committed
Factored configuration paramaters for the language server
1 parent 0869a5f commit 3ba5af0

File tree

5 files changed

+54
-66
lines changed

5 files changed

+54
-66
lines changed

Diff for: ls/builder.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,10 @@ func (ls *INOLanguageServer) generateBuildEnvironment(ctx context.Context, logge
159159
// Extract all build information from language server status
160160
ls.readLock(logger, false)
161161
sketchRoot := ls.sketchRoot
162-
fqbn := ls.config.SelectedBoard.Fqbn
162+
fqbn := ls.config.Fqbn
163163
buildPath := ls.buildPath
164+
cliPath := ls.config.CliPath
165+
cliConfigPath := ls.config.CliConfigPath
164166
type overridesFile struct {
165167
Overrides map[string]string `json:"overrides"`
166168
}
@@ -176,7 +178,7 @@ func (ls *INOLanguageServer) generateBuildEnvironment(ctx context.Context, logge
176178
ls.readUnlock(logger)
177179

178180
var success bool
179-
if true {
181+
if cliPath == nil {
180182
// Establish a connection with the gRPC server, started with the command:
181183
// arduino-cli daemon
182184
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure(), grpc.WithBlock())
@@ -246,8 +248,8 @@ func (ls *INOLanguageServer) generateBuildEnvironment(ctx context.Context, logge
246248
}
247249

248250
// Run arduino-cli to perform the build
249-
args := []string{globalCliPath,
250-
"--config-file", globalCliConfigPath,
251+
args := []string{cliPath.String(),
252+
"--config-file", cliConfigPath.String(),
251253
"compile",
252254
"--fqbn", fqbn,
253255
"--only-compilation-database",

Diff for: ls/ls.go

+23-50
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,13 @@ import (
2424
"go.bug.st/lsp/textedits"
2525
)
2626

27-
var globalCliPath string
28-
var globalCliConfigPath string
29-
var globalClangdPath string
30-
var globalFormatterConf *paths.Path
31-
var enableLogging bool
32-
33-
// Setup initializes global variables.
34-
func Setup(cliPath, cliConfigPath, clangdPath, formatFilePath string, _enableLogging bool) {
35-
globalCliPath = cliPath
36-
globalCliConfigPath = cliConfigPath
37-
globalClangdPath = clangdPath
38-
if formatFilePath != "" {
39-
globalFormatterConf = paths.New(formatFilePath)
40-
}
41-
enableLogging = _enableLogging
42-
}
43-
4427
// INOLanguageServer is a JSON-RPC handler that delegates messages to clangd.
4528
type INOLanguageServer struct {
29+
config *Config
4630
IDE *IDELSPServer
4731
Clangd *ClangdLSPClient
4832

49-
progressHandler *ProgressProxyHandler
50-
33+
progressHandler *ProgressProxyHandler
5134
closing chan bool
5235
clangdStarted *sync.Cond
5336
dataMux sync.RWMutex
@@ -62,20 +45,16 @@ type INOLanguageServer struct {
6245
trackedInoDocs map[string]lsp.TextDocumentItem
6346
inoDocsWithDiagnostics map[lsp.DocumentURI]bool
6447
sketchRebuilder *SketchRebuilder
65-
66-
config BoardConfig
6748
}
6849

69-
// BoardConfig describes the board and port selected by the user.
70-
type BoardConfig struct {
71-
SelectedBoard Board `json:"selectedBoard"`
72-
SelectedPort string `json:"selectedPort"`
73-
}
74-
75-
// Board structure.
76-
type Board struct {
77-
Name string `json:"name"`
78-
Fqbn string `json:"fqbn"`
50+
// Config describes the language server configuration.
51+
type Config struct {
52+
Fqbn string
53+
CliPath *paths.Path
54+
CliConfigPath *paths.Path
55+
ClangdPath *paths.Path
56+
FormatterConf *paths.Path
57+
EnableLogging bool
7958
}
8059

8160
var yellow = color.New(color.FgHiYellow)
@@ -129,17 +108,13 @@ func (ls *INOLanguageServer) readUnlock(logger jsonrpc.FunctionLogger) {
129108
}
130109

131110
// NewINOLanguageServer creates and configures an Arduino Language Server.
132-
func NewINOLanguageServer(stdin io.Reader, stdout io.Writer, board Board) *INOLanguageServer {
111+
func NewINOLanguageServer(stdin io.Reader, stdout io.Writer, config *Config) *INOLanguageServer {
133112
logger := NewLSPFunctionLogger(color.HiWhiteString, "LS: ")
134113
ls := &INOLanguageServer{
135114
trackedInoDocs: map[string]lsp.TextDocumentItem{},
136115
inoDocsWithDiagnostics: map[lsp.DocumentURI]bool{},
137116
closing: make(chan bool),
138-
// buildSketchSymbolsLoad: make(chan bool, 1),
139-
// buildSketchSymbolsCheck: make(chan bool, 1),
140-
config: BoardConfig{
141-
SelectedBoard: board,
142-
},
117+
config: config,
143118
}
144119
ls.clangdStarted = sync.NewCond(&ls.dataMux)
145120
ls.sketchRebuilder = NewSketchBuilder(ls)
@@ -157,12 +132,10 @@ func NewINOLanguageServer(stdin io.Reader, stdout io.Writer, board Board) *INOLa
157132
ls.buildSketchRoot = ls.buildPath.Join("sketch")
158133
}
159134

160-
if enableLogging {
161-
logger.Logf("Initial board configuration: %s", board)
162-
logger.Logf("Language server build path: %s", ls.buildPath)
163-
logger.Logf("Language server build sketch root: %s", ls.buildSketchRoot)
164-
logger.Logf("Language server compile-commands: %s", ls.compileCommandsDir.Join("compile_commands.json"))
165-
}
135+
logger.Logf("Initial board configuration: %s", ls.config.Fqbn)
136+
logger.Logf("Language server build path: %s", ls.buildPath)
137+
logger.Logf("Language server build sketch root: %s", ls.buildSketchRoot)
138+
logger.Logf("Language server compile-commands: %s", ls.compileCommandsDir.Join("compile_commands.json"))
166139

167140
ls.IDE = NewIDELSPServer(logger, stdin, stdout, ls)
168141
ls.progressHandler = NewProgressProxy(ls.IDE.conn)
@@ -210,14 +183,14 @@ func (ls *INOLanguageServer) InitializeReqFromIDE(ctx context.Context, logger js
210183
}
211184

212185
// Retrieve data folder
213-
dataFolder, err := extractDataFolderFromArduinoCLI(logger)
186+
dataFolder, err := ls.extractDataFolderFromArduinoCLI(logger)
214187
if err != nil {
215188
logger.Logf("error retrieving data folder from arduino-cli: %s", err)
216189
return
217190
}
218191

219192
// Start clangd
220-
ls.Clangd = NewClangdLSPClient(logger, ls.buildPath, ls.buildSketchCpp, dataFolder, ls)
193+
ls.Clangd = NewClangdLSPClient(logger, dataFolder, ls)
221194
go func() {
222195
defer streams.CatchAndLogPanic()
223196
ls.Clangd.Run()
@@ -1043,10 +1016,10 @@ func (ls *INOLanguageServer) CleanUp() {
10431016
}
10441017
}
10451018

1046-
func extractDataFolderFromArduinoCLI(logger jsonrpc.FunctionLogger) (*paths.Path, error) {
1019+
func (ls *INOLanguageServer) extractDataFolderFromArduinoCLI(logger jsonrpc.FunctionLogger) (*paths.Path, error) {
10471020
// XXX: do this from IDE or via gRPC
1048-
args := []string{globalCliPath,
1049-
"--config-file", globalCliConfigPath,
1021+
args := []string{ls.config.CliPath.String(),
1022+
"--config-file", ls.config.CliConfigPath.String(),
10501023
"config",
10511024
"dump",
10521025
"--format", "json",
@@ -1806,9 +1779,9 @@ WhitespaceSensitiveMacros: []
18061779
if sketchFormatterConf := ls.sketchRoot.Join(".clang-format"); sketchFormatterConf.Exist() {
18071780
// If a custom config is present in the sketch folder, use that one
18081781
try(sketchFormatterConf)
1809-
} else if globalFormatterConf != nil && globalFormatterConf.Exist() {
1782+
} else if ls.config.FormatterConf != nil && ls.config.FormatterConf.Exist() {
18101783
// Otherwise if a global config file is present, use that one
1811-
try(globalFormatterConf)
1784+
try(ls.config.FormatterConf)
18121785
}
18131786

18141787
targetFile := cppuri.AsPath()

Diff for: ls/lsp_client_clangd.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,17 @@ type ClangdLSPClient struct {
2121
ls *INOLanguageServer
2222
}
2323

24-
func NewClangdLSPClient(logger jsonrpc.FunctionLogger, compileCommandsDir, buildSketchCpp, dataFolder *paths.Path, inoLanguageServer *INOLanguageServer) *ClangdLSPClient {
24+
func NewClangdLSPClient(logger jsonrpc.FunctionLogger, dataFolder *paths.Path, ls *INOLanguageServer) *ClangdLSPClient {
2525
// Start clangd
2626
args := []string{
27-
globalClangdPath,
27+
ls.config.ClangdPath.String(),
2828
"-log=verbose",
29-
fmt.Sprintf(`--compile-commands-dir=%s`, compileCommandsDir),
29+
fmt.Sprintf(`--compile-commands-dir=%s`, ls.buildPath),
3030
}
3131
if dataFolder != nil {
3232
args = append(args, fmt.Sprintf("-query-driver=%s", dataFolder.Join("packages", "**")))
3333
}
3434

35-
// clangdStdout, clangdStdin, clangdStderr := startClangd(logger, compileCommandsDir, buildSketchCpp, dataFolder)
3635
logger.Logf(" Starting clangd: %s", strings.Join(args, " "))
3736
var clangdStdin io.WriteCloser
3837
var clangdStdout, clangdStderr io.ReadCloser
@@ -53,15 +52,15 @@ func NewClangdLSPClient(logger jsonrpc.FunctionLogger, compileCommandsDir, build
5352
}
5453

5554
clangdStdio := streams.NewReadWriteCloser(clangdStdout, clangdStdin)
56-
if enableLogging {
55+
if ls.config.EnableLogging {
5756
clangdStdio = streams.LogReadWriteCloserAs(clangdStdio, "inols-clangd.log")
5857
go io.Copy(streams.OpenLogFileAs("inols-clangd-err.log"), clangdStderr)
5958
} else {
6059
go io.Copy(os.Stderr, clangdStderr)
6160
}
6261

6362
client := &ClangdLSPClient{
64-
ls: inoLanguageServer,
63+
ls: ls,
6564
}
6665
client.conn = lsp.NewClient(clangdStdio, clangdStdio, client)
6766
client.conn.SetLogger(&LSPLogger{

Diff for: ls/unused.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ func (ls *INOLanguageServer) handleError(logger jsonrpc.FunctionLogger, err erro
2121
submatch := exp.FindStringSubmatch(errorStr)
2222
message = submatch[1]
2323
} else if strings.Contains(errorStr, "platform not installed") || strings.Contains(errorStr, "no FQBN provided") {
24-
if len(ls.config.SelectedBoard.Name) > 0 {
25-
board := ls.config.SelectedBoard.Name
26-
message = "Editor support may be inaccurate because the core for the board `" + board + "` is not installed."
24+
if ls.config.Fqbn != "" {
25+
message = "Editor support may be inaccurate because the core for the board `" + ls.config.Fqbn + "` is not installed."
2726
message += " Use the Boards Manager to install it."
2827
} else {
2928
// This case happens most often when the app is started for the first time and no

Diff for: main.go

+18-3
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,31 @@ func main() {
5656
if cliConfigPath == "" {
5757
log.Fatal("Path to ArduinoCLI config file must be set.")
5858
}
59+
if clangdPath == "" {
60+
log.Fatal("Path to Clangd must be set.")
61+
}
5962

60-
ls.Setup(cliPath, cliConfigPath, clangdPath, formatFilePath, enableLogging)
61-
initialBoard := ls.Board{Fqbn: initialFqbn, Name: initialBoardName}
63+
config := &ls.Config{
64+
Fqbn: initialFqbn,
65+
ClangdPath: paths.New(clangdPath),
66+
EnableLogging: enableLogging,
67+
}
68+
if cliPath != "" {
69+
config.CliPath = paths.New(cliPath)
70+
}
71+
if cliConfigPath != "" {
72+
config.CliConfigPath = paths.New(cliConfigPath)
73+
}
74+
if formatFilePath != "" {
75+
config.FormatterConf = paths.New(formatFilePath)
76+
}
6277

6378
stdio := streams.NewReadWriteCloser(os.Stdin, os.Stdout)
6479
if enableLogging {
6580
stdio = streams.LogReadWriteCloserAs(stdio, "inols.log")
6681
}
6782

68-
inoHandler := ls.NewINOLanguageServer(stdio, stdio, initialBoard)
83+
inoHandler := ls.NewINOLanguageServer(stdio, stdio, config)
6984

7085
// Intercept kill signal
7186
c := make(chan os.Signal, 2)

0 commit comments

Comments
 (0)