JSFiddle - React, Tailwind, and code Playground

by TimWolla

HTML

<textarea id="in" rows="10" cols="40"></textarea>
<button>Replay</button>
<textarea readonly="readonly" id="out" rows="10" cols="40"></textarea>

CoffeeScript

replay = (input) ->
	rows = (x.split /\s/ for x in input.split /\n/)
	expectedLineNo = 1
	pressedKeys = { }
	clipboard = ''
	numLock = yes
	capsLock = no
	cursor = 0
	column = undefined
	selection = undefined
	input = ''
	table =
		'`': '~'
		1: '!'
		2: '@'
		3: '#'
		4: '$'
		5: '%'
		6: '^'
		7: '&'
		8: '*'
		9: '('
		0: ')'
		'-': '_'
		'=': '+'
		'\\': '|'
		',': '<'
		'.': '>'
		'/': '?'
		';': ':'
		"'": '"'
		'[': '{'
		']': '}'
	insert = (insertText) ->
		if selection?
			[ selectionStart, selectionEnd ] = do fixSelection
			input = (input.substring 0, selectionStart) + insertText + (input.substring selectionEnd)
			cursor = (parseInt selectionStart) + insertText.length
			selection = undefined
		else
			input = (input.substring 0, cursor) + insertText + (input.substring cursor)
			cursor = cursor + insertText.length
	fixSelection = ->
		if selection?
			[ (Math.min selection, cursor), (Math.max selection, cursor) ]
		else
			[ 0, 0 ]
	getLineStart = ->
		start = (input.substring 0, cursor).lastIndexOf '\n'
		start++
		start += 80 while (cursor - start) > 80
		start
	getLineEnd = ->
		end = (input.substring cursor).indexOf '\n'
		if end is -1
			end = input.length
		else
			end += cursor + 1
		
		Math.min end, 80 + do getLineStart
	getColumn = ->
		console.error cursor, do getLineStart
		cursor - do getLineStart
	for row in rows
		[ lineNo, action, key ] = row
		throw new Error "Unexpected line #{lineNo}, expected #{expectedLineNo}" if expectedLineNo isnt parseInt lineNo
		throw new Error "Cannot release #{key} in line #{lineNo}" if action is 'R' and not pressedKeys[key]?
		throw new Error "Cannot press #{key} in line #{lineNo}" if action is 'P' and pressedKeys[key]?
		throw new Error "Cannot hit #{key} in line #{lineNo}" if action is 'H' and pressedKeys[key]?
		
		switch key
			when "Num Lock"
				numLock = not numLock
			when "Caps Lock"
				capsLock = not capsLock
			when "Tab"
				insert "\t"
			when "Space"
				insert " "
			when "Enter"
				insert...