website/cmd/ttyshot: Simplify opcode set.

Only opText, opPrompt and opTmux are needed now.
This commit is contained in:
Qi Xiao 2022-08-04 10:18:12 +01:00
parent 10ae6d6bb3
commit 82551c6b80
19 changed files with 33 additions and 149 deletions

View File

@ -172,34 +172,14 @@ func spawnElvish(homePath string, tty *os.File) (<-chan error, error) {
}
func executeScript(script []op, ctrl *os.File, homePath string) {
implicitEnter := true
for _, op := range script {
log.Println("executing", op)
switch op.typ {
case opText:
text := op.val.(string)
ctrl.WriteString(text)
if implicitEnter {
ctrl.Write([]byte{'\r'})
}
case opAlt:
ctrl.Write([]byte{'\033', op.val.(byte)})
case opCtrl:
ctrl.Write([]byte{op.val.(byte) & 0x1F})
case opEnter:
ctrl.Write([]byte{'\r'})
implicitEnter = true
case opUp:
ctrl.Write([]byte{'\033', '[', 'A'})
case opDown:
ctrl.Write([]byte{'\033', '[', 'B'})
case opRight:
ctrl.Write([]byte{'\033', '[', 'C'})
case opLeft:
ctrl.Write([]byte{'\033', '[', 'D'})
case opNoEnter:
implicitEnter = false
case opWaitForPrompt:
ctrl.WriteString("\r")
case opPrompt:
err := waitForOutput(ctrl, promptMarker,
func(bs []byte) bool { return bytes.HasSuffix(bs, []byte(promptMarker)) })
if err != nil {

View File

@ -53,10 +53,7 @@ func run(args []string) error {
if err != nil {
return err
}
spec, err := parseSpec(string(content))
if err != nil {
return err
}
spec := parseSpec(string(content))
homePath, err := setupHome()
if err != nil {

View File

@ -3,7 +3,6 @@
package main
import (
"errors"
"strings"
)
@ -11,17 +10,9 @@ type opType int
// Operations for driving a demo ttyshot.
const (
opEnter opType = iota // enable implicit Enter key and send an Enter key
opNoEnter // inhibit implicit Enter key
opUp // send Up arrow sequence
opDown // send Down arrow sequence
opRight // send Right arrow sequence
opLeft // send Left arrow sequence
opText // send the provided text, optionally followed by Enter
opAlt // send an alt sequence
opCtrl // send a control character
opWaitForPrompt // wait for prompt marker
opTmux // run tmux command
opText opType = iota // send the provided text, optionally followed by Enter
opPrompt // wait for prompt marker
opTmux // run tmux command
)
type op struct {
@ -29,81 +20,25 @@ type op struct {
val any
}
func parseSpec(content string) ([]op, error) {
func parseSpec(content string) []op {
lines := strings.Split(content, "\n")
ops := make([]op, 1, len(lines)+2)
ops[0] = op{opWaitForPrompt, nil}
ops := make([]op, 1, len(lines)+1)
ops[0] = op{opPrompt, nil}
for _, line := range lines {
if len(line) == 0 {
continue // ignore empty lines
}
if strings.HasPrefix(line, "#") && !strings.HasPrefix(line, "# ") {
directive, err := parseDirective(line[1:])
if err != nil {
return ops, err
}
ops = append(ops, directive)
var newOp op
if line == "#prompt" {
newOp = op{opPrompt, nil}
} else if strings.HasPrefix(line, "#") && !strings.HasPrefix(line, "# ") {
newOp = op{opTmux, strings.Fields(line[1:])}
} else {
ops = append(ops, op{opText, line})
newOp = op{opText, line}
}
ops = append(ops, newOp)
}
return ops, nil
}
func parseDirective(directive string) (op, error) {
if directive == "no-enter" {
return op{opNoEnter, nil}, nil
}
if directive == "enter" {
return op{opEnter, nil}, nil
}
// Tab is frequently used so it's useful to support it as a directive rather than requiring
// `//ctrl I`.
if directive == "tab" {
return op{opCtrl, byte('I')}, nil
}
if strings.HasPrefix(directive, "ctrl ") {
if len(directive) != 6 {
return op{}, errors.New("invalid ctrl directive: " + string(directive))
}
return op{opCtrl, directive[5]}, nil
}
if strings.HasPrefix(directive, "alt ") {
if len(directive) != 5 {
return op{}, errors.New("invalid alt directive: " + string(directive))
}
return op{opAlt, directive[4]}, nil
}
if directive == "prompt" {
return op{opWaitForPrompt, nil}, nil
}
if directive == "up" {
return op{opUp, nil}, nil
}
if directive == "down" {
return op{opDown, nil}, nil
}
if directive == "right" {
return op{opRight, nil}, nil
}
if directive == "left" {
return op{opLeft, nil}, nil
}
if strings.HasPrefix(directive, "send-keys ") {
return op{opTmux, strings.Fields(directive)}, nil
}
return op{}, errors.New("unrecognized directive: " + string(directive))
return ops
}

View File

@ -1,4 +1,3 @@
randint 1 7
#prompt
#no-enter
#up
#send-keys Up

View File

@ -2,6 +2,4 @@ randint 1 7
#prompt
# more commands ...
#prompt
#no-enter
ra
#up
#send-keys ra Up

View File

@ -1,4 +1 @@
#no-enter
#ctrl R
#up
#up
#send-keys C-R Up Up

View File

@ -1,2 +1 @@
#no-enter
#ctrl L
#send-keys C-L

View File

@ -1,4 +1,3 @@
cd elvish
#prompt
#no-enter
#ctrl N
#send-keys C-N

View File

@ -1,5 +1,3 @@
cd elvish
#prompt
#no-enter
vim
#tab
#send-keys vim Space Tab

View File

@ -1,6 +1,3 @@
cd elvish
#prompt
#no-enter
echo
#tab
.md
#send-keys echo Space Tab .md

View File

@ -1,5 +1,3 @@
cd elvish
#prompt
#no-enter
echo
#tab
#send-keys echo Space Tab

View File

@ -1,2 +1 @@
#no-enter
#ctrl R
#send-keys C-R

View File

@ -1,5 +1 @@
#no-enter
echo
#up
#up
#up
#send-keys echo Up Up Up

View File

@ -1,2 +1 @@
#no-enter
#up
#send-keys Up

View File

@ -1,5 +1,3 @@
echo abc def
#prompt
#no-enter
vim
#alt ,
#send-keys vim Space M-,

View File

@ -1,3 +1 @@
#no-enter
#ctrl L
local
#send-keys C-L local

View File

@ -1,2 +1 @@
#no-enter
#ctrl L
#send-keys C-L

View File

@ -1,4 +1,3 @@
cd elvish
#prompt
#no-enter
#ctrl N
#send-keys C-N

View File

@ -6,5 +6,4 @@ set edit:prompt = {
styled '❱ ' bright-red
}
#prompt
#no-enter
# Fancy unicode prompts!
#send-keys # Space Fancy Space unicode Space prompts!