From 12c377ea70c8928f96d02d0885744bd6818c10c6 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Fri, 25 Sep 2026 15:24:05 +0100 Subject: Add the first component and three surfaces Vega reads a verified Pure module by convention: a table view with a label column is a list (with optional badge, detail and tone), any other table is a table, _focus is its focused row, a title view is the title and other views are fields. lib/vega.aup gives aup apps the tones, which say what a row means; each surface decides how it looks or sounds. vega tui draws the screen in a terminal, keeps the focused row in view and evaluates only the cells on screen; vega cli prints plain lines for pipes; vega say speaks the screen and each focus change as sentences. Display width handles Hangul, CJK, emoji, combining marks and controls. tests/check.py compares the CLI and NUI output with a reference model of examples/todo.aup line for line, checks 9,600 TUI frames for scrolling, focus, badge alignment and the number of cells evaluated, drives the interactive TUI on a pseudo-terminal, and runs every aup example on every surface. --- examples/scores.aup | 35 +++++++++++++++++++++++++++++++++++ examples/todo.aup | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 examples/scores.aup create mode 100644 examples/todo.aup (limited to 'examples') diff --git a/examples/scores.aup b/examples/scores.aup new file mode 100644 index 0000000..14620e9 --- /dev/null +++ b/examples/scores.aup @@ -0,0 +1,35 @@ +# A table: a table view without a label column. Every column shows; a tone +# column colors a row. +use vega + +record Player { + name: text + score = 0 +} + +state players: list of Player +state at: index of players + +input join = text +input up = key ArrowUp +input down = key ArrowDown +input win = key KeyW +input lose = key KeyL + +on join { + players.append(Player { name: join }) + at = players.last +} +on up.down { at = at - 1 } +on down.down { at = at + 1 } +on win.down { at.score = at.score + 1 } +on lose.down { at.score = at.score - 1 } + +view title = "Scores" +view board = each p in players { + name = p.name + score = p.score + rank = if p.score > 2 { "gold" } else if p.score > 0 { "silver" } else { "-" } + tone = if p.score < 0 { vega.danger } else { vega.when(p.score > 2, vega.good) } +} +view board_focus = at.position diff --git a/examples/todo.aup b/examples/todo.aup new file mode 100644 index 0000000..a5ee3b0 --- /dev/null +++ b/examples/todo.aup @@ -0,0 +1,40 @@ +# A to-do list as Vega reads it: one spec, shown by the terminal (vega tui), +# printed for pipes (vega cli) and spoken as sentences (vega say). +use vega + +record Task { + title: text + done = 0 + urgent = 0 +} + +state tasks: list of Task +state at: index of tasks + +input add = text +input up = key ArrowUp +input down = key ArrowDown +input toggle = key Space +input urgent = key KeyU +input drop = key Delete + +on add { + tasks.append(Task { title: add }) + at = tasks.last +} +on up.down { at = at - 1 } +on down.down { at = at + 1 } +on toggle.down { at.done = !at.done } +on urgent.down { at.urgent = !at.urgent } +on drop.down { tasks.remove(at) } + +view title = "To do" +view left = "{tasks.count} tasks" + +# A list: label, and optionally tone, badge and detail per row. +view tasks_list = each task in tasks { + label = task.title + badge = if task.done { "done" } else if task.urgent { "urgent" } else { "" } + tone = if task.done { vega.muted } else { vega.when(task.urgent, vega.danger) } +} +view tasks_list_focus = at.position -- cgit v1.2.3