//! Syntax Highlighting Demo //! //! Run with: zig build syntax-demo const std = @import("std"); const zcatui = @import("zcatui"); const Terminal = zcatui.Terminal; const Rect = zcatui.Rect; const Buffer = zcatui.Buffer; const Style = zcatui.Style; const Color = zcatui.Color; const Block = zcatui.widgets.Block; const Borders = zcatui.widgets.Borders; const SyntaxHighlighter = zcatui.widgets.SyntaxHighlighter; const SyntaxLanguage = zcatui.widgets.SyntaxLanguage; const zig_code = \\const std = @import("std"); \\ \\pub fn main() !void { \\ const allocator = std.heap.page_allocator; \\ var list = std.ArrayList(u32).init(allocator); \\ defer list.deinit(); \\ \\ try list.append(42); \\ try list.append(100); \\ \\ for (list.items) |item| { \\ std.debug.print("{d}\n", .{item}); \\ } \\} ; const rust_code = \\use std::collections::HashMap; \\ \\fn main() { \\ let mut map = HashMap::new(); \\ map.insert("key", "value"); \\ \\ if let Some(val) = map.get("key") { \\ println!("Found: {}", val); \\ } \\ \\ // Iterate over map \\ for (k, v) in &map { \\ println!("{}: {}", k, v); \\ } \\} ; const python_code = \\import json \\from typing import List, Dict \\ \\def process_data(items: List[str]) -> Dict: \\ """Process a list of items.""" \\ result = {} \\ for i, item in enumerate(items): \\ result[f"item_{i}"] = item.upper() \\ return result \\ \\if __name__ == "__main__": \\ data = ["hello", "world"] \\ print(json.dumps(process_data(data))) ; const js_code = \\const express = require('express'); \\const app = express(); \\ \\// Middleware \\app.use(express.json()); \\ \\app.get('/api/users', async (req, res) => { \\ try { \\ const users = await fetchUsers(); \\ res.json({ success: true, data: users }); \\ } catch (err) { \\ res.status(500).json({ error: err.message }); \\ } \\}); \\ \\app.listen(3000, () => console.log('Server running')); ; const languages = [_]SyntaxLanguage{ .zig, .rust, .python, .javascript }; const lang_names = [_][]const u8{ "Zig", "Rust", "Python", "JavaScript" }; const codes = [_][]const u8{ zig_code, rust_code, python_code, js_code }; /// State for the demo const State = struct { selected: usize = 0, running: bool = true, }; pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); const allocator = gpa.allocator(); var term = try Terminal.init(allocator); defer term.deinit(); var state = State{}; while (state.running) { try term.drawWithContext(&state, render); if (try term.pollEvent(100)) |event| { switch (event) { .key => |key| { switch (key.code) { .char => |c| { if (c == 'q') state.running = false; if (c >= '1' and c <= '4') { state.selected = c - '1'; } }, .left => { if (state.selected > 0) state.selected -= 1; }, .right => { if (state.selected < languages.len - 1) state.selected += 1; }, .esc => state.running = false, else => {}, } }, else => {}, } } } } fn render(state: *State, area: Rect, buf: *Buffer) void { // Header with language tabs var x: u16 = 2; for (lang_names, 0..) |name, i| { const style = if (i == state.selected) (Style{}).fg(Color.black).bg(Color.cyan).bold() else (Style{}).fg(Color.white); _ = buf.setString(x, 0, " ", style); _ = buf.setString(x + 1, 0, name, style); _ = buf.setString(x + 1 + @as(u16, @intCast(name.len)), 0, " ", style); x += @as(u16, @intCast(name.len)) + 3; } // Code area const code_area = Rect.init(0, 2, area.width, area.height -| 4); const block = Block.init() .title(" Code ") .setBorders(Borders.all) .borderStyle((Style{}).fg(Color.rgb(80, 80, 80))); block.render(code_area, buf); const inner = Rect.init(1, 3, area.width -| 2, area.height -| 6); // Syntax highlighter const highlighter = SyntaxHighlighter.init(languages[state.selected]) .setLineNumbers(true); highlighter.render(codes[state.selected], 0, inner, buf); // Footer _ = buf.setString( 2, area.height -| 1, "Press 1-4 or left/right to change language, q to quit", (Style{}).fg(Color.rgb(100, 100, 100)), ); }