func runeEventKeys(s string) KeySequence {
	seq := make(KeySequence, 0)
	for _, r := range s {
		key := tcell.NewEventKey(tcell.KeyRune, r, tcell.ModNone)
		seq = append(seq, key)
	}
	return seq
}
runeEventKeys creates a slice of tcell.EventKey objects that corresponds to
the literal runes in the string.
package keysequence
import (
	"fmt"
	"strings"
	"github.com/ambientsound/visp/input/lexer"
	"github.com/ambientsound/visp/parser"
	"github.com/gdamore/tcell/v2"
)
var modifiers = map[string]tcell.ModMask{
	"s":     tcell.ModShift,
	"c":     tcell.ModCtrl,
	"a":     tcell.ModAlt,
	"m":     tcell.ModMeta,
	"shift": tcell.ModShift,
	"ctrl":  tcell.ModCtrl,
	"alt":   tcell.ModAlt,
	"meta":  tcell.ModMeta,
}
type Parser struct {
	parser.Parser
}
func NewParser(r *lexer.Scanner) *Parser {
	return &Parser{
		parser.Parser{S: r},
	}
}
func (p *Parser) ParseKeySequence() (KeySequence, error) {
	keyseq := make(KeySequence, 0)
	tok, lit := p.ScanIgnoreWhitespace()
Parse:
	for {
		switch tok {
		case lexer.TokenAngleLeft:
			p.Unscan()
			key, err := p.ParseSpecial()
			if err != nil {
				return nil, err
			}
			keyseq = append(keyseq, key)
		case lexer.TokenWhitespace, lexer.TokenEnd, lexer.TokenComment:
			p.Unscan()
			break Parse
		default:
			seq := runeEventKeys(lit)
			keyseq = append(keyseq, seq...)
		}
		tok, lit = p.Scan()
	}
	if len(keyseq) == 0 {
		return nil, fmt.Errorf("Unexpected '%s', expected key sequence", lit)
	}
	return keyseq, nil
}
func (p *Parser) ParseSpecial() (key *tcell.EventKey, err error) {
	var mod tcell.ModMask
	tok, lit := p.Scan()
	if tok != lexer.TokenAngleLeft {
		return nil, fmt.Errorf("Unexpected %v, expected left angle bracket", lit)
	}
Scam:
	for {
		tok, lit = p.Scan()
		if tok != lexer.TokenIdentifier {
			return nil, fmt.Errorf("Unexpected %v, expected identifier", lit)
		}
		lit = strings.ToLower(lit)
		tok, _ := p.Scan()
		switch tok {
		case lexer.TokenAngleRight:
			break Scam
		case lexer.TokenPlus, lexer.TokenMinus:
			break
		default:
			return nil, fmt.Errorf("Unexpected '%s', expected >", lit)
		}
		m, ok := modifiers[lit]
		if !ok {
			return nil, fmt.Errorf("Unexpected '%s', expected one of Shift, Ctrl, Alt, Meta", lit)
		}
		mod |= m
	}
	ev, ok := keyNames[lit]
	if !ok {
		if len(lit) != 1 {
			return nil, fmt.Errorf("Unknown key name '%s'", lit)
		}
		for _, r := range lit {
			return convertCtrlKey(tcell.NewEventKey(tcell.KeyRune, r, mod)), nil
		}
	}
	key = convertCtrlKey(tcell.NewEventKey(ev.Key(), ev.Rune(), mod))
	return key, nil
}