1
- import { useEffect , useRef , useContext } from 'react'
1
+ import { useEffect , useRef , useContext , useState } from 'react'
2
2
import { LeanMonacoEditor } from 'lean4monaco'
3
3
import { LeanMonacoContext } from './LeanMonaco'
4
+ import { RpcSessionAtPos } from 'lean4/src/infoview'
5
+ import { LeanClient } from 'lean4/src/leanclient'
6
+ import { Uri } from 'vscode'
7
+ import { RpcConnectParams } from '@leanprover/infoview-api'
4
8
5
9
function LeanMonacoEditorComponent ( { fileName, value} : { fileName : string , value : string } ) {
6
10
const codeviewRef = useRef < HTMLDivElement > ( null )
7
11
const leanMonaco = useContext ( LeanMonacoContext )
8
-
12
+
13
+ const [ leanMonacoEditor , setLeanMonacoEditor ] = useState < LeanMonacoEditor | null > ( null )
14
+ const [ client , setClient ] = useState < LeanClient | null > ( null )
15
+ const [ uri , setUri ] = useState < Uri | null > ( null )
16
+ const [ rpcSess , setRpcSess ] = useState < RpcSessionAtPos | null > ( null )
17
+
9
18
// You can start multiple `LeanMonacoEditor` instances
10
19
useEffect ( ( ) => {
11
20
if ( leanMonaco ) {
@@ -16,17 +25,104 @@ function LeanMonacoEditorComponent({fileName, value}: {fileName: string, value:
16
25
console . debug ( '[demo]: starting editor' )
17
26
await leanMonacoEditor . start ( codeviewRef . current ! , fileName , value )
18
27
console . debug ( '[demo]: editor started' )
28
+ setLeanMonacoEditor ( leanMonacoEditor )
19
29
} ) ( )
20
30
21
31
return ( ) => {
22
32
leanMonacoEditor . dispose ( )
23
33
}
24
34
}
25
- } , [ leanMonaco ] )
35
+ } , [ leanMonaco , fileName , value ] )
36
+
37
+ // RPC example: wait until there is a `client`
38
+ useEffect ( ( ) => {
39
+ const updateClient = ( ) => {
40
+ const clients = leanMonaco ?. clientProvider ?. getClients ( )
41
+ if ( clients ?. [ 0 ] ) {
42
+ setClient ( clients [ 0 ] )
43
+ return true
44
+ }
45
+ return false
46
+ }
47
+ updateClient ( )
48
+ const interval = setInterval ( ( ) => {
49
+ // try to get `client` until successful
50
+ if ( updateClient ( ) ) {
51
+ clearInterval ( interval )
52
+ }
53
+ } , 500 )
54
+ return ( ) => clearInterval ( interval )
55
+ } , [ leanMonaco ?. clientProvider ] )
56
+
57
+ // RPC example: wait until the `uri` is defined
58
+ useEffect ( ( ) => {
59
+ console . log ( 'connecting to RPC' )
60
+ console . log ( `client: ${ client } ` )
61
+ console . log ( `uri: ${ uri } ` )
62
+ if ( client && uri ) {
63
+ client . sendRequest ( '$/lean/rpc/connect' , { uri : uri . toString ( ) } as RpcConnectParams ) . then ( result => {
64
+ const sessionId = result . sessionId
65
+ console . debug ( `session id: ${ sessionId } ` )
66
+ const _rpcSess = new RpcSessionAtPos ( client , sessionId , uri . toString ( ) )
67
+ setRpcSess ( _rpcSess )
68
+ } ) } else { console . log ( `not ready: ${ uri } , ${ client } ` ) }
69
+ } , [ client , uri ] )
26
70
27
- return (
71
+ // RPC example: start new rpc session using `uri` and `client`
72
+ useEffect ( ( ) => {
73
+ const updateUri = ( ) => {
74
+ const model = leanMonacoEditor ?. editor ?. getModel ( )
75
+ if ( model ?. uri ) {
76
+ setUri ( model . uri )
77
+ return true
78
+ }
79
+ return false
80
+ }
81
+ updateUri ( )
82
+ console . log ( uri ) // TODO: remove me
83
+ const interval = setInterval ( ( ) => {
84
+ // try to get `uri` until successful
85
+ if ( updateUri ( ) ) {
86
+ clearInterval ( interval )
87
+ }
88
+ } , 500 )
89
+ return ( ) => clearInterval ( interval )
90
+ } , [ leanMonacoEditor ?. editor , uri ] )
91
+
92
+ return < >
28
93
< div className = 'codeview' ref = { codeviewRef } > </ div >
29
- )
94
+ < button onClick = { ( ) => {
95
+ if ( ! rpcSess ) {
96
+ console . warn ( 'rpc session does not exist yet.' )
97
+ return
98
+ }
99
+ // RPC example: send an RPC request
100
+ // (There is also `rpcSess.client.sendNotification`)
101
+ rpcSess . client . sendRequest ( '$/lean/rpc/call' ,
102
+ { method : "Lean.Widget.getInteractiveDiagnostics" ,
103
+ params : { lineRange : { start : 0 , end : 1 } } ,
104
+ textDocument : { uri : rpcSess . uri } ,
105
+ position : { line : 0 , character : 0 } ,
106
+ sessionId : rpcSess . sessionId
107
+ }
108
+ ) . then ( result => {
109
+ console . log ( "Got an answer to the Rpc request!" )
110
+ console . debug ( result )
111
+ } ) . catch ( reason => {
112
+ console . error ( `Rpc request failed!` )
113
+ console . debug ( reason )
114
+ } )
115
+ } } > Sample Rpc Request</ button >
116
+ < button onClick = { ( ) => {
117
+ if ( ! rpcSess ) {
118
+ console . warn ( 'rpc session does not exist yet.' )
119
+ return
120
+ }
121
+ // RPC example: send an RPC notification which the server does not understand:
122
+ // the server will return an error.
123
+ rpcSess . client . sendNotification ( 'lean4monaco/not/existing/notification' , { } )
124
+ } } > Sample Rpc Notification</ button >
125
+ </ >
30
126
}
31
127
32
128
export default LeanMonacoEditorComponent
0 commit comments