Skip to content

Commit

Permalink
feat: Doc comments for built-in functions
Browse files Browse the repository at this point in the history
  • Loading branch information
hedyhli committed Sep 7, 2024
1 parent 68a7ad4 commit 8be864c
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 14 deletions.
22 changes: 17 additions & 5 deletions builtins.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { snippetCompletion } from '@codemirror/autocomplete';
// For syntax highlighting
export const ident2kind = {};
export const completions = [];
export const docs = {};

export function normalizeIdentifier(name) {
return name[0].toUpperCase() + name.substr(1).toLowerCase();
Expand Down Expand Up @@ -406,18 +407,28 @@ export function initIdent2kind(preludeEnv) {
].forEach(kw => { ident2kind[kw] = "keyword" });

Object.entries(ident2kind).forEach(
entry => { completions.push({
label: entry[0],
type: entry[1] == "builtin" ? "function" : entry[1],
detail: entry[1],
}) }
entry => {
let doc = Docs[entry[0]];
completions.push({
label: entry[0],
type: entry[1] == "builtin" ? "function" : entry[1],
detail: entry[1],
info: doc ? () => {
const elem = document.createElement("div");
elem.innerHTML = doc;
return elem;
} : undefined,
})
}
);
console.log(Docs);
completions.push(snippetCompletion(
"Prints (${});",
{
label: "Prints",
type: "snippet",
detail: "snippet",
info: "Print a list of values",
}
));
completions.push(snippetCompletion(
Expand All @@ -426,6 +437,7 @@ export function initIdent2kind(preludeEnv) {
label: "Def",
type: "snippet",
detail: "snippet",
info: "Define a function",
}
));
}
Expand Down
34 changes: 26 additions & 8 deletions cognate.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Uncomment for tests and packaging
// import TreeSitter from 'web-tree-sitter';
import { ident2kind, Builtins, initIdent2kind, normalizeIdentifier, value2object } from './builtins.js';
import { ident2kind, Builtins, initIdent2kind, normalizeIdentifier, value2object, Docs as builtinsDocs } from './builtins.js';
import * as marked from 'marked';

const CALLSTACK_LIMIT = 3000;

Expand Down Expand Up @@ -301,6 +302,7 @@ export class Runner {
parse(tree, rootEnv, userCode) {
const root = tree.rootNode;
let bail = false;
let doc = undefined;

let rootBlock = node2object.block([], userCode);
rootBlock.env.parent = rootEnv;
Expand All @@ -321,10 +323,6 @@ export class Runner {
return;
}

if (name.endsWith("_comment")) {
return;
}

if (name == "ERROR") {
if (node.text != '') {
this.appendError(
Expand All @@ -349,14 +347,29 @@ export class Runner {
currentBlock.body.push(node2object.block([], userCode));
currentBlock.body[currentBlock.body.length-1].env = currentBlock.env;
break;
case "identifier":
case "multiline_comment":
doc = node.text.substring(1, node.text.length-1).trim();
break;
case "inline_comment":
case "line_comment":
return;
case "identifier": {
let normalized = normalizeIdentifier(node.text);
if (userCode) {
// TODO: Prevent extra call in node2object
let normalized = normalizeIdentifier(node.text);
if (ident2kind[normalized]) {
this.editor.addMark(node, ident2kind[normalized]);
}
}
if (normalized == 'Def') {
let obj = node2object.identifier(node, userCode);
obj.doc = doc;
currentBlock.body.push(obj);
doc = undefined;
break;
}
// Fallthrough;
}
case "number":
case "boolean":
case "symbol":
Expand Down Expand Up @@ -423,6 +436,10 @@ export class Runner {
} else {
currentBlock.env[previous.value] = { type: '_predeclared', kind: item.value };
}
if (!userCode && currentBlock.env.parent == undefined) {
console.log("setting", previous.value);
builtinsDocs[previous.value] = marked.parse(item.doc);
}
}
}
} else if (item.type == 'block') {
Expand Down Expand Up @@ -497,6 +514,7 @@ export class Runner {

// Parse
this.tree = G.ts.parser.parse(code, this.tree);
console.table(builtinsDocs);
let result = this.parse(this.tree, G.preludeEnv, true);
this.analyze(result.rootBlock);
this.editor.applyMarks(true);
Expand Down Expand Up @@ -702,7 +720,7 @@ export class Runner {
error = `in ${this.textMarked('Def')}: ${error}`;
break;
}
env[a.value] = { type: 'function', block: b };
env[a.value] = { type: 'function', block: b, doc: item.doc };
break;
}
case 'Let': {
Expand Down
2 changes: 1 addition & 1 deletion editor/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const coreExtensions = [
cmLanguage.bracketMatching(),

cmAutocomplete.closeBrackets(),
cmAutocomplete.autocompletion({ closeOnBlur: true }),
cmAutocomplete.autocompletion({ closeOnBlur: false }),

cmView.keymap.of([
...cmAutocomplete.closeBracketsKeymap,
Expand Down
32 changes: 32 additions & 0 deletions editor/theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ export const editorTheme = EditorView.theme({
padding: ".3rem .6rem",
fontSize: ".9rem",
maxWidth: "20rem",
"& > *:first-child": {
marginTop: ".25rem",
},
"& > *": {
marginTop: "1rem",
marginBottom: ".25rem",
},
},
".cm-tooltip-hover.cm-tooltip-above": {
marginTop: "-.3rem",
Expand Down Expand Up @@ -139,6 +146,31 @@ export const editorTheme = EditorView.theme({
".cm-completionInfo.cm-completionInfo-right": {
marginLeft: "5px",
},
".cm-tooltip.cm-completionInfo": {
fontFamily: "var(--mono-font)",
fontSize: ".9rem",
padding: ".3rem .8rem",
"& > div": {
paddingTop: "1rem",
},
"& pre": {
whiteSpace: "pre-wrap",
},
"& > *, & div > *": {
marginBottom: "0 !important",
marginTop: "0 !important",
},
},
".cm-tooltip.cm-completionInfo, .cm-tooltip.cm-tooltip-hover": {
"& pre code": {
lineHeight: "inherit",
},
"& pre": {
padding: ".75rem .75rem",
paddingRight: 0,
backgroundColor: "inherit",
}
},
".cm-completionDetail": {
float: "right",
color: c.ivory,
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"@codemirror/view": "^6.32.0",
"@lezer/highlight": "^1.2.0",
"@lezer/lr": "^1.4.2",
"marked": "^14.1.1",
"web-tree-sitter": "^0.22.6"
}
}
10 changes: 10 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8be864c

Please sign in to comment.