Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 1 addition & 12 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ const App = (): JSX.Element => {
const devToolsMaxHeight = 500;
const [devOpts, setDevOpts] = useState<DevOptions>({
showIDs: false,
inlineLabels: false,
alwaysShowLabels: true,
alwaysShowLabels: false,
});

useEffect(() => {
Expand Down Expand Up @@ -134,16 +133,6 @@ const DevMenu = (p: { opts: DevOptions; set: (opts: DevOptions) => void }) => (
/>
<label htmlFor="alwaysShowLabels">always show labels</label>
</div>
<div>
<input
type="checkbox"
id="inlineLabels"
checked={p.opts.inlineLabels}
onChange={(e) => p.set({ ...p.opts, inlineLabels: e.target.checked })}
className="mr-1"
/>
<label htmlFor="inlineLabels">inline labels</label>
</div>
</div>
);

Expand Down
6 changes: 1 addition & 5 deletions src/components/Edit/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import {
} from "@/primer-api";
import {
defaultTreeReactFlowProps,
inlineTreeReactFlowProps,
ScrollToDef,
} from "@/components/TreeReactFlow";
import { Mode } from "../Toolbar";
Expand All @@ -58,7 +57,6 @@ const initialLevel: Level = "Expert";

export type DevOptions = {
showIDs: boolean;
inlineLabels: boolean;
alwaysShowLabels: boolean;
};

Expand Down Expand Up @@ -287,9 +285,7 @@ const AppNoError = ({
.sort((a, b) => cmpName(a.name, b.name))
.map((d) => d.name.baseName);

const treeProps = p.devOpts.inlineLabels
? inlineTreeReactFlowProps
: defaultTreeReactFlowProps;
const treeProps = defaultTreeReactFlowProps;

return (
<div className="grid h-[100dvh] grid-cols-[auto_20rem]">
Expand Down
200 changes: 147 additions & 53 deletions src/components/TreeReactFlow/Flavor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from "@/primer-api";
import classNames from "classnames";
import "./reactflow.css";
import { Label } from "./Types";

export type NodeFlavor =
| NodeFlavorTextBody
Expand Down Expand Up @@ -421,24 +422,117 @@ export const flavorEdgeClasses = (flavor: NodeFlavor): string => {
}
};

export const flavorLabel = (flavor: NodeFlavor): string => {
// if these are going to have an `| undefined`, that only really makes sense if there's a `Level` input
// actually, idk, some stuff like `let` really don't need labels

// only used in beginner mode
export const flavorLabelBeginnerModeSyntax = (
flavor: NodeFlavorNoBody
): Label | undefined => {
const basicLabel = (contents: string): Label => ({
contents,
position: ["corner", "right"],
});
switch (flavor) {
case "Hole":
return "⚠️";
return basicLabel("misfit");
case "EmptyHole":
return "?";
return basicLabel("hole");
case "Ann":
return ":";
return basicLabel("type annotation");
case "App":
return "←";
return basicLabel("apply");
case "APP":
return "←";
return basicLabel("apply type");
case "Lam":
return basicLabel("lambda");
case "LAM":
return basicLabel("type lambda");
case "Let":
return undefined;
case "LetType":
return undefined;
case "Letrec":
return basicLabel("recursive let");
case "Case":
return basicLabel("match");
case "CaseWith":
return basicLabel("with");
case "TEmptyHole":
return basicLabel("type hole");
case "THole":
return basicLabel("misfit");
case "TFun":
return basicLabel("function type");
case "TApp":
return basicLabel("apply type");
case "TForall":
return basicLabel("forall");
case "TLet":
return basicLabel("type let");
case "PatternWildcard":
return basicLabel("🤷🏽‍♀️");
case "KType":
return basicLabel("type");
case "KHole":
return basicLabel("kind hole");
case "KFun":
return basicLabel("type constructor");
}
};

export const flavorLabelTextNode = (
flavor: NodeFlavorTextBody | NodeFlavorPrimBody
): Label | undefined => {
const basicLabel = (contents: string): Label => ({
contents,
position: ["corner", "right"],
});
switch (flavor) {
case "Con":
return basicLabel("V");
case "GlobalVar":
case "LocalVar":
return basicLabel("Var");
case "PrimCon":
return basicLabel("V");
case "TCon":
return basicLabel("T");
case "TVar":
return basicLabel("Var");
case "PatternCon":
return basicLabel("V");
case "PrimPattern":
return basicLabel("V");
case "VarBind":
return basicLabel("bind");
case "TVarBind":
return basicLabel("type bind");
}
};

export const flavorLabel = (flavor: NodeFlavor): Label | undefined => {
const contents = flavorLabelOld(flavor);
return { contents, position: ["corner", "right"] };
};
export const flavorLabelOld = (flavor: NodeFlavor): string => {
switch (flavor) {
case "Hole":
return "misfit";
case "EmptyHole":
return "hole";
case "Ann":
return "type annotation";
case "App":
return "apply";
case "APP":
return "apply type";
case "Con":
return "V";
case "Lam":
return "λ";
return "lambda";
case "LAM":
return "Λ";
return "type lambda";
case "GlobalVar":
return "Var";
case "LocalVar":
Expand All @@ -448,29 +542,29 @@ export const flavorLabel = (flavor: NodeFlavor): string => {
case "LetType":
return "let type";
case "Letrec":
return "let rec";
return "recursive let";
case "Case":
return "m";
return "match";
case "CaseWith":
return "w";
return "with";
case "PrimCon":
return "V";
case "TEmptyHole":
return "?";
return "type hole";
case "THole":
return "⚠️";
return "misfit";
case "TCon":
return "T";
case "TFun":
return "";
return "function type";
case "TVar":
return "Var";
case "TApp":
return "";
return "apply type";
case "TForall":
return "";
return "forall";
case "TLet":
return "let";
return "type let";
case "Pattern":
return "";
case "PatternCon":
Expand All @@ -480,11 +574,11 @@ export const flavorLabel = (flavor: NodeFlavor): string => {
case "PatternWildcard":
return "🤷🏽‍♀️";
case "KType":
return "";
return "type";
case "KHole":
return "?";
return "kind hole";
case "KFun":
return "";
return "type constructor";
case "VarBind":
return "bind";
case "TVarBind":
Expand All @@ -510,52 +604,52 @@ export const flavorIsSyntax = (flavor: NodeFlavorTextBody): boolean => {
}
};

export const noBodyFlavorContents = (flavor: NodeFlavorNoBody): string => {
export const syntaxNodeContents = (flavor: NodeFlavorNoBody): string => {
switch (flavor) {
case "Hole":
return "⚠️";
case "EmptyHole":
return "?";
case "Ann":
return "type annotation";
return ":";
case "App":
return "apply";
return "";
case "APP":
return "apply type";
return "←";
case "Lam":
return "λ";
case "LAM":
return "Λ";
case "Let":
return "let";
case "LetType":
return "let type";
case "Letrec":
return "let rec";
case "Case":
return "match";
return "m";
case "CaseWith":
return "with";
case "TFun":
return "function type";
case "TApp":
return "apply type";
case "Hole":
return "misfit";
case "EmptyHole":
return "hole";
return "w";
case "TEmptyHole":
return "type hole";
return "?";
case "THole":
return "misfit";
return "⚠️";
case "TFun":
return "→";
case "TApp":
return "←";
case "TForall":
return "∀";
case "TLet":
return "let";
case "PatternWildcard":
return "🤷🏽‍♀️";
case "KType":
return "type";
return "";
case "KHole":
return "kind hole";
return "?";
case "KFun":
return "type constructor";
case "LAM":
return "type lambda";
case "Lam":
return "lambda";
case "Let":
return "let";
case "LetType":
return "let type";
case "Letrec":
return "recursive let";
case "TForall":
return "forall";
case "TLet":
return "type let";
return "➜";
}
};

Expand Down
18 changes: 0 additions & 18 deletions src/components/TreeReactFlow/TreeReactFlow.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ComponentStory, ComponentMeta } from "@storybook/react";
import {
defaultTreeReactFlowProps,
inlineTreeReactFlowProps,
TreeReactFlow,
TreeReactFlowProps,
} from "./";
Expand Down Expand Up @@ -361,20 +360,3 @@ export const OddAndEvenMiscStyles: ComponentStory<typeof TreeReactFlow> = (
contents: { def: def5.name, node: { nodeType: "BodyNode", meta: 5 } },
},
});
export const OddAndEvenInline: ComponentStory<typeof TreeReactFlow> = (
args: TreeReactFlowProps
) =>
treeSized({
...inlineTreeReactFlowProps,
...args,
defs: oddEvenTrees.map(([baseName, term]) => ({
name: { qualifiedModule: [], baseName },
term,
type_: emptyTypeTree(baseName),
})),
typeDefs: [],
selection: {
tag: "SelectionDef",
contents: { def: def5.name, node: { nodeType: "BodyNode", meta: 5 } },
},
});
Loading