feat: highlight repl session
This commit is contained in:
parent
d86b028a06
commit
c671506a0b
|
@ -180,7 +180,7 @@ export const { hl } = require('./treesitter.linux-x64-gnu.node');
|
||||||
|
|
||||||
Once we have this library we can load it inside Node (almost) like any other module.
|
Once we have this library we can load it inside Node (almost) like any other module.
|
||||||
|
|
||||||
```
|
```node
|
||||||
Welcome to Node.js v21.6.1.
|
Welcome to Node.js v21.6.1.
|
||||||
Type ".help" for more information.
|
Type ".help" for more information.
|
||||||
> const treesitter = await import('./dist/index.js')
|
> const treesitter = await import('./dist/index.js')
|
||||||
|
|
|
@ -9,18 +9,74 @@ function text(value: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function span(name: string) {
|
function span(name: string, children: any[] = []) {
|
||||||
return {
|
return {
|
||||||
type: 'element',
|
type: 'element',
|
||||||
tagName: 'span',
|
tagName: 'span',
|
||||||
properties: {
|
properties: {
|
||||||
className: name.replace('.', '-'),
|
className: name.replace('.', '-'),
|
||||||
},
|
},
|
||||||
children: []
|
children,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function highlight(lang: string, code: string) {
|
||||||
|
const root: any[] = [];
|
||||||
|
const ptrs: any[] = [{ children: root }];
|
||||||
|
|
||||||
|
for (const event of treesitter.hl(lang, code)) {
|
||||||
|
switch (event.kind) {
|
||||||
|
case 'text': {
|
||||||
|
const node = text(event.text);
|
||||||
|
ptrs.at(-1).children.push(node);
|
||||||
|
} break;
|
||||||
|
case 'open': {
|
||||||
|
const node = span(event.name);
|
||||||
|
ptrs.at(-1).children.push(node);
|
||||||
|
ptrs.push(node);
|
||||||
|
} break;
|
||||||
|
case 'close': {
|
||||||
|
ptrs.pop();
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
function repl(prompt: string, lang: string, code: string) {
|
||||||
|
const chunks = [{ i: [] as any[], o: [] as any[] }];
|
||||||
|
|
||||||
|
for (const line of code.split('\n')) {
|
||||||
|
if (line.startsWith(prompt)) {
|
||||||
|
chunks.push({ i: [line], o: [] });
|
||||||
|
} else {
|
||||||
|
chunks.at(-1)!.o.push(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const out: any[] = [];
|
||||||
|
for (const { i, o } of chunks) {
|
||||||
|
if (i.length) {
|
||||||
|
out.push({
|
||||||
|
type: 'element',
|
||||||
|
tagName: 'div',
|
||||||
|
children: [
|
||||||
|
span('keyword-return', [text(prompt)]),
|
||||||
|
...highlight(lang, i[0].replace(prompt, '')),
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (o.length) {
|
||||||
|
out.push(text(o.join('\n')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export default function rehypeTreesitter() {
|
export default function rehypeTreesitter() {
|
||||||
return function (tree: any) {
|
return function (tree: any) {
|
||||||
visit(tree, null, (node, _, above) => {
|
visit(tree, null, (node, _, above) => {
|
||||||
|
@ -36,27 +92,10 @@ export default function rehypeTreesitter() {
|
||||||
...!!lang && { "data-lang": lang },
|
...!!lang && { "data-lang": lang },
|
||||||
};
|
};
|
||||||
|
|
||||||
const root = { children: [] };
|
switch (lang) {
|
||||||
const ptrs: any[] = [root];
|
case 'node': node.children = repl('>', 'js', code); break;
|
||||||
|
default: node.children = highlight(lang, code);
|
||||||
for (const event of treesitter.hl(lang, code)) {
|
|
||||||
switch (event.kind) {
|
|
||||||
case 'text': {
|
|
||||||
const inserted = text(event.text);
|
|
||||||
ptrs.at(-1).children.push(inserted);
|
|
||||||
} break;
|
|
||||||
case 'open': {
|
|
||||||
const inserted = span(event.name);
|
|
||||||
ptrs.at(-1).children.push(inserted);
|
|
||||||
ptrs.push(inserted);
|
|
||||||
} break;
|
|
||||||
case 'close': {
|
|
||||||
ptrs.pop();
|
|
||||||
} break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
node.children = root.children;
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue