Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions .vscode/settings-light.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,43 @@
}
},
{
"scope": "variable.parameter.nlp",
"scope": [
"variable.parameter.nlp",
"keyword.control.kb"
],
"settings": {
"foreground": "#696969"
}
},
{
"scope": "keyword.attribute.nlp",
"scope": "entity.other.attribute-name.nlp",
"settings": {
"foreground": "#e655f3"
}
},
{
"scope": "constant.numeric.tree",
"scope": [
"constant.numeric.tree",
"constant.numeric.kbb"
],
"settings": {
"foreground": "#5596f0"
}
},
{
"scope": "keyword.fired.tree",
"scope": "keyword.other.fired.tree",
"settings": {
"foreground": "#dc1b1b"
}
},
{
"scope": "keyword.rewrite.tree",
"scope": "entity.name.type.tree",
"settings": {
"foreground": "#000000"
}
},
{
"scope": "keyword.node.tree",
"scope": "string.unquoted.token.tree",
"settings": {
"foreground": "#4e8e3c"
}
Expand All @@ -50,25 +56,25 @@
}
},
{
"scope": "keyword.concept.kbb1",
"scope": "entity.name.type.level2.kbb",
"settings": {
"foreground": "#909228"
}
},
{
"scope": "keyword.concept.kbb",
"scope": "entity.name.type.level1.kbb",
"settings": {
"foreground": "#7e7e7e"
}
},
{
"scope": "keyword.concept.kbb1",
"scope": "entity.name.type.level2.kbb",
"settings": {
"foreground": "#2eb657"
}
},
{
"scope": "keyword.concept.kbb2",
"scope": "entity.name.type.level3.kbb",
"settings": {
"foreground": "#e049d9"
}
Expand Down
56 changes: 34 additions & 22 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,23 @@
}
},
{
"scope": "variable.parameter.nlp",
"scope": [
"variable.parameter.nlp",
"keyword.control.kb"
],
"settings": {
"foreground": "#696969",
"fontStyle": "bold"
}
},
{
"scope": "keyword.attribute.nlp",
"scope": "entity.other.attribute-name.nlp",
"settings": {
"foreground": "#e655f3"
}
},
{
"scope": "keyword.constants.nlp",
"scope": "constant.language.nlp",
"settings": {
"foreground": "#0a7b83",
"fontStyle": "bold"
Expand All @@ -44,27 +47,30 @@
}
},
{
"scope": "constant.numeric.tree",
"scope": [
"constant.numeric.tree",
"constant.numeric.kbb"
],
"settings": {
"foreground": "#5596f0"
}
},
{
"scope": "keyword.fired.tree",
"scope": "keyword.other.fired.tree",
"settings": {
"foreground": "#dc1b1b",
"fontStyle": "bold"
}
},
{
"scope": "keyword.rewrite.tree",
"scope": "entity.name.type.tree",
"settings": {
"foreground": "#000000",
"fontStyle": "bold"
}
},
{
"scope": "keyword.node.tree",
"scope": "string.unquoted.token.tree",
"settings": {
"foreground": "#4e8e3c",
"fontStyle": "bold"
Expand Down Expand Up @@ -98,28 +104,28 @@
}
},
{
"scope": "keyword.other.kbb",
"scope": "entity.name.type.level0.kbb",
"settings": {
"foreground": "#5d00d6",
"fontStyle": "bold"
}
},
{
"scope": "keyword.concept.kbb",
"scope": "entity.name.type.level1.kbb",
"settings": {
"foreground": "#7e7e7e",
"fontStyle": "bold"
}
},
{
"scope": "keyword.concept.kbb1",
"scope": "entity.name.type.level2.kbb",
"settings": {
"foreground": "#2eb657",
"fontStyle": "bold"
}
},
{
"scope": "keyword.concept.kbb2",
"scope": "entity.name.type.level3.kbb",
"settings": {
"foreground": "#e049d9",
"fontStyle": "bold"
Expand All @@ -143,20 +149,23 @@
}
},
{
"scope": "variable.parameter.nlp",
"scope": [
"variable.parameter.nlp",
"keyword.control.kb"
],
"settings": {
"foreground": "#f8fa87",
"fontStyle": "bold"
}
},
{
"scope": "keyword.attribute.nlp",
"scope": "entity.other.attribute-name.nlp",
"settings": {
"foreground": "#f293fb"
}
},
{
"scope": "keyword.constants.nlp",
"scope": "constant.language.nlp",
"settings": {
"foreground": "#4ec9b0",
"fontStyle": "bold"
Expand All @@ -172,27 +181,30 @@
}
},
{
"scope": "constant.numeric.tree",
"scope": [
"constant.numeric.tree",
"constant.numeric.kbb"
],
"settings": {
"foreground": "#93bffb"
}
},
{
"scope": "keyword.fired.tree",
"scope": "keyword.other.fired.tree",
"settings": {
"foreground": "#dc1b1b",
"fontStyle": "bold"
}
},
{
"scope": "keyword.rewrite.tree",
"scope": "entity.name.type.tree",
"settings": {
"foreground": "#f8fa87",
"fontStyle": "bold"
}
},
{
"scope": "keyword.node.tree",
"scope": "string.unquoted.token.tree",
"settings": {
"foreground": "#4e8e3c",
"fontStyle": "bold"
Expand All @@ -211,28 +223,28 @@
}
},
{
"scope": "keyword.other.kbb",
"scope": "entity.name.type.level0.kbb",
"settings": {
"foreground": "#896eff",
"fontStyle": "bold"
}
},
{
"scope": "keyword.concept.kbb",
"scope": "entity.name.type.level1.kbb",
"settings": {
"foreground": "#e3ee50",
"fontStyle": "bold"
}
},
{
"scope": "keyword.concept.kbb1",
"scope": "entity.name.type.level2.kbb",
"settings": {
"foreground": "#2eb657",
"fontStyle": "bold"
}
},
{
"scope": "keyword.concept.kbb2",
"scope": "entity.name.type.level3.kbb",
"settings": {
"foreground": "#e049d9",
"fontStyle": "bold"
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ All notable changes to the [VSCode NLP++ extension](http://vscode.visualtext.org

Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.

### 4.3.10
NLP++ files are colored by any VS Code theme, not only through the colors this extension writes into your settings.

- **The grammars use standard TextMate scope names** (#107). They used to name things after the color they should get rather than what they are. Constants like `_xWILD` were marked as keywords, a dictionary headword as a comment, and a few scopes, such as `literal.nlp`, had names no theme recognizes. Themes, and tools such as GitHub and Shiki that read these grammars, now color `@RULES`, constants, rule modifiers, node names and dictionary keys and values like the equivalent parts of other languages. The full list of renames is in the [grammar README](https://github.com/VisualText/nlpplus-tmbundle#scope-names).
- **Your analyzer colors are unchanged.** The extension's color rules in each analyzer workspace's `.vscode/settings.json` are rewritten to the new names the first time the workspace opens, so everything you saw before keeps its color. A settings file the extension cannot read, for example one with comments in it, is left alone.

### 4.3.9
Each analyzer keeps its own open files, and the analyzers you used last are a click away.

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"displayName": "NLP",
"description": "NLP++: the only computer programming language built for NLP — create and visually debug analyzers directly in VS Code.",
"icon": "resources/NLPppLogo.png",
"version": "4.3.9",
"version": "4.3.10",
"license": "MIT",
"publisher": "dehilster",
"enableApiProposals": false,
Expand Down
48 changes: 48 additions & 0 deletions src/language/langTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import { parseKbConcepts } from "./kbConcepts";
import { regionKindAt, RegionKind } from "./completion";
import { findEnclosingCall } from "./signature";
import { foldingRanges } from "./folding";
import { RENAMED_SCOPES, migrateScope, migrateTokenColors } from "./scopeMigration";
import * as fs from "fs";
import * as path from "path";
import { RuleLocator, visualColumn } from "./ruleLocator";
import { classifyTokens } from "./semanticTokens";
import { findUnknownCalls, levenshtein } from "./quickfix";
Expand Down Expand Up @@ -185,6 +188,51 @@ _verb <- verb @@
eq("column: two tabs", visualColumn("\t\tx", 2, 4), 9);
}

// ---- scope migration (#107) ------------------------------------------------
{
// The map must match the grammars it describes: no old name may survive in
// them unless it maps to itself, and every new name must exist in one.
const dir = path.join(__dirname, "..", "..", "grammars", "syntaxes");
const names = new Set<string>();
const walk = (o: unknown): void => {
if (Array.isArray(o)) o.forEach(walk);
else if (o && typeof o === "object") {
for (const [k, v] of Object.entries(o)) {
if ((k === "name" || k === "contentName") && typeof v === "string") names.add(v);
else walk(v);
}
}
};
for (const f of fs.readdirSync(dir).filter((f) => f.endsWith(".json"))) walk(JSON.parse(fs.readFileSync(path.join(dir, f), "utf8")));
for (const [oldName, renamed] of Object.entries(RENAMED_SCOPES)) {
check(`scopes: ${oldName} gone from grammars`, renamed.includes(oldName) || !names.has(oldName));
for (const n of renamed) check(`scopes: ${n} exists in a grammar`, names.has(n));
}

eq("scopes: one-to-one", JSON.stringify(migrateScope("keyword.region.nlp")), JSON.stringify({ scope: "keyword.control.directive.region.nlp", changed: true }));
eq("scopes: one-to-many keeps all", JSON.stringify(migrateScope("comment.line.dict").scope),
JSON.stringify(["entity.name.tag.dict", "comment.line.dict", "comment.line.kb", "comment.line.kbb", "comment.line.tree"]));
eq("scopes: list, deduplicated", JSON.stringify(migrateScope(["keyword.operator.nlp", "keyword.equals.nlp", "keyword.operator.assignment.nlp"]).scope),
JSON.stringify(["keyword.operator.nlp", "keyword.operator.assignment.nlp"]));
eq("scopes: comma string", JSON.stringify(migrateScope("keyword.fired.tree, keyword.rewrite.tree").scope),
JSON.stringify(["keyword.other.fired.tree", "entity.name.type.tree"]));
eq("scopes: unknown untouched", migrateScope("source.js keyword").changed, false);

const settings: Record<string, unknown> = {
"files.eol": "lf",
"editor.tokenColorCustomizations": {
"textMateRules": [{ scope: "keyword.constants.nlp", settings: { foreground: "#0a7b83" } }],
"[*Dark*]": { textMateRules: [{ scope: "keyword.fired.tree", settings: { foreground: "#ff0000" } }, { name: "no scope" }] },
},
};
check("scopes: settings migrated", migrateTokenColors(settings));
const block = settings["editor.tokenColorCustomizations"] as { textMateRules: { scope: string }[]; "[*Dark*]": { textMateRules: { scope?: string }[] } };
eq("scopes: top-level rule", block.textMateRules[0].scope, "constant.language.nlp");
eq("scopes: per-theme rule", block["[*Dark*]"].textMateRules[0].scope, "keyword.other.fired.tree");
eq("scopes: second run is a no-op", migrateTokenColors(settings), false);
eq("scopes: no block", migrateTokenColors({ "files.eol": "lf" }), false);
}

// ---- engine errors ---------------------------------------------------------
{
const log = [
Expand Down
2 changes: 1 addition & 1 deletion src/language/nlpxxData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const KEYWORDS = [
"cap", "cout", "else", "gp", "group", "if", "inc", "return", "while",
];

// Rule-element modifiers inside @RULES (grammar: keyword.attribute.nlp).
// Rule-element modifiers inside @RULES (grammar: entity.other.attribute-name.nlp).
export const RULE_KEYWORDS = [
"attr", "attrs", "base", "da", "deacc", "deaccent", "except", "excepts",
"fail", "fails", "gp", "group", "layer", "layers", "look", "lookahead",
Expand Down
Loading
Loading