func (aw *AnsiWriter) finish(parse func([]byte) error) error {
	var err error
	if parse != nil {
		err = parse(aw.buf[2:])
	}
	aw.buf = make([]byte, 0)
	return err
}
finish finishes an ANSI escape code and calls the parsing function. Afterwards
the escape buffer is emptied.
package prompt
import (
	"bytes"
	"os"
	"unicode/utf8"
	"unsafe"
)
const keyEventType = 0x0001
var (
	readConsoleInput = kernel.NewProc("ReadConsoleInputW")
)
type inputRecord struct {
	eventType uint16
	_     [2]byte
	event [16]byte
}
type keyEventRecord struct {
	keyDown         int32
	repeatCount     uint16
	virtualKeyCode  uint16
	virtualScanCode uint16
	char            uint16
	controlKeyState uint32
}
type AnsiReader struct {
	fd  uintptr
	buf []rune
}
func NewAnsiReader(in *os.File) *AnsiReader {
	return &AnsiReader{fd: in.Fd(), buf: make([]rune, 0)}
}
func (ar *AnsiReader) Read(b []byte) (int, error) {
	var read uint32
	n := 0
	if len(b) == 0 {
		return 0, nil
	}
	if len(ar.buf) == 0 {
		var runes []rune
		for runes == nil {
			rec := new(inputRecord)
			ret, _, err := readConsoleInput.Call(ar.fd, uintptr(unsafe.Pointer(rec)),
				1, uintptr(unsafe.Pointer(&read)))
			if ret == 0 {
				return 0, err
			}
			if rec.eventType != keyEventType {
				continue
			}
			ke := (*keyEventRecord)(unsafe.Pointer(&rec.event))
			if ke.keyDown == 0 {
				continue
			}
			shift := false
			if ke.controlKeyState&shiftKey != 0 {
				shift = true
			}
			ctrl := false
			if ke.controlKeyState&leftCtrlKey != 0 || ke.controlKeyState&rightCtrlKey != 0 {
				ctrl = true
			}
			alt := false
			if ke.controlKeyState&leftAltKey != 0 || ke.controlKeyState&rightAltKey != 0 {
				alt = true
			}
			if ke.char == ctrlH || ke.char == returnKey || ke.char == spaceKey {
				code := string(returnKey)
				if ke.char == ctrlH {
					code = string(backKey)
				} else if ke.char == spaceKey {
					code = string(spaceKey)
				}
				if alt {
					code = string(escKey) + code
				}
				runes = []rune(code)
				break
			}
			if ke.char > 0 {
				runes = []rune{rune(ke.char)}
			} else {
				code := string(escKey)
				switch ke.virtualKeyCode {
				case f1Key:
					if ctrl {
						continue
					}
					code += ar.shortFunction("P", shift, ctrl, alt)
				case f2Key:
					code += ar.shortFunction("Q", shift, ctrl, alt)
				case f3Key:
					code += ar.shortFunction("R", shift, ctrl, alt)
				case f4Key:
					code += ar.shortFunction("S", shift, ctrl, alt)
				case f5Key:
					code += ar.longFunction("15", shift, ctrl, alt)
				case f6Key:
					code += ar.longFunction("17", shift, ctrl, alt)
				case f7Key:
					code += ar.longFunction("18", shift, ctrl, alt)
				case f8Key:
					code += ar.longFunction("19", shift, ctrl, alt)
				case f9Key:
					code += ar.longFunction("20", shift, ctrl, alt)
				case f10Key:
					code += ar.longFunction("21", shift, ctrl, alt)
				case f11Key:
					code += ar.longFunction("23", shift, ctrl, alt)
				case f12Key:
					code += ar.longFunction("24", shift, ctrl, alt)
				case insertKey:
					if shift || ctrl {
						continue
					}
					code += ar.longFunction("2", shift, ctrl, alt)
				case deleteKey:
					code += ar.longFunction("3", shift, ctrl, alt)
				case homeKey:
					code += "OH"
				case endKey:
					code += "OF"
				case pgupKey:
					if shift {
						continue
					}
					code += ar.longFunction("5", shift, ctrl, alt)
				case pgdownKey:
					if shift {
						continue
					}
					code += ar.longFunction("6", shift, ctrl, alt)
				case upKey:
					code += ar.arrow("A", shift, ctrl, alt)
				case downKey:
					code += ar.arrow("B", shift, ctrl, alt)
				case leftKey:
					code += ar.arrow("D", shift, ctrl, alt)
				case rightKey:
					code += ar.arrow("C", shift, ctrl, alt)
				default:
					continue
				}
				runes = []rune(code)
			}
		}
		ar.buf = runes
	}
	for i, r := range ar.buf {
		if utf8.RuneLen(r) > len(b) {
			ar.buf = ar.buf[i:]
			return n, nil
		}
		nr := utf8.EncodeRune(b, r)
		b = b[nr:]
		n += nr
	}
	ar.buf = nil
	return n, nil
}
func (ar *AnsiReader) shortFunction(ident string, shift, ctrl, alt bool) string {
	code := "O"
	if shift {
		code += "1;2"
	} else if ctrl {
		code += "1;5"
	} else if alt {
		code += "1;3"
	}
	return code + ident
}
func (ar *AnsiReader) longFunction(ident string, shift, ctrl, alt bool) string {
	code := "["
	code += ident
	if shift {
		code += ";2"
	} else if ctrl {
		code += ";5"
	} else if alt {
		code += ";3"
	}
	return code + "~"
}
func (ar *AnsiReader) arrow(ident string, shift, ctrl, alt bool) string {
	code := "["
	if shift {
		code += "1;2"
	} else if ctrl {
		code += "1;5"
	} else if alt {
		code += "1;3"
	}
	return code + ident
}
type AnsiWriter struct {
	file *os.File
	buf  []byte
}
func NewAnsiWriter(out *os.File) *AnsiWriter {
	return &AnsiWriter{file: out, buf: make([]byte, 0)}
}
func (aw *AnsiWriter) Write(b []byte) (int, error) {
	needsProcessing := bytes.Contains(b, []byte(string(escKey)))
	if len(aw.buf) > 0 {
		needsProcessing = true
	}
	if !needsProcessing {
		return aw.file.Write(b)
	}
	p := make([]byte, 0)
	for _, char := range b {
		if char == escKey {
			aw.buf = append(aw.buf, char)
			continue
		}
		if len(aw.buf) == 1 && (char == '_' || char == 'P' || char == '[' ||
			char == ']' || char == '^' || char == ' ' || char == '#' ||
			char == '%' || char == '(' || char == ')' || char == '*' ||
			char == '+') {
			aw.buf = append(aw.buf, char)
			continue
		}
		if len(aw.buf) == 1 && (char == '7' || char == '8') {
			aw.buf = append(aw.buf, '_', char)
			err := aw.finish(nil)
			if err != nil {
				return 0, err
			}
			continue
		}
		if len(aw.buf) == 1 && (char == '=' || char == '>') {
			aw.buf = append(aw.buf, char)
			aw.finish(nil)
			continue
		}
		if len(aw.buf) == 1 && char == 'F' {
			aw.buf = append(aw.buf, '_', char)
			err := aw.finish(nil)
			if err != nil {
				return 0, err
			}
			continue
		}
		if len(aw.buf) == 1 && char == 'c' {
			aw.buf = append(aw.buf, '_', char)
			err := aw.finish(nil)
			if err != nil {
				return 0, err
			}
			continue
		}
		if len(aw.buf) >= 2 && aw.buf[1] == ' ' && (char == 'F' || char == 'G' ||
			char == 'L' || char == 'M' || char == 'N') {
			aw.buf = append(aw.buf, char)
			aw.finish(nil)
			continue
		}
		if len(aw.buf) >= 2 && aw.buf[1] == '#' && (char >= '3' && char <= '6') ||
			char == '8' {
			aw.buf = append(aw.buf, char)
			err := aw.finish(nil)
			if err != nil {
				return 0, err
			}
			continue
		}
		if len(aw.buf) >= 2 && aw.buf[1] == '%' && (char == '@' || char == 'G') {
			aw.buf = append(aw.buf, char)
			aw.finish(nil)
			continue
		}
		if len(aw.buf) >= 2 && (aw.buf[1] == '(' || aw.buf[1] == ')' ||
			aw.buf[1] == '*' || aw.buf[1] == '+') && (char == '0' ||
			(char >= '4' && char <= '7') || char == '=' || (char >= 'A' &&
			char <= 'C') || char == 'E' || char == 'H' || char == 'K' ||
			char == 'Q' || char == 'R' || char == 'Y') {
			aw.buf = append(aw.buf, char)
			aw.finish(nil)
			continue
		}
		if len(aw.buf) >= 2 && aw.buf[1] == '_' {
			aw.buf = append(aw.buf, char)
			if char == '\\' && aw.buf[len(aw.buf)-1] == escKey {
				aw.finish(nil)
			}
			continue
		}
		if len(aw.buf) >= 2 && aw.buf[1] == 'P' {
			aw.buf = append(aw.buf, char)
			if char == '\\' && aw.buf[len(aw.buf)-1] == escKey {
				err := aw.finish(nil)
				if err != nil {
					return 0, err
				}
			}
			continue
		}
		if len(aw.buf) >= 2 && aw.buf[1] == '[' {
			aw.buf = append(aw.buf, char)
			if char == '@' || (char >= 'A' && char <= 'M') || char == 'P' ||
				char == 'S' || char == 'T' || char == 'X' || char == 'Z' ||
				char == '`' || (char >= 'b' && char <= 'd') || (char >= 'f' &&
				char <= 'i') || (char >= 'l' && char <= 'n') || (char >= 'p' &&
				char <= 't') || char == 'w' || char == 'x' || char == 'z' ||
				char == '{' || char == '|' {
				err := aw.finish(nil)
				if err != nil {
					return 0, err
				}
			}
			continue
		}
		if len(aw.buf) >= 2 && aw.buf[1] == ']' {
			aw.buf = append(aw.buf, char)
			if len(aw.buf) == 4 && aw.buf[2] == '0' && char == ';' {
				aw.finish(nil)
				continue
			}
			if (char == '\\' && aw.buf[len(aw.buf)-1] == escKey) || char == ctrlG {
				err := aw.finish(nil)
				if err != nil {
					return 0, err
				}
			}
			continue
		}
		if len(aw.buf) >= 2 && aw.buf[1] == '^' {
			aw.buf = append(aw.buf, char)
			if char == '\\' && aw.buf[len(aw.buf)-1] == escKey {
				err := aw.finish(nil)
				if err != nil {
					return 0, err
				}
			}
			continue
		}
		if len(aw.buf) > 0 {
			aw.buf = make([]byte, 0)
		}
		p = append(p, char)
	}
	_, err := aw.file.Write(p)
	return len(b), err
}