tree-sitter-hast
Version:
Convert tree-sitter parsed trees to syntax-highlighted HAST
79 lines (78 loc) • 3.31 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const path = require("path");
const util_1 = require("util");
const cson = require("season");
const exists = util_1.promisify(fs.exists);
const readdir = util_1.promisify(fs.readdir);
const loadCson = util_1.promisify(cson.readFile);
const TREE_SITTER_SPEC_FILENAME = /^tree-sitter-(.*)\.cson$/;
function isTreeSitterAtomSpec(value) {
return (typeof value.parser === 'string' &&
!!value.scopes);
}
function loadLanguagesFromPackage(packageName) {
return __awaiter(this, void 0, void 0, function* () {
const langs = new Map();
const lookup_paths = module.paths;
if (require.main) {
for (let i = require.main.paths.length - 1; i >= 0; i--) {
const path = require.main.paths[i];
if (lookup_paths.indexOf(path) === -1)
lookup_paths.unshift(path);
}
}
let packageDir = null;
for (const lookup of lookup_paths) {
const p = path.join(lookup, packageName);
if (yield exists(p)) {
packageDir = p;
break;
}
}
if (!packageDir)
throw new Error(`could not find package: ${packageName}`);
const grammarsDir = path.join(packageDir, 'grammars');
const files = yield readdir(grammarsDir).catch(() => Promise.reject(new Error(`Package ${packageName} is not a valid atom language package`)));
for (const filename of files) {
const match = TREE_SITTER_SPEC_FILENAME.exec(filename);
if (match) {
const lang = match[1];
const spec = yield loadCson(path.join(grammarsDir, filename));
patchRegexes(spec);
if (isTreeSitterAtomSpec(spec)) {
const grammarPath = require.resolve(spec.parser, { paths: lookup_paths });
const grammar = require(grammarPath);
langs.set(lang, {
grammar, scopeMappings: spec.scopes
});
}
else {
throw new Error(`Invalid language specification for ${lang} in ${packageName}`);
}
}
}
return langs;
});
}
exports.loadLanguagesFromPackage = loadLanguagesFromPackage;
function patchRegexes(value) {
if (value instanceof Object) {
for (const key of Object.keys(value)) {
patchRegexes(value[key]);
}
const v = value;
if (typeof v.match === 'string') {
v.match = new RegExp(v.match);
}
}
}