This commit is contained in:
Michael Yang 2024-05-22 09:00:38 -07:00
parent 201d853fdf
commit f38353d6b9
7 changed files with 20 additions and 21 deletions

View file

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"syscall"
) )
type Prompt struct { type Prompt struct {
@ -63,7 +62,7 @@ func New(prompt Prompt) (*Instance, error) {
func (i *Instance) Readline() (string, error) { func (i *Instance) Readline() (string, error) {
if !i.Terminal.rawmode { if !i.Terminal.rawmode {
fd := syscall.Stdin fd := os.Stdin.Fd()
termios, err := SetRawMode(fd) termios, err := SetRawMode(fd)
if err != nil { if err != nil {
return "", err return "", err
@ -80,7 +79,7 @@ func (i *Instance) Readline() (string, error) {
fmt.Print(prompt) fmt.Print(prompt)
defer func() { defer func() {
fd := syscall.Stdin fd := os.Stdin.Fd()
//nolint:errcheck //nolint:errcheck
UnsetRawMode(fd, i.Terminal.termios) UnsetRawMode(fd, i.Terminal.termios)
i.Terminal.rawmode = false i.Terminal.rawmode = false
@ -216,7 +215,7 @@ func (i *Instance) Readline() (string, error) {
case CharCtrlW: case CharCtrlW:
buf.DeleteWord() buf.DeleteWord()
case CharCtrlZ: case CharCtrlZ:
fd := syscall.Stdin fd := os.Stdin.Fd()
return handleCharCtrlZ(fd, i.Terminal.termios) return handleCharCtrlZ(fd, i.Terminal.termios)
case CharEnter, CharCtrlJ: case CharEnter, CharCtrlJ:
output := buf.String() output := buf.String()
@ -248,7 +247,7 @@ func (i *Instance) HistoryDisable() {
} }
func NewTerminal() (*Terminal, error) { func NewTerminal() (*Terminal, error) {
fd := syscall.Stdin fd := os.Stdin.Fd()
termios, err := SetRawMode(fd) termios, err := SetRawMode(fd)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -6,7 +6,7 @@ import (
"syscall" "syscall"
) )
func handleCharCtrlZ(fd int, termios any) (string, error) { func handleCharCtrlZ(fd uintptr, termios any) (string, error) {
t := termios.(*Termios) t := termios.(*Termios)
if err := UnsetRawMode(fd, t); err != nil { if err := UnsetRawMode(fd, t); err != nil {
return "", err return "", err

View file

@ -1,6 +1,6 @@
package readline package readline
func handleCharCtrlZ(fd int, state any) (string, error) { func handleCharCtrlZ(fd uintptr, state any) (string, error) {
// not supported // not supported
return "", nil return "", nil
} }

View file

@ -8,7 +8,7 @@ import (
type Termios syscall.Termios type Termios syscall.Termios
func SetRawMode(fd int) (*Termios, error) { func SetRawMode(fd uintptr) (*Termios, error) {
termios, err := getTermios(fd) termios, err := getTermios(fd)
if err != nil { if err != nil {
return nil, err return nil, err
@ -25,13 +25,13 @@ func SetRawMode(fd int) (*Termios, error) {
return termios, setTermios(fd, &newTermios) return termios, setTermios(fd, &newTermios)
} }
func UnsetRawMode(fd int, termios any) error { func UnsetRawMode(fd uintptr, termios any) error {
t := termios.(*Termios) t := termios.(*Termios)
return setTermios(fd, t) return setTermios(fd, t)
} }
// IsTerminal returns true if the given file descriptor is a terminal. // IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool { func IsTerminal(fd uintptr) bool {
_, err := getTermios(fd) _, err := getTermios(fd)
return err == nil return err == nil
} }

View file

@ -7,17 +7,17 @@ import (
"unsafe" "unsafe"
) )
func getTermios(fd int) (*Termios, error) { func getTermios(fd uintptr) (*Termios, error) {
termios := new(Termios) termios := new(Termios)
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TIOCGETA, uintptr(unsafe.Pointer(termios)), 0, 0, 0) _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, syscall.TIOCGETA, uintptr(unsafe.Pointer(termios)), 0, 0, 0)
if err != 0 { if err != 0 {
return nil, err return nil, err
} }
return termios, nil return termios, nil
} }
func setTermios(fd int, termios *Termios) error { func setTermios(fd uintptr, termios *Termios) error {
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TIOCSETA, uintptr(unsafe.Pointer(termios)), 0, 0, 0) _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, syscall.TIOCSETA, uintptr(unsafe.Pointer(termios)), 0, 0, 0)
if err != 0 { if err != 0 {
return err return err
} }

View file

@ -10,17 +10,17 @@ import (
const tcgets = 0x5401 const tcgets = 0x5401
const tcsets = 0x5402 const tcsets = 0x5402
func getTermios(fd int) (*Termios, error) { func getTermios(fd uintptr) (*Termios, error) {
termios := new(Termios) termios := new(Termios)
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), tcgets, uintptr(unsafe.Pointer(termios)), 0, 0, 0) _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, tcgets, uintptr(unsafe.Pointer(termios)), 0, 0, 0)
if err != 0 { if err != 0 {
return nil, err return nil, err
} }
return termios, nil return termios, nil
} }
func setTermios(fd int, termios *Termios) error { func setTermios(fd uintptr, termios *Termios) error {
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), tcsets, uintptr(unsafe.Pointer(termios)), 0, 0, 0) _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, tcsets, uintptr(unsafe.Pointer(termios)), 0, 0, 0)
if err != 0 { if err != 0 {
return err return err
} }

View file

@ -9,13 +9,13 @@ type State struct {
} }
// IsTerminal checks if the given file descriptor is associated with a terminal // IsTerminal checks if the given file descriptor is associated with a terminal
func IsTerminal(fd int) bool { func IsTerminal(fd uintptr) bool {
var st uint32 var st uint32
err := windows.GetConsoleMode(windows.Handle(fd), &st) err := windows.GetConsoleMode(windows.Handle(fd), &st)
return err == nil return err == nil
} }
func SetRawMode(fd int) (*State, error) { func SetRawMode(fd uintptr) (*State, error) {
var st uint32 var st uint32
if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
return nil, err return nil, err
@ -32,7 +32,7 @@ func SetRawMode(fd int) (*State, error) {
return &State{st}, nil return &State{st}, nil
} }
func UnsetRawMode(fd int, state any) error { func UnsetRawMode(fd uintptr, state any) error {
s := state.(*State) s := state.(*State)
return windows.SetConsoleMode(windows.Handle(fd), s.mode) return windows.SetConsoleMode(windows.Handle(fd), s.mode)
} }