@@ -20,26 +20,83 @@ import { NotificationCenter } from '../notification-center';
2020import { SketchContribution , URI } from './contribution' ;
2121import { BoardsDataStore } from '../boards/boards-data-store' ;
2222
23+ interface DaemonAddress {
24+ /**
25+ * The host where the Arduino CLI daemon is available.
26+ */
27+ readonly hostname : string ;
28+ /**
29+ * The port where the Arduino CLI daemon is listening.
30+ */
31+ readonly port : number ;
32+ /**
33+ * The [id](https://arduino.github.io/arduino-cli/latest/rpc/commands/#instance) of the initialized core Arduino client instance.
34+ */
35+ readonly instance : number ;
36+ }
37+
38+ interface StartLanguageServerParams {
39+ /**
40+ * Absolute filesystem path to the Arduino Language Server executable.
41+ */
42+ readonly lsPath : string ;
43+ /**
44+ * The hostname and the port for the gRPC channel connecting to the Arduino CLI daemon.
45+ * The `instance` number is for the initialized core Arduino client.
46+ */
47+ readonly daemonAddress : DaemonAddress ;
48+ /**
49+ * Absolute filesystem path to [`clangd`](https://clangd.llvm.org/).
50+ */
51+ readonly clangdPath : string ;
52+ /**
53+ * The board is relevant to start a specific "flavor" of the language.
54+ */
55+ readonly board : { fqbn : string ; name ?: string } ;
56+ /**
57+ * `true` if the LS should generate the log files into the default location. The default location is the `cwd` of the process.
58+ * It's very often the same as the workspace root of the IDE, aka the sketch folder.
59+ * When it is a string, it is the absolute filesystem path to the folder to generate the log files.
60+ * If `string`, but the path is inaccessible, the log files will be generated into the default location.
61+ */
62+ readonly log ?: boolean | string ;
63+ /**
64+ * Optional `env` for the language server process.
65+ */
66+ readonly env ?: NodeJS . ProcessEnv ;
67+ /**
68+ * Additional flags for the Arduino Language server process.
69+ */
70+ readonly flags ?: readonly string [ ] ;
71+ /**
72+ * Set to `true`, to enable `Diagnostics`.
73+ */
74+ readonly realTimeDiagnostics ?: boolean ;
75+ /**
76+ * If `true`, the logging is not forwarded to the _Output_ view via the language client.
77+ */
78+ readonly silentOutput ?: boolean ;
79+ }
80+
81+ /**
82+ * The FQBN the language server runs with or `undefined` if it could not start.
83+ */
84+ type StartLanguageServerResult = string | undefined ;
85+
2386@injectable ( )
2487export class InoLanguage extends SketchContribution {
2588 @inject ( HostedPluginEvents )
2689 private readonly hostedPluginEvents : HostedPluginEvents ;
27-
2890 @inject ( ExecutableService )
2991 private readonly executableService : ExecutableService ;
30-
3192 @inject ( ArduinoDaemon )
3293 private readonly daemon : ArduinoDaemon ;
33-
3494 @inject ( BoardsService )
3595 private readonly boardsService : BoardsService ;
36-
3796 @inject ( BoardsServiceProvider )
3897 private readonly boardsServiceProvider : BoardsServiceProvider ;
39-
4098 @inject ( NotificationCenter )
4199 private readonly notificationCenter : NotificationCenter ;
42-
43100 @inject ( BoardsDataStore )
44101 private readonly boardDataStore : BoardsDataStore ;
45102
@@ -129,6 +186,10 @@ export class InoLanguage extends SketchContribution {
129186 if ( ! port ) {
130187 return ;
131188 }
189+ const portNumber = Number . parseInt ( port , 10 ) ; // TODO: IDE2 APIs should provide a number and not string
190+ if ( Number . isNaN ( portNumber ) ) {
191+ return ;
192+ }
132193 const release = await this . languageServerStartMutex . acquire ( ) ;
133194 const toDisposeOnRelease = new DisposableCollection ( ) ;
134195 try {
@@ -197,22 +258,22 @@ export class InoLanguage extends SketchContribution {
197258 ) ;
198259 toDisposeOnRelease . push ( Disposable . create ( ( ) => clearTimeout ( timer ) ) ) ;
199260 } ) ,
200- this . commandService . executeCommand < string > (
201- 'arduino.languageserver.start' ,
202- {
203- lsPath ,
204- cliDaemonAddr : `localhost: ${ port } ` ,
205- clangdPath ,
206- log : currentSketchPath ? currentSketchPath : log ,
207- cliDaemonInstance : '1' ,
208- board : {
209- fqbn : fqbnWithConfig ,
210- name : name ? `" ${ name } "` : undefined ,
211- } ,
212- realTimeDiagnostics ,
213- silentOutput : true ,
214- }
215- ) ,
261+ this . start ( {
262+ lsPath ,
263+ daemonAddress : {
264+ hostname : 'localhost' ,
265+ port : portNumber ,
266+ instance : 1 , // TODO: get it from the backend
267+ } ,
268+ clangdPath ,
269+ log : currentSketchPath ? currentSketchPath : log ,
270+ board : {
271+ fqbn : fqbnWithConfig ,
272+ name ,
273+ } ,
274+ realTimeDiagnostics ,
275+ silentOutput : true ,
276+ } ) ,
216277 ] ) ;
217278 } catch ( e ) {
218279 console . log ( `Failed to start language server. Original FQBN: ${ fqbn } ` , e ) ;
@@ -222,4 +283,13 @@ export class InoLanguage extends SketchContribution {
222283 release ( ) ;
223284 }
224285 }
286+
287+ private async start (
288+ params : StartLanguageServerParams
289+ ) : Promise < StartLanguageServerResult | undefined > {
290+ return this . commandService . executeCommand < StartLanguageServerResult > (
291+ 'arduino.languageserver.start' ,
292+ params
293+ ) ;
294+ }
225295}
0 commit comments