exec_context.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. package hhc_ast
  2. import (
  3. "bytes"
  4. "fmt"
  5. "git.swzry.com/zry/go-hhc-cli/hhc_common"
  6. "io"
  7. "strings"
  8. )
  9. type ExecuteFunc func(ctx *ExecUserContext)
  10. type ExecContext struct {
  11. sdtctx *SDTWalkContext
  12. euc *ExecUserContext
  13. }
  14. func WrapNewExecContext(wc *SDTWalkContext, stdout, stderr io.Writer, termWidth int) *ExecContext {
  15. euc := &ExecUserContext{
  16. stderr: stderr,
  17. stdout: stdout,
  18. willGotoPrintResultMode: false,
  19. enableRawInput: false,
  20. resBuffer: make([]string, 0),
  21. termWidth: termWidth,
  22. nextView: "",
  23. willChangePrompt: false,
  24. nextPrompt: "",
  25. }
  26. ec := &ExecContext{
  27. sdtctx: wc,
  28. euc: euc,
  29. }
  30. euc.ec = ec
  31. return ec
  32. }
  33. func (ec *ExecContext) GetUserContext() *ExecUserContext {
  34. return ec.euc
  35. }
  36. func (ec *ExecContext) WillGotoPrintResultMode() bool {
  37. return ec.euc.willGotoPrintResultMode
  38. }
  39. func (ec *ExecContext) GetResultPrintLines() []string {
  40. return ec.euc.resBuffer
  41. }
  42. func (ec *ExecContext) WriteRune(r rune) {
  43. if ec.euc.enableRawInput {
  44. if ec.euc.rawInputBuffer != nil {
  45. ec.euc.rawInputBuffer.WriteRune(r)
  46. }
  47. }
  48. }
  49. func (ec *ExecContext) GetNextView() string {
  50. return ec.euc.nextView
  51. }
  52. func (ec *ExecContext) GetNextPrompt() (bool, string) {
  53. return ec.euc.willChangePrompt, ec.euc.nextPrompt
  54. }
  55. type ExecUserContext struct {
  56. ec *ExecContext
  57. willGotoPrintResultMode bool
  58. stdout io.Writer
  59. stderr io.Writer
  60. enableRawInput bool
  61. rawInputBuffer *bytes.Buffer
  62. resBuffer []string
  63. termWidth int
  64. nextView string
  65. willChangePrompt bool
  66. nextPrompt string
  67. }
  68. func (euc *ExecUserContext) RawStdOutPrint(a ...interface{}) (int, error) {
  69. return fmt.Fprint(euc.stdout, a...)
  70. }
  71. func (euc *ExecUserContext) RawStdErrPrint(a ...interface{}) (int, error) {
  72. return fmt.Fprint(euc.stderr, a...)
  73. }
  74. func (euc *ExecUserContext) RawStdOutPrintf(format string, a ...interface{}) (int, error) {
  75. return fmt.Fprintf(euc.stdout, format, a...)
  76. }
  77. func (euc *ExecUserContext) RawStdErrPrintf(format string, a ...interface{}) (int, error) {
  78. return fmt.Fprintf(euc.stderr, format, a...)
  79. }
  80. func (euc *ExecUserContext) EnableRawInput() {
  81. euc.enableRawInput = true
  82. euc.rawInputBuffer = bytes.NewBuffer([]byte{})
  83. }
  84. func (euc *ExecUserContext) DisableRawInput() {
  85. euc.enableRawInput = false
  86. euc.rawInputBuffer = nil
  87. }
  88. func (euc *ExecUserContext) RawReadRune() (rune, int, error) {
  89. if euc.enableRawInput {
  90. if euc.rawInputBuffer != nil {
  91. return euc.rawInputBuffer.ReadRune()
  92. }
  93. }
  94. return 0, 0, fmt.Errorf("raw input not enable")
  95. }
  96. func (euc *ExecUserContext) ResultPrintRaw(r []string) {
  97. euc.willGotoPrintResultMode = true
  98. euc.resBuffer = append(euc.resBuffer, r...)
  99. }
  100. func (euc *ExecUserContext) ResultPrintSingleLineString(s string) {
  101. r := hhc_common.PrintStringIntoLines(s, euc.termWidth)
  102. euc.ResultPrintRaw(r)
  103. }
  104. func (euc *ExecUserContext) ResultPrintMultiLineString(s string) {
  105. ssr := strings.Replace(s, "\r\n", "\n", -1)
  106. ssr = strings.Replace(ssr, "\r", "\n", -1)
  107. lines := strings.Split(ssr, "\n")
  108. for _, v := range lines {
  109. euc.ResultPrintSingleLineString(v)
  110. }
  111. }
  112. func (euc *ExecUserContext) GetSubCount() int {
  113. an := euc.ec.sdtctx.ASTNodes
  114. return len(an)
  115. }
  116. func (euc *ExecUserContext) GetSubType(index int) (isArg, isSubCmd bool) {
  117. an := euc.ec.sdtctx.ASTNodes
  118. lan := len(an)
  119. if index >= lan {
  120. return false, false
  121. }
  122. san := an[index]
  123. switch san.(type) {
  124. case ASTNode_ValArg:
  125. return true, false
  126. case ASTNode_Command:
  127. return false, true
  128. default:
  129. return false, false
  130. }
  131. }
  132. func (euc *ExecUserContext) GetArgument(index int) (string, bool) {
  133. an := euc.ec.sdtctx.ASTNodes
  134. lan := len(an)
  135. if index >= lan {
  136. return "", false
  137. }
  138. san := an[index]
  139. arg, ok := san.(ASTNode_ValArg)
  140. if ok {
  141. return arg.GetTokenRaw(), true
  142. } else {
  143. return "", false
  144. }
  145. }
  146. func (euc *ExecUserContext) GetSubCommand(index int) (string, bool) {
  147. an := euc.ec.sdtctx.ASTNodes
  148. lan := len(an)
  149. if index >= lan {
  150. return "", false
  151. }
  152. san := an[index]
  153. cmd, ok := san.(ASTNode_Command)
  154. if ok {
  155. return cmd.Name, true
  156. } else {
  157. return "", false
  158. }
  159. }
  160. func (euc *ExecUserContext) ChangeView(nextView string) {
  161. euc.nextView = nextView
  162. }
  163. func (euc *ExecUserContext) ChangePrompt(nextPrompt string) {
  164. euc.willChangePrompt = true
  165. euc.nextPrompt = nextPrompt
  166. }
  167. func (euc *ExecUserContext) ChangeTitle(title string) {
  168. _, _ = euc.RawStdOutPrintf("\033]0;%s\007", title)
  169. }