|
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