initial commit

This commit is contained in:
2026-04-05 16:08:59 +03:00
commit 75ab9bec9f
1117 changed files with 789034 additions and 0 deletions

21
editor/node_modules/@lezer/common/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (C) 2018 by Marijn Haverbeke <marijn@haverbeke.berlin> and others
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

14
editor/node_modules/@lezer/common/README.md generated vendored Normal file
View File

@@ -0,0 +1,14 @@
# @lezer/common
[ [**WEBSITE**](http://lezer.codemirror.net) | [**ISSUES**](https://github.com/lezer-parser/lezer/issues) | [**FORUM**](https://discuss.codemirror.net/c/lezer) | [**CHANGELOG**](https://github.com/lezer-parser/common/blob/master/CHANGELOG.md) ]
[Lezer](https://lezer.codemirror.net/) is an incremental parser system
intended for use in an editor or similar system.
@lezer/common provides the syntax tree data structure and parser
abstractions for Lezer parsers.
Its programming interface is documented on [the
website](https://lezer.codemirror.net/docs/ref/#common).
This code is licensed under an MIT license.

2209
editor/node_modules/@lezer/common/dist/index.cjs generated vendored Normal file

File diff suppressed because it is too large Load Diff

1174
editor/node_modules/@lezer/common/dist/index.d.cts generated vendored Normal file

File diff suppressed because it is too large Load Diff

1174
editor/node_modules/@lezer/common/dist/index.d.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

2196
editor/node_modules/@lezer/common/dist/index.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

32
editor/node_modules/@lezer/common/package.json generated vendored Normal file
View File

@@ -0,0 +1,32 @@
{
"name": "@lezer/common",
"version": "1.5.1",
"description": "Syntax tree data structure and parser interfaces for the lezer parser",
"main": "dist/index.cjs",
"type": "module",
"exports": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"module": "dist/index.js",
"types": "dist/index.d.ts",
"author": "Marijn Haverbeke <marijn@haverbeke.berlin>",
"license": "MIT",
"devDependencies": {
"ist": "^1.1.1",
"@marijn/buildtool": "^0.1.5",
"@types/mocha": "^5.2.6",
"mocha": "^10.2.0",
"ts-node": "^10.9.2"
},
"files": ["dist"],
"repository": {
"type" : "git",
"url" : "https://github.com/lezer-parser/common.git"
},
"scripts": {
"watch": "node build.js --watch",
"prepare": "node build.js",
"test": "mocha"
}
}

21
editor/node_modules/@lezer/generator/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (C) 2018 by Marijn Haverbeke <marijn@haverbeke.berlin> and others
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

27
editor/node_modules/@lezer/generator/README.md generated vendored Normal file
View File

@@ -0,0 +1,27 @@
# @lezer/generator
[ [**WEBSITE**](http://lezer.codemirror.net) | [**ISSUES**](https://github.com/lezer-parser/lezer/issues) | [**FORUM**](https://discuss.codemirror.net/c/lezer) | [**CHANGELOG**](https://github.com/lezer-parser/generator/blob/master/CHANGELOG.md) ]
This is an [LR(1)](https://en.wikipedia.org/wiki/LR_parser) (more precisely pseudo-[LALR](https://en.wikipedia.org/wiki/LALR_parser),with opt-in [GLR](https://en.wikipedia.org/wiki/GLR_parser)) parser generator which outputs grammars that can be used by the [Lezer](https://github.com/lezer-parser/lezer/) parser.
This package exports both a command-line parser generator tool called [`lezer-generator`](https://lezer.codemirror.net/docs/guide/#building-a-grammar) and a [programming interface](https://lezer.codemirror.net/docs/ref/#generator).
The grammar format that the tool accepts is documented in the [system guide](https://lezer.codemirror.net/docs/guide/#writing-a-grammar).
See `test/cases/` for some simple example grammars, or [lezer-javascript](https://github.com/lezer-parser/javascript) for a real grammar.
You can import `"@lezer/generator/rollup"` to get a [Rollup](https://rollupjs.org/guide/en/) plugin that will transform files ending in `.grammar` or `.grammar.terms` (a pseudo-source referring to the terms produced by the `.grammar` file) as part of the rollup build process.
```javascript
import {lezer} from "@lezer/generator/rollup"
export default {
input: "./in.js",
output: {file: "out.js", format: "cjs"},
plugins: [lezer()]
}
```
The plugin can be passed `lezer({exportName})` option to configure the name of the parser export.
The code is licensed under an MIT license.

4313
editor/node_modules/@lezer/generator/dist/index.cjs generated vendored Normal file

File diff suppressed because it is too large Load Diff

95
editor/node_modules/@lezer/generator/dist/index.d.cts generated vendored Normal file
View File

@@ -0,0 +1,95 @@
import { NodePropSource, NodeProp } from '@lezer/common';
import { ExternalTokenizer, Stack, ContextTracker, LRParser } from '@lezer/lr';
type BuildOptions = {
/**
The name of the grammar file
*/
fileName?: string;
/**
A function that should be called with warnings. The default is
to call `console.warn`.
*/
warn?: (message: string) => void;
/**
Whether to include term names in the output file. Defaults to
false.
*/
includeNames?: boolean;
/**
Determines the module system used by the output file. Can be
either `"cjs"` (CommonJS) or `"es"` (ES2015 module), defaults to
`"es"`.
*/
moduleStyle?: string;
/**
Set this to true to output TypeScript code instead of plain
JavaScript.
*/
typeScript?: boolean;
/**
The name of the export that holds the parser in the output file.
Defaults to `"parser"`.
*/
exportName?: string;
/**
When calling `buildParser`, this can be used to provide
placeholders for external tokenizers.
*/
externalTokenizer?: (name: string, terms: {
[name: string]: number;
}) => ExternalTokenizer;
/**
Used by `buildParser` to resolve external prop sources.
*/
externalPropSource?: (name: string) => NodePropSource;
/**
Provide placeholders for external specializers when using
`buildParser`.
*/
externalSpecializer?: (name: string, terms: {
[name: string]: number;
}) => (value: string, stack: Stack) => number;
/**
If given, will be used to initialize external props in the parser
returned by `buildParser`.
*/
externalProp?: (name: string) => NodeProp<any>;
/**
If given, will be used as context tracker in a parser built with
`buildParser`.
*/
contextTracker?: ContextTracker<any> | ((terms: {
[name: string]: number;
}) => ContextTracker<any>);
};
/**
Build an in-memory parser instance for a given grammar. This is
mostly useful for testing. If your grammar uses external
tokenizers, you'll have to provide the `externalTokenizer` option
for the returned parser to be able to parse anything.
*/
declare function buildParser(text: string, options?: BuildOptions): LRParser;
/**
Build the code that represents the parser tables for a given
grammar description. The `parser` property in the return value
holds the main file that exports the `Parser` instance. The
`terms` property holds a declaration file that defines constants
for all of the named terms in grammar, holding their ids as value.
This is useful when external code, such as a tokenizer, needs to
be able to use these ids. It is recommended to run a tree-shaking
bundler when importing this file, since you usually only need a
handful of the many terms in your code.
*/
declare function buildParserFile(text: string, options?: BuildOptions): {
parser: string;
terms: string;
};
/**
The type of error raised when the parser generator finds an issue.
*/
declare class GenError extends Error {
}
export { type BuildOptions, GenError, buildParser, buildParserFile };

95
editor/node_modules/@lezer/generator/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,95 @@
import { NodePropSource, NodeProp } from '@lezer/common';
import { ExternalTokenizer, Stack, ContextTracker, LRParser } from '@lezer/lr';
type BuildOptions = {
/**
The name of the grammar file
*/
fileName?: string;
/**
A function that should be called with warnings. The default is
to call `console.warn`.
*/
warn?: (message: string) => void;
/**
Whether to include term names in the output file. Defaults to
false.
*/
includeNames?: boolean;
/**
Determines the module system used by the output file. Can be
either `"cjs"` (CommonJS) or `"es"` (ES2015 module), defaults to
`"es"`.
*/
moduleStyle?: string;
/**
Set this to true to output TypeScript code instead of plain
JavaScript.
*/
typeScript?: boolean;
/**
The name of the export that holds the parser in the output file.
Defaults to `"parser"`.
*/
exportName?: string;
/**
When calling `buildParser`, this can be used to provide
placeholders for external tokenizers.
*/
externalTokenizer?: (name: string, terms: {
[name: string]: number;
}) => ExternalTokenizer;
/**
Used by `buildParser` to resolve external prop sources.
*/
externalPropSource?: (name: string) => NodePropSource;
/**
Provide placeholders for external specializers when using
`buildParser`.
*/
externalSpecializer?: (name: string, terms: {
[name: string]: number;
}) => (value: string, stack: Stack) => number;
/**
If given, will be used to initialize external props in the parser
returned by `buildParser`.
*/
externalProp?: (name: string) => NodeProp<any>;
/**
If given, will be used as context tracker in a parser built with
`buildParser`.
*/
contextTracker?: ContextTracker<any> | ((terms: {
[name: string]: number;
}) => ContextTracker<any>);
};
/**
Build an in-memory parser instance for a given grammar. This is
mostly useful for testing. If your grammar uses external
tokenizers, you'll have to provide the `externalTokenizer` option
for the returned parser to be able to parse anything.
*/
declare function buildParser(text: string, options?: BuildOptions): LRParser;
/**
Build the code that represents the parser tables for a given
grammar description. The `parser` property in the return value
holds the main file that exports the `Parser` instance. The
`terms` property holds a declaration file that defines constants
for all of the named terms in grammar, holding their ids as value.
This is useful when external code, such as a tokenizer, needs to
be able to use these ids. It is recommended to run a tree-shaking
bundler when importing this file, since you usually only need a
handful of the many terms in your code.
*/
declare function buildParserFile(text: string, options?: BuildOptions): {
parser: string;
terms: string;
};
/**
The type of error raised when the parser generator finds an issue.
*/
declare class GenError extends Error {
}
export { type BuildOptions, GenError, buildParser, buildParserFile };

4309
editor/node_modules/@lezer/generator/dist/index.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,45 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var path = require('path');
var fs = require('fs');
var index_js = require('./index.cjs');
function lezer(config = {}) {
let built = Object.create(null);
return {
name: "rollup-plugin-lezer",
resolveId(source, importer) {
let m = /^([^\0].*\.grammar)(\.terms)?$/.exec(source);
if (!m) return null
let id = path.resolve(importer ? path.dirname(importer) : process.cwd(), m[1]);
return m[2] ? `\0${id}.terms` : id
},
load(id) {
let m = /^\0?(.*\.grammar)(\.terms)?$/.exec(id);
if (!m) return null
if (!m[2]) this.addWatchFile(id);
let base = m[1];
let build = built[base] || (built[base] = fs.promises.readFile(base, "utf8").then(code => index_js.buildParserFile(code, {
fileName: base,
moduleStyle: "es",
exportName: config.exportName,
warn: message => this.warn(message)
})));
return build.then(result => m[2] ? result.terms : result.parser)
},
watchChange(id) {
if (built[id]) built[id] = null;
}
}
}
const rollup = lezer;
exports.lezer = lezer;
exports.rollup = rollup;

View File

@@ -0,0 +1,3 @@
import {Plugin} from "rollup"
export function lezer(config?: {exportName?: string}): Plugin

View File

@@ -0,0 +1,3 @@
import {Plugin} from "rollup"
export function lezer(config?: {exportName?: string}): Plugin

View File

@@ -0,0 +1,38 @@
import {resolve, dirname} from "path"
import {promises as fs} from "fs"
import {buildParserFile} from "./index.js"
export function lezer(config = {}) {
let built = Object.create(null)
return {
name: "rollup-plugin-lezer",
resolveId(source, importer) {
let m = /^([^\0].*\.grammar)(\.terms)?$/.exec(source)
if (!m) return null
let id = resolve(importer ? dirname(importer) : process.cwd(), m[1])
return m[2] ? `\0${id}.terms` : id
},
load(id) {
let m = /^\0?(.*\.grammar)(\.terms)?$/.exec(id)
if (!m) return null
if (!m[2]) this.addWatchFile(id)
let base = m[1]
let build = built[base] || (built[base] = fs.readFile(base, "utf8").then(code => buildParserFile(code, {
fileName: base,
moduleStyle: "es",
exportName: config.exportName,
warn: message => this.warn(message)
})))
return build.then(result => m[2] ? result.terms : result.parser)
},
watchChange(id) {
if (built[id]) built[id] = null
}
}
}
export const rollup = lezer

187
editor/node_modules/@lezer/generator/dist/test.cjs generated vendored Normal file
View File

@@ -0,0 +1,187 @@
'use strict';
var common = require('@lezer/common');
const none = [];
class TestSpec {
constructor(name, props, children = none, wildcard = false) {
this.name = name;
this.props = props;
this.children = children;
this.wildcard = wildcard;
}
static parse(spec) {
let pos = 0, tok = "sof", value = "";
function err() {
throw new SyntaxError("Invalid test spec: " + spec);
}
function next() {
while (pos < spec.length && /\s/.test(spec.charAt(pos)))
pos++;
if (pos == spec.length)
return tok = "eof";
let next = spec.charAt(pos++);
if (next == "(" && spec.slice(pos, pos + 4) == "...)") {
pos += 4;
return tok = "...";
}
if (/[\[\](),=]/.test(next))
return tok = next;
if (/[^()\[\],="\s]/.test(next)) {
let name = /[^()\[\],="\s]*/.exec(spec.slice(pos - 1));
value = name[0];
pos += name[0].length - 1;
return tok = "name";
}
if (next == '"') {
let content = /^"((?:[^\\"]|\\.)*)"/.exec(spec.slice(pos - 1)) || err();
value = JSON.parse(content[0]);
pos += content[0].length - 1;
return tok = "name";
}
return err();
}
next();
function parseSeq() {
let seq = [];
while (tok != "eof" && tok != ")") {
seq.push(parse());
if (tok == ",")
next();
}
return seq;
}
function parse() {
let name = value, children = none, props = [], wildcard = false;
if (tok != "name")
err();
next();
if (tok == "[") {
next();
while (tok != "]") {
if (tok != "name")
err();
let prop = common.NodeProp[value], val = "";
if (!(prop instanceof common.NodeProp))
err();
next();
if (tok == "=") {
next();
if (tok != "name")
err();
val = value;
next();
}
props.push({ prop, value: prop.deserialize(val) });
}
next();
}
if (tok == "(") {
next();
children = parseSeq();
// @ts-ignore TypeScript doesn't understand that `next` may have mutated `tok` (#9998)
if (tok != ")")
err();
next();
}
else if (tok == "...") {
wildcard = true;
next();
}
return new TestSpec(name, props, children, wildcard);
}
let result = parseSeq();
if (tok != "eof")
err();
return result;
}
matches(type) {
if (type.name != this.name)
return false;
for (let { prop, value } of this.props)
if ((value || type.prop(prop)) && JSON.stringify(type.prop(prop)) != JSON.stringify(value))
return false;
return true;
}
}
function defaultIgnore(type) { return /\W/.test(type.name); }
function testTree(tree, expect, mayIgnore = defaultIgnore) {
let specs = TestSpec.parse(expect);
let stack = [specs], pos = [0];
tree.iterate({
enter(n) {
if (!n.name)
return;
let last = stack.length - 1, index = pos[last], seq = stack[last];
let next = index < seq.length ? seq[index] : null;
if (next && next.matches(n.type)) {
if (next.wildcard) {
pos[last]++;
return false;
}
pos.push(0);
stack.push(next.children);
return undefined;
}
else if (mayIgnore(n.type)) {
return false;
}
else {
let parent = last > 0 ? stack[last - 1][pos[last - 1]].name : "tree";
let after = next ? next.name + (parent == "tree" ? "" : " in " + parent) : `end of ${parent}`;
throw new Error(`Expected ${after}, got ${n.name} at ${n.to} \n${tree}`);
}
},
leave(n) {
if (!n.name)
return;
let last = stack.length - 1, index = pos[last], seq = stack[last];
if (index < seq.length)
throw new Error(`Unexpected end of ${n.name}. Expected ${seq.slice(index).map(s => s.name).join(", ")} at ${n.from}\n${tree}`);
pos.pop();
stack.pop();
pos[last - 1]++;
}
});
if (pos[0] != specs.length)
throw new Error(`Unexpected end of tree. Expected ${stack[0].slice(pos[0]).map(s => s.name).join(", ")} at ${tree.length}\n${tree}`);
}
function toLineContext(file, index) {
const endEol = file.indexOf('\n', index + 80);
const endIndex = endEol === -1 ? file.length : endEol;
return file.substring(index, endIndex).split(/\n/).map(str => ' | ' + str).join('\n');
}
function fileTests(file, fileName, mayIgnore = defaultIgnore) {
let caseExpr = /\s*#[ \t]*(.*)(?:\r\n|\r|\n)([^]*?)==+>([^]*?)(?:$|(?:\r\n|\r|\n)+(?=#))/gy;
let tests = [];
let lastIndex = 0;
for (;;) {
let m = caseExpr.exec(file);
if (!m)
throw new Error(`Unexpected file format in ${fileName} around\n\n${toLineContext(file, lastIndex)}`);
let text = m[2].trim(), expected = m[3].trim();
let [, name, configStr] = /(.*?)(\{.*?\})?$/.exec(m[1]);
let config = configStr ? JSON.parse(configStr) : null;
let strict = !/⚠|\.\.\./.test(expected);
tests.push({
name,
text,
expected,
configStr,
config,
strict,
run(parser) {
if (parser.configure && (strict || config))
parser = parser.configure(Object.assign({ strict }, config));
testTree(parser.parse(text), expected, mayIgnore);
}
});
lastIndex = m.index + m[0].length;
if (lastIndex == file.length)
break;
}
return tests;
}
exports.fileTests = fileTests;
exports.testTree = testTree;

15
editor/node_modules/@lezer/generator/dist/test.d.cts generated vendored Normal file
View File

@@ -0,0 +1,15 @@
import { Tree, Parser, NodeType } from '@lezer/common';
declare function defaultIgnore(type: NodeType): boolean;
declare function testTree(tree: Tree, expect: string, mayIgnore?: typeof defaultIgnore): void;
declare function fileTests(file: string, fileName: string, mayIgnore?: typeof defaultIgnore): {
name: string;
text: string;
expected: string;
configStr: string;
config: object;
strict: boolean;
run(parser: Parser): void;
}[];
export { fileTests, testTree };

15
editor/node_modules/@lezer/generator/dist/test.d.ts generated vendored Normal file
View File

@@ -0,0 +1,15 @@
import { Tree, Parser, NodeType } from '@lezer/common';
declare function defaultIgnore(type: NodeType): boolean;
declare function testTree(tree: Tree, expect: string, mayIgnore?: typeof defaultIgnore): void;
declare function fileTests(file: string, fileName: string, mayIgnore?: typeof defaultIgnore): {
name: string;
text: string;
expected: string;
configStr: string;
config: object;
strict: boolean;
run(parser: Parser): void;
}[];
export { fileTests, testTree };

184
editor/node_modules/@lezer/generator/dist/test.js generated vendored Normal file
View File

@@ -0,0 +1,184 @@
import { NodeProp } from '@lezer/common';
const none = [];
class TestSpec {
constructor(name, props, children = none, wildcard = false) {
this.name = name;
this.props = props;
this.children = children;
this.wildcard = wildcard;
}
static parse(spec) {
let pos = 0, tok = "sof", value = "";
function err() {
throw new SyntaxError("Invalid test spec: " + spec);
}
function next() {
while (pos < spec.length && /\s/.test(spec.charAt(pos)))
pos++;
if (pos == spec.length)
return tok = "eof";
let next = spec.charAt(pos++);
if (next == "(" && spec.slice(pos, pos + 4) == "...)") {
pos += 4;
return tok = "...";
}
if (/[\[\](),=]/.test(next))
return tok = next;
if (/[^()\[\],="\s]/.test(next)) {
let name = /[^()\[\],="\s]*/.exec(spec.slice(pos - 1));
value = name[0];
pos += name[0].length - 1;
return tok = "name";
}
if (next == '"') {
let content = /^"((?:[^\\"]|\\.)*)"/.exec(spec.slice(pos - 1)) || err();
value = JSON.parse(content[0]);
pos += content[0].length - 1;
return tok = "name";
}
return err();
}
next();
function parseSeq() {
let seq = [];
while (tok != "eof" && tok != ")") {
seq.push(parse());
if (tok == ",")
next();
}
return seq;
}
function parse() {
let name = value, children = none, props = [], wildcard = false;
if (tok != "name")
err();
next();
if (tok == "[") {
next();
while (tok != "]") {
if (tok != "name")
err();
let prop = NodeProp[value], val = "";
if (!(prop instanceof NodeProp))
err();
next();
if (tok == "=") {
next();
if (tok != "name")
err();
val = value;
next();
}
props.push({ prop, value: prop.deserialize(val) });
}
next();
}
if (tok == "(") {
next();
children = parseSeq();
// @ts-ignore TypeScript doesn't understand that `next` may have mutated `tok` (#9998)
if (tok != ")")
err();
next();
}
else if (tok == "...") {
wildcard = true;
next();
}
return new TestSpec(name, props, children, wildcard);
}
let result = parseSeq();
if (tok != "eof")
err();
return result;
}
matches(type) {
if (type.name != this.name)
return false;
for (let { prop, value } of this.props)
if ((value || type.prop(prop)) && JSON.stringify(type.prop(prop)) != JSON.stringify(value))
return false;
return true;
}
}
function defaultIgnore(type) { return /\W/.test(type.name); }
function testTree(tree, expect, mayIgnore = defaultIgnore) {
let specs = TestSpec.parse(expect);
let stack = [specs], pos = [0];
tree.iterate({
enter(n) {
if (!n.name)
return;
let last = stack.length - 1, index = pos[last], seq = stack[last];
let next = index < seq.length ? seq[index] : null;
if (next && next.matches(n.type)) {
if (next.wildcard) {
pos[last]++;
return false;
}
pos.push(0);
stack.push(next.children);
return undefined;
}
else if (mayIgnore(n.type)) {
return false;
}
else {
let parent = last > 0 ? stack[last - 1][pos[last - 1]].name : "tree";
let after = next ? next.name + (parent == "tree" ? "" : " in " + parent) : `end of ${parent}`;
throw new Error(`Expected ${after}, got ${n.name} at ${n.to} \n${tree}`);
}
},
leave(n) {
if (!n.name)
return;
let last = stack.length - 1, index = pos[last], seq = stack[last];
if (index < seq.length)
throw new Error(`Unexpected end of ${n.name}. Expected ${seq.slice(index).map(s => s.name).join(", ")} at ${n.from}\n${tree}`);
pos.pop();
stack.pop();
pos[last - 1]++;
}
});
if (pos[0] != specs.length)
throw new Error(`Unexpected end of tree. Expected ${stack[0].slice(pos[0]).map(s => s.name).join(", ")} at ${tree.length}\n${tree}`);
}
function toLineContext(file, index) {
const endEol = file.indexOf('\n', index + 80);
const endIndex = endEol === -1 ? file.length : endEol;
return file.substring(index, endIndex).split(/\n/).map(str => ' | ' + str).join('\n');
}
function fileTests(file, fileName, mayIgnore = defaultIgnore) {
let caseExpr = /\s*#[ \t]*(.*)(?:\r\n|\r|\n)([^]*?)==+>([^]*?)(?:$|(?:\r\n|\r|\n)+(?=#))/gy;
let tests = [];
let lastIndex = 0;
for (;;) {
let m = caseExpr.exec(file);
if (!m)
throw new Error(`Unexpected file format in ${fileName} around\n\n${toLineContext(file, lastIndex)}`);
let text = m[2].trim(), expected = m[3].trim();
let [, name, configStr] = /(.*?)(\{.*?\})?$/.exec(m[1]);
let config = configStr ? JSON.parse(configStr) : null;
let strict = !/⚠|\.\.\./.test(expected);
tests.push({
name,
text,
expected,
configStr,
config,
strict,
run(parser) {
if (parser.configure && (strict || config))
parser = parser.configure(Object.assign({ strict }, config));
testTree(parser.parse(text), expected, mayIgnore);
}
});
lastIndex = m.index + m[0].length;
if (lastIndex == file.length)
break;
}
return tests;
}
export { fileTests, testTree };

56
editor/node_modules/@lezer/generator/package.json generated vendored Normal file
View File

@@ -0,0 +1,56 @@
{
"name": "@lezer/generator",
"version": "1.8.0",
"description": "Parser generator for the incremental lezer parser",
"main": "dist/index.cjs",
"type": "module",
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./test": {
"import": "./dist/test.js",
"require": "./dist/test.cjs"
},
"./dist/test": {
"import": "./dist/test.js",
"require": "./dist/test.cjs"
},
"./rollup": {
"import": "./dist/rollup-plugin-lezer.js",
"require": "./dist/rollup-plugin-lezer.cjs"
}
},
"module": "dist/index.js",
"types": "dist/index.d.ts",
"author": "Marijn Haverbeke <marijn@haverbeke.berlin>",
"license": "MIT",
"devDependencies": {
"@marijn/buildtool": "^0.1.6",
"@types/mocha": "^5.2.6",
"@types/node": "^20.5.0",
"ist": "^1.1.1",
"mocha": "^10.2.0",
"ts-node": "^10.9.2"
},
"dependencies": {
"@lezer/common": "^1.1.0",
"@lezer/lr": "^1.3.0"
},
"files": [
"dist"
],
"repository": {
"type": "git",
"url": "https://github.com/lezer-parser/generator.git"
},
"scripts": {
"watch": "node build.js --watch",
"prepare": "node build.js",
"test": "mocha"
},
"bin": {
"lezer-generator": "./src/lezer-generator.cjs"
}
}

63
editor/node_modules/@lezer/generator/src/lezer-generator.cjs generated vendored Executable file
View File

@@ -0,0 +1,63 @@
#!/usr/bin/env node
const {buildParserFile, GenError} = require("..")
let file = undefined, out = undefined, moduleStyle = "es", includeNames = false, exportName = undefined, noTerms = false, typeScript = false
const {writeFileSync, readFileSync} = require("fs")
const usage = "Usage: lezer-generator [--cjs] [--names] [--noTerms] [--typeScript] [--output outfile] [--export name] file"
for (let i = 2; i < process.argv.length;) {
let arg = process.argv[i++]
if (!/^-/.test(arg)) {
if (file) error("Multiple input files given")
file = arg
} else if (arg == "--help") {
console.log(usage)
process.exit(0)
} else if (arg == "--cjs") {
moduleStyle = "cjs"
} else if (arg == "-o" || arg == "--output") {
if (out) error("Multiple output files given")
out = process.argv[i++]
} else if (arg == "--names") {
includeNames = true
} else if (arg == "--export") {
exportName = process.argv[i++]
} else if (arg == "--noTerms") {
noTerms = true
} else if (arg == "--typeScript") {
typeScript = true
} else {
error("Unrecognized option " + arg)
}
}
if (!file) error("No input file given")
function error(msg) {
console.error(msg)
console.log(usage)
process.exit(1)
}
let parser, terms
try {
;({parser, terms} = buildParserFile(readFileSync(file, "utf8"), {
fileName: file, moduleStyle, includeNames, exportName, typeScript
}))
} catch (e) {
console.error(e instanceof GenError ? e.message : e.stack)
process.exit(1)
}
if (out) {
let ext = /^(.*)\.(c?js|mjs|ts|esm?)$/.exec(out)
let outExt = typeScript ? "ts" : "js"
let [parserFile, termFile] = ext ? [out, ext[1] + ".terms." + ext[2]] : [out + "." + outExt, out + ".terms." + outExt]
writeFileSync(parserFile, parser)
if (!noTerms) writeFileSync(termFile, terms)
console.log(`Wrote ${parserFile}${noTerms ? "" : ` and ${termFile}`}`)
} else {
console.log(parser)
}

21
editor/node_modules/@lezer/highlight/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (C) 2018 by Marijn Haverbeke <marijn@haverbeke.berlin> and others
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

14
editor/node_modules/@lezer/highlight/README.md generated vendored Normal file
View File

@@ -0,0 +1,14 @@
# @lezer/highlight
[ [**WEBSITE**](http://lezer.codemirror.net) | [**ISSUES**](https://github.com/lezer-parser/lezer/issues) | [**FORUM**](https://discuss.codemirror.net/c/lezer) | [**CHANGELOG**](https://github.com/lezer-parser/highlight/blob/master/CHANGELOG.md) ]
[Lezer](https://lezer.codemirror.net/) is an incremental parser system
intended for use in an editor or similar system.
@lezer/highlight provides a syntax highlighting framework for Lezer
parse trees.
Its programming interface is documented on [the
website](https://lezer.codemirror.net/docs/ref/#highlight).
This code is licensed under an MIT license.

936
editor/node_modules/@lezer/highlight/dist/index.cjs generated vendored Normal file
View File

@@ -0,0 +1,936 @@
'use strict';
var common = require('@lezer/common');
let nextTagID = 0;
/**
Highlighting tags are markers that denote a highlighting category.
They are [associated](#highlight.styleTags) with parts of a syntax
tree by a language mode, and then mapped to an actual CSS style by
a [highlighter](#highlight.Highlighter).
Because syntax tree node types and highlight styles have to be
able to talk the same language, CodeMirror uses a mostly _closed_
[vocabulary](#highlight.tags) of syntax tags (as opposed to
traditional open string-based systems, which make it hard for
highlighting themes to cover all the tokens produced by the
various languages).
It _is_ possible to [define](#highlight.Tag^define) your own
highlighting tags for system-internal use (where you control both
the language package and the highlighter), but such tags will not
be picked up by regular highlighters (though you can derive them
from standard tags to allow highlighters to fall back to those).
*/
class Tag {
/**
@internal
*/
constructor(
/**
The optional name of the base tag @internal
*/
name,
/**
The set of this tag and all its parent tags, starting with
this one itself and sorted in order of decreasing specificity.
*/
set,
/**
The base unmodified tag that this one is based on, if it's
modified @internal
*/
base,
/**
The modifiers applied to this.base @internal
*/
modified) {
this.name = name;
this.set = set;
this.base = base;
this.modified = modified;
/**
@internal
*/
this.id = nextTagID++;
}
toString() {
let { name } = this;
for (let mod of this.modified)
if (mod.name)
name = `${mod.name}(${name})`;
return name;
}
static define(nameOrParent, parent) {
let name = typeof nameOrParent == "string" ? nameOrParent : "?";
if (nameOrParent instanceof Tag)
parent = nameOrParent;
if (parent === null || parent === void 0 ? void 0 : parent.base)
throw new Error("Can not derive from a modified tag");
let tag = new Tag(name, [], null, []);
tag.set.push(tag);
if (parent)
for (let t of parent.set)
tag.set.push(t);
return tag;
}
/**
Define a tag _modifier_, which is a function that, given a tag,
will return a tag that is a subtag of the original. Applying the
same modifier to a twice tag will return the same value (`m1(t1)
== m1(t1)`) and applying multiple modifiers will, regardless or
order, produce the same tag (`m1(m2(t1)) == m2(m1(t1))`).
When multiple modifiers are applied to a given base tag, each
smaller set of modifiers is registered as a parent, so that for
example `m1(m2(m3(t1)))` is a subtype of `m1(m2(t1))`,
`m1(m3(t1)`, and so on.
*/
static defineModifier(name) {
let mod = new Modifier(name);
return (tag) => {
if (tag.modified.indexOf(mod) > -1)
return tag;
return Modifier.get(tag.base || tag, tag.modified.concat(mod).sort((a, b) => a.id - b.id));
};
}
}
let nextModifierID = 0;
class Modifier {
constructor(name) {
this.name = name;
this.instances = [];
this.id = nextModifierID++;
}
static get(base, mods) {
if (!mods.length)
return base;
let exists = mods[0].instances.find(t => t.base == base && sameArray(mods, t.modified));
if (exists)
return exists;
let set = [], tag = new Tag(base.name, set, base, mods);
for (let m of mods)
m.instances.push(tag);
let configs = powerSet(mods);
for (let parent of base.set)
if (!parent.modified.length)
for (let config of configs)
set.push(Modifier.get(parent, config));
return tag;
}
}
function sameArray(a, b) {
return a.length == b.length && a.every((x, i) => x == b[i]);
}
function powerSet(array) {
let sets = [[]];
for (let i = 0; i < array.length; i++) {
for (let j = 0, e = sets.length; j < e; j++) {
sets.push(sets[j].concat(array[i]));
}
}
return sets.sort((a, b) => b.length - a.length);
}
/**
This function is used to add a set of tags to a language syntax
via [`NodeSet.extend`](#common.NodeSet.extend) or
[`LRParser.configure`](#lr.LRParser.configure).
The argument object maps node selectors to [highlighting
tags](#highlight.Tag) or arrays of tags.
Node selectors may hold one or more (space-separated) node paths.
Such a path can be a [node name](#common.NodeType.name), or
multiple node names (or `*` wildcards) separated by slash
characters, as in `"Block/Declaration/VariableName"`. Such a path
matches the final node but only if its direct parent nodes are the
other nodes mentioned. A `*` in such a path matches any parent,
but only a single level—wildcards that match multiple parents
aren't supported, both for efficiency reasons and because Lezer
trees make it rather hard to reason about what they would match.)
A path can be ended with `/...` to indicate that the tag assigned
to the node should also apply to all child nodes, even if they
match their own style (by default, only the innermost style is
used).
When a path ends in `!`, as in `Attribute!`, no further matching
happens for the node's child nodes, and the entire node gets the
given style.
In this notation, node names that contain `/`, `!`, `*`, or `...`
must be quoted as JSON strings.
For example:
```javascript
parser.configure({props: [
styleTags({
// Style Number and BigNumber nodes
"Number BigNumber": tags.number,
// Style Escape nodes whose parent is String
"String/Escape": tags.escape,
// Style anything inside Attributes nodes
"Attributes!": tags.meta,
// Add a style to all content inside Italic nodes
"Italic/...": tags.emphasis,
// Style InvalidString nodes as both `string` and `invalid`
"InvalidString": [tags.string, tags.invalid],
// Style the node named "/" as punctuation
'"/"': tags.punctuation
})
]})
```
*/
function styleTags(spec) {
let byName = Object.create(null);
for (let prop in spec) {
let tags = spec[prop];
if (!Array.isArray(tags))
tags = [tags];
for (let part of prop.split(" "))
if (part) {
let pieces = [], mode = 2 /* Mode.Normal */, rest = part;
for (let pos = 0;;) {
if (rest == "..." && pos > 0 && pos + 3 == part.length) {
mode = 1 /* Mode.Inherit */;
break;
}
let m = /^"(?:[^"\\]|\\.)*?"|[^\/!]+/.exec(rest);
if (!m)
throw new RangeError("Invalid path: " + part);
pieces.push(m[0] == "*" ? "" : m[0][0] == '"' ? JSON.parse(m[0]) : m[0]);
pos += m[0].length;
if (pos == part.length)
break;
let next = part[pos++];
if (pos == part.length && next == "!") {
mode = 0 /* Mode.Opaque */;
break;
}
if (next != "/")
throw new RangeError("Invalid path: " + part);
rest = part.slice(pos);
}
let last = pieces.length - 1, inner = pieces[last];
if (!inner)
throw new RangeError("Invalid path: " + part);
let rule = new Rule(tags, mode, last > 0 ? pieces.slice(0, last) : null);
byName[inner] = rule.sort(byName[inner]);
}
}
return ruleNodeProp.add(byName);
}
const ruleNodeProp = new common.NodeProp({
combine(a, b) {
let cur, root, take;
while (a || b) {
if (!a || b && a.depth >= b.depth) {
take = b;
b = b.next;
}
else {
take = a;
a = a.next;
}
if (cur && cur.mode == take.mode && !take.context && !cur.context)
continue;
let copy = new Rule(take.tags, take.mode, take.context);
if (cur)
cur.next = copy;
else
root = copy;
cur = copy;
}
return root;
}
});
class Rule {
constructor(tags, mode, context, next) {
this.tags = tags;
this.mode = mode;
this.context = context;
this.next = next;
}
get opaque() { return this.mode == 0 /* Mode.Opaque */; }
get inherit() { return this.mode == 1 /* Mode.Inherit */; }
sort(other) {
if (!other || other.depth < this.depth) {
this.next = other;
return this;
}
other.next = this.sort(other.next);
return other;
}
get depth() { return this.context ? this.context.length : 0; }
}
Rule.empty = new Rule([], 2 /* Mode.Normal */, null);
/**
Define a [highlighter](#highlight.Highlighter) from an array of
tag/class pairs. Classes associated with more specific tags will
take precedence.
*/
function tagHighlighter(tags, options) {
let map = Object.create(null);
for (let style of tags) {
if (!Array.isArray(style.tag))
map[style.tag.id] = style.class;
else
for (let tag of style.tag)
map[tag.id] = style.class;
}
let { scope, all = null } = options || {};
return {
style: (tags) => {
let cls = all;
for (let tag of tags) {
for (let sub of tag.set) {
let tagClass = map[sub.id];
if (tagClass) {
cls = cls ? cls + " " + tagClass : tagClass;
break;
}
}
}
return cls;
},
scope
};
}
function highlightTags(highlighters, tags) {
let result = null;
for (let highlighter of highlighters) {
let value = highlighter.style(tags);
if (value)
result = result ? result + " " + value : value;
}
return result;
}
/**
Highlight the given [tree](#common.Tree) with the given
[highlighter](#highlight.Highlighter). Often, the higher-level
[`highlightCode`](#highlight.highlightCode) function is easier to
use.
*/
function highlightTree(tree, highlighter,
/**
Assign styling to a region of the text. Will be called, in order
of position, for any ranges where more than zero classes apply.
`classes` is a space separated string of CSS classes.
*/
putStyle,
/**
The start of the range to highlight.
*/
from = 0,
/**
The end of the range.
*/
to = tree.length) {
let builder = new HighlightBuilder(from, Array.isArray(highlighter) ? highlighter : [highlighter], putStyle);
builder.highlightRange(tree.cursor(), from, to, "", builder.highlighters);
builder.flush(to);
}
/**
Highlight the given tree with the given highlighter, calling
`putText` for every piece of text, either with a set of classes or
with the empty string when unstyled, and `putBreak` for every line
break.
*/
function highlightCode(code, tree, highlighter, putText, putBreak, from = 0, to = code.length) {
let pos = from;
function writeTo(p, classes) {
if (p <= pos)
return;
for (let text = code.slice(pos, p), i = 0;;) {
let nextBreak = text.indexOf("\n", i);
let upto = nextBreak < 0 ? text.length : nextBreak;
if (upto > i)
putText(text.slice(i, upto), classes);
if (nextBreak < 0)
break;
putBreak();
i = nextBreak + 1;
}
pos = p;
}
highlightTree(tree, highlighter, (from, to, classes) => {
writeTo(from, "");
writeTo(to, classes);
}, from, to);
writeTo(to, "");
}
class HighlightBuilder {
constructor(at, highlighters, span) {
this.at = at;
this.highlighters = highlighters;
this.span = span;
this.class = "";
}
startSpan(at, cls) {
if (cls != this.class) {
this.flush(at);
if (at > this.at)
this.at = at;
this.class = cls;
}
}
flush(to) {
if (to > this.at && this.class)
this.span(this.at, to, this.class);
}
highlightRange(cursor, from, to, inheritedClass, highlighters) {
let { type, from: start, to: end } = cursor;
if (start >= to || end <= from)
return;
if (type.isTop)
highlighters = this.highlighters.filter(h => !h.scope || h.scope(type));
let cls = inheritedClass;
let rule = getStyleTags(cursor) || Rule.empty;
let tagCls = highlightTags(highlighters, rule.tags);
if (tagCls) {
if (cls)
cls += " ";
cls += tagCls;
if (rule.mode == 1 /* Mode.Inherit */)
inheritedClass += (inheritedClass ? " " : "") + tagCls;
}
this.startSpan(Math.max(from, start), cls);
if (rule.opaque)
return;
let mounted = cursor.tree && cursor.tree.prop(common.NodeProp.mounted);
if (mounted && mounted.overlay) {
let inner = cursor.node.enter(mounted.overlay[0].from + start, 1);
let innerHighlighters = this.highlighters.filter(h => !h.scope || h.scope(mounted.tree.type));
let hasChild = cursor.firstChild();
for (let i = 0, pos = start;; i++) {
let next = i < mounted.overlay.length ? mounted.overlay[i] : null;
let nextPos = next ? next.from + start : end;
let rangeFrom = Math.max(from, pos), rangeTo = Math.min(to, nextPos);
if (rangeFrom < rangeTo && hasChild) {
while (cursor.from < rangeTo) {
this.highlightRange(cursor, rangeFrom, rangeTo, inheritedClass, highlighters);
this.startSpan(Math.min(rangeTo, cursor.to), cls);
if (cursor.to >= nextPos || !cursor.nextSibling())
break;
}
}
if (!next || nextPos > to)
break;
pos = next.to + start;
if (pos > from) {
this.highlightRange(inner.cursor(), Math.max(from, next.from + start), Math.min(to, pos), "", innerHighlighters);
this.startSpan(Math.min(to, pos), cls);
}
}
if (hasChild)
cursor.parent();
}
else if (cursor.firstChild()) {
if (mounted)
inheritedClass = "";
do {
if (cursor.to <= from)
continue;
if (cursor.from >= to)
break;
this.highlightRange(cursor, from, to, inheritedClass, highlighters);
this.startSpan(Math.min(to, cursor.to), cls);
} while (cursor.nextSibling());
cursor.parent();
}
}
}
/**
Match a syntax node's [highlight rules](#highlight.styleTags). If
there's a match, return its set of tags, and whether it is
opaque (uses a `!`) or applies to all child nodes (`/...`).
*/
function getStyleTags(node) {
let rule = node.type.prop(ruleNodeProp);
while (rule && rule.context && !node.matchContext(rule.context))
rule = rule.next;
return rule || null;
}
const t = Tag.define;
const comment = t(), name = t(), typeName = t(name), propertyName = t(name), literal = t(), string = t(literal), number = t(literal), content = t(), heading = t(content), keyword = t(), operator = t(), punctuation = t(), bracket = t(punctuation), meta = t();
/**
The default set of highlighting [tags](#highlight.Tag).
This collection is heavily biased towards programming languages,
and necessarily incomplete. A full ontology of syntactic
constructs would fill a stack of books, and be impractical to
write themes for. So try to make do with this set. If all else
fails, [open an
issue](https://github.com/codemirror/codemirror.next) to propose a
new tag, or [define](#highlight.Tag^define) a local custom tag for
your use case.
Note that it is not obligatory to always attach the most specific
tag possible to an element—if your grammar can't easily
distinguish a certain type of element (such as a local variable),
it is okay to style it as its more general variant (a variable).
For tags that extend some parent tag, the documentation links to
the parent.
*/
const tags = {
/**
A comment.
*/
comment,
/**
A line [comment](#highlight.tags.comment).
*/
lineComment: t(comment),
/**
A block [comment](#highlight.tags.comment).
*/
blockComment: t(comment),
/**
A documentation [comment](#highlight.tags.comment).
*/
docComment: t(comment),
/**
Any kind of identifier.
*/
name,
/**
The [name](#highlight.tags.name) of a variable.
*/
variableName: t(name),
/**
A type [name](#highlight.tags.name).
*/
typeName: typeName,
/**
A tag name (subtag of [`typeName`](#highlight.tags.typeName)).
*/
tagName: t(typeName),
/**
A property or field [name](#highlight.tags.name).
*/
propertyName: propertyName,
/**
An attribute name (subtag of [`propertyName`](#highlight.tags.propertyName)).
*/
attributeName: t(propertyName),
/**
The [name](#highlight.tags.name) of a class.
*/
className: t(name),
/**
A label [name](#highlight.tags.name).
*/
labelName: t(name),
/**
A namespace [name](#highlight.tags.name).
*/
namespace: t(name),
/**
The [name](#highlight.tags.name) of a macro.
*/
macroName: t(name),
/**
A literal value.
*/
literal,
/**
A string [literal](#highlight.tags.literal).
*/
string,
/**
A documentation [string](#highlight.tags.string).
*/
docString: t(string),
/**
A character literal (subtag of [string](#highlight.tags.string)).
*/
character: t(string),
/**
An attribute value (subtag of [string](#highlight.tags.string)).
*/
attributeValue: t(string),
/**
A number [literal](#highlight.tags.literal).
*/
number,
/**
An integer [number](#highlight.tags.number) literal.
*/
integer: t(number),
/**
A floating-point [number](#highlight.tags.number) literal.
*/
float: t(number),
/**
A boolean [literal](#highlight.tags.literal).
*/
bool: t(literal),
/**
Regular expression [literal](#highlight.tags.literal).
*/
regexp: t(literal),
/**
An escape [literal](#highlight.tags.literal), for example a
backslash escape in a string.
*/
escape: t(literal),
/**
A color [literal](#highlight.tags.literal).
*/
color: t(literal),
/**
A URL [literal](#highlight.tags.literal).
*/
url: t(literal),
/**
A language keyword.
*/
keyword,
/**
The [keyword](#highlight.tags.keyword) for the self or this
object.
*/
self: t(keyword),
/**
The [keyword](#highlight.tags.keyword) for null.
*/
null: t(keyword),
/**
A [keyword](#highlight.tags.keyword) denoting some atomic value.
*/
atom: t(keyword),
/**
A [keyword](#highlight.tags.keyword) that represents a unit.
*/
unit: t(keyword),
/**
A modifier [keyword](#highlight.tags.keyword).
*/
modifier: t(keyword),
/**
A [keyword](#highlight.tags.keyword) that acts as an operator.
*/
operatorKeyword: t(keyword),
/**
A control-flow related [keyword](#highlight.tags.keyword).
*/
controlKeyword: t(keyword),
/**
A [keyword](#highlight.tags.keyword) that defines something.
*/
definitionKeyword: t(keyword),
/**
A [keyword](#highlight.tags.keyword) related to defining or
interfacing with modules.
*/
moduleKeyword: t(keyword),
/**
An operator.
*/
operator,
/**
An [operator](#highlight.tags.operator) that dereferences something.
*/
derefOperator: t(operator),
/**
Arithmetic-related [operator](#highlight.tags.operator).
*/
arithmeticOperator: t(operator),
/**
Logical [operator](#highlight.tags.operator).
*/
logicOperator: t(operator),
/**
Bit [operator](#highlight.tags.operator).
*/
bitwiseOperator: t(operator),
/**
Comparison [operator](#highlight.tags.operator).
*/
compareOperator: t(operator),
/**
[Operator](#highlight.tags.operator) that updates its operand.
*/
updateOperator: t(operator),
/**
[Operator](#highlight.tags.operator) that defines something.
*/
definitionOperator: t(operator),
/**
Type-related [operator](#highlight.tags.operator).
*/
typeOperator: t(operator),
/**
Control-flow [operator](#highlight.tags.operator).
*/
controlOperator: t(operator),
/**
Program or markup punctuation.
*/
punctuation,
/**
[Punctuation](#highlight.tags.punctuation) that separates
things.
*/
separator: t(punctuation),
/**
Bracket-style [punctuation](#highlight.tags.punctuation).
*/
bracket,
/**
Angle [brackets](#highlight.tags.bracket) (usually `<` and `>`
tokens).
*/
angleBracket: t(bracket),
/**
Square [brackets](#highlight.tags.bracket) (usually `[` and `]`
tokens).
*/
squareBracket: t(bracket),
/**
Parentheses (usually `(` and `)` tokens). Subtag of
[bracket](#highlight.tags.bracket).
*/
paren: t(bracket),
/**
Braces (usually `{` and `}` tokens). Subtag of
[bracket](#highlight.tags.bracket).
*/
brace: t(bracket),
/**
Content, for example plain text in XML or markup documents.
*/
content,
/**
[Content](#highlight.tags.content) that represents a heading.
*/
heading,
/**
A level 1 [heading](#highlight.tags.heading).
*/
heading1: t(heading),
/**
A level 2 [heading](#highlight.tags.heading).
*/
heading2: t(heading),
/**
A level 3 [heading](#highlight.tags.heading).
*/
heading3: t(heading),
/**
A level 4 [heading](#highlight.tags.heading).
*/
heading4: t(heading),
/**
A level 5 [heading](#highlight.tags.heading).
*/
heading5: t(heading),
/**
A level 6 [heading](#highlight.tags.heading).
*/
heading6: t(heading),
/**
A prose [content](#highlight.tags.content) separator (such as a horizontal rule).
*/
contentSeparator: t(content),
/**
[Content](#highlight.tags.content) that represents a list.
*/
list: t(content),
/**
[Content](#highlight.tags.content) that represents a quote.
*/
quote: t(content),
/**
[Content](#highlight.tags.content) that is emphasized.
*/
emphasis: t(content),
/**
[Content](#highlight.tags.content) that is styled strong.
*/
strong: t(content),
/**
[Content](#highlight.tags.content) that is part of a link.
*/
link: t(content),
/**
[Content](#highlight.tags.content) that is styled as code or
monospace.
*/
monospace: t(content),
/**
[Content](#highlight.tags.content) that has a strike-through
style.
*/
strikethrough: t(content),
/**
Inserted text in a change-tracking format.
*/
inserted: t(),
/**
Deleted text.
*/
deleted: t(),
/**
Changed text.
*/
changed: t(),
/**
An invalid or unsyntactic element.
*/
invalid: t(),
/**
Metadata or meta-instruction.
*/
meta,
/**
[Metadata](#highlight.tags.meta) that applies to the entire
document.
*/
documentMeta: t(meta),
/**
[Metadata](#highlight.tags.meta) that annotates or adds
attributes to a given syntactic element.
*/
annotation: t(meta),
/**
Processing instruction or preprocessor directive. Subtag of
[meta](#highlight.tags.meta).
*/
processingInstruction: t(meta),
/**
[Modifier](#highlight.Tag^defineModifier) that indicates that a
given element is being defined. Expected to be used with the
various [name](#highlight.tags.name) tags.
*/
definition: Tag.defineModifier("definition"),
/**
[Modifier](#highlight.Tag^defineModifier) that indicates that
something is constant. Mostly expected to be used with
[variable names](#highlight.tags.variableName).
*/
constant: Tag.defineModifier("constant"),
/**
[Modifier](#highlight.Tag^defineModifier) used to indicate that
a [variable](#highlight.tags.variableName) or [property
name](#highlight.tags.propertyName) is being called or defined
as a function.
*/
function: Tag.defineModifier("function"),
/**
[Modifier](#highlight.Tag^defineModifier) that can be applied to
[names](#highlight.tags.name) to indicate that they belong to
the language's standard environment.
*/
standard: Tag.defineModifier("standard"),
/**
[Modifier](#highlight.Tag^defineModifier) that indicates a given
[names](#highlight.tags.name) is local to some scope.
*/
local: Tag.defineModifier("local"),
/**
A generic variant [modifier](#highlight.Tag^defineModifier) that
can be used to tag language-specific alternative variants of
some common tag. It is recommended for themes to define special
forms of at least the [string](#highlight.tags.string) and
[variable name](#highlight.tags.variableName) tags, since those
come up a lot.
*/
special: Tag.defineModifier("special")
};
for (let name in tags) {
let val = tags[name];
if (val instanceof Tag)
val.name = name;
}
/**
This is a highlighter that adds stable, predictable classes to
tokens, for styling with external CSS.
The following tags are mapped to their name prefixed with `"tok-"`
(for example `"tok-comment"`):
* [`link`](#highlight.tags.link)
* [`heading`](#highlight.tags.heading)
* [`emphasis`](#highlight.tags.emphasis)
* [`strong`](#highlight.tags.strong)
* [`keyword`](#highlight.tags.keyword)
* [`atom`](#highlight.tags.atom)
* [`bool`](#highlight.tags.bool)
* [`url`](#highlight.tags.url)
* [`labelName`](#highlight.tags.labelName)
* [`inserted`](#highlight.tags.inserted)
* [`deleted`](#highlight.tags.deleted)
* [`literal`](#highlight.tags.literal)
* [`string`](#highlight.tags.string)
* [`number`](#highlight.tags.number)
* [`variableName`](#highlight.tags.variableName)
* [`typeName`](#highlight.tags.typeName)
* [`namespace`](#highlight.tags.namespace)
* [`className`](#highlight.tags.className)
* [`macroName`](#highlight.tags.macroName)
* [`propertyName`](#highlight.tags.propertyName)
* [`operator`](#highlight.tags.operator)
* [`comment`](#highlight.tags.comment)
* [`meta`](#highlight.tags.meta)
* [`punctuation`](#highlight.tags.punctuation)
* [`invalid`](#highlight.tags.invalid)
In addition, these mappings are provided:
* [`regexp`](#highlight.tags.regexp),
[`escape`](#highlight.tags.escape), and
[`special`](#highlight.tags.special)[`(string)`](#highlight.tags.string)
are mapped to `"tok-string2"`
* [`special`](#highlight.tags.special)[`(variableName)`](#highlight.tags.variableName)
to `"tok-variableName2"`
* [`local`](#highlight.tags.local)[`(variableName)`](#highlight.tags.variableName)
to `"tok-variableName tok-local"`
* [`definition`](#highlight.tags.definition)[`(variableName)`](#highlight.tags.variableName)
to `"tok-variableName tok-definition"`
* [`definition`](#highlight.tags.definition)[`(propertyName)`](#highlight.tags.propertyName)
to `"tok-propertyName tok-definition"`
*/
const classHighlighter = tagHighlighter([
{ tag: tags.link, class: "tok-link" },
{ tag: tags.heading, class: "tok-heading" },
{ tag: tags.emphasis, class: "tok-emphasis" },
{ tag: tags.strong, class: "tok-strong" },
{ tag: tags.keyword, class: "tok-keyword" },
{ tag: tags.atom, class: "tok-atom" },
{ tag: tags.bool, class: "tok-bool" },
{ tag: tags.url, class: "tok-url" },
{ tag: tags.labelName, class: "tok-labelName" },
{ tag: tags.inserted, class: "tok-inserted" },
{ tag: tags.deleted, class: "tok-deleted" },
{ tag: tags.literal, class: "tok-literal" },
{ tag: tags.string, class: "tok-string" },
{ tag: tags.number, class: "tok-number" },
{ tag: [tags.regexp, tags.escape, tags.special(tags.string)], class: "tok-string2" },
{ tag: tags.variableName, class: "tok-variableName" },
{ tag: tags.local(tags.variableName), class: "tok-variableName tok-local" },
{ tag: tags.definition(tags.variableName), class: "tok-variableName tok-definition" },
{ tag: tags.special(tags.variableName), class: "tok-variableName2" },
{ tag: tags.definition(tags.propertyName), class: "tok-propertyName tok-definition" },
{ tag: tags.typeName, class: "tok-typeName" },
{ tag: tags.namespace, class: "tok-namespace" },
{ tag: tags.className, class: "tok-className" },
{ tag: tags.macroName, class: "tok-macroName" },
{ tag: tags.propertyName, class: "tok-propertyName" },
{ tag: tags.operator, class: "tok-operator" },
{ tag: tags.comment, class: "tok-comment" },
{ tag: tags.meta, class: "tok-meta" },
{ tag: tags.invalid, class: "tok-invalid" },
{ tag: tags.punctuation, class: "tok-punctuation" }
]);
exports.Tag = Tag;
exports.classHighlighter = classHighlighter;
exports.getStyleTags = getStyleTags;
exports.highlightCode = highlightCode;
exports.highlightTree = highlightTree;
exports.styleTags = styleTags;
exports.tagHighlighter = tagHighlighter;
exports.tags = tags;

623
editor/node_modules/@lezer/highlight/dist/index.d.cts generated vendored Normal file
View File

@@ -0,0 +1,623 @@
import * as _lezer_common from '@lezer/common';
import { NodeType, Tree, SyntaxNodeRef } from '@lezer/common';
/**
Highlighting tags are markers that denote a highlighting category.
They are [associated](#highlight.styleTags) with parts of a syntax
tree by a language mode, and then mapped to an actual CSS style by
a [highlighter](#highlight.Highlighter).
Because syntax tree node types and highlight styles have to be
able to talk the same language, CodeMirror uses a mostly _closed_
[vocabulary](#highlight.tags) of syntax tags (as opposed to
traditional open string-based systems, which make it hard for
highlighting themes to cover all the tokens produced by the
various languages).
It _is_ possible to [define](#highlight.Tag^define) your own
highlighting tags for system-internal use (where you control both
the language package and the highlighter), but such tags will not
be picked up by regular highlighters (though you can derive them
from standard tags to allow highlighters to fall back to those).
*/
declare class Tag {
/**
The set of this tag and all its parent tags, starting with
this one itself and sorted in order of decreasing specificity.
*/
readonly set: Tag[];
toString(): string;
/**
Define a new tag. If `parent` is given, the tag is treated as a
sub-tag of that parent, and
[highlighters](#highlight.tagHighlighter) that don't mention
this tag will try to fall back to the parent tag (or grandparent
tag, etc).
*/
static define(name?: string, parent?: Tag): Tag;
static define(parent?: Tag): Tag;
/**
Define a tag _modifier_, which is a function that, given a tag,
will return a tag that is a subtag of the original. Applying the
same modifier to a twice tag will return the same value (`m1(t1)
== m1(t1)`) and applying multiple modifiers will, regardless or
order, produce the same tag (`m1(m2(t1)) == m2(m1(t1))`).
When multiple modifiers are applied to a given base tag, each
smaller set of modifiers is registered as a parent, so that for
example `m1(m2(m3(t1)))` is a subtype of `m1(m2(t1))`,
`m1(m3(t1)`, and so on.
*/
static defineModifier(name?: string): (tag: Tag) => Tag;
}
/**
This function is used to add a set of tags to a language syntax
via [`NodeSet.extend`](#common.NodeSet.extend) or
[`LRParser.configure`](#lr.LRParser.configure).
The argument object maps node selectors to [highlighting
tags](#highlight.Tag) or arrays of tags.
Node selectors may hold one or more (space-separated) node paths.
Such a path can be a [node name](#common.NodeType.name), or
multiple node names (or `*` wildcards) separated by slash
characters, as in `"Block/Declaration/VariableName"`. Such a path
matches the final node but only if its direct parent nodes are the
other nodes mentioned. A `*` in such a path matches any parent,
but only a single level—wildcards that match multiple parents
aren't supported, both for efficiency reasons and because Lezer
trees make it rather hard to reason about what they would match.)
A path can be ended with `/...` to indicate that the tag assigned
to the node should also apply to all child nodes, even if they
match their own style (by default, only the innermost style is
used).
When a path ends in `!`, as in `Attribute!`, no further matching
happens for the node's child nodes, and the entire node gets the
given style.
In this notation, node names that contain `/`, `!`, `*`, or `...`
must be quoted as JSON strings.
For example:
```javascript
parser.configure({props: [
styleTags({
// Style Number and BigNumber nodes
"Number BigNumber": tags.number,
// Style Escape nodes whose parent is String
"String/Escape": tags.escape,
// Style anything inside Attributes nodes
"Attributes!": tags.meta,
// Add a style to all content inside Italic nodes
"Italic/...": tags.emphasis,
// Style InvalidString nodes as both `string` and `invalid`
"InvalidString": [tags.string, tags.invalid],
// Style the node named "/" as punctuation
'"/"': tags.punctuation
})
]})
```
*/
declare function styleTags(spec: {
[selector: string]: Tag | readonly Tag[];
}): _lezer_common.NodePropSource;
/**
A highlighter defines a mapping from highlighting tags and
language scopes to CSS class names. They are usually defined via
[`tagHighlighter`](#highlight.tagHighlighter) or some wrapper
around that, but it is also possible to implement them from
scratch.
*/
interface Highlighter {
/**
Get the set of classes that should be applied to the given set
of highlighting tags, or null if this highlighter doesn't assign
a style to the tags.
*/
style(tags: readonly Tag[]): string | null;
/**
When given, the highlighter will only be applied to trees on
whose [top](#common.NodeType.isTop) node this predicate returns
true.
*/
scope?(node: NodeType): boolean;
}
/**
Define a [highlighter](#highlight.Highlighter) from an array of
tag/class pairs. Classes associated with more specific tags will
take precedence.
*/
declare function tagHighlighter(tags: readonly {
tag: Tag | readonly Tag[];
class: string;
}[], options?: {
/**
By default, highlighters apply to the entire document. You can
scope them to a single language by providing the tree's
[top](#common.NodeType.isTop) node type here.
*/
scope?: (node: NodeType) => boolean;
/**
Add a style to _all_ tokens. Probably only useful in combination
with `scope`.
*/
all?: string;
}): Highlighter;
/**
Highlight the given [tree](#common.Tree) with the given
[highlighter](#highlight.Highlighter). Often, the higher-level
[`highlightCode`](#highlight.highlightCode) function is easier to
use.
*/
declare function highlightTree(tree: Tree, highlighter: Highlighter | readonly Highlighter[],
/**
Assign styling to a region of the text. Will be called, in order
of position, for any ranges where more than zero classes apply.
`classes` is a space separated string of CSS classes.
*/
putStyle: (from: number, to: number, classes: string) => void,
/**
The start of the range to highlight.
*/
from?: number,
/**
The end of the range.
*/
to?: number): void;
/**
Highlight the given tree with the given highlighter, calling
`putText` for every piece of text, either with a set of classes or
with the empty string when unstyled, and `putBreak` for every line
break.
*/
declare function highlightCode(code: string, tree: Tree, highlighter: Highlighter | readonly Highlighter[], putText: (code: string, classes: string) => void, putBreak: () => void, from?: number, to?: number): void;
/**
Match a syntax node's [highlight rules](#highlight.styleTags). If
there's a match, return its set of tags, and whether it is
opaque (uses a `!`) or applies to all child nodes (`/...`).
*/
declare function getStyleTags(node: SyntaxNodeRef): {
tags: readonly Tag[];
opaque: boolean;
inherit: boolean;
} | null;
/**
The default set of highlighting [tags](#highlight.Tag).
This collection is heavily biased towards programming languages,
and necessarily incomplete. A full ontology of syntactic
constructs would fill a stack of books, and be impractical to
write themes for. So try to make do with this set. If all else
fails, [open an
issue](https://github.com/codemirror/codemirror.next) to propose a
new tag, or [define](#highlight.Tag^define) a local custom tag for
your use case.
Note that it is not obligatory to always attach the most specific
tag possible to an element—if your grammar can't easily
distinguish a certain type of element (such as a local variable),
it is okay to style it as its more general variant (a variable).
For tags that extend some parent tag, the documentation links to
the parent.
*/
declare const tags: {
/**
A comment.
*/
comment: Tag;
/**
A line [comment](#highlight.tags.comment).
*/
lineComment: Tag;
/**
A block [comment](#highlight.tags.comment).
*/
blockComment: Tag;
/**
A documentation [comment](#highlight.tags.comment).
*/
docComment: Tag;
/**
Any kind of identifier.
*/
name: Tag;
/**
The [name](#highlight.tags.name) of a variable.
*/
variableName: Tag;
/**
A type [name](#highlight.tags.name).
*/
typeName: Tag;
/**
A tag name (subtag of [`typeName`](#highlight.tags.typeName)).
*/
tagName: Tag;
/**
A property or field [name](#highlight.tags.name).
*/
propertyName: Tag;
/**
An attribute name (subtag of [`propertyName`](#highlight.tags.propertyName)).
*/
attributeName: Tag;
/**
The [name](#highlight.tags.name) of a class.
*/
className: Tag;
/**
A label [name](#highlight.tags.name).
*/
labelName: Tag;
/**
A namespace [name](#highlight.tags.name).
*/
namespace: Tag;
/**
The [name](#highlight.tags.name) of a macro.
*/
macroName: Tag;
/**
A literal value.
*/
literal: Tag;
/**
A string [literal](#highlight.tags.literal).
*/
string: Tag;
/**
A documentation [string](#highlight.tags.string).
*/
docString: Tag;
/**
A character literal (subtag of [string](#highlight.tags.string)).
*/
character: Tag;
/**
An attribute value (subtag of [string](#highlight.tags.string)).
*/
attributeValue: Tag;
/**
A number [literal](#highlight.tags.literal).
*/
number: Tag;
/**
An integer [number](#highlight.tags.number) literal.
*/
integer: Tag;
/**
A floating-point [number](#highlight.tags.number) literal.
*/
float: Tag;
/**
A boolean [literal](#highlight.tags.literal).
*/
bool: Tag;
/**
Regular expression [literal](#highlight.tags.literal).
*/
regexp: Tag;
/**
An escape [literal](#highlight.tags.literal), for example a
backslash escape in a string.
*/
escape: Tag;
/**
A color [literal](#highlight.tags.literal).
*/
color: Tag;
/**
A URL [literal](#highlight.tags.literal).
*/
url: Tag;
/**
A language keyword.
*/
keyword: Tag;
/**
The [keyword](#highlight.tags.keyword) for the self or this
object.
*/
self: Tag;
/**
The [keyword](#highlight.tags.keyword) for null.
*/
null: Tag;
/**
A [keyword](#highlight.tags.keyword) denoting some atomic value.
*/
atom: Tag;
/**
A [keyword](#highlight.tags.keyword) that represents a unit.
*/
unit: Tag;
/**
A modifier [keyword](#highlight.tags.keyword).
*/
modifier: Tag;
/**
A [keyword](#highlight.tags.keyword) that acts as an operator.
*/
operatorKeyword: Tag;
/**
A control-flow related [keyword](#highlight.tags.keyword).
*/
controlKeyword: Tag;
/**
A [keyword](#highlight.tags.keyword) that defines something.
*/
definitionKeyword: Tag;
/**
A [keyword](#highlight.tags.keyword) related to defining or
interfacing with modules.
*/
moduleKeyword: Tag;
/**
An operator.
*/
operator: Tag;
/**
An [operator](#highlight.tags.operator) that dereferences something.
*/
derefOperator: Tag;
/**
Arithmetic-related [operator](#highlight.tags.operator).
*/
arithmeticOperator: Tag;
/**
Logical [operator](#highlight.tags.operator).
*/
logicOperator: Tag;
/**
Bit [operator](#highlight.tags.operator).
*/
bitwiseOperator: Tag;
/**
Comparison [operator](#highlight.tags.operator).
*/
compareOperator: Tag;
/**
[Operator](#highlight.tags.operator) that updates its operand.
*/
updateOperator: Tag;
/**
[Operator](#highlight.tags.operator) that defines something.
*/
definitionOperator: Tag;
/**
Type-related [operator](#highlight.tags.operator).
*/
typeOperator: Tag;
/**
Control-flow [operator](#highlight.tags.operator).
*/
controlOperator: Tag;
/**
Program or markup punctuation.
*/
punctuation: Tag;
/**
[Punctuation](#highlight.tags.punctuation) that separates
things.
*/
separator: Tag;
/**
Bracket-style [punctuation](#highlight.tags.punctuation).
*/
bracket: Tag;
/**
Angle [brackets](#highlight.tags.bracket) (usually `<` and `>`
tokens).
*/
angleBracket: Tag;
/**
Square [brackets](#highlight.tags.bracket) (usually `[` and `]`
tokens).
*/
squareBracket: Tag;
/**
Parentheses (usually `(` and `)` tokens). Subtag of
[bracket](#highlight.tags.bracket).
*/
paren: Tag;
/**
Braces (usually `{` and `}` tokens). Subtag of
[bracket](#highlight.tags.bracket).
*/
brace: Tag;
/**
Content, for example plain text in XML or markup documents.
*/
content: Tag;
/**
[Content](#highlight.tags.content) that represents a heading.
*/
heading: Tag;
/**
A level 1 [heading](#highlight.tags.heading).
*/
heading1: Tag;
/**
A level 2 [heading](#highlight.tags.heading).
*/
heading2: Tag;
/**
A level 3 [heading](#highlight.tags.heading).
*/
heading3: Tag;
/**
A level 4 [heading](#highlight.tags.heading).
*/
heading4: Tag;
/**
A level 5 [heading](#highlight.tags.heading).
*/
heading5: Tag;
/**
A level 6 [heading](#highlight.tags.heading).
*/
heading6: Tag;
/**
A prose [content](#highlight.tags.content) separator (such as a horizontal rule).
*/
contentSeparator: Tag;
/**
[Content](#highlight.tags.content) that represents a list.
*/
list: Tag;
/**
[Content](#highlight.tags.content) that represents a quote.
*/
quote: Tag;
/**
[Content](#highlight.tags.content) that is emphasized.
*/
emphasis: Tag;
/**
[Content](#highlight.tags.content) that is styled strong.
*/
strong: Tag;
/**
[Content](#highlight.tags.content) that is part of a link.
*/
link: Tag;
/**
[Content](#highlight.tags.content) that is styled as code or
monospace.
*/
monospace: Tag;
/**
[Content](#highlight.tags.content) that has a strike-through
style.
*/
strikethrough: Tag;
/**
Inserted text in a change-tracking format.
*/
inserted: Tag;
/**
Deleted text.
*/
deleted: Tag;
/**
Changed text.
*/
changed: Tag;
/**
An invalid or unsyntactic element.
*/
invalid: Tag;
/**
Metadata or meta-instruction.
*/
meta: Tag;
/**
[Metadata](#highlight.tags.meta) that applies to the entire
document.
*/
documentMeta: Tag;
/**
[Metadata](#highlight.tags.meta) that annotates or adds
attributes to a given syntactic element.
*/
annotation: Tag;
/**
Processing instruction or preprocessor directive. Subtag of
[meta](#highlight.tags.meta).
*/
processingInstruction: Tag;
/**
[Modifier](#highlight.Tag^defineModifier) that indicates that a
given element is being defined. Expected to be used with the
various [name](#highlight.tags.name) tags.
*/
definition: (tag: Tag) => Tag;
/**
[Modifier](#highlight.Tag^defineModifier) that indicates that
something is constant. Mostly expected to be used with
[variable names](#highlight.tags.variableName).
*/
constant: (tag: Tag) => Tag;
/**
[Modifier](#highlight.Tag^defineModifier) used to indicate that
a [variable](#highlight.tags.variableName) or [property
name](#highlight.tags.propertyName) is being called or defined
as a function.
*/
function: (tag: Tag) => Tag;
/**
[Modifier](#highlight.Tag^defineModifier) that can be applied to
[names](#highlight.tags.name) to indicate that they belong to
the language's standard environment.
*/
standard: (tag: Tag) => Tag;
/**
[Modifier](#highlight.Tag^defineModifier) that indicates a given
[names](#highlight.tags.name) is local to some scope.
*/
local: (tag: Tag) => Tag;
/**
A generic variant [modifier](#highlight.Tag^defineModifier) that
can be used to tag language-specific alternative variants of
some common tag. It is recommended for themes to define special
forms of at least the [string](#highlight.tags.string) and
[variable name](#highlight.tags.variableName) tags, since those
come up a lot.
*/
special: (tag: Tag) => Tag;
};
/**
This is a highlighter that adds stable, predictable classes to
tokens, for styling with external CSS.
The following tags are mapped to their name prefixed with `"tok-"`
(for example `"tok-comment"`):
* [`link`](#highlight.tags.link)
* [`heading`](#highlight.tags.heading)
* [`emphasis`](#highlight.tags.emphasis)
* [`strong`](#highlight.tags.strong)
* [`keyword`](#highlight.tags.keyword)
* [`atom`](#highlight.tags.atom)
* [`bool`](#highlight.tags.bool)
* [`url`](#highlight.tags.url)
* [`labelName`](#highlight.tags.labelName)
* [`inserted`](#highlight.tags.inserted)
* [`deleted`](#highlight.tags.deleted)
* [`literal`](#highlight.tags.literal)
* [`string`](#highlight.tags.string)
* [`number`](#highlight.tags.number)
* [`variableName`](#highlight.tags.variableName)
* [`typeName`](#highlight.tags.typeName)
* [`namespace`](#highlight.tags.namespace)
* [`className`](#highlight.tags.className)
* [`macroName`](#highlight.tags.macroName)
* [`propertyName`](#highlight.tags.propertyName)
* [`operator`](#highlight.tags.operator)
* [`comment`](#highlight.tags.comment)
* [`meta`](#highlight.tags.meta)
* [`punctuation`](#highlight.tags.punctuation)
* [`invalid`](#highlight.tags.invalid)
In addition, these mappings are provided:
* [`regexp`](#highlight.tags.regexp),
[`escape`](#highlight.tags.escape), and
[`special`](#highlight.tags.special)[`(string)`](#highlight.tags.string)
are mapped to `"tok-string2"`
* [`special`](#highlight.tags.special)[`(variableName)`](#highlight.tags.variableName)
to `"tok-variableName2"`
* [`local`](#highlight.tags.local)[`(variableName)`](#highlight.tags.variableName)
to `"tok-variableName tok-local"`
* [`definition`](#highlight.tags.definition)[`(variableName)`](#highlight.tags.variableName)
to `"tok-variableName tok-definition"`
* [`definition`](#highlight.tags.definition)[`(propertyName)`](#highlight.tags.propertyName)
to `"tok-propertyName tok-definition"`
*/
declare const classHighlighter: Highlighter;
export { type Highlighter, Tag, classHighlighter, getStyleTags, highlightCode, highlightTree, styleTags, tagHighlighter, tags };

623
editor/node_modules/@lezer/highlight/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,623 @@
import * as _lezer_common from '@lezer/common';
import { NodeType, Tree, SyntaxNodeRef } from '@lezer/common';
/**
Highlighting tags are markers that denote a highlighting category.
They are [associated](#highlight.styleTags) with parts of a syntax
tree by a language mode, and then mapped to an actual CSS style by
a [highlighter](#highlight.Highlighter).
Because syntax tree node types and highlight styles have to be
able to talk the same language, CodeMirror uses a mostly _closed_
[vocabulary](#highlight.tags) of syntax tags (as opposed to
traditional open string-based systems, which make it hard for
highlighting themes to cover all the tokens produced by the
various languages).
It _is_ possible to [define](#highlight.Tag^define) your own
highlighting tags for system-internal use (where you control both
the language package and the highlighter), but such tags will not
be picked up by regular highlighters (though you can derive them
from standard tags to allow highlighters to fall back to those).
*/
declare class Tag {
/**
The set of this tag and all its parent tags, starting with
this one itself and sorted in order of decreasing specificity.
*/
readonly set: Tag[];
toString(): string;
/**
Define a new tag. If `parent` is given, the tag is treated as a
sub-tag of that parent, and
[highlighters](#highlight.tagHighlighter) that don't mention
this tag will try to fall back to the parent tag (or grandparent
tag, etc).
*/
static define(name?: string, parent?: Tag): Tag;
static define(parent?: Tag): Tag;
/**
Define a tag _modifier_, which is a function that, given a tag,
will return a tag that is a subtag of the original. Applying the
same modifier to a twice tag will return the same value (`m1(t1)
== m1(t1)`) and applying multiple modifiers will, regardless or
order, produce the same tag (`m1(m2(t1)) == m2(m1(t1))`).
When multiple modifiers are applied to a given base tag, each
smaller set of modifiers is registered as a parent, so that for
example `m1(m2(m3(t1)))` is a subtype of `m1(m2(t1))`,
`m1(m3(t1)`, and so on.
*/
static defineModifier(name?: string): (tag: Tag) => Tag;
}
/**
This function is used to add a set of tags to a language syntax
via [`NodeSet.extend`](#common.NodeSet.extend) or
[`LRParser.configure`](#lr.LRParser.configure).
The argument object maps node selectors to [highlighting
tags](#highlight.Tag) or arrays of tags.
Node selectors may hold one or more (space-separated) node paths.
Such a path can be a [node name](#common.NodeType.name), or
multiple node names (or `*` wildcards) separated by slash
characters, as in `"Block/Declaration/VariableName"`. Such a path
matches the final node but only if its direct parent nodes are the
other nodes mentioned. A `*` in such a path matches any parent,
but only a single level—wildcards that match multiple parents
aren't supported, both for efficiency reasons and because Lezer
trees make it rather hard to reason about what they would match.)
A path can be ended with `/...` to indicate that the tag assigned
to the node should also apply to all child nodes, even if they
match their own style (by default, only the innermost style is
used).
When a path ends in `!`, as in `Attribute!`, no further matching
happens for the node's child nodes, and the entire node gets the
given style.
In this notation, node names that contain `/`, `!`, `*`, or `...`
must be quoted as JSON strings.
For example:
```javascript
parser.configure({props: [
styleTags({
// Style Number and BigNumber nodes
"Number BigNumber": tags.number,
// Style Escape nodes whose parent is String
"String/Escape": tags.escape,
// Style anything inside Attributes nodes
"Attributes!": tags.meta,
// Add a style to all content inside Italic nodes
"Italic/...": tags.emphasis,
// Style InvalidString nodes as both `string` and `invalid`
"InvalidString": [tags.string, tags.invalid],
// Style the node named "/" as punctuation
'"/"': tags.punctuation
})
]})
```
*/
declare function styleTags(spec: {
[selector: string]: Tag | readonly Tag[];
}): _lezer_common.NodePropSource;
/**
A highlighter defines a mapping from highlighting tags and
language scopes to CSS class names. They are usually defined via
[`tagHighlighter`](#highlight.tagHighlighter) or some wrapper
around that, but it is also possible to implement them from
scratch.
*/
interface Highlighter {
/**
Get the set of classes that should be applied to the given set
of highlighting tags, or null if this highlighter doesn't assign
a style to the tags.
*/
style(tags: readonly Tag[]): string | null;
/**
When given, the highlighter will only be applied to trees on
whose [top](#common.NodeType.isTop) node this predicate returns
true.
*/
scope?(node: NodeType): boolean;
}
/**
Define a [highlighter](#highlight.Highlighter) from an array of
tag/class pairs. Classes associated with more specific tags will
take precedence.
*/
declare function tagHighlighter(tags: readonly {
tag: Tag | readonly Tag[];
class: string;
}[], options?: {
/**
By default, highlighters apply to the entire document. You can
scope them to a single language by providing the tree's
[top](#common.NodeType.isTop) node type here.
*/
scope?: (node: NodeType) => boolean;
/**
Add a style to _all_ tokens. Probably only useful in combination
with `scope`.
*/
all?: string;
}): Highlighter;
/**
Highlight the given [tree](#common.Tree) with the given
[highlighter](#highlight.Highlighter). Often, the higher-level
[`highlightCode`](#highlight.highlightCode) function is easier to
use.
*/
declare function highlightTree(tree: Tree, highlighter: Highlighter | readonly Highlighter[],
/**
Assign styling to a region of the text. Will be called, in order
of position, for any ranges where more than zero classes apply.
`classes` is a space separated string of CSS classes.
*/
putStyle: (from: number, to: number, classes: string) => void,
/**
The start of the range to highlight.
*/
from?: number,
/**
The end of the range.
*/
to?: number): void;
/**
Highlight the given tree with the given highlighter, calling
`putText` for every piece of text, either with a set of classes or
with the empty string when unstyled, and `putBreak` for every line
break.
*/
declare function highlightCode(code: string, tree: Tree, highlighter: Highlighter | readonly Highlighter[], putText: (code: string, classes: string) => void, putBreak: () => void, from?: number, to?: number): void;
/**
Match a syntax node's [highlight rules](#highlight.styleTags). If
there's a match, return its set of tags, and whether it is
opaque (uses a `!`) or applies to all child nodes (`/...`).
*/
declare function getStyleTags(node: SyntaxNodeRef): {
tags: readonly Tag[];
opaque: boolean;
inherit: boolean;
} | null;
/**
The default set of highlighting [tags](#highlight.Tag).
This collection is heavily biased towards programming languages,
and necessarily incomplete. A full ontology of syntactic
constructs would fill a stack of books, and be impractical to
write themes for. So try to make do with this set. If all else
fails, [open an
issue](https://github.com/codemirror/codemirror.next) to propose a
new tag, or [define](#highlight.Tag^define) a local custom tag for
your use case.
Note that it is not obligatory to always attach the most specific
tag possible to an element—if your grammar can't easily
distinguish a certain type of element (such as a local variable),
it is okay to style it as its more general variant (a variable).
For tags that extend some parent tag, the documentation links to
the parent.
*/
declare const tags: {
/**
A comment.
*/
comment: Tag;
/**
A line [comment](#highlight.tags.comment).
*/
lineComment: Tag;
/**
A block [comment](#highlight.tags.comment).
*/
blockComment: Tag;
/**
A documentation [comment](#highlight.tags.comment).
*/
docComment: Tag;
/**
Any kind of identifier.
*/
name: Tag;
/**
The [name](#highlight.tags.name) of a variable.
*/
variableName: Tag;
/**
A type [name](#highlight.tags.name).
*/
typeName: Tag;
/**
A tag name (subtag of [`typeName`](#highlight.tags.typeName)).
*/
tagName: Tag;
/**
A property or field [name](#highlight.tags.name).
*/
propertyName: Tag;
/**
An attribute name (subtag of [`propertyName`](#highlight.tags.propertyName)).
*/
attributeName: Tag;
/**
The [name](#highlight.tags.name) of a class.
*/
className: Tag;
/**
A label [name](#highlight.tags.name).
*/
labelName: Tag;
/**
A namespace [name](#highlight.tags.name).
*/
namespace: Tag;
/**
The [name](#highlight.tags.name) of a macro.
*/
macroName: Tag;
/**
A literal value.
*/
literal: Tag;
/**
A string [literal](#highlight.tags.literal).
*/
string: Tag;
/**
A documentation [string](#highlight.tags.string).
*/
docString: Tag;
/**
A character literal (subtag of [string](#highlight.tags.string)).
*/
character: Tag;
/**
An attribute value (subtag of [string](#highlight.tags.string)).
*/
attributeValue: Tag;
/**
A number [literal](#highlight.tags.literal).
*/
number: Tag;
/**
An integer [number](#highlight.tags.number) literal.
*/
integer: Tag;
/**
A floating-point [number](#highlight.tags.number) literal.
*/
float: Tag;
/**
A boolean [literal](#highlight.tags.literal).
*/
bool: Tag;
/**
Regular expression [literal](#highlight.tags.literal).
*/
regexp: Tag;
/**
An escape [literal](#highlight.tags.literal), for example a
backslash escape in a string.
*/
escape: Tag;
/**
A color [literal](#highlight.tags.literal).
*/
color: Tag;
/**
A URL [literal](#highlight.tags.literal).
*/
url: Tag;
/**
A language keyword.
*/
keyword: Tag;
/**
The [keyword](#highlight.tags.keyword) for the self or this
object.
*/
self: Tag;
/**
The [keyword](#highlight.tags.keyword) for null.
*/
null: Tag;
/**
A [keyword](#highlight.tags.keyword) denoting some atomic value.
*/
atom: Tag;
/**
A [keyword](#highlight.tags.keyword) that represents a unit.
*/
unit: Tag;
/**
A modifier [keyword](#highlight.tags.keyword).
*/
modifier: Tag;
/**
A [keyword](#highlight.tags.keyword) that acts as an operator.
*/
operatorKeyword: Tag;
/**
A control-flow related [keyword](#highlight.tags.keyword).
*/
controlKeyword: Tag;
/**
A [keyword](#highlight.tags.keyword) that defines something.
*/
definitionKeyword: Tag;
/**
A [keyword](#highlight.tags.keyword) related to defining or
interfacing with modules.
*/
moduleKeyword: Tag;
/**
An operator.
*/
operator: Tag;
/**
An [operator](#highlight.tags.operator) that dereferences something.
*/
derefOperator: Tag;
/**
Arithmetic-related [operator](#highlight.tags.operator).
*/
arithmeticOperator: Tag;
/**
Logical [operator](#highlight.tags.operator).
*/
logicOperator: Tag;
/**
Bit [operator](#highlight.tags.operator).
*/
bitwiseOperator: Tag;
/**
Comparison [operator](#highlight.tags.operator).
*/
compareOperator: Tag;
/**
[Operator](#highlight.tags.operator) that updates its operand.
*/
updateOperator: Tag;
/**
[Operator](#highlight.tags.operator) that defines something.
*/
definitionOperator: Tag;
/**
Type-related [operator](#highlight.tags.operator).
*/
typeOperator: Tag;
/**
Control-flow [operator](#highlight.tags.operator).
*/
controlOperator: Tag;
/**
Program or markup punctuation.
*/
punctuation: Tag;
/**
[Punctuation](#highlight.tags.punctuation) that separates
things.
*/
separator: Tag;
/**
Bracket-style [punctuation](#highlight.tags.punctuation).
*/
bracket: Tag;
/**
Angle [brackets](#highlight.tags.bracket) (usually `<` and `>`
tokens).
*/
angleBracket: Tag;
/**
Square [brackets](#highlight.tags.bracket) (usually `[` and `]`
tokens).
*/
squareBracket: Tag;
/**
Parentheses (usually `(` and `)` tokens). Subtag of
[bracket](#highlight.tags.bracket).
*/
paren: Tag;
/**
Braces (usually `{` and `}` tokens). Subtag of
[bracket](#highlight.tags.bracket).
*/
brace: Tag;
/**
Content, for example plain text in XML or markup documents.
*/
content: Tag;
/**
[Content](#highlight.tags.content) that represents a heading.
*/
heading: Tag;
/**
A level 1 [heading](#highlight.tags.heading).
*/
heading1: Tag;
/**
A level 2 [heading](#highlight.tags.heading).
*/
heading2: Tag;
/**
A level 3 [heading](#highlight.tags.heading).
*/
heading3: Tag;
/**
A level 4 [heading](#highlight.tags.heading).
*/
heading4: Tag;
/**
A level 5 [heading](#highlight.tags.heading).
*/
heading5: Tag;
/**
A level 6 [heading](#highlight.tags.heading).
*/
heading6: Tag;
/**
A prose [content](#highlight.tags.content) separator (such as a horizontal rule).
*/
contentSeparator: Tag;
/**
[Content](#highlight.tags.content) that represents a list.
*/
list: Tag;
/**
[Content](#highlight.tags.content) that represents a quote.
*/
quote: Tag;
/**
[Content](#highlight.tags.content) that is emphasized.
*/
emphasis: Tag;
/**
[Content](#highlight.tags.content) that is styled strong.
*/
strong: Tag;
/**
[Content](#highlight.tags.content) that is part of a link.
*/
link: Tag;
/**
[Content](#highlight.tags.content) that is styled as code or
monospace.
*/
monospace: Tag;
/**
[Content](#highlight.tags.content) that has a strike-through
style.
*/
strikethrough: Tag;
/**
Inserted text in a change-tracking format.
*/
inserted: Tag;
/**
Deleted text.
*/
deleted: Tag;
/**
Changed text.
*/
changed: Tag;
/**
An invalid or unsyntactic element.
*/
invalid: Tag;
/**
Metadata or meta-instruction.
*/
meta: Tag;
/**
[Metadata](#highlight.tags.meta) that applies to the entire
document.
*/
documentMeta: Tag;
/**
[Metadata](#highlight.tags.meta) that annotates or adds
attributes to a given syntactic element.
*/
annotation: Tag;
/**
Processing instruction or preprocessor directive. Subtag of
[meta](#highlight.tags.meta).
*/
processingInstruction: Tag;
/**
[Modifier](#highlight.Tag^defineModifier) that indicates that a
given element is being defined. Expected to be used with the
various [name](#highlight.tags.name) tags.
*/
definition: (tag: Tag) => Tag;
/**
[Modifier](#highlight.Tag^defineModifier) that indicates that
something is constant. Mostly expected to be used with
[variable names](#highlight.tags.variableName).
*/
constant: (tag: Tag) => Tag;
/**
[Modifier](#highlight.Tag^defineModifier) used to indicate that
a [variable](#highlight.tags.variableName) or [property
name](#highlight.tags.propertyName) is being called or defined
as a function.
*/
function: (tag: Tag) => Tag;
/**
[Modifier](#highlight.Tag^defineModifier) that can be applied to
[names](#highlight.tags.name) to indicate that they belong to
the language's standard environment.
*/
standard: (tag: Tag) => Tag;
/**
[Modifier](#highlight.Tag^defineModifier) that indicates a given
[names](#highlight.tags.name) is local to some scope.
*/
local: (tag: Tag) => Tag;
/**
A generic variant [modifier](#highlight.Tag^defineModifier) that
can be used to tag language-specific alternative variants of
some common tag. It is recommended for themes to define special
forms of at least the [string](#highlight.tags.string) and
[variable name](#highlight.tags.variableName) tags, since those
come up a lot.
*/
special: (tag: Tag) => Tag;
};
/**
This is a highlighter that adds stable, predictable classes to
tokens, for styling with external CSS.
The following tags are mapped to their name prefixed with `"tok-"`
(for example `"tok-comment"`):
* [`link`](#highlight.tags.link)
* [`heading`](#highlight.tags.heading)
* [`emphasis`](#highlight.tags.emphasis)
* [`strong`](#highlight.tags.strong)
* [`keyword`](#highlight.tags.keyword)
* [`atom`](#highlight.tags.atom)
* [`bool`](#highlight.tags.bool)
* [`url`](#highlight.tags.url)
* [`labelName`](#highlight.tags.labelName)
* [`inserted`](#highlight.tags.inserted)
* [`deleted`](#highlight.tags.deleted)
* [`literal`](#highlight.tags.literal)
* [`string`](#highlight.tags.string)
* [`number`](#highlight.tags.number)
* [`variableName`](#highlight.tags.variableName)
* [`typeName`](#highlight.tags.typeName)
* [`namespace`](#highlight.tags.namespace)
* [`className`](#highlight.tags.className)
* [`macroName`](#highlight.tags.macroName)
* [`propertyName`](#highlight.tags.propertyName)
* [`operator`](#highlight.tags.operator)
* [`comment`](#highlight.tags.comment)
* [`meta`](#highlight.tags.meta)
* [`punctuation`](#highlight.tags.punctuation)
* [`invalid`](#highlight.tags.invalid)
In addition, these mappings are provided:
* [`regexp`](#highlight.tags.regexp),
[`escape`](#highlight.tags.escape), and
[`special`](#highlight.tags.special)[`(string)`](#highlight.tags.string)
are mapped to `"tok-string2"`
* [`special`](#highlight.tags.special)[`(variableName)`](#highlight.tags.variableName)
to `"tok-variableName2"`
* [`local`](#highlight.tags.local)[`(variableName)`](#highlight.tags.variableName)
to `"tok-variableName tok-local"`
* [`definition`](#highlight.tags.definition)[`(variableName)`](#highlight.tags.variableName)
to `"tok-variableName tok-definition"`
* [`definition`](#highlight.tags.definition)[`(propertyName)`](#highlight.tags.propertyName)
to `"tok-propertyName tok-definition"`
*/
declare const classHighlighter: Highlighter;
export { type Highlighter, Tag, classHighlighter, getStyleTags, highlightCode, highlightTree, styleTags, tagHighlighter, tags };

927
editor/node_modules/@lezer/highlight/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,927 @@
import { NodeProp } from '@lezer/common';
let nextTagID = 0;
/**
Highlighting tags are markers that denote a highlighting category.
They are [associated](#highlight.styleTags) with parts of a syntax
tree by a language mode, and then mapped to an actual CSS style by
a [highlighter](#highlight.Highlighter).
Because syntax tree node types and highlight styles have to be
able to talk the same language, CodeMirror uses a mostly _closed_
[vocabulary](#highlight.tags) of syntax tags (as opposed to
traditional open string-based systems, which make it hard for
highlighting themes to cover all the tokens produced by the
various languages).
It _is_ possible to [define](#highlight.Tag^define) your own
highlighting tags for system-internal use (where you control both
the language package and the highlighter), but such tags will not
be picked up by regular highlighters (though you can derive them
from standard tags to allow highlighters to fall back to those).
*/
class Tag {
/**
@internal
*/
constructor(
/**
The optional name of the base tag @internal
*/
name,
/**
The set of this tag and all its parent tags, starting with
this one itself and sorted in order of decreasing specificity.
*/
set,
/**
The base unmodified tag that this one is based on, if it's
modified @internal
*/
base,
/**
The modifiers applied to this.base @internal
*/
modified) {
this.name = name;
this.set = set;
this.base = base;
this.modified = modified;
/**
@internal
*/
this.id = nextTagID++;
}
toString() {
let { name } = this;
for (let mod of this.modified)
if (mod.name)
name = `${mod.name}(${name})`;
return name;
}
static define(nameOrParent, parent) {
let name = typeof nameOrParent == "string" ? nameOrParent : "?";
if (nameOrParent instanceof Tag)
parent = nameOrParent;
if (parent === null || parent === void 0 ? void 0 : parent.base)
throw new Error("Can not derive from a modified tag");
let tag = new Tag(name, [], null, []);
tag.set.push(tag);
if (parent)
for (let t of parent.set)
tag.set.push(t);
return tag;
}
/**
Define a tag _modifier_, which is a function that, given a tag,
will return a tag that is a subtag of the original. Applying the
same modifier to a twice tag will return the same value (`m1(t1)
== m1(t1)`) and applying multiple modifiers will, regardless or
order, produce the same tag (`m1(m2(t1)) == m2(m1(t1))`).
When multiple modifiers are applied to a given base tag, each
smaller set of modifiers is registered as a parent, so that for
example `m1(m2(m3(t1)))` is a subtype of `m1(m2(t1))`,
`m1(m3(t1)`, and so on.
*/
static defineModifier(name) {
let mod = new Modifier(name);
return (tag) => {
if (tag.modified.indexOf(mod) > -1)
return tag;
return Modifier.get(tag.base || tag, tag.modified.concat(mod).sort((a, b) => a.id - b.id));
};
}
}
let nextModifierID = 0;
class Modifier {
constructor(name) {
this.name = name;
this.instances = [];
this.id = nextModifierID++;
}
static get(base, mods) {
if (!mods.length)
return base;
let exists = mods[0].instances.find(t => t.base == base && sameArray(mods, t.modified));
if (exists)
return exists;
let set = [], tag = new Tag(base.name, set, base, mods);
for (let m of mods)
m.instances.push(tag);
let configs = powerSet(mods);
for (let parent of base.set)
if (!parent.modified.length)
for (let config of configs)
set.push(Modifier.get(parent, config));
return tag;
}
}
function sameArray(a, b) {
return a.length == b.length && a.every((x, i) => x == b[i]);
}
function powerSet(array) {
let sets = [[]];
for (let i = 0; i < array.length; i++) {
for (let j = 0, e = sets.length; j < e; j++) {
sets.push(sets[j].concat(array[i]));
}
}
return sets.sort((a, b) => b.length - a.length);
}
/**
This function is used to add a set of tags to a language syntax
via [`NodeSet.extend`](#common.NodeSet.extend) or
[`LRParser.configure`](#lr.LRParser.configure).
The argument object maps node selectors to [highlighting
tags](#highlight.Tag) or arrays of tags.
Node selectors may hold one or more (space-separated) node paths.
Such a path can be a [node name](#common.NodeType.name), or
multiple node names (or `*` wildcards) separated by slash
characters, as in `"Block/Declaration/VariableName"`. Such a path
matches the final node but only if its direct parent nodes are the
other nodes mentioned. A `*` in such a path matches any parent,
but only a single level—wildcards that match multiple parents
aren't supported, both for efficiency reasons and because Lezer
trees make it rather hard to reason about what they would match.)
A path can be ended with `/...` to indicate that the tag assigned
to the node should also apply to all child nodes, even if they
match their own style (by default, only the innermost style is
used).
When a path ends in `!`, as in `Attribute!`, no further matching
happens for the node's child nodes, and the entire node gets the
given style.
In this notation, node names that contain `/`, `!`, `*`, or `...`
must be quoted as JSON strings.
For example:
```javascript
parser.configure({props: [
styleTags({
// Style Number and BigNumber nodes
"Number BigNumber": tags.number,
// Style Escape nodes whose parent is String
"String/Escape": tags.escape,
// Style anything inside Attributes nodes
"Attributes!": tags.meta,
// Add a style to all content inside Italic nodes
"Italic/...": tags.emphasis,
// Style InvalidString nodes as both `string` and `invalid`
"InvalidString": [tags.string, tags.invalid],
// Style the node named "/" as punctuation
'"/"': tags.punctuation
})
]})
```
*/
function styleTags(spec) {
let byName = Object.create(null);
for (let prop in spec) {
let tags = spec[prop];
if (!Array.isArray(tags))
tags = [tags];
for (let part of prop.split(" "))
if (part) {
let pieces = [], mode = 2 /* Mode.Normal */, rest = part;
for (let pos = 0;;) {
if (rest == "..." && pos > 0 && pos + 3 == part.length) {
mode = 1 /* Mode.Inherit */;
break;
}
let m = /^"(?:[^"\\]|\\.)*?"|[^\/!]+/.exec(rest);
if (!m)
throw new RangeError("Invalid path: " + part);
pieces.push(m[0] == "*" ? "" : m[0][0] == '"' ? JSON.parse(m[0]) : m[0]);
pos += m[0].length;
if (pos == part.length)
break;
let next = part[pos++];
if (pos == part.length && next == "!") {
mode = 0 /* Mode.Opaque */;
break;
}
if (next != "/")
throw new RangeError("Invalid path: " + part);
rest = part.slice(pos);
}
let last = pieces.length - 1, inner = pieces[last];
if (!inner)
throw new RangeError("Invalid path: " + part);
let rule = new Rule(tags, mode, last > 0 ? pieces.slice(0, last) : null);
byName[inner] = rule.sort(byName[inner]);
}
}
return ruleNodeProp.add(byName);
}
const ruleNodeProp = new NodeProp({
combine(a, b) {
let cur, root, take;
while (a || b) {
if (!a || b && a.depth >= b.depth) {
take = b;
b = b.next;
}
else {
take = a;
a = a.next;
}
if (cur && cur.mode == take.mode && !take.context && !cur.context)
continue;
let copy = new Rule(take.tags, take.mode, take.context);
if (cur)
cur.next = copy;
else
root = copy;
cur = copy;
}
return root;
}
});
class Rule {
constructor(tags, mode, context, next) {
this.tags = tags;
this.mode = mode;
this.context = context;
this.next = next;
}
get opaque() { return this.mode == 0 /* Mode.Opaque */; }
get inherit() { return this.mode == 1 /* Mode.Inherit */; }
sort(other) {
if (!other || other.depth < this.depth) {
this.next = other;
return this;
}
other.next = this.sort(other.next);
return other;
}
get depth() { return this.context ? this.context.length : 0; }
}
Rule.empty = new Rule([], 2 /* Mode.Normal */, null);
/**
Define a [highlighter](#highlight.Highlighter) from an array of
tag/class pairs. Classes associated with more specific tags will
take precedence.
*/
function tagHighlighter(tags, options) {
let map = Object.create(null);
for (let style of tags) {
if (!Array.isArray(style.tag))
map[style.tag.id] = style.class;
else
for (let tag of style.tag)
map[tag.id] = style.class;
}
let { scope, all = null } = options || {};
return {
style: (tags) => {
let cls = all;
for (let tag of tags) {
for (let sub of tag.set) {
let tagClass = map[sub.id];
if (tagClass) {
cls = cls ? cls + " " + tagClass : tagClass;
break;
}
}
}
return cls;
},
scope
};
}
function highlightTags(highlighters, tags) {
let result = null;
for (let highlighter of highlighters) {
let value = highlighter.style(tags);
if (value)
result = result ? result + " " + value : value;
}
return result;
}
/**
Highlight the given [tree](#common.Tree) with the given
[highlighter](#highlight.Highlighter). Often, the higher-level
[`highlightCode`](#highlight.highlightCode) function is easier to
use.
*/
function highlightTree(tree, highlighter,
/**
Assign styling to a region of the text. Will be called, in order
of position, for any ranges where more than zero classes apply.
`classes` is a space separated string of CSS classes.
*/
putStyle,
/**
The start of the range to highlight.
*/
from = 0,
/**
The end of the range.
*/
to = tree.length) {
let builder = new HighlightBuilder(from, Array.isArray(highlighter) ? highlighter : [highlighter], putStyle);
builder.highlightRange(tree.cursor(), from, to, "", builder.highlighters);
builder.flush(to);
}
/**
Highlight the given tree with the given highlighter, calling
`putText` for every piece of text, either with a set of classes or
with the empty string when unstyled, and `putBreak` for every line
break.
*/
function highlightCode(code, tree, highlighter, putText, putBreak, from = 0, to = code.length) {
let pos = from;
function writeTo(p, classes) {
if (p <= pos)
return;
for (let text = code.slice(pos, p), i = 0;;) {
let nextBreak = text.indexOf("\n", i);
let upto = nextBreak < 0 ? text.length : nextBreak;
if (upto > i)
putText(text.slice(i, upto), classes);
if (nextBreak < 0)
break;
putBreak();
i = nextBreak + 1;
}
pos = p;
}
highlightTree(tree, highlighter, (from, to, classes) => {
writeTo(from, "");
writeTo(to, classes);
}, from, to);
writeTo(to, "");
}
class HighlightBuilder {
constructor(at, highlighters, span) {
this.at = at;
this.highlighters = highlighters;
this.span = span;
this.class = "";
}
startSpan(at, cls) {
if (cls != this.class) {
this.flush(at);
if (at > this.at)
this.at = at;
this.class = cls;
}
}
flush(to) {
if (to > this.at && this.class)
this.span(this.at, to, this.class);
}
highlightRange(cursor, from, to, inheritedClass, highlighters) {
let { type, from: start, to: end } = cursor;
if (start >= to || end <= from)
return;
if (type.isTop)
highlighters = this.highlighters.filter(h => !h.scope || h.scope(type));
let cls = inheritedClass;
let rule = getStyleTags(cursor) || Rule.empty;
let tagCls = highlightTags(highlighters, rule.tags);
if (tagCls) {
if (cls)
cls += " ";
cls += tagCls;
if (rule.mode == 1 /* Mode.Inherit */)
inheritedClass += (inheritedClass ? " " : "") + tagCls;
}
this.startSpan(Math.max(from, start), cls);
if (rule.opaque)
return;
let mounted = cursor.tree && cursor.tree.prop(NodeProp.mounted);
if (mounted && mounted.overlay) {
let inner = cursor.node.enter(mounted.overlay[0].from + start, 1);
let innerHighlighters = this.highlighters.filter(h => !h.scope || h.scope(mounted.tree.type));
let hasChild = cursor.firstChild();
for (let i = 0, pos = start;; i++) {
let next = i < mounted.overlay.length ? mounted.overlay[i] : null;
let nextPos = next ? next.from + start : end;
let rangeFrom = Math.max(from, pos), rangeTo = Math.min(to, nextPos);
if (rangeFrom < rangeTo && hasChild) {
while (cursor.from < rangeTo) {
this.highlightRange(cursor, rangeFrom, rangeTo, inheritedClass, highlighters);
this.startSpan(Math.min(rangeTo, cursor.to), cls);
if (cursor.to >= nextPos || !cursor.nextSibling())
break;
}
}
if (!next || nextPos > to)
break;
pos = next.to + start;
if (pos > from) {
this.highlightRange(inner.cursor(), Math.max(from, next.from + start), Math.min(to, pos), "", innerHighlighters);
this.startSpan(Math.min(to, pos), cls);
}
}
if (hasChild)
cursor.parent();
}
else if (cursor.firstChild()) {
if (mounted)
inheritedClass = "";
do {
if (cursor.to <= from)
continue;
if (cursor.from >= to)
break;
this.highlightRange(cursor, from, to, inheritedClass, highlighters);
this.startSpan(Math.min(to, cursor.to), cls);
} while (cursor.nextSibling());
cursor.parent();
}
}
}
/**
Match a syntax node's [highlight rules](#highlight.styleTags). If
there's a match, return its set of tags, and whether it is
opaque (uses a `!`) or applies to all child nodes (`/...`).
*/
function getStyleTags(node) {
let rule = node.type.prop(ruleNodeProp);
while (rule && rule.context && !node.matchContext(rule.context))
rule = rule.next;
return rule || null;
}
const t = Tag.define;
const comment = t(), name = t(), typeName = t(name), propertyName = t(name), literal = t(), string = t(literal), number = t(literal), content = t(), heading = t(content), keyword = t(), operator = t(), punctuation = t(), bracket = t(punctuation), meta = t();
/**
The default set of highlighting [tags](#highlight.Tag).
This collection is heavily biased towards programming languages,
and necessarily incomplete. A full ontology of syntactic
constructs would fill a stack of books, and be impractical to
write themes for. So try to make do with this set. If all else
fails, [open an
issue](https://github.com/codemirror/codemirror.next) to propose a
new tag, or [define](#highlight.Tag^define) a local custom tag for
your use case.
Note that it is not obligatory to always attach the most specific
tag possible to an element—if your grammar can't easily
distinguish a certain type of element (such as a local variable),
it is okay to style it as its more general variant (a variable).
For tags that extend some parent tag, the documentation links to
the parent.
*/
const tags = {
/**
A comment.
*/
comment,
/**
A line [comment](#highlight.tags.comment).
*/
lineComment: t(comment),
/**
A block [comment](#highlight.tags.comment).
*/
blockComment: t(comment),
/**
A documentation [comment](#highlight.tags.comment).
*/
docComment: t(comment),
/**
Any kind of identifier.
*/
name,
/**
The [name](#highlight.tags.name) of a variable.
*/
variableName: t(name),
/**
A type [name](#highlight.tags.name).
*/
typeName: typeName,
/**
A tag name (subtag of [`typeName`](#highlight.tags.typeName)).
*/
tagName: t(typeName),
/**
A property or field [name](#highlight.tags.name).
*/
propertyName: propertyName,
/**
An attribute name (subtag of [`propertyName`](#highlight.tags.propertyName)).
*/
attributeName: t(propertyName),
/**
The [name](#highlight.tags.name) of a class.
*/
className: t(name),
/**
A label [name](#highlight.tags.name).
*/
labelName: t(name),
/**
A namespace [name](#highlight.tags.name).
*/
namespace: t(name),
/**
The [name](#highlight.tags.name) of a macro.
*/
macroName: t(name),
/**
A literal value.
*/
literal,
/**
A string [literal](#highlight.tags.literal).
*/
string,
/**
A documentation [string](#highlight.tags.string).
*/
docString: t(string),
/**
A character literal (subtag of [string](#highlight.tags.string)).
*/
character: t(string),
/**
An attribute value (subtag of [string](#highlight.tags.string)).
*/
attributeValue: t(string),
/**
A number [literal](#highlight.tags.literal).
*/
number,
/**
An integer [number](#highlight.tags.number) literal.
*/
integer: t(number),
/**
A floating-point [number](#highlight.tags.number) literal.
*/
float: t(number),
/**
A boolean [literal](#highlight.tags.literal).
*/
bool: t(literal),
/**
Regular expression [literal](#highlight.tags.literal).
*/
regexp: t(literal),
/**
An escape [literal](#highlight.tags.literal), for example a
backslash escape in a string.
*/
escape: t(literal),
/**
A color [literal](#highlight.tags.literal).
*/
color: t(literal),
/**
A URL [literal](#highlight.tags.literal).
*/
url: t(literal),
/**
A language keyword.
*/
keyword,
/**
The [keyword](#highlight.tags.keyword) for the self or this
object.
*/
self: t(keyword),
/**
The [keyword](#highlight.tags.keyword) for null.
*/
null: t(keyword),
/**
A [keyword](#highlight.tags.keyword) denoting some atomic value.
*/
atom: t(keyword),
/**
A [keyword](#highlight.tags.keyword) that represents a unit.
*/
unit: t(keyword),
/**
A modifier [keyword](#highlight.tags.keyword).
*/
modifier: t(keyword),
/**
A [keyword](#highlight.tags.keyword) that acts as an operator.
*/
operatorKeyword: t(keyword),
/**
A control-flow related [keyword](#highlight.tags.keyword).
*/
controlKeyword: t(keyword),
/**
A [keyword](#highlight.tags.keyword) that defines something.
*/
definitionKeyword: t(keyword),
/**
A [keyword](#highlight.tags.keyword) related to defining or
interfacing with modules.
*/
moduleKeyword: t(keyword),
/**
An operator.
*/
operator,
/**
An [operator](#highlight.tags.operator) that dereferences something.
*/
derefOperator: t(operator),
/**
Arithmetic-related [operator](#highlight.tags.operator).
*/
arithmeticOperator: t(operator),
/**
Logical [operator](#highlight.tags.operator).
*/
logicOperator: t(operator),
/**
Bit [operator](#highlight.tags.operator).
*/
bitwiseOperator: t(operator),
/**
Comparison [operator](#highlight.tags.operator).
*/
compareOperator: t(operator),
/**
[Operator](#highlight.tags.operator) that updates its operand.
*/
updateOperator: t(operator),
/**
[Operator](#highlight.tags.operator) that defines something.
*/
definitionOperator: t(operator),
/**
Type-related [operator](#highlight.tags.operator).
*/
typeOperator: t(operator),
/**
Control-flow [operator](#highlight.tags.operator).
*/
controlOperator: t(operator),
/**
Program or markup punctuation.
*/
punctuation,
/**
[Punctuation](#highlight.tags.punctuation) that separates
things.
*/
separator: t(punctuation),
/**
Bracket-style [punctuation](#highlight.tags.punctuation).
*/
bracket,
/**
Angle [brackets](#highlight.tags.bracket) (usually `<` and `>`
tokens).
*/
angleBracket: t(bracket),
/**
Square [brackets](#highlight.tags.bracket) (usually `[` and `]`
tokens).
*/
squareBracket: t(bracket),
/**
Parentheses (usually `(` and `)` tokens). Subtag of
[bracket](#highlight.tags.bracket).
*/
paren: t(bracket),
/**
Braces (usually `{` and `}` tokens). Subtag of
[bracket](#highlight.tags.bracket).
*/
brace: t(bracket),
/**
Content, for example plain text in XML or markup documents.
*/
content,
/**
[Content](#highlight.tags.content) that represents a heading.
*/
heading,
/**
A level 1 [heading](#highlight.tags.heading).
*/
heading1: t(heading),
/**
A level 2 [heading](#highlight.tags.heading).
*/
heading2: t(heading),
/**
A level 3 [heading](#highlight.tags.heading).
*/
heading3: t(heading),
/**
A level 4 [heading](#highlight.tags.heading).
*/
heading4: t(heading),
/**
A level 5 [heading](#highlight.tags.heading).
*/
heading5: t(heading),
/**
A level 6 [heading](#highlight.tags.heading).
*/
heading6: t(heading),
/**
A prose [content](#highlight.tags.content) separator (such as a horizontal rule).
*/
contentSeparator: t(content),
/**
[Content](#highlight.tags.content) that represents a list.
*/
list: t(content),
/**
[Content](#highlight.tags.content) that represents a quote.
*/
quote: t(content),
/**
[Content](#highlight.tags.content) that is emphasized.
*/
emphasis: t(content),
/**
[Content](#highlight.tags.content) that is styled strong.
*/
strong: t(content),
/**
[Content](#highlight.tags.content) that is part of a link.
*/
link: t(content),
/**
[Content](#highlight.tags.content) that is styled as code or
monospace.
*/
monospace: t(content),
/**
[Content](#highlight.tags.content) that has a strike-through
style.
*/
strikethrough: t(content),
/**
Inserted text in a change-tracking format.
*/
inserted: t(),
/**
Deleted text.
*/
deleted: t(),
/**
Changed text.
*/
changed: t(),
/**
An invalid or unsyntactic element.
*/
invalid: t(),
/**
Metadata or meta-instruction.
*/
meta,
/**
[Metadata](#highlight.tags.meta) that applies to the entire
document.
*/
documentMeta: t(meta),
/**
[Metadata](#highlight.tags.meta) that annotates or adds
attributes to a given syntactic element.
*/
annotation: t(meta),
/**
Processing instruction or preprocessor directive. Subtag of
[meta](#highlight.tags.meta).
*/
processingInstruction: t(meta),
/**
[Modifier](#highlight.Tag^defineModifier) that indicates that a
given element is being defined. Expected to be used with the
various [name](#highlight.tags.name) tags.
*/
definition: Tag.defineModifier("definition"),
/**
[Modifier](#highlight.Tag^defineModifier) that indicates that
something is constant. Mostly expected to be used with
[variable names](#highlight.tags.variableName).
*/
constant: Tag.defineModifier("constant"),
/**
[Modifier](#highlight.Tag^defineModifier) used to indicate that
a [variable](#highlight.tags.variableName) or [property
name](#highlight.tags.propertyName) is being called or defined
as a function.
*/
function: Tag.defineModifier("function"),
/**
[Modifier](#highlight.Tag^defineModifier) that can be applied to
[names](#highlight.tags.name) to indicate that they belong to
the language's standard environment.
*/
standard: Tag.defineModifier("standard"),
/**
[Modifier](#highlight.Tag^defineModifier) that indicates a given
[names](#highlight.tags.name) is local to some scope.
*/
local: Tag.defineModifier("local"),
/**
A generic variant [modifier](#highlight.Tag^defineModifier) that
can be used to tag language-specific alternative variants of
some common tag. It is recommended for themes to define special
forms of at least the [string](#highlight.tags.string) and
[variable name](#highlight.tags.variableName) tags, since those
come up a lot.
*/
special: Tag.defineModifier("special")
};
for (let name in tags) {
let val = tags[name];
if (val instanceof Tag)
val.name = name;
}
/**
This is a highlighter that adds stable, predictable classes to
tokens, for styling with external CSS.
The following tags are mapped to their name prefixed with `"tok-"`
(for example `"tok-comment"`):
* [`link`](#highlight.tags.link)
* [`heading`](#highlight.tags.heading)
* [`emphasis`](#highlight.tags.emphasis)
* [`strong`](#highlight.tags.strong)
* [`keyword`](#highlight.tags.keyword)
* [`atom`](#highlight.tags.atom)
* [`bool`](#highlight.tags.bool)
* [`url`](#highlight.tags.url)
* [`labelName`](#highlight.tags.labelName)
* [`inserted`](#highlight.tags.inserted)
* [`deleted`](#highlight.tags.deleted)
* [`literal`](#highlight.tags.literal)
* [`string`](#highlight.tags.string)
* [`number`](#highlight.tags.number)
* [`variableName`](#highlight.tags.variableName)
* [`typeName`](#highlight.tags.typeName)
* [`namespace`](#highlight.tags.namespace)
* [`className`](#highlight.tags.className)
* [`macroName`](#highlight.tags.macroName)
* [`propertyName`](#highlight.tags.propertyName)
* [`operator`](#highlight.tags.operator)
* [`comment`](#highlight.tags.comment)
* [`meta`](#highlight.tags.meta)
* [`punctuation`](#highlight.tags.punctuation)
* [`invalid`](#highlight.tags.invalid)
In addition, these mappings are provided:
* [`regexp`](#highlight.tags.regexp),
[`escape`](#highlight.tags.escape), and
[`special`](#highlight.tags.special)[`(string)`](#highlight.tags.string)
are mapped to `"tok-string2"`
* [`special`](#highlight.tags.special)[`(variableName)`](#highlight.tags.variableName)
to `"tok-variableName2"`
* [`local`](#highlight.tags.local)[`(variableName)`](#highlight.tags.variableName)
to `"tok-variableName tok-local"`
* [`definition`](#highlight.tags.definition)[`(variableName)`](#highlight.tags.variableName)
to `"tok-variableName tok-definition"`
* [`definition`](#highlight.tags.definition)[`(propertyName)`](#highlight.tags.propertyName)
to `"tok-propertyName tok-definition"`
*/
const classHighlighter = tagHighlighter([
{ tag: tags.link, class: "tok-link" },
{ tag: tags.heading, class: "tok-heading" },
{ tag: tags.emphasis, class: "tok-emphasis" },
{ tag: tags.strong, class: "tok-strong" },
{ tag: tags.keyword, class: "tok-keyword" },
{ tag: tags.atom, class: "tok-atom" },
{ tag: tags.bool, class: "tok-bool" },
{ tag: tags.url, class: "tok-url" },
{ tag: tags.labelName, class: "tok-labelName" },
{ tag: tags.inserted, class: "tok-inserted" },
{ tag: tags.deleted, class: "tok-deleted" },
{ tag: tags.literal, class: "tok-literal" },
{ tag: tags.string, class: "tok-string" },
{ tag: tags.number, class: "tok-number" },
{ tag: [tags.regexp, tags.escape, tags.special(tags.string)], class: "tok-string2" },
{ tag: tags.variableName, class: "tok-variableName" },
{ tag: tags.local(tags.variableName), class: "tok-variableName tok-local" },
{ tag: tags.definition(tags.variableName), class: "tok-variableName tok-definition" },
{ tag: tags.special(tags.variableName), class: "tok-variableName2" },
{ tag: tags.definition(tags.propertyName), class: "tok-propertyName tok-definition" },
{ tag: tags.typeName, class: "tok-typeName" },
{ tag: tags.namespace, class: "tok-namespace" },
{ tag: tags.className, class: "tok-className" },
{ tag: tags.macroName, class: "tok-macroName" },
{ tag: tags.propertyName, class: "tok-propertyName" },
{ tag: tags.operator, class: "tok-operator" },
{ tag: tags.comment, class: "tok-comment" },
{ tag: tags.meta, class: "tok-meta" },
{ tag: tags.invalid, class: "tok-invalid" },
{ tag: tags.punctuation, class: "tok-punctuation" }
]);
export { Tag, classHighlighter, getStyleTags, highlightCode, highlightTree, styleTags, tagHighlighter, tags };

31
editor/node_modules/@lezer/highlight/package.json generated vendored Normal file
View File

@@ -0,0 +1,31 @@
{
"name": "@lezer/highlight",
"version": "1.2.3",
"description": "Highlighting system for Lezer parse trees",
"main": "dist/index.cjs",
"type": "module",
"exports": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"module": "dist/index.js",
"types": "dist/index.d.ts",
"author": "Marijn Haverbeke <marijn@haverbeke.berlin>",
"license": "MIT",
"devDependencies": {
"@marijn/buildtool": "0.1.3",
"typescript": "^5.0.0"
},
"dependencies": {
"@lezer/common": "^1.3.0"
},
"files": ["dist"],
"repository": {
"type" : "git",
"url" : "https://github.com/lezer-parser/highlight.git"
},
"scripts": {
"watch": "node build.js --watch",
"prepare": "node build.js"
}
}

21
editor/node_modules/@lezer/lr/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (C) 2018 by Marijn Haverbeke <marijn@haverbeke.berlin> and others
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

25
editor/node_modules/@lezer/lr/README.md generated vendored Normal file
View File

@@ -0,0 +1,25 @@
# @lezer/lr
[ [**WEBSITE**](http://lezer.codemirror.net) | [**ISSUES**](https://github.com/lezer-parser/lezer/issues) | [**FORUM**](https://discuss.codemirror.net/c/lezer) | [**CHANGELOG**](https://github.com/lezer-parser/lr/blob/master/CHANGELOG.md) ]
Lezer ("reader" in Dutch, pronounced pretty much as laser) is an
incremental GLR parser intended for use in an editor or similar
system, which needs to keep a representation of the program current
during changes and in the face of syntax errors.
It prioritizes speed and compactness (both of parser table files and
of syntax tree) over having a highly usable parse tree—trees nodes are
just blobs with a start, end, tag, and set of child nodes, with no
further labeling of child nodes or extra metadata.
This package contains the run-time LR parser library. It consumes
parsers generated by
[@lezer/generator](https://github.com/lezer-parser/generator).
The parser programming interface is documented on [the
website](https://lezer.codemirror.net/docs/ref/#lr).
The code is licensed under an MIT license.
This project was hugely inspired by
[tree-sitter](http://tree-sitter.github.io/tree-sitter/).

45
editor/node_modules/@lezer/lr/dist/constants.d.ts generated vendored Normal file
View File

@@ -0,0 +1,45 @@
export declare const enum Action {
ReduceFlag = 65536,
ValueMask = 65535,
ReduceDepthShift = 19,
RepeatFlag = 131072,
GotoFlag = 131072,
StayFlag = 262144
}
export declare const enum StateFlag {
Skipped = 1,
Accepting = 2
}
export declare const enum Specialize {
Specialize = 0,
Extend = 1
}
export declare const enum Term {
Err = 0
}
export declare const enum Seq {
End = 65535,
Done = 0,
Next = 1,
Other = 2
}
export declare const enum ParseState {
Flags = 0,
Actions = 1,
Skip = 2,
TokenizerMask = 3,
DefaultReduce = 4,
ForcedReduce = 5,
Size = 6
}
export declare const enum Encode {
BigValCode = 126,
BigVal = 65535,
Start = 32,
Gap1 = 34,
Gap2 = 92,
Base = 46
}
export declare const enum File {
Version = 14
}

5
editor/node_modules/@lezer/lr/dist/constants.js generated vendored Normal file
View File

@@ -0,0 +1,5 @@
"use strict";
// This file defines some constants that are needed both in this
// package and in lezer-generator, so that the generator code can
// access them without them being part of lezer's public interface.
exports.__esModule = true;

1891
editor/node_modules/@lezer/lr/dist/index.cjs generated vendored Normal file

File diff suppressed because it is too large Load Diff

303
editor/node_modules/@lezer/lr/dist/index.d.cts generated vendored Normal file
View File

@@ -0,0 +1,303 @@
import { Tree, NodePropSource, ParseWrapper, Parser, NodeSet, Input, TreeFragment, PartialParse, NodeType } from '@lezer/common';
/**
A parse stack. These are used internally by the parser to track
parsing progress. They also provide some properties and methods
that external code such as a tokenizer can use to get information
about the parse state.
*/
declare class Stack {
/**
The input position up to which this stack has parsed.
*/
pos: number;
/**
The stack's current [context](#lr.ContextTracker) value, if
any. Its type will depend on the context tracker's type
parameter, or it will be `null` if there is no context
tracker.
*/
get context(): any;
/**
Check if the given term would be able to be shifted (optionally
after some reductions) on this stack. This can be useful for
external tokenizers that want to make sure they only provide a
given token when it applies.
*/
canShift(term: number): boolean;
/**
Get the parser used by this stack.
*/
get parser(): LRParser;
/**
Test whether a given dialect (by numeric ID, as exported from
the terms file) is enabled.
*/
dialectEnabled(dialectID: number): boolean;
private shiftContext;
private reduceContext;
private updateContext;
}
/**
[Tokenizers](#lr.ExternalTokenizer) interact with the input
through this interface. It presents the input as a stream of
characters, tracking lookahead and hiding the complexity of
[ranges](#common.Parser.parse^ranges) from tokenizer code.
*/
declare class InputStream {
/**
Backup chunk
*/
private chunk2;
private chunk2Pos;
/**
The character code of the next code unit in the input, or -1
when the stream is at the end of the input.
*/
next: number;
/**
The current position of the stream. Note that, due to parses
being able to cover non-contiguous
[ranges](#common.Parser.startParse), advancing the stream does
not always mean its position moves a single unit.
*/
pos: number;
private rangeIndex;
private range;
/**
Look at a code unit near the stream position. `.peek(0)` equals
`.next`, `.peek(-1)` gives you the previous character, and so
on.
Note that looking around during tokenizing creates dependencies
on potentially far-away content, which may reduce the
effectiveness incremental parsing—when looking forward—or even
cause invalid reparses when looking backward more than 25 code
units, since the library does not track lookbehind.
*/
peek(offset: number): number;
/**
Accept a token. By default, the end of the token is set to the
current stream position, but you can pass an offset (relative to
the stream position) to change that.
*/
acceptToken(token: number, endOffset?: number): void;
/**
Accept a token ending at a specific given position.
*/
acceptTokenTo(token: number, endPos: number): void;
private getChunk;
private readNext;
/**
Move the stream forward N (defaults to 1) code units. Returns
the new value of [`next`](#lr.InputStream.next).
*/
advance(n?: number): number;
private setDone;
}
interface Tokenizer {
}
/**
@hide
*/
declare class LocalTokenGroup implements Tokenizer {
readonly precTable: number;
readonly elseToken?: number | undefined;
contextual: boolean;
fallback: boolean;
extend: boolean;
readonly data: Readonly<Uint16Array>;
constructor(data: Readonly<Uint16Array> | string, precTable: number, elseToken?: number | undefined);
token(input: InputStream, stack: Stack): void;
}
interface ExternalOptions {
/**
When set to true, mark this tokenizer as depending on the
current parse stack, which prevents its result from being cached
between parser actions at the same positions.
*/
contextual?: boolean;
/**
By defaults, when a tokenizer returns a token, that prevents
tokenizers with lower precedence from even running. When
`fallback` is true, the tokenizer is allowed to run when a
previous tokenizer returned a token that didn't match any of the
current state's actions.
*/
fallback?: boolean;
/**
When set to true, tokenizing will not stop after this tokenizer
has produced a token. (But it will still fail to reach this one
if a higher-precedence tokenizer produced a token.)
*/
extend?: boolean;
}
/**
`@external tokens` declarations in the grammar should resolve to
an instance of this class.
*/
declare class ExternalTokenizer {
/**
Create a tokenizer. The first argument is the function that,
given an input stream, scans for the types of tokens it
recognizes at the stream's position, and calls
[`acceptToken`](#lr.InputStream.acceptToken) when it finds
one.
*/
constructor(
/**
@internal
*/
token: (input: InputStream, stack: Stack) => void, options?: ExternalOptions);
}
/**
Context trackers are used to track stateful context (such as
indentation in the Python grammar, or parent elements in the XML
grammar) needed by external tokenizers. You declare them in a
grammar file as `@context exportName from "module"`.
Context values should be immutable, and can be updated (replaced)
on shift or reduce actions.
The export used in a `@context` declaration should be of this
type.
*/
declare class ContextTracker<T> {
/**
Define a context tracker.
*/
constructor(spec: {
/**
The initial value of the context at the start of the parse.
*/
start: T;
/**
Update the context when the parser executes a
[shift](https://en.wikipedia.org/wiki/LR_parser#Shift_and_reduce_actions)
action.
*/
shift?(context: T, term: number, stack: Stack, input: InputStream): T;
/**
Update the context when the parser executes a reduce action.
*/
reduce?(context: T, term: number, stack: Stack, input: InputStream): T;
/**
Update the context when the parser reuses a node from a tree
fragment.
*/
reuse?(context: T, node: Tree, stack: Stack, input: InputStream): T;
/**
Reduce a context value to a number (for cheap storage and
comparison). Only needed for strict contexts.
*/
hash?(context: T): number;
/**
By default, nodes can only be reused during incremental
parsing if they were created in the same context as the one in
which they are reused. Set this to false to disable that
check (and the overhead of storing the hashes).
*/
strict?: boolean;
});
}
/**
Configuration options when
[reconfiguring](#lr.LRParser.configure) a parser.
*/
interface ParserConfig {
/**
Node prop values to add to the parser's node set.
*/
props?: readonly NodePropSource[];
/**
The name of the `@top` declaration to parse from. If not
specified, the first top rule declaration in the grammar is
used.
*/
top?: string;
/**
A space-separated string of dialects to enable.
*/
dialect?: string;
/**
Replace the given external tokenizers with new ones.
*/
tokenizers?: {
from: ExternalTokenizer;
to: ExternalTokenizer;
}[];
/**
Replace external specializers with new ones.
*/
specializers?: {
from: (value: string, stack: Stack) => number;
to: (value: string, stack: Stack) => number;
}[];
/**
Replace the context tracker with a new one.
*/
contextTracker?: ContextTracker<any>;
/**
When true, the parser will raise an exception, rather than run
its error-recovery strategies, when the input doesn't match the
grammar.
*/
strict?: boolean;
/**
Add a wrapper, which can extend parses created by this parser
with additional logic (usually used to add
[mixed-language](#common.parseMixed) parsing).
*/
wrap?: ParseWrapper;
/**
The maximum length of the TreeBuffers generated in the output
tree. Defaults to 1024.
*/
bufferLength?: number;
}
/**
Holds the parse tables for a given grammar, as generated by
`lezer-generator`, and provides [methods](#common.Parser) to parse
content with.
*/
declare class LRParser extends Parser {
/**
The nodes used in the trees emitted by this parser.
*/
readonly nodeSet: NodeSet;
createParse(input: Input, fragments: readonly TreeFragment[], ranges: readonly {
from: number;
to: number;
}[]): PartialParse;
/**
Configure the parser. Returns a new parser instance that has the
given settings modified. Settings not provided in `config` are
kept from the original parser.
*/
configure(config: ParserConfig): LRParser;
/**
Tells you whether any [parse wrappers](#lr.ParserConfig.wrap)
are registered for this parser.
*/
hasWrappers(): boolean;
/**
Returns the name associated with a given term. This will only
work for all terms when the parser was generated with the
`--names` option. By default, only the names of tagged terms are
stored.
*/
getName(term: number): string;
/**
The type of top node produced by the parser.
*/
get topNode(): NodeType;
/**
Used by the output of the parser generator. Not available to
user code. @hide
*/
static deserialize(spec: any): LRParser;
}
export { ContextTracker, ExternalTokenizer, InputStream, LRParser, LocalTokenGroup, type ParserConfig, Stack };

303
editor/node_modules/@lezer/lr/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,303 @@
import { Tree, NodePropSource, ParseWrapper, Parser, NodeSet, Input, TreeFragment, PartialParse, NodeType } from '@lezer/common';
/**
A parse stack. These are used internally by the parser to track
parsing progress. They also provide some properties and methods
that external code such as a tokenizer can use to get information
about the parse state.
*/
declare class Stack {
/**
The input position up to which this stack has parsed.
*/
pos: number;
/**
The stack's current [context](#lr.ContextTracker) value, if
any. Its type will depend on the context tracker's type
parameter, or it will be `null` if there is no context
tracker.
*/
get context(): any;
/**
Check if the given term would be able to be shifted (optionally
after some reductions) on this stack. This can be useful for
external tokenizers that want to make sure they only provide a
given token when it applies.
*/
canShift(term: number): boolean;
/**
Get the parser used by this stack.
*/
get parser(): LRParser;
/**
Test whether a given dialect (by numeric ID, as exported from
the terms file) is enabled.
*/
dialectEnabled(dialectID: number): boolean;
private shiftContext;
private reduceContext;
private updateContext;
}
/**
[Tokenizers](#lr.ExternalTokenizer) interact with the input
through this interface. It presents the input as a stream of
characters, tracking lookahead and hiding the complexity of
[ranges](#common.Parser.parse^ranges) from tokenizer code.
*/
declare class InputStream {
/**
Backup chunk
*/
private chunk2;
private chunk2Pos;
/**
The character code of the next code unit in the input, or -1
when the stream is at the end of the input.
*/
next: number;
/**
The current position of the stream. Note that, due to parses
being able to cover non-contiguous
[ranges](#common.Parser.startParse), advancing the stream does
not always mean its position moves a single unit.
*/
pos: number;
private rangeIndex;
private range;
/**
Look at a code unit near the stream position. `.peek(0)` equals
`.next`, `.peek(-1)` gives you the previous character, and so
on.
Note that looking around during tokenizing creates dependencies
on potentially far-away content, which may reduce the
effectiveness incremental parsing—when looking forward—or even
cause invalid reparses when looking backward more than 25 code
units, since the library does not track lookbehind.
*/
peek(offset: number): number;
/**
Accept a token. By default, the end of the token is set to the
current stream position, but you can pass an offset (relative to
the stream position) to change that.
*/
acceptToken(token: number, endOffset?: number): void;
/**
Accept a token ending at a specific given position.
*/
acceptTokenTo(token: number, endPos: number): void;
private getChunk;
private readNext;
/**
Move the stream forward N (defaults to 1) code units. Returns
the new value of [`next`](#lr.InputStream.next).
*/
advance(n?: number): number;
private setDone;
}
interface Tokenizer {
}
/**
@hide
*/
declare class LocalTokenGroup implements Tokenizer {
readonly precTable: number;
readonly elseToken?: number | undefined;
contextual: boolean;
fallback: boolean;
extend: boolean;
readonly data: Readonly<Uint16Array>;
constructor(data: Readonly<Uint16Array> | string, precTable: number, elseToken?: number | undefined);
token(input: InputStream, stack: Stack): void;
}
interface ExternalOptions {
/**
When set to true, mark this tokenizer as depending on the
current parse stack, which prevents its result from being cached
between parser actions at the same positions.
*/
contextual?: boolean;
/**
By defaults, when a tokenizer returns a token, that prevents
tokenizers with lower precedence from even running. When
`fallback` is true, the tokenizer is allowed to run when a
previous tokenizer returned a token that didn't match any of the
current state's actions.
*/
fallback?: boolean;
/**
When set to true, tokenizing will not stop after this tokenizer
has produced a token. (But it will still fail to reach this one
if a higher-precedence tokenizer produced a token.)
*/
extend?: boolean;
}
/**
`@external tokens` declarations in the grammar should resolve to
an instance of this class.
*/
declare class ExternalTokenizer {
/**
Create a tokenizer. The first argument is the function that,
given an input stream, scans for the types of tokens it
recognizes at the stream's position, and calls
[`acceptToken`](#lr.InputStream.acceptToken) when it finds
one.
*/
constructor(
/**
@internal
*/
token: (input: InputStream, stack: Stack) => void, options?: ExternalOptions);
}
/**
Context trackers are used to track stateful context (such as
indentation in the Python grammar, or parent elements in the XML
grammar) needed by external tokenizers. You declare them in a
grammar file as `@context exportName from "module"`.
Context values should be immutable, and can be updated (replaced)
on shift or reduce actions.
The export used in a `@context` declaration should be of this
type.
*/
declare class ContextTracker<T> {
/**
Define a context tracker.
*/
constructor(spec: {
/**
The initial value of the context at the start of the parse.
*/
start: T;
/**
Update the context when the parser executes a
[shift](https://en.wikipedia.org/wiki/LR_parser#Shift_and_reduce_actions)
action.
*/
shift?(context: T, term: number, stack: Stack, input: InputStream): T;
/**
Update the context when the parser executes a reduce action.
*/
reduce?(context: T, term: number, stack: Stack, input: InputStream): T;
/**
Update the context when the parser reuses a node from a tree
fragment.
*/
reuse?(context: T, node: Tree, stack: Stack, input: InputStream): T;
/**
Reduce a context value to a number (for cheap storage and
comparison). Only needed for strict contexts.
*/
hash?(context: T): number;
/**
By default, nodes can only be reused during incremental
parsing if they were created in the same context as the one in
which they are reused. Set this to false to disable that
check (and the overhead of storing the hashes).
*/
strict?: boolean;
});
}
/**
Configuration options when
[reconfiguring](#lr.LRParser.configure) a parser.
*/
interface ParserConfig {
/**
Node prop values to add to the parser's node set.
*/
props?: readonly NodePropSource[];
/**
The name of the `@top` declaration to parse from. If not
specified, the first top rule declaration in the grammar is
used.
*/
top?: string;
/**
A space-separated string of dialects to enable.
*/
dialect?: string;
/**
Replace the given external tokenizers with new ones.
*/
tokenizers?: {
from: ExternalTokenizer;
to: ExternalTokenizer;
}[];
/**
Replace external specializers with new ones.
*/
specializers?: {
from: (value: string, stack: Stack) => number;
to: (value: string, stack: Stack) => number;
}[];
/**
Replace the context tracker with a new one.
*/
contextTracker?: ContextTracker<any>;
/**
When true, the parser will raise an exception, rather than run
its error-recovery strategies, when the input doesn't match the
grammar.
*/
strict?: boolean;
/**
Add a wrapper, which can extend parses created by this parser
with additional logic (usually used to add
[mixed-language](#common.parseMixed) parsing).
*/
wrap?: ParseWrapper;
/**
The maximum length of the TreeBuffers generated in the output
tree. Defaults to 1024.
*/
bufferLength?: number;
}
/**
Holds the parse tables for a given grammar, as generated by
`lezer-generator`, and provides [methods](#common.Parser) to parse
content with.
*/
declare class LRParser extends Parser {
/**
The nodes used in the trees emitted by this parser.
*/
readonly nodeSet: NodeSet;
createParse(input: Input, fragments: readonly TreeFragment[], ranges: readonly {
from: number;
to: number;
}[]): PartialParse;
/**
Configure the parser. Returns a new parser instance that has the
given settings modified. Settings not provided in `config` are
kept from the original parser.
*/
configure(config: ParserConfig): LRParser;
/**
Tells you whether any [parse wrappers](#lr.ParserConfig.wrap)
are registered for this parser.
*/
hasWrappers(): boolean;
/**
Returns the name associated with a given term. This will only
work for all terms when the parser was generated with the
`--names` option. By default, only the names of tagged terms are
stored.
*/
getName(term: number): string;
/**
The type of top node produced by the parser.
*/
get topNode(): NodeType;
/**
Used by the output of the parser generator. Not available to
user code. @hide
*/
static deserialize(spec: any): LRParser;
}
export { ContextTracker, ExternalTokenizer, InputStream, LRParser, LocalTokenGroup, type ParserConfig, Stack };

1884
editor/node_modules/@lezer/lr/dist/index.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

32
editor/node_modules/@lezer/lr/package.json generated vendored Normal file
View File

@@ -0,0 +1,32 @@
{
"name": "@lezer/lr",
"version": "1.4.8",
"description": "Incremental parser",
"main": "dist/index.cjs",
"type": "module",
"exports": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"module": "dist/index.js",
"types": "dist/index.d.ts",
"author": "Marijn Haverbeke <marijn@haverbeke.berlin>",
"license": "MIT",
"repository": {
"type" : "git",
"url" : "https://github.com/lezer-parser/lr.git"
},
"devDependencies": {
"@marijn/buildtool": "^0.1.5",
"@types/node": "^20.6.2"
},
"dependencies": {
"@lezer/common": "^1.0.0"
},
"files": ["dist"],
"scripts": {
"test": "echo 'Tests are in @lezer/generator'",
"watch": "node build.js --watch",
"prepare": "node build.js; tsc src/constants.ts -d --outDir dist"
}
}