Skip to content

Commit 2df04f1

Browse files
committed
feat(language): editor support for the grip directive
1 parent 9a8f6da commit 2df04f1

4 files changed

Lines changed: 27 additions & 3 deletions

File tree

editors/vscode/syntaxes/posecode.tmLanguage.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
},
3030
"keywords": {
3131
"name": "keyword.control.posecode",
32-
"match": "\\b(posecode|rig|pose|start|step|repeat|ground-lock|cue|hold)\\b"
32+
"match": "\\b(posecode|rig|prop|pose|start|step|repeat|clip|ground-lock|reach|pin|grip|turn|travel|cue|hold)\\b"
3333
},
3434
"kinds": {
3535
"name": "storage.type.posecode",

packages/posecode-language/src/completion.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function contextFor(prefix: string, line: number): Context {
5151
if (/^\s*pose\s+start\s*=\s*[\w-]*$/.test(prefix)) return "pose";
5252
if (/^\s*step\s+"[^"]*"\s+[0-9.]+s\s+[\w-]*$/.test(prefix)) return "easing";
5353
if (/^\s*ground-lock\s*:\s*[\w,\s-]*$/.test(prefix)) return "effector";
54-
if (/^\s*(reach|pin)\s*:\s*[\w-]*$/.test(prefix)) return "reach-effector";
54+
if (/^\s*(reach|pin|grip)\s*:\s*[\w-]*$/.test(prefix)) return "reach-effector";
5555
if (/^\s*[\w-]+\s*:\s*[\w-]*$/.test(prefix)) return "action";
5656

5757
if (/^\s*[\w-]*$/.test(prefix)) {

packages/posecode-language/src/vocab.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export const PROPS = ["chair", "wall", "bar", "box", "dip-bars"];
3232
export const TOP_KEYWORDS = ["rig", "prop", "pose", "clip", "step", "repeat"];
3333

3434
/** Keywords valid as step children. */
35-
export const CHILD_KEYWORDS = ["ground-lock", "reach", "pin", "turn", "travel", "cue"];
35+
export const CHILD_KEYWORDS = ["ground-lock", "reach", "pin", "grip", "turn", "travel", "cue"];
3636

3737
/** Short docs surfaced on hover and as completion detail. */
3838
export const KEYWORD_DOCS: Record<string, string> = {
@@ -53,6 +53,7 @@ export const KEYWORD_DOCS: Record<string, string> = {
5353
reach:
5454
"Drives an effector to a target via ROM-constrained IK: `reach: hand_left ankle_left`, `reach: hands floor`.",
5555
pin: "Moves the body so an effector sits on an anchor: `pin: hands bar` (hang, pull up, step up, dip).",
56+
grip: "Holds a bar/rail: `grip: hands bar`. Each hand gets its own two-point anchor (bar_left/bar_right), the arm bends via IK onto it, and the fingers wrap the bar. Use for pull-up, dead-hang, hanging knee raise.",
5657
turn: "Turns the figure to face a new direction: `turn: 360` (degrees, yaw about vertical). Absolute, carried across phases. Standing poses only.",
5758
travel: "Moves the figure across the floor: `travel: 0.4 0` (world x z metres from the start spot). Absolute, carried across phases. Standing poses only.",
5859
cue: "A short coaching cue shown while this phase plays.",

packages/posecode-language/test/language.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,26 @@ describe("timing modes (L2)", () => {
135135
expect(hint?.message).toContain("settle");
136136
});
137137
});
138+
139+
describe("grip directive (L3.2)", () => {
140+
it("offers grip as a step child keyword", () => {
141+
const doc = ['posecode exercise "x"', " rig humanoid", ' step "Hang" 1s flow:', " "].join("\n");
142+
const line = doc.split("\n")[3]!;
143+
const labels = getCompletions(doc, 3, line.length).map((i) => i.label);
144+
expect(labels).toContain("grip");
145+
});
146+
147+
it("completes effectors after `grip:`", () => {
148+
const doc = ['posecode exercise "x"', " rig humanoid", ' step "Hang" 1s flow:', " grip: "].join("\n");
149+
const line = doc.split("\n")[3]!;
150+
const labels = getCompletions(doc, 3, line.length).map((i) => i.label);
151+
expect(labels).toContain("hands");
152+
});
153+
154+
it("hovers grip with its doc", () => {
155+
const doc = ['posecode exercise "x"', " rig humanoid", ' step "Hang" 1s flow:', " grip: hands bar"].join("\n");
156+
const line = doc.split("\n")[3]!;
157+
const h = getHover(doc, 3, line.indexOf("grip") + 1);
158+
expect(h?.contents.toLowerCase()).toContain("bar");
159+
});
160+
});

0 commit comments

Comments
 (0)