forked from mirror/readline
add todo: support windows
This commit is contained in:
parent
593678baa5
commit
8dc3117d78
|
@ -19,6 +19,7 @@ You can read the source code in [example/main.go](https://github.com/chzyer/read
|
|||
|
||||
# Todo
|
||||
|
||||
* Add support for windows
|
||||
* Vim mode
|
||||
* More funny examples
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
|
@ -26,7 +25,7 @@ func NewTerminal(cfg *Config) (*Terminal, error) {
|
|||
if err := cfg.Init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
state, err := MakeRaw(syscall.Stdin)
|
||||
state, err := MakeRaw(StdinFd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -131,5 +130,5 @@ func (t *Terminal) Close() error {
|
|||
}
|
||||
t.stopChan <- struct{}{}
|
||||
t.wg.Wait()
|
||||
return Restore(syscall.Stdin, t.state)
|
||||
return Restore(StdinFd, t.state)
|
||||
}
|
||||
|
|
24
utils.go
24
utils.go
|
@ -1,9 +1,7 @@
|
|||
package readline
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unicode"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
|
@ -67,28 +65,6 @@ func escapeKey(r rune) rune {
|
|||
return r
|
||||
}
|
||||
|
||||
type winsize struct {
|
||||
Row uint16
|
||||
Col uint16
|
||||
Xpixel uint16
|
||||
Ypixel uint16
|
||||
}
|
||||
|
||||
// get width of the terminal
|
||||
// we can cache it here and refresh after received signal
|
||||
func getWidth() int {
|
||||
ws := &winsize{}
|
||||
retCode, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
|
||||
uintptr(syscall.Stdin),
|
||||
uintptr(syscall.TIOCGWINSZ),
|
||||
uintptr(unsafe.Pointer(ws)))
|
||||
|
||||
if int(retCode) == -1 {
|
||||
panic(errno)
|
||||
}
|
||||
return int(ws.Col)
|
||||
}
|
||||
|
||||
func RunesEqual(a, b []rune) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd
|
||||
|
||||
package readline
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
StdinFd = syscall.Stdin
|
||||
)
|
||||
|
||||
type winsize struct {
|
||||
Row uint16
|
||||
Col uint16
|
||||
Xpixel uint16
|
||||
Ypixel uint16
|
||||
}
|
||||
|
||||
// get width of the terminal
|
||||
func getWidth() int {
|
||||
ws := &winsize{}
|
||||
retCode, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
|
||||
uintptr(StdinFd),
|
||||
uintptr(syscall.TIOCGWINSZ),
|
||||
uintptr(unsafe.Pointer(ws)))
|
||||
|
||||
if int(retCode) == -1 {
|
||||
panic(errno)
|
||||
}
|
||||
return int(ws.Col)
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
// +build windows
|
||||
|
||||
package readline
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type (
|
||||
short int16
|
||||
word uint16
|
||||
|
||||
small_rect struct {
|
||||
left short
|
||||
top short
|
||||
right short
|
||||
bottom short
|
||||
}
|
||||
|
||||
coord struct {
|
||||
x short
|
||||
y short
|
||||
}
|
||||
|
||||
console_screen_buffer_info struct {
|
||||
size coord
|
||||
cursor_position coord
|
||||
attributes word
|
||||
window small_rect
|
||||
maximum_window_size coord
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
StdinFd = 0
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
tmp_info console_screen_buffer_info
|
||||
|
||||
proc_get_console_screen_buffer_info = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
||||
)
|
||||
|
||||
func get_console_screen_buffer_info(h syscall.Handle, info *console_screen_buffer_info) (err error) {
|
||||
r0, _, e1 := syscall.Syscall(proc_get_console_screen_buffer_info.Addr(),
|
||||
2, uintptr(h), uintptr(unsafe.Pointer(info)), 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func get_term_size(out syscall.Handle) coord {
|
||||
err := get_console_screen_buffer_info(out, &tmp_info)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return tmp_info.size
|
||||
}
|
||||
|
||||
// get width of the terminal
|
||||
func getWidth() int {
|
||||
return int(get_term_size(syscall.Stdin).x)
|
||||
}
|
Loading…
Reference in New Issue