term_windows.go 1.07 KB
Newer Older
mashun1's avatar
v1  
mashun1 committed
1
2
3
4
5
6
7
8
9
10
11
package readline

import (
	"golang.org/x/sys/windows"
)

type State struct {
	mode uint32
}

// IsTerminal checks if the given file descriptor is associated with a terminal
xuxzh1's avatar
init  
xuxzh1 committed
12
func IsTerminal(fd uintptr) bool {
mashun1's avatar
v1  
mashun1 committed
13
14
15
16
17
	var st uint32
	err := windows.GetConsoleMode(windows.Handle(fd), &st)
	return err == nil
}

xuxzh1's avatar
init  
xuxzh1 committed
18
func SetRawMode(fd uintptr) (*State, error) {
mashun1's avatar
v1  
mashun1 committed
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
	var st uint32
	if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
		return nil, err
	}

	// this enables raw mode by turning off various flags in the console mode: https://pkg.go.dev/golang.org/x/sys/windows#pkg-constants
	raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)

	// turn on ENABLE_VIRTUAL_TERMINAL_INPUT to enable escape sequences
	raw |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT
	if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil {
		return nil, err
	}
	return &State{st}, nil
}

xuxzh1's avatar
init  
xuxzh1 committed
35
func UnsetRawMode(fd uintptr, state any) error {
mashun1's avatar
v1  
mashun1 committed
36
37
38
	s := state.(*State)
	return windows.SetConsoleMode(windows.Handle(fd), s.mode)
}