add todo: support windows

This commit is contained in:
Cheney 2015-09-27 11:41:05 +08:00
parent 593678baa5
commit 8dc3117d78
5 changed files with 103 additions and 27 deletions

View File

@ -19,6 +19,7 @@ You can read the source code in [example/main.go](https://github.com/chzyer/read
# Todo # Todo
* Add support for windows
* Vim mode * Vim mode
* More funny examples * More funny examples

View File

@ -6,7 +6,6 @@ import (
"os" "os"
"sync" "sync"
"sync/atomic" "sync/atomic"
"syscall"
"golang.org/x/crypto/ssh/terminal" "golang.org/x/crypto/ssh/terminal"
) )
@ -26,7 +25,7 @@ func NewTerminal(cfg *Config) (*Terminal, error) {
if err := cfg.Init(); err != nil { if err := cfg.Init(); err != nil {
return nil, err return nil, err
} }
state, err := MakeRaw(syscall.Stdin) state, err := MakeRaw(StdinFd)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -131,5 +130,5 @@ func (t *Terminal) Close() error {
} }
t.stopChan <- struct{}{} t.stopChan <- struct{}{}
t.wg.Wait() t.wg.Wait()
return Restore(syscall.Stdin, t.state) return Restore(StdinFd, t.state)
} }

View File

@ -1,9 +1,7 @@
package readline package readline
import ( import (
"syscall"
"unicode" "unicode"
"unsafe"
"golang.org/x/crypto/ssh/terminal" "golang.org/x/crypto/ssh/terminal"
) )
@ -67,28 +65,6 @@ func escapeKey(r rune) rune {
return r 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 { func RunesEqual(a, b []rune) bool {
if len(a) != len(b) { if len(a) != len(b) {
return false return false

33
utils_unix.go Normal file
View File

@ -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)
}

67
utils_windows.go Normal file
View File

@ -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)
}