Skip to content

Commit 335faad

Browse files
committed
feat: add RPC sample to demo
1 parent 9f5c6aa commit 335faad

File tree

2 files changed

+102
-6
lines changed

2 files changed

+102
-6
lines changed

demo/src/LeanMonacoEditor.tsx

+101-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
1-
import { useEffect, useRef, useContext } from 'react'
1+
import { useEffect, useRef, useContext, useState } from 'react'
22
import { LeanMonacoEditor } from 'lean4monaco'
33
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'
48

59
function LeanMonacoEditorComponent({fileName, value}: {fileName: string, value: string}) {
610
const codeviewRef = useRef<HTMLDivElement>(null)
711
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+
918
// You can start multiple `LeanMonacoEditor` instances
1019
useEffect(() => {
1120
if (leanMonaco) {
@@ -16,17 +25,104 @@ function LeanMonacoEditorComponent({fileName, value}: {fileName: string, value:
1625
console.debug('[demo]: starting editor')
1726
await leanMonacoEditor.start(codeviewRef.current!, fileName, value)
1827
console.debug('[demo]: editor started')
28+
setLeanMonacoEditor(leanMonacoEditor)
1929
})()
2030

2131
return () => {
2232
leanMonacoEditor.dispose()
2333
}
2434
}
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])
2670

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 <>
2893
<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+
</>
30126
}
31127

32128
export default LeanMonacoEditorComponent

src/vscode-lean4

0 commit comments

Comments
 (0)