zmk/docs/src/keymap-upgrade/properties.ts

66 lines
1.6 KiB
TypeScript

import type { SyntaxNode, Tree } from "web-tree-sitter";
import { captureHasText, Devicetree, findCapture } from "./parser";
import { TextEdit } from "./textedit";
/**
* Upgrades deprecated properties.
*/
export function upgradeProperties(tree: Tree) {
return removeLabels(tree);
}
/**
* Renames "label" properties in keymap layers to "display-name". Removes all
* other "label" properties.
*/
function removeLabels(tree: Tree) {
const edits: TextEdit[] = [];
const query = Devicetree.query("(property name: (identifier) @name) @prop");
const matches = query.matches(tree.rootNode);
for (const { captures } of matches) {
const name = findCapture("name", captures);
const node = findCapture("prop", captures);
if (name?.text === "label" && node) {
if (isLayerLabel(node)) {
edits.push(TextEdit.fromNode(name, "display-name"));
} else {
edits.push(TextEdit.fromNode(node, ""));
}
}
}
return edits;
}
/**
* Given a "label" property node, returns whether it is a label for a keymap layer.
*/
function isLayerLabel(node: SyntaxNode) {
const maybeKeymap = node.parent?.parent;
if (!maybeKeymap) {
return false;
}
const query = Devicetree.query(
`(property
name: (identifier) @name
value: (string_literal) @value
) @prop`
);
const matches = query.matches(maybeKeymap);
for (const { captures } of matches) {
if (
findCapture("prop", captures)?.parent?.equals(maybeKeymap) &&
captureHasText("name", captures, "compatible") &&
captureHasText("value", captures, '"zmk,keymap"')
) {
return true;
}
}
return false;
}