tty.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package tty
  2. import (
  3. "os"
  4. "strings"
  5. "unicode"
  6. )
  7. func Open() (*TTY, error) {
  8. return open()
  9. }
  10. func (tty *TTY) Raw() (func() error, error) {
  11. return tty.raw()
  12. }
  13. func (tty *TTY) MustRaw() func() error {
  14. f, err := tty.raw()
  15. if err != nil {
  16. panic(err.Error())
  17. }
  18. return f
  19. }
  20. func (tty *TTY) Buffered() bool {
  21. return tty.buffered()
  22. }
  23. func (tty *TTY) ReadRune() (rune, error) {
  24. return tty.readRune()
  25. }
  26. func (tty *TTY) Close() error {
  27. return tty.close()
  28. }
  29. func (tty *TTY) Size() (int, int, error) {
  30. return tty.size()
  31. }
  32. func (tty *TTY) Input() *os.File {
  33. return tty.input()
  34. }
  35. func (tty *TTY) Output() *os.File {
  36. return tty.output()
  37. }
  38. // Display types.
  39. const (
  40. displayNone = iota
  41. displayRune
  42. displayMask
  43. )
  44. func (tty *TTY) readString(displayType int) (string, error) {
  45. rs := []rune{}
  46. loop:
  47. for {
  48. r, err := tty.readRune()
  49. if err != nil {
  50. return "", err
  51. }
  52. switch r {
  53. case 13:
  54. break loop
  55. case 8, 127:
  56. if len(rs) > 0 {
  57. rs = rs[:len(rs)-1]
  58. if displayType != displayNone {
  59. tty.Output().WriteString("\b \b")
  60. }
  61. }
  62. default:
  63. if unicode.IsPrint(r) {
  64. rs = append(rs, r)
  65. switch displayType {
  66. case displayRune:
  67. tty.Output().WriteString(string(r))
  68. case displayMask:
  69. tty.Output().WriteString("*")
  70. }
  71. }
  72. }
  73. }
  74. return string(rs), nil
  75. }
  76. func (tty *TTY) ReadString() (string, error) {
  77. defer tty.Output().WriteString("\n")
  78. return tty.readString(displayRune)
  79. }
  80. func (tty *TTY) ReadPassword() (string, error) {
  81. defer tty.Output().WriteString("\n")
  82. return tty.readString(displayMask)
  83. }
  84. func (tty *TTY) ReadPasswordNoEcho() (string, error) {
  85. defer tty.Output().WriteString("\n")
  86. return tty.readString(displayNone)
  87. }
  88. func (tty *TTY) ReadPasswordClear() (string, error) {
  89. s, err := tty.readString(displayMask)
  90. tty.Output().WriteString(
  91. strings.Repeat("\b", len(s)) +
  92. strings.Repeat(" ", len(s)) +
  93. strings.Repeat("\b", len(s)))
  94. return s, err
  95. }
  96. type WINSIZE struct {
  97. W int
  98. H int
  99. }
  100. func (tty *TTY) SIGWINCH() chan WINSIZE {
  101. return tty.sigwinch()
  102. }