Skip to content

Commit 9c3c875

Browse files
authored
Merge pull request #41 from thaJeztah/split_implementations
split exported functions from implementation
2 parents 4793886 + bb04910 commit 9c3c875

File tree

8 files changed

+206
-180
lines changed

8 files changed

+206
-180
lines changed

Diff for: doc.go

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Package term provides structures and helper functions to work with
2+
// terminal (state, sizes).
3+
package term

Diff for: tc.go

-20
This file was deleted.

Diff for: term.go

+43-60
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,85 @@
1-
//go:build !windows
2-
// +build !windows
3-
4-
// Package term provides structures and helper functions to work with
5-
// terminal (state, sizes).
61
package term
72

8-
import (
9-
"errors"
10-
"io"
11-
"os"
12-
13-
"golang.org/x/sys/unix"
14-
)
3+
import "io"
154

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
257

268
// Winsize represents the size of the terminal window.
279
type Winsize struct {
2810
Height uint16
2911
Width uint16
30-
x uint16
31-
y uint16
12+
13+
// Only used on Unix
14+
x uint16
15+
y uint16
3216
}
3317

3418
// 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].
3523
func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
36-
return os.Stdin, os.Stdout, os.Stderr
24+
return stdStreams()
3725
}
3826

3927
// 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)
4841
}
4942

5043
// IsTerminal returns true if the given file descriptor is a terminal.
5144
func IsTerminal(fd uintptr) bool {
52-
_, err := tcget(fd)
53-
return err == nil
45+
return isTerminal(fd)
5446
}
5547

5648
// RestoreTerminal restores the terminal connected to the given file descriptor
5749
// to a previous state.
5850
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)
6352
}
6453

6554
// SaveState saves the state of the terminal connected to the given file descriptor.
6655
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)
7257
}
7358

7459
// DisableEcho applies the specified state to the terminal connected to the file
7560
// descriptor, with echo disabled.
7661
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)
8463
}
8564

8665
// 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)
9571
}
9672

9773
// SetRawTerminalOutput puts the output of terminal connected to the given file
9874
// descriptor into raw mode. On UNIX, this does nothing and returns nil for the
9975
// 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)
10285
}

Diff for: term_unix.go

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//go:build !windows
2+
// +build !windows
3+
4+
package term
5+
6+
import (
7+
"errors"
8+
"io"
9+
"os"
10+
11+
"golang.org/x/sys/unix"
12+
)
13+
14+
// ErrInvalidState is returned if the state of the terminal is invalid.
15+
//
16+
// Deprecated: ErrInvalidState is no longer used.
17+
var ErrInvalidState = errors.New("Invalid terminal state")
18+
19+
// terminalState holds the platform-specific state / console mode for the terminal.
20+
type terminalState struct {
21+
termios unix.Termios
22+
}
23+
24+
func stdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
25+
return os.Stdin, os.Stdout, os.Stderr
26+
}
27+
28+
func getFdInfo(in interface{}) (uintptr, bool) {
29+
var inFd uintptr
30+
var isTerminalIn bool
31+
if file, ok := in.(*os.File); ok {
32+
inFd = file.Fd()
33+
isTerminalIn = isTerminal(inFd)
34+
}
35+
return inFd, isTerminalIn
36+
}
37+
38+
func getWinsize(fd uintptr) (*Winsize, error) {
39+
uws, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ)
40+
ws := &Winsize{Height: uws.Row, Width: uws.Col, x: uws.Xpixel, y: uws.Ypixel}
41+
return ws, err
42+
}
43+
44+
func setWinsize(fd uintptr, ws *Winsize) error {
45+
return unix.IoctlSetWinsize(int(fd), unix.TIOCSWINSZ, &unix.Winsize{
46+
Row: ws.Height,
47+
Col: ws.Width,
48+
Xpixel: ws.x,
49+
Ypixel: ws.y,
50+
})
51+
}
52+
53+
func isTerminal(fd uintptr) bool {
54+
_, err := tcget(fd)
55+
return err == nil
56+
}
57+
58+
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)
63+
}
64+
65+
func saveState(fd uintptr) (*State, error) {
66+
termios, err := tcget(fd)
67+
if err != nil {
68+
return nil, err
69+
}
70+
return &State{termios: *termios}, nil
71+
}
72+
73+
func disableEcho(fd uintptr, state *State) error {
74+
newState := state.termios
75+
newState.Lflag &^= unix.ECHO
76+
77+
return tcset(fd, &newState)
78+
}
79+
80+
func setRawTerminal(fd uintptr) (*State, error) {
81+
return makeRaw(fd)
82+
}
83+
84+
func setRawTerminalOutput(fd uintptr) (*State, error) {
85+
return nil, nil
86+
}
87+
88+
func tcget(fd uintptr) (*unix.Termios, error) {
89+
p, err := unix.IoctlGetTermios(int(fd), getTermios)
90+
if err != nil {
91+
return nil, err
92+
}
93+
return p, nil
94+
}
95+
96+
func tcset(fd uintptr, p *unix.Termios) error {
97+
return unix.IoctlSetTermios(int(fd), setTermios, p)
98+
}

0 commit comments

Comments
 (0)