gitstack

grindlemire/go-tui code browser

1.7 KB Go 56 lines 2026-05-18 · 389d343 raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//go:build windows

package tui

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

// rawModeState stores the original console mode for restoration.
type rawModeState struct {
	fd   windows.Handle
	mode uint32
}

// enableRawMode puts the Windows console into raw-ish mode and returns the
// previous mode for restoration.
func enableRawMode(fd int) (*rawModeState, error) {
	h := windows.Handle(fd)

	var mode uint32
	if err := windows.GetConsoleMode(h, &mode); err != nil {
		return nil, err
	}

	raw := mode
	// Strip cooked-mode flags plus quick-edit (mouse-text-selection hijacks button
	// records) and VT input (we read INPUT_RECORDs directly, so we don't want the
	// console pre-translating keys into escape byte streams).
	raw &^= windows.ENABLE_ECHO_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_VIRTUAL_TERMINAL_INPUT | windows.ENABLE_QUICK_EDIT_MODE
	raw |= windows.ENABLE_EXTENDED_FLAGS | windows.ENABLE_WINDOW_INPUT | windows.ENABLE_MOUSE_INPUT

	if err := windows.SetConsoleMode(h, raw); err != nil {
		return nil, err
	}

	return &rawModeState{fd: h, mode: mode}, nil
}

// disableRawMode restores the console to its previous mode.
func disableRawMode(state *rawModeState) error {
	if state == nil {
		return nil
	}
	return windows.SetConsoleMode(state.fd, state.mode)
}

// getTerminalSize returns the terminal dimensions.
func getTerminalSize(fd int) (width, height int, err error) {
	h := windows.Handle(fd)
	var info windows.ConsoleScreenBufferInfo
	if err := windows.GetConsoleScreenBufferInfo(h, &info); err != nil {
		return 0, 0, err
	}

	width = int(info.Window.Right - info.Window.Left + 1)
	height = int(info.Window.Bottom - info.Window.Top + 1)
	return width, height, nil
}