Skip to content

Commit

Permalink
feat: write an ESLint plugin to check code point names
Browse files Browse the repository at this point in the history
  • Loading branch information
aradzie committed Oct 27, 2024
1 parent 164c3ad commit 9ce7b62
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 17 deletions.
5 changes: 2 additions & 3 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable n/no-extraneous-import */

import js from "@eslint/js";
import keybr from "@keybr/scripts/lib/eslint-plugin-keybr.js";
import confusingBrowserGlobals from "confusing-browser-globals";
import ava from "eslint-plugin-ava";
import formatjs from "eslint-plugin-formatjs";
Expand Down Expand Up @@ -32,6 +33,7 @@ export default [
react.configs.flat["jsx-runtime"],
node.configs["flat/recommended-module"],
ava.configs["flat/recommended"],
keybr.configs["recommended"],
{
ignores: ["packages/server/**", "packages/server-cli/**"],
plugins: { "react-hooks": reactHooks },
Expand Down Expand Up @@ -87,10 +89,7 @@ export default [
// configure node
"n/file-extension-in-import": ["error", "always"],
"n/hashbang": "off",
"n/no-path-concat": "off",
"n/no-process-exit": "off",
"n/no-unsupported-features/es-builtins": "off",
"n/no-unsupported-features/es-syntax": "off",
"n/no-unsupported-features/node-builtins": "off",
"n/prefer-global/buffer": ["error", "always"],
"n/prefer-global/console": ["error", "always"],
Expand Down
2 changes: 1 addition & 1 deletion packages/keybr-generators/lib/layout/diacritics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const makeDeadCharacter = (
if (dead != null) {
return dead;
}
if (codePoint === /* * */ 0x002a) {
if (codePoint === /* "*" */ 0x002a) {
return { dead: codePoint };
}
console.error(
Expand Down
2 changes: 1 addition & 1 deletion packages/keybr-generators/lib/layout/import-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ function parseCharacterList(
}

if (a.length === 2) {
if (a[0] === /* * */ 0x002a) {
if (a[0] === /* "*" */ 0x002a) {
characters.push(makeDeadCharacter(keyId, a[1]));
continue;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/keybr-keyboard-ui/lib/Key.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ test.serial("dead labels", (t) => {
[
{ dead: /* COMBINING GRAVE ACCENT */ 0x0300 },
{ dead: /* COMBINING ACUTE ACCENT */ 0x0301 },
{ dead: /* * */ 0x002a },
{ dead: /* * */ 0x002a },
{ dead: /* "*" */ 0x002a },
{ dead: /* "*" */ 0x002a },
],
);

Expand Down
8 changes: 4 additions & 4 deletions packages/keybr-keyboard/lib/keyboard.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ test("data", (t) => {
Equal: [
{ dead: /* COMBINING ACUTE ACCENT */ 0x0301 },
{ dead: /* COMBINING GRAVE ACCENT */ 0x0300 },
{ dead: /* * */ 0x002a },
{ dead: /* * */ 0x002a },
{ dead: /* "*" */ 0x002a },
{ dead: /* "*" */ 0x002a },
],
};
const geometryDict: GeometryDict = {
Expand Down Expand Up @@ -124,8 +124,8 @@ test("data", (t) => {
"Equal",
{ dead: /* COMBINING ACUTE ACCENT */ 0x0301 },
{ dead: /* COMBINING GRAVE ACCENT */ 0x0300 },
{ dead: /* * */ 0x002a },
{ dead: /* * */ 0x002a },
{ dead: /* "*" */ 0x002a },
{ dead: /* "*" */ 0x002a },
),
);

Expand Down
4 changes: 2 additions & 2 deletions packages/keybr-keyboard/lib/keycharacters.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ test("codepoint characters", (t) => {
test("dead characters", (t) => {
const characters = new KeyCharacters(
"KeyA",
{ dead: /* * */ 0x002a },
{ dead: /* * */ 0x002a },
{ dead: /* "*" */ 0x002a },
{ dead: /* "*" */ 0x002a },
null,
null,
);
Expand Down
2 changes: 0 additions & 2 deletions packages/keybr-unicode/lib/whitespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export const isLinebreak = (codePoint: CodePoint): boolean =>
codePoint === /* LINE TABULATION */ 0x000b ||
codePoint === /* FORM FEED */ 0x000c ||
codePoint === /* CARRIAGE RETURN */ 0x000d ||
codePoint === /* NEXT LINE */ 0x0085 ||
codePoint === /* LINE SEPARATOR */ 0x2028 ||
codePoint === /* PARAGRAPH SEPARATOR */ 0x2029;

Expand All @@ -18,7 +17,6 @@ export const isWhitespace = (codePoint: CodePoint): boolean =>
codePoint === /* FORM FEED */ 0x000c ||
codePoint === /* CARRIAGE RETURN */ 0x000d ||
codePoint === /* SPACE */ 0x0020 ||
codePoint === /* NEXT LINE */ 0x0085 ||
codePoint === /* NO-BREAK SPACE */ 0x00a0 ||
codePoint === /* EN QUAD */ 0x2000 ||
codePoint === /* EM QUAD */ 0x2001 ||
Expand Down
2 changes: 1 addition & 1 deletion scripts/config-lint.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { existsSync } from "node:fs";
import { join } from "node:path";
import { globSync } from "glob";
import { readJsonSync, writeJsonSync } from "./lib/fs.js";
import { readJsonSync, writeJsonSync } from "./lib/fs-json.js";
import { packageJsonKeys, tsconfigJsonKeys } from "./lib/key-order.js";
import { findDeps, printUnusedDeps } from "./lib/lang.js";
import { sortJson } from "./lib/sort-json.js";
Expand Down
16 changes: 16 additions & 0 deletions scripts/lib/codepoints.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import unicodeNames from "@unicode/unicode-16.0.0/Names/index.js";

const controlNames = new Map([
[0x0000, "NULL"],
[0x0008, "BACKSPACE"],
[0x0009, "CHARACTER TABULATION"],
[0x000a, "LINE FEED"],
[0x000b, "LINE TABULATION"],
[0x000c, "FORM FEED"],
[0x000d, "CARRIAGE RETURN"],
[0x001b, "ESCAPE"],
]);

export function getCodePointName(codePoint) {
return controlNames.get(codePoint) ?? unicodeNames.get(codePoint) ?? "?";
}
72 changes: 72 additions & 0 deletions scripts/lib/eslint-plugin-keybr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { getCodePointName } from "./codepoints.js";

const rule = {
meta: {
type: "problem",
docs: {
description: "Checks code point name comments.",
},
fixable: "code",
schema: [],
},
create(context) {
return {
Literal(node) {
if (
node.type === "Literal" &&
typeof node.value === "number" &&
/0x[0-9a-fA-F]{4}/.test(node.raw)
) {
const [comment] = context.sourceCode.getCommentsBefore(node);
if (comment?.type === "Block") {
const name1 =
node.value === /* QUOTATION MARK */ 0x0022
? ` '"' `
: ` "${String.fromCodePoint(node.value)}" `;
const name2 = ` ${getCodePointName(node.value)} `;
if (comment.value !== name1 && comment.value !== name2) {
const expected = comment.value.includes('"')
? `/*${name1}*/`
: `/*${name2}*/`;
context.report({
node,
message:
"Invalid code point name comment, expected: {{ expected }}",
data: {
expected,
},
fix(fixer) {
return fixer.replaceText(comment, expected);
},
});
}
}
}
},
};
},
};

const plugin = {
meta: {
name: "eslint-plugin-keybr",
version: "0.0.0",
},
configs: {},
rules: {
"codepoint-names": rule,
},
};

Object.assign(plugin.configs, {
recommended: {
plugins: {
keybr: plugin,
},
rules: {
"keybr/codepoint-names": "error",
},
},
});

export default plugin;
File renamed without changes.
2 changes: 1 addition & 1 deletion scripts/translate.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { writeFileSync } from "node:fs";
import { join } from "node:path";
import { compile, extract } from "@formatjs/cli-lib";
import { globSync } from "glob";
import { readJsonSync, writeJsonSync } from "./lib/fs.js";
import { readJsonSync, writeJsonSync } from "./lib/fs-json.js";
import { getHashDigest } from "./lib/intl.js";
import { findPackages, rootDir } from "./root.js";

Expand Down

0 comments on commit 9ce7b62

Please sign in to comment.