1
- import { posix } from 'path' ;
1
+ import { stat } from 'fs' ;
2
+ import { basename } from 'path' ;
3
+ import { promisify } from 'util' ;
2
4
import { spawnSync } from 'child_process' ;
3
5
import deepEqual from 'deep-equal' ;
4
6
import WebRequest from 'web-request' ;
@@ -13,6 +15,13 @@ interface LanguageServerConfig {
13
15
readonly fqbn : string ;
14
16
readonly name ?: string ;
15
17
}
18
+ /**
19
+ * `true` if the LS should generate log files into the default location. The default location is `cwd` of the process. It's very often the same
20
+ * as the workspace root of the IDE, aka the sketch folder.
21
+ * When it is a string, it is the folder where the log files should be generated. If the path is invalid (does not exist, not a folder),
22
+ * the log files will be generated into the default location.
23
+ */
24
+ readonly log ?: boolean | string ;
16
25
readonly env ?: any ;
17
26
readonly flags ?: string [ ] ;
18
27
}
@@ -71,7 +80,7 @@ async function startDebug(_: ExtensionContext, config: DebugConfig): Promise<boo
71
80
if ( ! rawStdout ) {
72
81
if ( rawStdErr ) {
73
82
if ( rawStdErr . indexOf ( 'compiled sketch not found in' ) !== - 1 ) {
74
- vscode . window . showErrorMessage ( `Sketch '${ posix . basename ( config . sketchPath ) } ' was not compiled. Please compile the sketch and start debugging again.` ) ;
83
+ vscode . window . showErrorMessage ( `Sketch '${ basename ( config . sketchPath ) } ' was not compiled. Please compile the sketch and start debugging again.` ) ;
75
84
} else {
76
85
vscode . window . showErrorMessage ( rawStdErr ) ;
77
86
}
@@ -125,29 +134,44 @@ async function startLanguageServer(context: ExtensionContext, config: LanguageSe
125
134
}
126
135
if ( ! languageClient || ! deepEqual ( latestConfig , config ) ) {
127
136
latestConfig = config ;
128
- languageClient = buildLanguageClient ( config ) ;
137
+ languageClient = await buildLanguageClient ( config ) ;
129
138
crashCount = 0 ;
130
139
}
131
140
132
141
languageServerDisposable = languageClient . start ( ) ;
133
142
context . subscriptions . push ( languageServerDisposable ) ;
134
143
}
135
144
136
- function buildLanguageClient ( config : LanguageServerConfig ) : LanguageClient {
145
+ async function buildLanguageClient ( config : LanguageServerConfig ) : Promise < LanguageClient > {
137
146
if ( ! serverOutputChannel ) {
138
147
serverOutputChannel = vscode . window . createOutputChannel ( 'Arduino Language Server' ) ;
139
148
}
140
149
if ( ! serverTraceChannel ) {
141
150
serverTraceChannel = vscode . window . createOutputChannel ( 'Arduino Language Server (trace)' ) ;
142
151
}
143
- const { lsPath : command , clangdPath, cliPath, board, flags, env } = config ;
152
+ const { lsPath : command , clangdPath, cliPath, board, flags, env, log } = config ;
144
153
const args = [ '-clangd' , clangdPath , '-cli' , cliPath , '-fqbn' , board . fqbn ] ;
145
154
if ( board . name ) {
146
155
args . push ( '-board-name' , board . name ) ;
147
156
}
148
157
if ( flags && flags . length ) {
149
158
args . push ( ...flags ) ;
150
159
}
160
+ if ( ! ! log ) {
161
+ args . push ( '-log' ) ;
162
+ let logPath : string | undefined = undefined ;
163
+ if ( typeof log === 'string' ) {
164
+ try {
165
+ const stats = await promisify ( stat ) ( log ) ;
166
+ if ( stats . isDirectory ( ) ) {
167
+ logPath = log ;
168
+ }
169
+ } catch { }
170
+ }
171
+ if ( logPath ) {
172
+ args . push ( '-logpath' , logPath ) ;
173
+ }
174
+ }
151
175
return new LanguageClient (
152
176
'ino' ,
153
177
'Arduino Language Server' ,
0 commit comments