|
1 |
| -//go:build !windows |
2 |
| -// +build !windows |
3 |
| - |
4 |
| -// Package term provides structures and helper functions to work with |
5 |
| -// terminal (state, sizes). |
6 | 1 | package term
|
7 | 2 |
|
8 |
| -import ( |
9 |
| - "errors" |
10 |
| - "io" |
11 |
| - "os" |
12 |
| - |
13 |
| - "golang.org/x/sys/unix" |
14 |
| -) |
| 3 | +import "io" |
15 | 4 |
|
16 |
| -// ErrInvalidState is returned if the state of the terminal is invalid. |
17 |
| -// |
18 |
| -// Deprecated: ErrInvalidState is no longer used. |
19 |
| -var ErrInvalidState = errors.New("Invalid terminal state") |
20 |
| - |
21 |
| -// State represents the state of the terminal. |
22 |
| -type State struct { |
23 |
| - termios unix.Termios |
24 |
| -} |
| 5 | +// State holds the platform-specific state / console mode for the terminal. |
| 6 | +type State terminalState |
25 | 7 |
|
26 | 8 | // Winsize represents the size of the terminal window.
|
27 | 9 | type Winsize struct {
|
28 | 10 | Height uint16
|
29 | 11 | Width uint16
|
30 |
| - x uint16 |
31 |
| - y uint16 |
| 12 | + |
| 13 | + // Only used on Unix |
| 14 | + x uint16 |
| 15 | + y uint16 |
32 | 16 | }
|
33 | 17 |
|
34 | 18 | // StdStreams returns the standard streams (stdin, stdout, stderr).
|
| 19 | +// |
| 20 | +// On Windows, it attempts to turn on VT handling on all std handles if |
| 21 | +// supported, or falls back to terminal emulation. On Unix, this returns |
| 22 | +// the standard [os.Stdin], [os.Stdout] and [os.Stderr]. |
35 | 23 | func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
|
36 |
| - return os.Stdin, os.Stdout, os.Stderr |
| 24 | + return stdStreams() |
37 | 25 | }
|
38 | 26 |
|
39 | 27 | // GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal.
|
40 |
| -func GetFdInfo(in interface{}) (uintptr, bool) { |
41 |
| - var inFd uintptr |
42 |
| - var isTerminalIn bool |
43 |
| - if file, ok := in.(*os.File); ok { |
44 |
| - inFd = file.Fd() |
45 |
| - isTerminalIn = IsTerminal(inFd) |
46 |
| - } |
47 |
| - return inFd, isTerminalIn |
| 28 | +func GetFdInfo(in interface{}) (fd uintptr, isTerminal bool) { |
| 29 | + return getFdInfo(in) |
| 30 | +} |
| 31 | + |
| 32 | +// GetWinsize returns the window size based on the specified file descriptor. |
| 33 | +func GetWinsize(fd uintptr) (*Winsize, error) { |
| 34 | + return getWinsize(fd) |
| 35 | +} |
| 36 | + |
| 37 | +// SetWinsize tries to set the specified window size for the specified file |
| 38 | +// descriptor. It is only implemented on Unix, and returns an error on Windows. |
| 39 | +func SetWinsize(fd uintptr, ws *Winsize) error { |
| 40 | + return setWinsize(fd, ws) |
48 | 41 | }
|
49 | 42 |
|
50 | 43 | // IsTerminal returns true if the given file descriptor is a terminal.
|
51 | 44 | func IsTerminal(fd uintptr) bool {
|
52 |
| - _, err := tcget(fd) |
53 |
| - return err == nil |
| 45 | + return isTerminal(fd) |
54 | 46 | }
|
55 | 47 |
|
56 | 48 | // RestoreTerminal restores the terminal connected to the given file descriptor
|
57 | 49 | // to a previous state.
|
58 | 50 | func RestoreTerminal(fd uintptr, state *State) error {
|
59 |
| - if state == nil { |
60 |
| - return errors.New("invalid terminal state") |
61 |
| - } |
62 |
| - return tcset(fd, &state.termios) |
| 51 | + return restoreTerminal(fd, state) |
63 | 52 | }
|
64 | 53 |
|
65 | 54 | // SaveState saves the state of the terminal connected to the given file descriptor.
|
66 | 55 | func SaveState(fd uintptr) (*State, error) {
|
67 |
| - termios, err := tcget(fd) |
68 |
| - if err != nil { |
69 |
| - return nil, err |
70 |
| - } |
71 |
| - return &State{termios: *termios}, nil |
| 56 | + return saveState(fd) |
72 | 57 | }
|
73 | 58 |
|
74 | 59 | // DisableEcho applies the specified state to the terminal connected to the file
|
75 | 60 | // descriptor, with echo disabled.
|
76 | 61 | func DisableEcho(fd uintptr, state *State) error {
|
77 |
| - newState := state.termios |
78 |
| - newState.Lflag &^= unix.ECHO |
79 |
| - |
80 |
| - if err := tcset(fd, &newState); err != nil { |
81 |
| - return err |
82 |
| - } |
83 |
| - return nil |
| 62 | + return disableEcho(fd, state) |
84 | 63 | }
|
85 | 64 |
|
86 | 65 | // SetRawTerminal puts the terminal connected to the given file descriptor into
|
87 |
| -// raw mode and returns the previous state. On UNIX, this puts both the input |
88 |
| -// and output into raw mode. On Windows, it only puts the input into raw mode. |
89 |
| -func SetRawTerminal(fd uintptr) (*State, error) { |
90 |
| - oldState, err := MakeRaw(fd) |
91 |
| - if err != nil { |
92 |
| - return nil, err |
93 |
| - } |
94 |
| - return oldState, err |
| 66 | +// raw mode and returns the previous state. On UNIX, this is the equivalent of |
| 67 | +// [MakeRaw], and puts both the input and output into raw mode. On Windows, it |
| 68 | +// only puts the input into raw mode. |
| 69 | +func SetRawTerminal(fd uintptr) (previousState *State, err error) { |
| 70 | + return setRawTerminal(fd) |
95 | 71 | }
|
96 | 72 |
|
97 | 73 | // SetRawTerminalOutput puts the output of terminal connected to the given file
|
98 | 74 | // descriptor into raw mode. On UNIX, this does nothing and returns nil for the
|
99 | 75 | // state. On Windows, it disables LF -> CRLF translation.
|
100 |
| -func SetRawTerminalOutput(fd uintptr) (*State, error) { |
101 |
| - return nil, nil |
| 76 | +func SetRawTerminalOutput(fd uintptr) (previousState *State, err error) { |
| 77 | + return setRawTerminalOutput(fd) |
| 78 | +} |
| 79 | + |
| 80 | +// MakeRaw puts the terminal (Windows Console) connected to the |
| 81 | +// given file descriptor into raw mode and returns the previous state of |
| 82 | +// the terminal so that it can be restored. |
| 83 | +func MakeRaw(fd uintptr) (previousState *State, err error) { |
| 84 | + return makeRaw(fd) |
102 | 85 | }
|
0 commit comments