diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-12 20:14:47 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-12 20:14:47 +0200 |
| commit | 3f8679be9373ee7508d512dfdfc1dda0839c7f90 (patch) | |
| tree | ec02eb075f6c4e90f21baa2fe674e86a2f7f6a62 /internal/tui/keys.go | |
| parent | 24a84671ace373ae331fa83a1ff484990f4dff0e (diff) | |
| download | krino-3f8679be9373ee7508d512dfdfc1dda0839c7f90.tar.gz krino-3f8679be9373ee7508d512dfdfc1dda0839c7f90.zip | |
krino: acting — trash, journal, apply, lock, review, undo
Diffstat (limited to 'internal/tui/keys.go')
| -rw-r--r-- | internal/tui/keys.go | 37 |
1 files changed, 37 insertions, 0 deletions
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 +} |
