/**
* @fileOverview
*
* Mostly copied from https://github.com/leanprover/vscode-lean4/blob/master/lean4-infoview/src/infoview/goals.tsx
*/
import * as React from 'react'
import { InteractiveHypothesisBundle_nonAnonymousNames, MVarId, TaggedText_stripTags } from '@leanprover/infoview-api'
import { EditorContext } from '../../../../node_modules/lean4-infoview/src/infoview/contexts';
import { Locations, LocationsContext, SelectableLocation } from '../../../../node_modules/lean4-infoview/src/infoview/goalLocation';
import { InteractiveCode } from '../../../../node_modules/lean4-infoview/src/infoview/interactiveCode'
import { WithTooltipOnHover } from '../../../../node_modules/lean4-infoview/src/infoview/tooltips';
import { InputModeContext } from './context';
import { InteractiveGoal, InteractiveGoals, InteractiveGoalsWithHints, InteractiveHypothesisBundle, ProofState } from './rpc_api';
import { RpcSessionAtPos } from '@leanprover/infoview/*';
import { DocumentPosition } from '../../../../node_modules/lean4-infoview/src/infoview/util';
import { DiagnosticSeverity } from 'vscode-languageserver-protocol';
/** Returns true if `h` is inaccessible according to Lean's default name rendering. */
function isInaccessibleName(h: string): boolean {
return h.indexOf('✝') >= 0;
}
function goalToString(g: InteractiveGoal): string {
let ret = ''
if (g.userName) {
ret += `case ${g.userName}\n`
}
for (const h of g.hyps) {
const names = InteractiveHypothesisBundle_nonAnonymousNames(h).join(' ')
ret += `${names} : ${TaggedText_stripTags(h.type)}`
if (h.val) {
ret += ` := ${TaggedText_stripTags(h.val)}`
}
ret += '\n'
}
ret += `⊢ ${TaggedText_stripTags(g.type)}`
return ret
}
export function goalsToString(goals: InteractiveGoals): string {
return goals.goals.map(g => goalToString(g)).join('\n\n')
}
export function goalsWithHintsToString(goals: InteractiveGoalsWithHints): string {
return goals.goals.map(g => goalToString(g.goal)).join('\n\n')
}
interface GoalFilterState {
/** If true reverse the list of hypotheses, if false present the order received from LSP. */
reverse: boolean,
/** If true show hypotheses that have isType=True, otherwise hide them. */
showType: boolean,
/** If true show hypotheses that have isInstance=True, otherwise hide them. */
showInstance: boolean,
/** If true show hypotheses that contain a dagger in the name, otherwise hide them. */
showHiddenAssumption: boolean
/** If true show the bodies of let-values, otherwise hide them. */
showLetValue: boolean;
}
function getFilteredHypotheses(hyps: InteractiveHypothesisBundle[], filter: GoalFilterState): InteractiveHypothesisBundle[] {
return hyps.reduce((acc: InteractiveHypothesisBundle[], h) => {
if (h.isInstance && !filter.showInstance) return acc
if (h.isType && !filter.showType) return acc
const names = filter.showHiddenAssumption ? h.names : h.names.filter(n => !isInaccessibleName(n))
const hNew: InteractiveHypothesisBundle = filter.showLetValue ? { ...h, names } : { ...h, names, val: undefined }
if (names.length !== 0) acc.push(hNew)
return acc
}, [])
}
interface HypProps {
hyp: InteractiveHypothesisBundle
mvarId?: MVarId
}
function Hyp({ hyp: h, mvarId }: HypProps) {
const locs = React.useContext(LocationsContext)
const namecls: string = 'mr1 ' +
(h.isInserted ? 'inserted-text ' : '') +
(h.isRemoved ? 'removed-text ' : '')
const names = InteractiveHypothesisBundle_nonAnonymousNames(h).map((n, i) =>