Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Golangにおける端末制御 リッチなターミナルUIの実現方法

4,118 views

Published on

CA.go 第2回「Golangにおける端末制御 リッチなターミナルUIの実現方法」発表資料
#ca_go #golang

Published in: Engineering
  • Be the first to comment

Golangにおける端末制御 リッチなターミナルUIの実現方法

  1. 1. CA.go #2 Golang UI AbemaTV Masashi SHIBATA c-bata c_bata_! "
  2. 2. https://github.com/c-bata/go-prompt python-prompt-toolkit Go
  3. 3. Topic 1 termios canonical mode / non-canonical mode raw mode / cbreak mode termios structure KEYWORDS
  4. 4. Ctrl-C Enter https://github.com/c-bata/go-prompt/blob/master/_tools/vt100_debug.go
  5. 5. Non-Cannonical Mode ( )
  6. 6. https://golang.org/pkg/syscall/#Termios type Termios struct { Iflag uint32 Oflag uint32 Cflag uint32 Lflag uint32 Line uint8 Cc [32]uint8 Pad_cgo_0 [3]byte Ispeed uint32 Ospeed uint32 } termios tcgetattr / tcsetattr
  7. 7. https://golang.org/pkg/syscall/#Termios type Termios struct { Iflag uint32 Oflag uint32 Cflag uint32 Lflag uint32 Line uint8 Cc [32]uint8 Pad_cgo_0 [3]byte Ispeed uint32 Ospeed uint32 } termios tcgetattr / tcsetattr ICANON(2bit )
  8. 8. https://golang.org/pkg/syscall/#Termios type Termios struct { Iflag uint32 Oflag uint32 Cflag uint32 Lflag uint32 Line uint8 Cc [32]uint8 Pad_cgo_0 [3]byte Ispeed uint32 Ospeed uint32 } termios tcgetattr / tcsetattr VMIN / VTIME
  9. 9. raw raw mode VMIN=1 / VTIME=0
  10. 10. github.com/pkg/term // Cfmakeraw modifies attr for raw mode. func Cfmakeraw(attr *syscall.Termios) { attr.Iflag &^= syscall.BRKINT | syscall.ICRNL | syscall.INPCK | syscall.ISTRIP | syscall.IXON attr.Oflag &^= syscall.OPOST attr.Cflag &^= syscall.CSIZE | syscall.PARENB attr.Cflag |= syscall.CS8 attr.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.IEXTEN | syscall.ISIG attr.Cc[syscall.VMIN] = 1 attr.Cc[syscall.VTIME] = 0 } https://github.com/pkg/term/blob/master/termios/termios.go
  11. 11. https://github.com/c-bata/go-prompt/blob/master/vt100_input.go Byte var asciiSequences []*ASCIICode = []*ASCIICode{ {Key: Escape, ASCIICode: []byte{0x1b}}, {Key: ControlSpace, ASCIICode: []byte{0x00}}, {Key: ControlA, ASCIICode: []byte{0x1}}, {Key: ControlB, ASCIICode: []byte{0x2}}, {Key: ControlC, ASCIICode: []byte{0x3}}, {Key: ControlD, ASCIICode: []byte{0x4}}, {Key: ControlE, ASCIICode: []byte{0x5}}, {Key: ControlF, ASCIICode: []byte{0x6}}, {Key: ControlG, ASCIICode: []byte{0x7}}, {Key: ControlH, ASCIICode: []byte{0x8}}, : }
  12. 12. https://github.com/c-bata/go-prompt/blob/master/_tools/vt100_debug.go 🎉 KeyBinding ) ab←c acb
  13. 13. Topic 2 VT100 digital terminal device Escape sequences KEYWORDS
  14. 14. UI
  15. 15. https://ja.wikipedia.org/wiki/VT100https://ja.wikipedia.org/wiki/ASR-33
  16. 16. https://ja.wikipedia.org/wiki/VT100https://ja.wikipedia.org/wiki/ASR-33 1960-1970
  17. 17. https://ja.wikipedia.org/wiki/VT100https://ja.wikipedia.org/wiki/ASR-33 ( ) →
  18. 18. VT100 Escape Sequences VT100 ANSI
  19. 19. VT100 syscall.Write(syscall.Stdin, []byte("x1b[4;30;46m")) syscall.Write(syscall.Stdin, []byte("Hello Worldn")) syscall.Write(syscall.Stdin, []byte("x1b[0m")) http://vt100.net/docs/vt100-ug/chapter3.html
  20. 20. VT100 syscall.Write(syscall.Stdin, []byte("x1b[4;30;46m")) syscall.Write(syscall.Stdin, []byte("Hello Worldn")) syscall.Write(syscall.Stdin, []byte("x1b[0m")) http://vt100.net/docs/vt100-ug/chapter3.html x1b[ 4;30;46 m Control Sequence Introducer (CSI)
  21. 21. VT100 syscall.Write(syscall.Stdin, []byte("x1b[4;30;46m")) syscall.Write(syscall.Stdin, []byte("Hello Worldn")) syscall.Write(syscall.Stdin, []byte("x1b[0m")) http://vt100.net/docs/vt100-ug/chapter3.html x1b[ 4;30;46 m : :
  22. 22. VT100 syscall.Write(syscall.Stdin, []byte("x1b[4;30;46m")) syscall.Write(syscall.Stdin, []byte("Hello Worldn")) syscall.Write(syscall.Stdin, []byte("x1b[0m")) http://vt100.net/docs/vt100-ug/chapter3.html x1b[ 4;30;46 m Final Character
  23. 23. Topic 3 ioctl system call and TIOCGWINSZ SIGWINCH KEYWORDS
  24. 24. kube-prompt
  25. 25. Window https://github.com/c-bata/go-prompt/blob/master/_tools/window_size.go func GetWinSize(fd int) (row, col uint16, err error) { var ws *winsize retCode, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(syscall.Stdin), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(ws))) if int(retCode) == -1 { return 0, 0, fmt.Errorf(“failed with %d”, retCode) } return ws.Row, ws.Col, nil } ioctl TIOCGWINSZ SIGWINCH
  26. 26. Window https://github.com/c-bata/go-prompt/blob/master/_tools/window_size.go

×