From 1dc87c3ed7069e7d0ab21b107ef470e3c793ca9e Mon Sep 17 00:00:00 2001 From: ruki Date: Mon, 27 Oct 2025 22:54:33 +0800 Subject: improve tty --- tests/modules/tty/quick_example.lua | 140 ++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 tests/modules/tty/quick_example.lua (limited to 'tests/modules/tty/quick_example.lua') diff --git a/tests/modules/tty/quick_example.lua b/tests/modules/tty/quick_example.lua new file mode 100644 index 000000000..6b68394f7 --- /dev/null +++ b/tests/modules/tty/quick_example.lua @@ -0,0 +1,140 @@ +-- Quick example: Demonstrates the most common use cases + +import("core.base.tty") + +function example1_simple_progress() + print("\n=== Example 1: Simple Progress Bar ===\n") + + if not tty.has_vtansi() then + print("ANSI not supported") + return + end + + print("Downloading file...") + for i = 0, 100, 5 do + local width = 40 + local filled = math.floor(i / 100 * width) + local bar = string.rep("█", filled) .. string.rep("░", width - filled) + + -- Move to start of line, clear it, and redraw + tty.cr() + tty.erase_line() + io.write(string.format("[%s] %3d%%", bar, i)) + io.flush() + + os.sleep(50) + end + print("") -- New line after progress +end + +function example2_update_previous_line() + print("\n=== Example 2: Update Previous Line ===\n") + + if not tty.has_vtansi() then + print("ANSI not supported") + return + end + + print("Building project...") + print("Status: Starting...") + + os.sleep(1000) + + -- Go back and update the status line + tty.cursor_move_up(1) + tty.erase_line() + io.write("Status: Compiling files...") + io.flush() + print("") -- Move to next line + + os.sleep(1000) + + tty.cursor_move_up(1) + tty.erase_line() + io.write("Status: Done! ✓") + io.flush() + print("") +end + +function example3_multi_line_update() + print("\n=== Example 3: Multi-line Updates ===\n") + + if not tty.has_vtansi() then + print("ANSI not supported") + return + end + + -- Create a simple status board + print("Task 1: Waiting...") + print("Task 2: Waiting...") + print("Task 3: Waiting...") + + tty.cursor_hide() + + -- Update Task 1 + tty.cursor_save() + tty.cursor_move_up(3) + tty.erase_line() + io.write("Task 1: Running... ") + io.flush() + tty.cursor_restore() + os.sleep(500) + + tty.cursor_save() + tty.cursor_move_up(3) + tty.erase_line() + io.write("Task 1: Done ✓") + io.flush() + tty.cursor_restore() + + -- Update Task 2 + tty.cursor_save() + tty.cursor_move_up(2) + tty.erase_line() + io.write("Task 2: Running... ") + io.flush() + tty.cursor_restore() + os.sleep(500) + + tty.cursor_save() + tty.cursor_move_up(2) + tty.erase_line() + io.write("Task 2: Done ✓") + io.flush() + tty.cursor_restore() + + -- Update Task 3 + tty.cursor_save() + tty.cursor_move_up(1) + tty.erase_line() + io.write("Task 3: Running... ") + io.flush() + tty.cursor_restore() + os.sleep(500) + + tty.cursor_save() + tty.cursor_move_up(1) + tty.erase_line() + io.write("Task 3: Done ✓") + io.flush() + tty.cursor_restore() + + tty.cursor_show() +end + +function main() + print(string.rep("=", 60)) + print("TTY Cursor Control - Quick Examples") + print(string.rep("=", 60)) + + example1_simple_progress() + example2_update_previous_line() + example3_multi_line_update() + + print("\n" .. string.rep("=", 60)) + print("All examples completed!") + print("Check test.lua, cursor_control.lua, and live_dashboard.lua") + print("for more advanced examples.") + print(string.rep("=", 60)) +end + -- cgit v1.3.1 From 5b49833ed61286d6c75f0005c4e96092380946eb Mon Sep 17 00:00:00 2001 From: ruki Date: Mon, 27 Oct 2025 22:56:18 +0800 Subject: improve tty test --- tests/modules/tty/cursor_control.lua | 64 +++++++++++----------- tests/modules/tty/live_dashboard.lua | 76 ++++++++++++++------------ tests/modules/tty/quick_example.lua | 65 +++++++++++----------- tests/modules/tty/test.lua | 102 +++++++++++++++++------------------ 4 files changed, 152 insertions(+), 155 deletions(-) (limited to 'tests/modules/tty/quick_example.lua') diff --git a/tests/modules/tty/cursor_control.lua b/tests/modules/tty/cursor_control.lua index 2a28bed93..fb0f27886 100644 --- a/tests/modules/tty/cursor_control.lua +++ b/tests/modules/tty/cursor_control.lua @@ -25,41 +25,40 @@ function main() print("=== TTY Cursor Control Demo ===") print("This demo shows partial screen refresh using cursor positioning") - print("\n") + print("") -- Hide cursor for smoother display tty.cursor_hide() - print("Demo 1: Multiple Progress Bars (Parallel Updates)") + print("\nDemo 1: Multiple Progress Bars (Parallel Updates)") print("------------------------------------------------") -- Reserve lines for progress bars - print("Task 1: Downloading") - print("Task 2: Compiling ") - print("Task 3: Linking ") + io.write("Task 1: Downloading\n") + io.write("Task 2: Compiling \n") + io.write("Task 3: Linking \n") + io.flush() -- Simulate three parallel task progress bars for step = 1, 100 do - -- Task 1 progress - local progress1 = step / 100 - tty.cursor_save() + -- Move to Task 1 line (3 lines up from current position) tty.cursor_move_up(3) + + -- Update Task 1 progress + local progress1 = step / 100 _progress_bar_inline("Task 1: Downloading", progress1) - tty.cursor_restore() + io.write("\n") - -- Task 2 progress (starts later, progresses faster) + -- Update Task 2 progress (starts later, progresses faster) local progress2 = math.max(0, math.min(1.0, (step - 10) / 80)) - tty.cursor_save() - tty.cursor_move_up(2) _progress_bar_inline("Task 2: Compiling ", progress2) - tty.cursor_restore() + io.write("\n") - -- Task 3 progress (starts even later) + -- Update Task 3 progress (starts even later) local progress3 = math.max(0, math.min(1.0, (step - 30) / 60)) - tty.cursor_save() - tty.cursor_move_up(1) _progress_bar_inline("Task 3: Linking ", progress3) - tty.cursor_restore() + io.write("\n") + io.flush() os.sleep(30) -- 30ms delay end @@ -68,8 +67,9 @@ function main() print("--------------------------------") -- Print initial status and counter - print("Status: Waiting...") - print("Counter: 0") + io.write("Status: Waiting...\n") + io.write("Counter: 0\n") + io.flush() local statuses = { "Initializing...", @@ -82,23 +82,21 @@ function main() } for i, status in ipairs(statuses) do - -- Update status line - tty.cursor_save() + -- Move to status line (2 lines up) tty.cursor_move_up(2) + + -- Update status line tty.cr() tty.erase_line() io.write(string.format("Status: %s", status)) - io.flush() - tty.cursor_restore() + io.write("\n") -- Update counter line - tty.cursor_save() - tty.cursor_move_up(1) tty.cr() tty.erase_line() io.write(string.format("Counter: %d", i * 100)) + io.write("\n") io.flush() - tty.cursor_restore() os.sleep(500) end @@ -109,20 +107,22 @@ function main() print("\n\nDemo 3: Erase and Update Specific Line") print("----------------------------------------") - print("Line 1: This line will stay") - print("Line 2: This line will be updated...") - print("Line 3: This line will stay too") + io.write("Line 1: This line will stay\n") + io.write("Line 2: This line will be updated...\n") + io.write("Line 3: This line will stay too\n") + io.flush() os.sleep(1000) - -- Update only the middle line - tty.cursor_save() + -- Update only the middle line (2 lines up) tty.cursor_move_up(2) tty.cr() tty.erase_line() io.write("Line 2: Updated content! ✓") io.flush() - tty.cursor_restore() + + -- Move cursor to end + tty.cursor_move_down(2) print("\n\nAll demos completed!") print("\nKey features demonstrated:") print(" - cursor_move_up/down/left/right: Move cursor relatively") diff --git a/tests/modules/tty/live_dashboard.lua b/tests/modules/tty/live_dashboard.lua index fa239de87..c479d487c 100644 --- a/tests/modules/tty/live_dashboard.lua +++ b/tests/modules/tty/live_dashboard.lua @@ -17,81 +17,90 @@ function simulate_build_process() tty.cursor_hide() -- Print task list - print("⏸ Parse project files [" .. string.rep("░", 30) .. "] 0%") - print("⏸ Resolve dependencies [" .. string.rep("░", 30) .. "] 0%") - print("⏸ Compile sources [" .. string.rep("░", 30) .. "] 0%") - print("⏸ Link executable [" .. string.rep("░", 30) .. "] 0%") - print("⏸ Create package [" .. string.rep("░", 30) .. "] 0%") - print("\nRecent logs:") + io.write("⏸ Parse project files [" .. string.rep("░", 30) .. "] 0%\n") + io.write("⏸ Resolve dependencies [" .. string.rep("░", 30) .. "] 0%\n") + io.write("⏸ Compile sources [" .. string.rep("░", 30) .. "] 0%\n") + io.write("⏸ Link executable [" .. string.rep("░", 30) .. "] 0%\n") + io.write("⏸ Create package [" .. string.rep("░", 30) .. "] 0%\n") + io.write("\nRecent logs:\n") + io.flush() + + local log_count = 0 - local function update_task(row_offset, icon, name, progress) - tty.cursor_save() - tty.cursor_move_up(row_offset) + local function update_task_line(task_index, icon, name, progress) + -- Move to the task line (from current cursor position) + -- We need to go up: log_count lines + 1 separator line + (5 - task_index) task lines + local lines_up = log_count + 1 + (5 - task_index + 1) + tty.cursor_move_up(lines_up) + tty.cr() tty.erase_line() local bar_width = 30 local filled = math.floor(progress * bar_width) local bar = string.rep("█", filled) .. string.rep("░", bar_width - filled) - io.write(string.format("%s %-24s [%s] %3d%%", icon, name, bar, math.floor(progress * 100))) + io.write(string.format("%s %-24s [%s] %3d%%\n", icon, name, bar, math.floor(progress * 100))) + + -- Move back down + tty.cursor_move_down(lines_up - 1) io.flush() - tty.cursor_restore() end local function add_log(message) io.write(string.format("[%s] %s\n", os.date("%H:%M:%S"), message)) io.flush() + log_count = log_count + 1 end scheduler.co_start(function() - -- Task 1: Parse + -- Task 1: Parse (index 1, top task) add_log("Starting project parsing...") for i = 1, 20 do - update_task(7, "▶", "Parse project files", i / 20) + update_task_line(1, "▶", "Parse project files", i / 20) os.sleep(50) end - update_task(7, "✓", "Parse project files", 1.0) + update_task_line(1, "✓", "Parse project files", 1.0) add_log("Project parsed successfully") os.sleep(200) - -- Task 2: Dependencies + -- Task 2: Dependencies (index 2) add_log("Resolving dependencies...") for i = 1, 15 do - update_task(6, "▶", "Resolve dependencies", i / 15) + update_task_line(2, "▶", "Resolve dependencies", i / 15) os.sleep(80) end - update_task(6, "✓", "Resolve dependencies", 1.0) + update_task_line(2, "✓", "Resolve dependencies", 1.0) add_log("Dependencies resolved: 12 packages") os.sleep(200) - -- Task 3: Compile + -- Task 3: Compile (index 3) add_log("Compiling source files...") local source_files = {"main.cpp", "utils.cpp", "config.cpp", "parser.cpp", "builder.cpp"} for i = 1, #source_files do - update_task(5, "▶", "Compile sources", i / #source_files) + update_task_line(3, "▶", "Compile sources", i / #source_files) add_log("Compiling " .. source_files[i]) os.sleep(300) end - update_task(5, "✓", "Compile sources", 1.0) + update_task_line(3, "✓", "Compile sources", 1.0) add_log("Compilation completed: 5 files") os.sleep(200) - -- Task 4: Link + -- Task 4: Link (index 4) add_log("Linking executable...") for i = 1, 10 do - update_task(4, "▶", "Link executable", i / 10) + update_task_line(4, "▶", "Link executable", i / 10) os.sleep(100) end - update_task(4, "✓", "Link executable", 1.0) + update_task_line(4, "✓", "Link executable", 1.0) add_log("Executable created: build/myapp") os.sleep(200) - -- Task 5: Package + -- Task 5: Package (index 5, bottom task) add_log("Creating package...") for i = 1, 8 do - update_task(3, "▶", "Create package", i / 8) + update_task_line(5, "▶", "Create package", i / 8) os.sleep(120) end - update_task(3, "✓", "Create package", 1.0) + update_task_line(5, "✓", "Create package", 1.0) add_log("Package created: dist/myapp-1.0.0.tar.gz") -- Done @@ -112,32 +121,29 @@ function demo_spinner() end print("\n\n=== Spinner Demo ===") - print("Loading") + io.write("Loading\n") + io.flush() local frames = {"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"} tty.cursor_hide() for round = 1, 3 do for _, frame in ipairs(frames) do - tty.cursor_save() tty.cursor_move_up(1) + tty.cr() tty.erase_line() - io.write(string.format("Loading %s [round %d/3]", frame, round)) + io.write(string.format("Loading %s [round %d/3]\n", frame, round)) io.flush() - tty.cursor_restore() os.sleep(80) end end - tty.cursor_save() tty.cursor_move_up(1) + tty.cr() tty.erase_line() - io.write("Loading ✓ Complete!") + io.write("Loading ✓ Complete!\n") io.flush() - tty.cursor_restore() tty.cursor_show() - - print("") end function main() diff --git a/tests/modules/tty/quick_example.lua b/tests/modules/tty/quick_example.lua index 6b68394f7..794a79d58 100644 --- a/tests/modules/tty/quick_example.lua +++ b/tests/modules/tty/quick_example.lua @@ -35,25 +35,26 @@ function example2_update_previous_line() return end - print("Building project...") - print("Status: Starting...") + io.write("Building project...\n") + io.write("Status: Starting...\n") + io.flush() os.sleep(1000) -- Go back and update the status line tty.cursor_move_up(1) + tty.cr() tty.erase_line() - io.write("Status: Compiling files...") + io.write("Status: Compiling files...\n") io.flush() - print("") -- Move to next line os.sleep(1000) tty.cursor_move_up(1) + tty.cr() tty.erase_line() - io.write("Status: Done! ✓") + io.write("Status: Done! ✓\n") io.flush() - print("") end function example3_multi_line_update() @@ -65,59 +66,55 @@ function example3_multi_line_update() end -- Create a simple status board - print("Task 1: Waiting...") - print("Task 2: Waiting...") - print("Task 3: Waiting...") + io.write("Task 1: Waiting...\n") + io.write("Task 2: Waiting...\n") + io.write("Task 3: Waiting...\n") + io.flush() tty.cursor_hide() - -- Update Task 1 - tty.cursor_save() + -- Update Task 1 to Running tty.cursor_move_up(3) + tty.cr() tty.erase_line() - io.write("Task 1: Running... ") + io.write("Task 1: Running... \n") io.flush() - tty.cursor_restore() os.sleep(500) - tty.cursor_save() - tty.cursor_move_up(3) + -- Update Task 1 to Done + tty.cursor_move_up(1) + tty.cr() tty.erase_line() - io.write("Task 1: Done ✓") + io.write("Task 1: Done ✓\n") io.flush() - tty.cursor_restore() - -- Update Task 2 - tty.cursor_save() - tty.cursor_move_up(2) + -- Update Task 2 to Running + tty.cr() tty.erase_line() - io.write("Task 2: Running... ") + io.write("Task 2: Running... \n") io.flush() - tty.cursor_restore() os.sleep(500) - tty.cursor_save() - tty.cursor_move_up(2) + -- Update Task 2 to Done + tty.cursor_move_up(1) + tty.cr() tty.erase_line() - io.write("Task 2: Done ✓") + io.write("Task 2: Done ✓\n") io.flush() - tty.cursor_restore() - -- Update Task 3 - tty.cursor_save() - tty.cursor_move_up(1) + -- Update Task 3 to Running + tty.cr() tty.erase_line() - io.write("Task 3: Running... ") + io.write("Task 3: Running... \n") io.flush() - tty.cursor_restore() os.sleep(500) - tty.cursor_save() + -- Update Task 3 to Done tty.cursor_move_up(1) + tty.cr() tty.erase_line() - io.write("Task 3: Done ✓") + io.write("Task 3: Done ✓\n") io.flush() - tty.cursor_restore() tty.cursor_show() end diff --git a/tests/modules/tty/test.lua b/tests/modules/tty/test.lua index af72006ff..f236fcbeb 100644 --- a/tests/modules/tty/test.lua +++ b/tests/modules/tty/test.lua @@ -7,21 +7,24 @@ function test_cursor_move() end print("\n=== Test: cursor_move ===") - print("Line 1") - print("Line 2") - print("Line 3") - print("Line 4") - print("Line 5") + io.write("Line 1\n") + io.write("Line 2\n") + io.write("Line 3\n") + io.write("Line 4\n") + io.write("Line 5\n") + io.flush() os.sleep(1000) -- Move to line 3 and update content - tty.cursor_save() tty.cursor_move_up(3) + tty.cr() tty.erase_line() - io.write("Line 3 - UPDATED!") + io.write("Line 3 - UPDATED!\n") io.flush() - tty.cursor_restore() + + -- Move cursor back to end + tty.cursor_move_down(2) print("\n✓ cursor_move_up test passed") end @@ -35,10 +38,9 @@ function test_cursor_move_directions() -- Create a small coordinate system for i = 1, 5 do - print(string.rep(" ", 60)) + io.write(string.rep(" ", 60) .. "\n") end - - tty.cursor_save() + io.flush() -- Move to starting position tty.cursor_move_up(5) @@ -70,9 +72,12 @@ function test_cursor_move_directions() io.write("UP") io.flush() - tty.cursor_restore() + -- Move to end + tty.cursor_move_down(3) + io.write("\n") + io.flush() - print("\n✓ cursor movement directions test passed") + print("✓ cursor movement directions test passed") end function test_cursor_hide_show() @@ -102,27 +107,25 @@ function test_erase_operations() print("\n=== Test: erase operations ===") - -- 测试 erase_line_to_end + -- Test erase_line_to_end io.write("This is a long line that will be partially erased") io.flush() os.sleep(1000) tty.cursor_move_left(30) tty.erase_line_to_end() - io.write("<- erased to end") + io.write("<- erased to end\n") io.flush() - print("") os.sleep(1000) - -- 测试整行擦除 + -- Test full line erase io.write("This entire line will be erased") io.flush() os.sleep(1000) tty.cr() tty.erase_line() - io.write("Replaced!") + io.write("Replaced!\n") io.flush() - print("") print("✓ erase operations test passed") end @@ -134,78 +137,69 @@ function test_partial_screen_update() print("\n=== Test: partial screen update ===") - -- 创建一个表格 - print("┌────────────────────────────────┐") - print("│ Task │ Status │") - print("├────────────────────────────────┤") - print("│ Compile │ Pending... │") - print("│ Link │ Pending... │") - print("│ Package │ Pending... │") - print("└────────────────────────────────┘") + -- Create a table + io.write("┌────────────────────────────────┐\n") + io.write("│ Task │ Status │\n") + io.write("├────────────────────────────────┤\n") + io.write("│ Compile │ Pending... │\n") + io.write("│ Link │ Pending... │\n") + io.write("│ Package │ Pending... │\n") + io.write("└────────────────────────────────┘\n") + io.flush() os.sleep(1000) + tty.cursor_hide() - -- 更新第一个任务状态 - tty.cursor_save() + -- Update first task status tty.cursor_move_up(4) tty.cursor_move_to_col(32) tty.erase_line_to_end() - io.write("│ Running... │") + io.write("│ Running... │\n") io.flush() - tty.cursor_restore() os.sleep(800) - tty.cursor_save() - tty.cursor_move_up(4) + tty.cursor_move_up(1) tty.cursor_move_to_col(32) tty.erase_line_to_end() - io.write("│ Done! ✓ │") + io.write("│ Done! ✓ │\n") io.flush() - tty.cursor_restore() os.sleep(500) - -- 更新第二个任务状态 - tty.cursor_save() - tty.cursor_move_up(3) + -- Update second task status tty.cursor_move_to_col(32) tty.erase_line_to_end() - io.write("│ Running... │") + io.write("│ Running... │\n") io.flush() - tty.cursor_restore() os.sleep(800) - tty.cursor_save() - tty.cursor_move_up(3) + tty.cursor_move_up(1) tty.cursor_move_to_col(32) tty.erase_line_to_end() - io.write("│ Done! ✓ │") + io.write("│ Done! ✓ │\n") io.flush() - tty.cursor_restore() os.sleep(500) - -- 更新第三个任务状态 - tty.cursor_save() - tty.cursor_move_up(2) + -- Update third task status tty.cursor_move_to_col(32) tty.erase_line_to_end() - io.write("│ Running... │") + io.write("│ Running... │\n") io.flush() - tty.cursor_restore() os.sleep(800) - tty.cursor_save() - tty.cursor_move_up(2) + tty.cursor_move_up(1) tty.cursor_move_to_col(32) tty.erase_line_to_end() - io.write("│ Done! ✓ │") + io.write("│ Done! ✓ │\n") io.flush() - tty.cursor_restore() + + tty.cursor_show() + tty.cursor_move_down(1) print("\n✓ partial screen update test passed") end function main(...) - -- 运行所有测试 + -- Run all tests test_cursor_move() test_cursor_move_directions() test_cursor_hide_show() -- cgit v1.3.1