diff --git a/src/tui.zig b/src/tui.zig index 5b2c93f..11aa0af 100644 --- a/src/tui.zig +++ b/src/tui.zig @@ -477,13 +477,17 @@ pub const App = struct { } } + /// Handles keypresses in symbol_input mode (activated by `/`). + /// Mini text input for typing a ticker symbol (e.g. AAPL, BRK.B, ^GSPC). fn handleInputKey(self: *App, ctx: *vaxis.vxfw.EventContext, key: vaxis.Key) void { + // Cancel input, return to normal mode if (key.codepoint == vaxis.Key.escape) { self.mode = .normal; self.input_len = 0; self.setStatus("Cancelled"); return ctx.consumeAndRedraw(); } + // Commit: uppercase the input, set as active symbol, switch to quote tab if (key.codepoint == vaxis.Key.enter) { if (self.input_len > 0) { for (self.input_buf[0..self.input_len]) |*ch| ch.* = std.ascii.toUpper(ch.*); @@ -499,17 +503,19 @@ pub const App = struct { self.input_len = 0; return ctx.consumeAndRedraw(); } + // Delete last character if (key.codepoint == vaxis.Key.backspace) { if (self.input_len > 0) self.input_len -= 1; return ctx.consumeAndRedraw(); } + // Ctrl+U: clear entire input (readline convention) if (key.matches('u', .{ .ctrl = true })) { self.input_len = 0; return ctx.consumeAndRedraw(); } - if (key.codepoint >= 0x20 and key.codepoint < 0x7f and self.input_len < self.input_buf.len) { - const c: u8 = @intCast(key.codepoint); - self.input_buf[self.input_len] = std.ascii.toUpper(c); + // Accept printable ASCII (letters, digits, dots, hyphens, carets for tickers) + if (key.codepoint < std.math.maxInt(u7) and std.ascii.isPrint(@intCast(key.codepoint)) and self.input_len < self.input_buf.len) { + self.input_buf[self.input_len] = @intCast(key.codepoint); self.input_len += 1; return ctx.consumeAndRedraw(); }