Skip to content

Commit

Permalink
split code into files and fixed generate script
Browse files Browse the repository at this point in the history
  • Loading branch information
harrydowning committed Aug 28, 2024
1 parent a83a139 commit 56badf4
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 181 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@
},
"scripts": {
"build": "tsc && esbuild dist/extension.js --bundle --platform=node --outfile=dist/extension.js --allow-overwrite --minify --external:vscode",
"generate": "ts-node -e \"import { generateFiles } from './src/extension'; generateFiles()\"",
"generate": "ts-node src/generate.ts",
"lint": "eslint",
"format": "prettier . --check"
}
}
}
8 changes: 8 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,11 @@ export const LANGUAGES = {
yaml: "source.yaml",
};
/* eslint-disable sort-keys */

export type Languages = {
[key: string]: {
name: string;
scopeName: string;
stripIndent: boolean;
};
};
180 changes: 1 addition & 179 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,190 +1,12 @@
import vscode from "vscode";
import fs from "fs";
import {
INCLUDE_CONFIG,
LANGUAGES,
packageJson,
SUB_INCLUDE_CONFIG,
VERSION_STATE,
} from "./constants";

type Languages = {
[key: string]: {
name: string;
scopeName: string;
stripIndent: boolean;
};
};

class Writable {
path;
#absolutePath;

constructor(path: string) {
this.path = path;
this.#absolutePath = `${__dirname}/../${path}`;
}

write() {
const data = JSON.stringify(this.valueOf(), null, 2);
let fileData;

try {
fileData = fs.readFileSync(this.#absolutePath).toString();
} catch {
fileData = undefined;
}

if (fileData === data) {
return false;
}

try {
fs.writeFileSync(this.#absolutePath, data);
} catch (err) {
console.error(err);
return false;
}

console.log(`File '${this.#absolutePath}' saved.`);
return true;
}
}

class InjectionGrammar extends Writable {
embeddedScopeNamePrefix = "meta.embedded.inline";
scopeName;
injectionScopeName;
languages;

constructor(injectionScopeName: string, languages: Languages) {
super(`./syntaxes/${injectionScopeName}.injection.tmLanguage.json`);
this.scopeName = `${injectionScopeName}.injection`;
this.injectionScopeName = injectionScopeName;
this.languages = languages;
}

#getPatterns() {
const entries = Object.entries(this.languages);
return entries.map(([id, { scopeName, stripIndent }]) => ({
begin: `(?i)(?:(\\|)|(>))([1-9])?([-+])?\\s+(#\\s*(?:${id})\\s*\\n)`,
beginCaptures: {
1: {
name: "keyword.control.flow.block-scalar.literal.yaml",
},
2: {
name: "keyword.control.flow.block-scalar.folded.yaml",
},
3: {
name: "constant.numeric.indentation-indicator.yaml",
},
4: {
name: "storage.modifier.chomping-indicator.yaml",
},
5: {
name: "entity.name.type.yaml",
},
},
end: "^(?=\\S)|(?!\\G)",
patterns: [
{
begin: "(?>^|\\G)([ ]+)(?! )",
end: "^(?!\\1|\\s*$)",
while: stripIndent ? "^$|\\1" : undefined,
name: `${this.embeddedScopeNamePrefix}.${id}`,
patterns: [{ include: scopeName }],
},
],
}));
}

valueOf() {
return {
scopeName: this.scopeName,
injectionSelector: `L:${this.injectionScopeName}`,
patterns: this.#getPatterns(),
};
}
}

class Package extends Writable {
#injectionGrammars;
constructor(injectionGrammars: InjectionGrammar[]) {
super(`package.json`);
this.#injectionGrammars = injectionGrammars;
}

#getEmbeddedLanguages(injectionGrammar: InjectionGrammar) {
const languages = injectionGrammar.languages;
const ids = Object.keys(languages);
return Object.fromEntries(
ids.map((id) => [
`${injectionGrammar.embeddedScopeNamePrefix}.${id}`,
languages[id].name,
]),
);
}

valueOf() {
return {
...packageJson,
contributes: {
...packageJson.contributes,
grammars: this.#injectionGrammars.map((injectionGrammar) => ({
path: injectionGrammar.path,
scopeName: injectionGrammar.scopeName,
injectTo: [injectionGrammar.injectionScopeName],
embeddedLanguages: this.#getEmbeddedLanguages(injectionGrammar),
})),
},
};
}
}

const normalizeLanguages = (languages: { [key: string]: unknown }) => {
const normalizedLanguages: Languages = {};
for (const id in languages) {
let language = languages[id];
if (typeof language === "string") {
language = { scopeName: language };
}

if (typeof language === "object" && language !== null) {
if (!("scopeName" in language)) {
continue;
}

if (typeof language.scopeName !== "string") {
continue;
}

normalizedLanguages[id] = {
name:
"name" in language && typeof language.name === "string"
? language.name
: id,
scopeName: language.scopeName,
stripIndent:
"stripIndent" in language && typeof language.stripIndent === "boolean"
? language.stripIndent
: false,
};
}
}
return normalizedLanguages;
};

export const generateFiles = (languages = LANGUAGES) => {
const parsedLanguages = normalizeLanguages(languages);
const grammars = [
new InjectionGrammar("source.yaml", parsedLanguages),
new InjectionGrammar("source.github-actions-workflow", parsedLanguages),
];

const writables = [new Package(grammars), ...grammars];

return writables.map((writable) => writable.write()).some(Boolean);
};
import { generateFiles } from "./generate";

const updateExtension = () => {
const settings = vscode.workspace.getConfiguration(packageJson.name);
Expand Down
52 changes: 52 additions & 0 deletions src/generate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { LANGUAGES, Languages } from "./constants";
import { InjectionGrammar } from "./injection-grammar";
import { Package } from "./package";

const normalizeLanguages = (languages: { [key: string]: unknown }) => {
const normalizedLanguages: Languages = {};
for (const id in languages) {
let language = languages[id];
if (typeof language === "string") {
language = { scopeName: language };
}

if (typeof language === "object" && language !== null) {
if (!("scopeName" in language)) {
continue;
}

if (typeof language.scopeName !== "string") {
continue;
}

normalizedLanguages[id] = {
name:
"name" in language && typeof language.name === "string"
? language.name
: id,
scopeName: language.scopeName,
stripIndent:
"stripIndent" in language && typeof language.stripIndent === "boolean"
? language.stripIndent
: false,
};
}
}
return normalizedLanguages;
};

export const generateFiles = (languages = LANGUAGES) => {
const parsedLanguages = normalizeLanguages(languages);
const grammars = [
new InjectionGrammar("source.yaml", parsedLanguages),
new InjectionGrammar("source.github-actions-workflow", parsedLanguages),
];

const writables = [new Package(grammars), ...grammars];

return writables.map((writable) => writable.write()).some(Boolean);
};

if (require.main === module) {
generateFiles();
}
58 changes: 58 additions & 0 deletions src/injection-grammar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Languages } from "./constants";
import { Writable } from "./writable";

export class InjectionGrammar extends Writable {
embeddedScopeNamePrefix = "meta.embedded.inline";
scopeName;
injectionScopeName;
languages;

constructor(injectionScopeName: string, languages: Languages) {
super(`./syntaxes/${injectionScopeName}.injection.tmLanguage.json`);
this.scopeName = `${injectionScopeName}.injection`;
this.injectionScopeName = injectionScopeName;
this.languages = languages;
}

#getPatterns() {
const entries = Object.entries(this.languages);
return entries.map(([id, { scopeName, stripIndent }]) => ({
begin: `(?i)(?:(\\|)|(>))([1-9])?([-+])?\\s+(#\\s*(?:${id})\\s*\\n)`,
beginCaptures: {
1: {
name: "keyword.control.flow.block-scalar.literal.yaml",
},
2: {
name: "keyword.control.flow.block-scalar.folded.yaml",
},
3: {
name: "constant.numeric.indentation-indicator.yaml",
},
4: {
name: "storage.modifier.chomping-indicator.yaml",
},
5: {
name: "entity.name.type.yaml",
},
},
end: "^(?=\\S)|(?!\\G)",
patterns: [
{
begin: "(?>^|\\G)([ ]+)(?! )",
end: "^(?!\\1|\\s*$)",
while: stripIndent ? "^$|\\1" : undefined,
name: `${this.embeddedScopeNamePrefix}.${id}`,
patterns: [{ include: scopeName }],
},
],
}));
}

valueOf() {
return {
scopeName: this.scopeName,
injectionSelector: `L:${this.injectionScopeName}`,
patterns: this.#getPatterns(),
};
}
}
37 changes: 37 additions & 0 deletions src/package.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { packageJson } from "./constants";
import { InjectionGrammar } from "./injection-grammar";
import { Writable } from "./writable";

export class Package extends Writable {
#injectionGrammars;
constructor(injectionGrammars: InjectionGrammar[]) {
super(`package.json`);
this.#injectionGrammars = injectionGrammars;
}

#getEmbeddedLanguages(injectionGrammar: InjectionGrammar) {
const languages = injectionGrammar.languages;
const ids = Object.keys(languages);
return Object.fromEntries(
ids.map((id) => [
`${injectionGrammar.embeddedScopeNamePrefix}.${id}`,
languages[id].name,
]),
);
}

valueOf() {
return {
...packageJson,
contributes: {
...packageJson.contributes,
grammars: this.#injectionGrammars.map((injectionGrammar) => ({
path: injectionGrammar.path,
scopeName: injectionGrammar.scopeName,
injectTo: [injectionGrammar.injectionScopeName],
embeddedLanguages: this.#getEmbeddedLanguages(injectionGrammar),
})),
},
};
}
}
Loading

0 comments on commit 56badf4

Please sign in to comment.