start custom infoview
This commit is contained in:
@@ -0,0 +1,50 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { useEffect, useState, useRef } from 'react';
|
||||||
|
import { EditorApi } from '@leanprover/infoview-api'
|
||||||
|
import { LeanClient } from 'lean4web/client/src/editor/leanclient';
|
||||||
|
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js'
|
||||||
|
import * as ls from 'vscode-languageserver-protocol'
|
||||||
|
|
||||||
|
// TODO: move into Lean 4 web
|
||||||
|
function toLanguageServerPosition (pos: monaco.Position): ls.Position {
|
||||||
|
return {line : pos.lineNumber - 1, character: pos.column - 1}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Infoview({ ready, editor, editorApi, uri, leanClient } : {ready: boolean, editor: monaco.editor.IStandaloneCodeEditor, editorApi: EditorApi, uri: any, leanClient: LeanClient}) {
|
||||||
|
const [rpcSession, setRpcSession] = useState<string>()
|
||||||
|
const [goals, setGoals] = useState<any[]>(null)
|
||||||
|
const liftOff = async () => {
|
||||||
|
const rpcSession = await editorApi.createRpcSession(uri)
|
||||||
|
const fetchInteractiveGoals = () => {
|
||||||
|
const pos = toLanguageServerPosition(editor.getPosition())
|
||||||
|
leanClient.sendRequest("$/lean/rpc/call", {"method":"Lean.Widget.getInteractiveGoals",
|
||||||
|
"params":{"textDocument":{uri}, "position": pos},
|
||||||
|
"sessionId":rpcSession,
|
||||||
|
"textDocument":{uri},
|
||||||
|
"position": pos
|
||||||
|
}).then(({ goals }) => {
|
||||||
|
setGoals(goals)
|
||||||
|
}).catch((err) => {
|
||||||
|
console.error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
setRpcSession(rpcSession)
|
||||||
|
editor.onDidChangeCursorPosition((ev) => {
|
||||||
|
fetchInteractiveGoals()
|
||||||
|
})
|
||||||
|
leanClient.didChange(async (ev) => {
|
||||||
|
fetchInteractiveGoals()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (ready) {
|
||||||
|
liftOff()
|
||||||
|
}
|
||||||
|
}, [ready])
|
||||||
|
// Lean.Widget.getInteractiveGoals
|
||||||
|
|
||||||
|
return (<div>Number of Goals: {goals !== null ? goals.length : "None"}</div>)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Infoview
|
||||||
@@ -23,6 +23,7 @@ import { renderInfoview } from '@leanprover/infoview'
|
|||||||
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js'
|
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js'
|
||||||
import './level.css'
|
import './level.css'
|
||||||
import { ConnectionContext } from '../connection';
|
import { ConnectionContext } from '../connection';
|
||||||
|
import Infoview from './Infoview';
|
||||||
|
|
||||||
interface LevelProps {
|
interface LevelProps {
|
||||||
nbLevels: any;
|
nbLevels: any;
|
||||||
@@ -36,8 +37,8 @@ function Level({ nbLevels, level, setCurLevel, setLevelTitle, setFinished }: Lev
|
|||||||
const [index, setIndex] = useState(level) // Level number
|
const [index, setIndex] = useState(level) // Level number
|
||||||
const [tacticDocs, setTacticDocs] = useState([])
|
const [tacticDocs, setTacticDocs] = useState([])
|
||||||
const [lemmaDocs, setLemmaDocs] = useState([])
|
const [lemmaDocs, setLemmaDocs] = useState([])
|
||||||
const [editor, setEditor] = useState(null)
|
const [editor, setEditor] = useState<monaco.editor.IStandaloneCodeEditor|null>(null)
|
||||||
const [infoProvider, setInfoProvider] = useState(null)
|
const [infoProvider, setInfoProvider] = useState<null|InfoProvider>(null)
|
||||||
const [infoviewApi, setInfoviewApi] = useState(null)
|
const [infoviewApi, setInfoviewApi] = useState(null)
|
||||||
|
|
||||||
const [leanData, setLeanData] = useState({goals: []})
|
const [leanData, setLeanData] = useState({goals: []})
|
||||||
@@ -49,6 +50,8 @@ function Level({ nbLevels, level, setCurLevel, setLevelTitle, setFinished }: Lev
|
|||||||
const infoviewRef = useRef<HTMLDivElement>(null)
|
const infoviewRef = useRef<HTMLDivElement>(null)
|
||||||
const messagePanelRef = useRef<HTMLDivElement>(null)
|
const messagePanelRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
|
const [ready, setReady] = useState(false)
|
||||||
|
|
||||||
const [message, setMessage] = useState("")
|
const [message, setMessage] = useState("")
|
||||||
const [messageOpen, setMessageOpen] = useState(false)
|
const [messageOpen, setMessageOpen] = useState(false)
|
||||||
|
|
||||||
@@ -103,21 +106,20 @@ function Level({ nbLevels, level, setCurLevel, setLevelTitle, setFinished }: Lev
|
|||||||
return () => { editor.dispose() }
|
return () => { editor.dispose() }
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
const uri = `file:///level${level}`
|
||||||
|
|
||||||
// The next function will be called when the level changes
|
// The next function will be called when the level changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editor) {
|
if (editor) {
|
||||||
const uri = monaco.Uri.parse(`file:///level${level}`)
|
const model = monaco.editor.createModel('', 'lean4', monaco.Uri.parse(uri))
|
||||||
const model = monaco.editor.createModel('', 'lean4', uri)
|
|
||||||
|
|
||||||
editor.setModel(model)
|
editor.setModel(model)
|
||||||
infoviewApi.serverRestarted(leanClient.initializeResult)
|
infoviewApi.serverRestarted(leanClient.initializeResult)
|
||||||
infoProvider.openPreview(editor, infoviewApi)
|
infoProvider.openPreview(editor, infoviewApi)
|
||||||
|
setReady(true)
|
||||||
|
|
||||||
new AbbreviationRewriter(new AbbreviationProvider(), model, editor)
|
new AbbreviationRewriter(new AbbreviationProvider(), model, editor)
|
||||||
|
|
||||||
// setInfoProvider(infoProvider)
|
|
||||||
// setInfoviewApi(infoviewApi)
|
|
||||||
|
|
||||||
leanClient.sendRequest("loadLevel", {world: "TestWorld", level}).then((res) => {
|
leanClient.sendRequest("loadLevel", {world: "TestWorld", level}).then((res) => {
|
||||||
setLevelTitle("Level " + res["index"] + ": " + res["title"])
|
setLevelTitle("Level " + res["index"] + ": " + res["title"])
|
||||||
setIndex(parseInt(res["index"]))
|
setIndex(parseInt(res["index"]))
|
||||||
@@ -156,6 +158,7 @@ function Level({ nbLevels, level, setCurLevel, setLevelTitle, setFinished }: Lev
|
|||||||
<Button disabled={index <= 1} onClick={() => { loadLevel(index - 1) }} sx={{ ml: 3, mt: 2, mb: 2 }} disableFocusRipple>Previous Level</Button>
|
<Button disabled={index <= 1} onClick={() => { loadLevel(index - 1) }} sx={{ ml: 3, mt: 2, mb: 2 }} disableFocusRipple>Previous Level</Button>
|
||||||
<Button disabled={index >= nbLevels} onClick={() => { loadLevel(index + 1) }} sx={{ ml: 3, mt: 2, mb: 2 }} disableFocusRipple>Next Level</Button>
|
<Button disabled={index >= nbLevels} onClick={() => { loadLevel(index + 1) }} sx={{ ml: 3, mt: 2, mb: 2 }} disableFocusRipple>Next Level</Button>
|
||||||
<div ref={infoviewRef} className="infoview vscode-light"></div>
|
<div ref={infoviewRef} className="infoview vscode-light"></div>
|
||||||
|
<Infoview ready={ready} leanClient={leanClient} editor={editor} editorApi={infoProvider?.getApi()} uri={uri} />
|
||||||
{/* <TacticState goals={leanData.goals} errors={errors} lastTactic={lastTactic} completed={completed} /> */}
|
{/* <TacticState goals={leanData.goals} errors={errors} lastTactic={lastTactic} completed={completed} /> */}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
Reference in New Issue
Block a user