Make edits to AST and then use formatter

This commit is contained in:
Misode
2024-10-23 06:10:14 +02:00
parent a0f3e71000
commit 18332b9dbc
5 changed files with 47 additions and 45 deletions

View File

@@ -2,26 +2,27 @@ import type { JsonNode } from '@spyglassmc/json'
import { JsonArrayNode, JsonBooleanNode, JsonNumberNode, JsonObjectNode, JsonStringNode } from '@spyglassmc/json'
import type { ListType, LiteralType, McdocType } from '@spyglassmc/mcdoc'
import type { SimplifiedStructType } from '@spyglassmc/mcdoc/lib/runtime/checker/index.js'
import { useCallback } from 'preact/hooks'
import { useLocale } from '../../contexts/Locale.jsx'
import type { Edit } from '../../services/Spyglass.js'
import type { AstEdit } from '../../services/Spyglass.js'
import { Octicon } from '../Octicon.jsx'
interface Props {
node: JsonNode | undefined
makeEdits: (edits: Edit[]) => void
makeEdit: (edit: AstEdit) => void
}
export function McdocRoot({ node, makeEdits } : Props) {
export function McdocRoot({ node, makeEdit } : Props) {
const type = node?.typeDef ?? { kind: 'unsafe' }
if (type.kind === 'struct') {
return <StructBody type={type} node={node} makeEdits={makeEdits} />
return <StructBody type={type} node={node} makeEdit={makeEdit} />
}
return <>
<div class="node-header">
<Head simpleType={type} node={node} makeEdits={makeEdits} />
<Head simpleType={type} node={node} makeEdit={makeEdit} />
</div>
<Body simpleType={type} node={node} makeEdits={makeEdits} />
<Body simpleType={type} node={node} makeEdit={makeEdit} />
</>
}
@@ -91,14 +92,14 @@ function Head({ simpleType, optional, node }: HeadProps) {
interface BodyProps extends Props {
simpleType: McdocType
}
function Body({ simpleType, node, makeEdits }: BodyProps) {
function Body({ simpleType, node, makeEdit }: BodyProps) {
const type = node?.typeDef ?? simpleType
if (node?.typeDef?.kind === 'struct') {
if (node.typeDef.fields.length === 0) {
return <></>
}
return <div class="node-body">
<StructBody type={node.typeDef} node={node} makeEdits={makeEdits} />
<StructBody type={node.typeDef} node={node} makeEdit={makeEdit} />
</div>
}
if (node?.typeDef?.kind === 'list') {
@@ -107,7 +108,7 @@ function Body({ simpleType, node, makeEdits }: BodyProps) {
return <></>
}
return <div class="node-body">
<ListBody type={node.typeDef} node={node} makeEdits={makeEdits} />
<ListBody type={node.typeDef} node={node} makeEdit={makeEdit} />
</div>
}
if (type.kind === 'byte' || type.kind === 'short' || type.kind === 'int' || type.kind === 'boolean') {
@@ -120,7 +121,7 @@ function Body({ simpleType, node, makeEdits }: BodyProps) {
interface StructBodyProps extends Props {
type: SimplifiedStructType
}
function StructBody({ type, node, makeEdits }: StructBodyProps) {
function StructBody({ type, node, makeEdit }: StructBodyProps) {
if (!JsonObjectNode.is(node)) {
return <></>
}
@@ -139,9 +140,9 @@ function StructBody({ type, node, makeEdits }: StructBodyProps) {
return <div class="node">
<div class="node-header">
<Key label={key} />
<Head simpleType={field.type} node={child} optional={field.optional} makeEdits={makeEdits} />
<Head simpleType={field.type} node={child} optional={field.optional} makeEdit={makeEdit} />
</div>
<Body simpleType={field.type} node={child} makeEdits={makeEdits} />
<Body simpleType={field.type} node={child} makeEdit={makeEdit} />
</div>
})}
</>
@@ -156,17 +157,22 @@ function Key({ label }: { label: string | number | boolean }) {
interface ListBodyProps extends Props {
type: ListType
}
function ListBody({ type, node, makeEdits }: ListBodyProps) {
function ListBody({ type, node, makeEdit }: ListBodyProps) {
const { locale } = useLocale()
if (!JsonArrayNode.is(node)) {
return <></>
}
const onRemoveItem = useCallback((index: number) => {
makeEdit(() => {
node.children.splice(index, 1)
})
}, [makeEdit, node])
return <>
{node.children.map((item, index) => {
const child = item.value
return <div class="node">
<div class="node-header">
<button class="remove tooltipped tip-se" aria-label={locale('remove')} onClick={() => makeEdits([{ range: item.range, text: '' }])}>
<button class="remove tooltipped tip-se" aria-label={locale('remove')} onClick={() => onRemoveItem(index)}>
{Octicon.trashcan}
</button>
{node.children.length > 1 && <div class="node-move">
@@ -178,9 +184,9 @@ function ListBody({ type, node, makeEdits }: ListBodyProps) {
</button>
</div>}
<Key label="entry" />
<Head simpleType={type.item} node={child} makeEdits={makeEdits} />
<Head simpleType={type.item} node={child} makeEdit={makeEdit} />
</div>
<Body simpleType={type.item} node={child} makeEdits={makeEdits} />
<Body simpleType={type.item} node={child} makeEdit={makeEdit} />
</div>
})}
</>

View File

@@ -119,7 +119,7 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
return
}
Analytics.undoGenerator(gen.id, 1, 'menu')
await service.undoEdits(uri)
await service.undoEdit(uri)
}
const redo = async (e: MouseEvent) => {
e.stopPropagation()
@@ -127,7 +127,7 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
return
}
Analytics.redoGenerator(gen.id, 1, 'menu')
await service?.redoEdits(uri)
await service?.redoEdit(uri)
}
useEffect(() => {
@@ -137,10 +137,10 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) {
}
if (e.ctrlKey && e.key === 'z') {
Analytics.undoGenerator(gen.id, 1, 'hotkey')
await service.undoEdits(uri)
await service.undoEdit(uri)
} else if (e.ctrlKey && e.key === 'y') {
Analytics.redoGenerator(gen.id, 1, 'hotkey')
await service.redoEdits(uri)
await service.redoEdit(uri)
}
}
const onKeyDown = (e: KeyboardEvent) => {

View File

@@ -3,7 +3,7 @@ import { JsonFileNode } from '@spyglassmc/json'
import { useCallback, useErrorBoundary } from 'preact/hooks'
import { useLocale } from '../../contexts/index.js'
import { useDocAndNode, useSpyglass } from '../../contexts/Spyglass.jsx'
import type { Edit } from '../../services/Spyglass.js'
import type { AstEdit } from '../../services/Spyglass.js'
import { McdocRoot } from './McdocRenderer.jsx'
type TreePanelProps = {
@@ -27,14 +27,14 @@ export function Tree({ docAndNode, onError }: TreePanelProps) {
})
if (error) return <></>
const makeEdits = useCallback((edits: Edit[]) => {
const makeEdit = useCallback((edit: AstEdit) => {
if (!service) {
return
}
service.applyEdits(docAndNode.doc.uri, edits)
service.applyEdit(docAndNode.doc.uri, edit)
}, [service, docAndNode])
return <div class="tree node-root" data-cy="tree">
<McdocRoot node={fileChild.children[0]} makeEdits={makeEdits} />
<McdocRoot node={fileChild.children[0]} makeEdit={makeEdit} />
</div>
}