From 3f8679be9373ee7508d512dfdfc1dda0839c7f90 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sat, 12 Sep 2026 20:14:47 +0200 Subject: krino: acting — trash, journal, apply, lock, review, undo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/tui/keys.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 internal/tui/keys.go (limited to 'internal/tui/keys.go') diff --git a/internal/tui/keys.go b/internal/tui/keys.go new file mode 100644 index 0000000..e88a326 --- /dev/null +++ b/internal/tui/keys.go @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package tui + +import ( + "fmt" + "os" + + "golang.org/x/term" +) + +// ReadKey reads one keypress without Enter, restoring the terminal before +// it returns - on every path, including an error. It always reads a +// single byte; only a terminal is first put into raw mode, so a +// non-terminal (a pipe, in tests) needs no pty to exercise it. +func ReadKey(in *os.File) (rune, error) { + fd := int(in.Fd()) + if !isTerminal(fd) { + return readByte(in) + } + + state, err := term.MakeRaw(fd) + if err != nil { + return 0, fmt.Errorf("tui: %w", err) + } + defer term.Restore(fd, state) + + return readByte(in) +} + +func readByte(in *os.File) (rune, error) { + var b [1]byte + if _, err := in.Read(b[:]); err != nil { + return 0, err + } + return rune(b[0]), nil +} -- cgit v1.3