package hhc_ast import ( "bytes" "fmt" "git.swzry.com/zry/go-hhc-cli/hhc_common" "io" "strings" ) type ExecuteFunc func(ctx *ExecUserContext) type ExecContext struct { sdtctx *SDTWalkContext euc *ExecUserContext } func WrapNewExecContext(wc *SDTWalkContext, stdout, stderr io.Writer, termWidth int) *ExecContext { euc := &ExecUserContext{ stderr: stderr, stdout: stdout, willGotoPrintResultMode: false, enableRawInput: false, resBuffer: make([]string, 0), termWidth: termWidth, nextView: "", willChangePrompt: false, nextPrompt: "", } ec := &ExecContext{ sdtctx: wc, euc: euc, } euc.ec = ec return ec } func (ec *ExecContext) GetUserContext() *ExecUserContext { return ec.euc } func (ec *ExecContext) WillGotoPrintResultMode() bool { return ec.euc.willGotoPrintResultMode } func (ec *ExecContext) GetResultPrintLines() []string { return ec.euc.resBuffer } func (ec *ExecContext) WriteRune(r rune) { if ec.euc.enableRawInput { if ec.euc.rawInputBuffer != nil { ec.euc.rawInputBuffer.WriteRune(r) } } } func (ec *ExecContext) GetNextView() string { return ec.euc.nextView } func (ec *ExecContext) GetNextPrompt() (bool, string) { return ec.euc.willChangePrompt, ec.euc.nextPrompt } type ExecUserContext struct { ec *ExecContext willGotoPrintResultMode bool stdout io.Writer stderr io.Writer enableRawInput bool rawInputBuffer *bytes.Buffer resBuffer []string termWidth int nextView string willChangePrompt bool nextPrompt string } func (euc *ExecUserContext) RawStdOutPrint(a ...interface{}) (int, error) { return fmt.Fprint(euc.stdout, a...) } func (euc *ExecUserContext) RawStdErrPrint(a ...interface{}) (int, error) { return fmt.Fprint(euc.stderr, a...) } func (euc *ExecUserContext) RawStdOutPrintf(format string, a ...interface{}) (int, error) { return fmt.Fprintf(euc.stdout, format, a...) } func (euc *ExecUserContext) RawStdErrPrintf(format string, a ...interface{}) (int, error) { return fmt.Fprintf(euc.stderr, format, a...) } func (euc *ExecUserContext) EnableRawInput() { euc.enableRawInput = true euc.rawInputBuffer = bytes.NewBuffer([]byte{}) } func (euc *ExecUserContext) DisableRawInput() { euc.enableRawInput = false euc.rawInputBuffer = nil } func (euc *ExecUserContext) RawReadRune() (rune, int, error) { if euc.enableRawInput { if euc.rawInputBuffer != nil { return euc.rawInputBuffer.ReadRune() } } return 0, 0, fmt.Errorf("raw input not enable") } func (euc *ExecUserContext) ResultPrintRaw(r []string) { euc.willGotoPrintResultMode = true euc.resBuffer = append(euc.resBuffer, r...) } func (euc *ExecUserContext) ResultPrintSingleLineString(s string) { r := hhc_common.PrintStringIntoLines(s, euc.termWidth) euc.ResultPrintRaw(r) } func (euc *ExecUserContext) ResultPrintMultiLineString(s string) { ssr := strings.Replace(s, "\r\n", "\n", -1) ssr = strings.Replace(ssr, "\r", "\n", -1) lines := strings.Split(ssr, "\n") for _, v := range lines { euc.ResultPrintSingleLineString(v) } } func (euc *ExecUserContext) GetSubCount() int { an := euc.ec.sdtctx.ASTNodes return len(an) } func (euc *ExecUserContext) GetSubType(index int) (isArg, isSubCmd bool) { an := euc.ec.sdtctx.ASTNodes lan := len(an) if index >= lan { return false, false } san := an[index] switch san.(type) { case ASTNode_ValArg: return true, false case ASTNode_Command: return false, true default: return false, false } } func (euc *ExecUserContext) GetArgument(index int) (string, bool) { an := euc.ec.sdtctx.ASTNodes lan := len(an) if index >= lan { return "", false } san := an[index] arg, ok := san.(ASTNode_ValArg) if ok { return arg.GetTokenRaw(), true } else { return "", false } } func (euc *ExecUserContext) GetSubCommand(index int) (string, bool) { an := euc.ec.sdtctx.ASTNodes lan := len(an) if index >= lan { return "", false } san := an[index] cmd, ok := san.(ASTNode_Command) if ok { return cmd.Name, true } else { return "", false } } func (euc *ExecUserContext) ChangeView(nextView string) { euc.nextView = nextView } func (euc *ExecUserContext) ChangePrompt(nextPrompt string) { euc.willChangePrompt = true euc.nextPrompt = nextPrompt } func (euc *ExecUserContext) ChangeTitle(title string) { _, _ = euc.RawStdOutPrintf("\033]0;%s\007", title) }