From ad83c87454c84f4d2fc7b2a391a4cf621a3ea971 Mon Sep 17 00:00:00 2001 From: Patrick Devine Date: Tue, 14 Nov 2023 16:52:34 -0800 Subject: [PATCH] add back in the windows terminal file --- editor/term_windows.go | 67 +++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/editor/term_windows.go b/editor/term_windows.go index eb63f2239..3d1c80e19 100644 --- a/editor/term_windows.go +++ b/editor/term_windows.go @@ -1,43 +1,62 @@ -// +build windows -package editor +package readline import ( "syscall" "unsafe" ) -type State uint32 +const ( + enableLineInput = 2 + enableWindowInput = 8 + enableMouseInput = 16 + enableInsertMode = 32 + enableQuickEditMode = 64 + enableExtendedFlags = 128 + enableProcessedOutput = 1 + enableWrapAtEolOutput = 2 + enableAutoPosition = 256 // Cursor position is not affected by writing data to the console. + enableEchoInput = 4 // Characters are written to the console as they're read. + enableProcessedInput = 1 // Enables input processing (like recognizing Ctrl+C). +) var kernel32 = syscall.NewLazyDLL("kernel32.dll") var ( - procGetConsoleMode = kernel32.NewProc("GetConsoleMode") - procSetConsoleMode = kernel32.NewProc("SetConsoleMode") - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") + procGetConsoleMode = kernel32.NewProc("GetConsoleMode") + procSetConsoleMode = kernel32.NewProc("SetConsoleMode") ) -// IsTerminal returns true if the given file descriptor is a terminal. +type State struct { + mode uint32 +} + +// IsTerminal checks if the given file descriptor is associated with a terminal func IsTerminal(fd int) bool { - var st uint32 - r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) - return r != 0 && e == 0 + var st uint32 + r, _, e := syscall.SyscallN(procGetConsoleMode.Addr(), uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) + // if the call succeeds and doesn't produce an error, it's a terminal + return r != 0 && e == 0 } -func SetRawMode(fd int) (State, err) { - var state State - _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&state)), 0) - if e != 0 { - return 0, error(e) - } - raw := state &^ (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput) - _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(raw), 0) - if e != 0 { - return nil, error(e) - } - return state, nil +func SetRawMode(fd int) (*State, error) { + var st uint32 + // retrieve the current mode of the terminal + _, _, e := syscall.SyscallN(procGetConsoleMode.Addr(), uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) + if e != 0 { + return nil, error(e) + } + // modify the mode to set it to raw + raw := st &^ (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput) + // apply the new mode to the terminal + _, _, e = syscall.SyscallN(procSetConsoleMode.Addr(), uintptr(fd), uintptr(raw), 0) + if e != 0 { + return nil, error(e) + } + // return the original state so that it can be restored later + return &State{st}, nil } -func UnsetRawMode(fd int, state State) error { - _, _, err := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(state.mode), 0) +func UnsetRawMode(fd int, state *State) error { + _, _, err := syscall.SyscallN(procSetConsoleMode.Addr(), uintptr(fd), uintptr(state.mode), 0) return err }