@@ -2,7 +2,6 @@ import React from 'react';
22import styled from '@emotion/styled' ;
33import { keyframes } from '@emotion/core' ;
44import * as monaco from 'monaco-editor/esm/vs/editor/editor.api' ;
5- const { MonacoServices } = require ( 'monaco-languageclient/lib/monaco-services' ) ;
65
76import configureCadence , { CADENCE_LANGUAGE_ID } from 'util/cadence' ;
87import {
@@ -108,18 +107,16 @@ type EditorState = {
108107 viewState : any ;
109108} ;
110109
111- let monacoServicesInstalled = false ;
112-
113- type CodeGetter = ( index : number ) => string | undefined ;
114-
115110type CadenceEditorProps = {
111+ type : EntityType ;
116112 code : string ;
117113 mount : string ;
118114 show : boolean ;
119115 onChange : any ;
120116 activeId : string ;
121- type : EntityType ;
122- getCode : CodeGetter ;
117+ languageServer : CadenceLanguageServer
118+ callbacks : Callbacks
119+ serverReady : boolean
123120} ;
124121
125122type CadenceEditorState = {
@@ -144,7 +141,9 @@ class CadenceEditor extends React.Component<
144141 onChange : any ;
145142 activeId : string ;
146143 type : EntityType ;
147- getCode : CodeGetter ;
144+ languageServer : any ;
145+ callbacks : Callbacks ;
146+ serverReady : boolean ;
148147 } ) {
149148 super ( props ) ;
150149
@@ -164,73 +163,38 @@ class CadenceEditor extends React.Component<
164163 }
165164
166165 async componentDidMount ( ) {
167- const editor = monaco . editor . create (
168- document . getElementById ( this . props . mount ) ,
169- {
170- theme : 'vs-light' ,
171- language : CADENCE_LANGUAGE_ID ,
172- minimap : {
173- enabled : false ,
166+ await this . initEditor ( )
167+
168+ if ( this . props . serverReady ) {
169+ await this . loadLanguageClient ( )
170+ }
171+ }
172+
173+ async initEditor ( ) {
174+ this . editor = monaco . editor . create (
175+ document . getElementById ( this . props . mount ) ,
176+ {
177+ theme : 'vs-light' ,
178+ language : CADENCE_LANGUAGE_ID ,
179+ minimap : {
180+ enabled : false ,
181+ } ,
174182 } ,
175- } ,
176183 ) ;
177- this . editor = editor ;
178-
179184 this . _subscription = this . editor . onDidChangeModelContent ( ( event : any ) => {
180185 this . props . onChange ( this . editor . getValue ( ) , event ) ;
181186 } ) ;
182187
183188 const state = this . getOrCreateEditorState (
184- this . props . activeId ,
185- this . props . code ,
189+ this . props . activeId ,
190+ this . props . code ,
186191 ) ;
187192 this . editor . setModel ( state . model ) ;
188193 this . editor . focus ( ) ;
189-
190- if ( this . props . activeId && ! this . callbacks ) {
191- const getCode = ( index : number ) => this . props . getCode ( index ) ;
192- await this . loadLanguageServer ( getCode ) ;
193- }
194194 }
195195
196- private async loadLanguageServer ( getCode : CodeGetter ) {
197- this . callbacks = {
198- // The actual callback will be set as soon as the language server is initialized
199- toServer : null ,
200-
201- // The actual callback will be set as soon as the language server is initialized
202- onClientClose : null ,
203-
204- // The actual callback will be set as soon as the language client is initialized
205- onServerClose : null ,
206-
207- // The actual callback will be set as soon as the language client is initialized
208- toClient : null ,
209-
210- getAddressCode ( address : string ) : string | undefined {
211- const number = parseInt ( address , 16 ) ;
212- if ( ! number ) {
213- return ;
214- }
215- return getCode ( number - 1 ) ;
216- } ,
217- } ;
218-
219- // The Monaco Language Client services have to be installed globally, once.
220- // An editor must be passed, which is only used for commands.
221- // As the Cadence language server is not providing any commands this is OK
222-
223- if ( ! monacoServicesInstalled ) {
224- monacoServicesInstalled = true ;
225- MonacoServices . install ( monaco ) ;
226- }
227-
228- // Start one language server per editor.
229- // Even though one language server can handle multiple documents,
230- // this demonstrates this is possible and is more resilient:
231- // if the server for one editor crashes, it does not break the other editors
232-
233- await CadenceLanguageServer . create ( this . callbacks ) ;
196+ private async loadLanguageClient ( ) {
197+ this . callbacks = this . props . callbacks ;
234198
235199 this . languageClient = createCadenceLanguageClient ( this . callbacks ) ;
236200 this . languageClient . start ( ) ;
@@ -345,13 +309,26 @@ class CadenceEditor extends React.Component<
345309
346310 async componentDidUpdate ( prevProps : any ) {
347311 if ( this . props . activeId !== prevProps . activeId ) {
348- this . switchEditor ( prevProps . activeId , this . props . activeId ) ;
349- this . destroyMonaco ( ) ;
350- await this . componentDidMount ( ) ;
312+ await this . swapMonacoEditor ( prevProps . activeId , this . props . activeId )
351313 }
314+
315+ const serverStatusChanged = this . props . serverReady !== prevProps . serverReady
316+ const activeIdChanged = this . props . activeId !== prevProps . activeId
317+ const typeChanged = this . props . type !== prevProps . type
318+ if ( serverStatusChanged || activeIdChanged || typeChanged ) {
319+ if ( this . props . callbacks . toServer !== null ) {
320+ await this . loadLanguageClient ( )
321+ }
322+ }
323+ }
324+
325+ async swapMonacoEditor ( prev : any , current : any ) {
326+ await this . destroyMonaco ( ) ;
327+ await this . initEditor ( ) ;
328+ this . switchEditor ( prev , current ) ;
352329 }
353330
354- destroyMonaco ( ) {
331+ destroyMonaco ( ) {
355332 if ( this . editor ) {
356333 this . editor . dispose ( ) ;
357334 const model = this . editor . getModel ( ) ;
0 commit comments