edit.go
func (e *Edit) KeyHandler(ev termbox.Event) bool {
	var inString int

	switch ev.Key {
	case termbox.KeyCtrlA, termbox.KeyHome:
		e.cx = e.trueX
		e.at = 0
		setCursor(e.cx, e.cy)
		e.Render()
		return true
	case termbox.KeyCtrlE, termbox.KeyEnd:
		if len(e.display) < e.trueW-1 {
			// no need to call display
			e.cx = e.trueX + len(e.display) - e.at
			setCursor(e.cx, e.cy)
			return true
		}
		e.cx = e.trueX + e.trueW - 1
		e.at = len(e.display) - e.trueW + 1
		setCursor(e.cx, e.cy)
		e.Render()
		return true
	case termbox.KeyCtrlU:
		e.cx = e.trueX
		e.at = 0
		e.display = []rune("")
		setCursor(e.cx, e.cy)
		e.Render()
		return true
	case termbox.KeyArrowRight:
		// check to see if we have content on the right hand side
		if e.cx-e.trueX == len(e.display[e.at:]) {
			return true
		}
		e.cx++
		if e.cx > e.trueW+e.trueX-1 {
			e.cx = e.trueW + e.trueX - 1

			// check for end of string before moving at
			if len(e.display[e.at:]) == 0 {
				return true
			}
			e.at++
			e.Render()
			return true
		}
		setCursor(e.cx, e.cy)
		return true
	case termbox.KeyArrowLeft:
		e.cx--
		if e.cx < e.trueX {
			e.cx = e.trueX
			e.at--
			if e.at < 0 {
				e.at = 0
			}
			e.Render()
		}
		setCursor(e.cx, e.cy)
		return true
	case termbox.KeyDelete:
		inString = e.cx - e.trueX + e.at
		if len(e.display) == inString {
			return true
		}
		// remove from slice
		e.display = append(e.display[:inString],
			e.display[inString+1:]...)
		e.Render()
		return true
	case termbox.KeyBackspace, termbox.KeyBackspace2:
		inString = e.cx - e.trueX + e.at
		if inString <= 0 {
			return true
		}
		e.display = append(e.display[:inString-1],
			e.display[inString:]...)

		// cursor left magic
		if e.cx == e.trueX+1 {
			if e.at > e.trueW-1 {
				e.cx = e.trueW - 1
			} else {
				e.cx = e.at + e.trueX
			}
			if e.at >= e.cx {
				e.at -= e.cx
			}
		} else {
			e.cx--
		}
		setCursor(e.cx, e.cy)
		e.Render()
		return true
	case termbox.KeySpace:
		// use space
		ev.Ch = ' '
	case termbox.KeyEnter:
		*e.target = string(e.display)
		// return false and let the application decide if it wants
		// to consume the action
		return false
	}

	// normal runes are displayed and stored
	if ev.Ch != 0 && ev.Mod != 0 && ev.Key == 0 {
		// forward special
		return false
	} else if ev.Ch == 0 {
		return false
	}

	inString = e.cx - e.trueX + e.at
	e.display = insert(e.display, inString, ev.Ch)
	if e.cx < e.trueW+e.trueX-1 {
		e.cx++
		setCursor(e.cx, e.cy)
	} else {
		e.at++
	}

	e.Render()
	return true
}
func (e *Edit) KeyHandler(ev termbox.Event) bool {
	var inString int

	switch ev.Key {
	case termbox.KeyCtrlA, termbox.KeyHome:
		e.cx = e.trueX
		e.at = 0
		setCursor(e.cx, e.cy)
		e.Render()
		return true
	case termbox.KeyCtrlE, termbox.KeyEnd:
		if len(e.display) < e.trueW-1 {
			// no need to call display
			e.cx = e.trueX + len(e.display) - e.at
			setCursor(e.cx, e.cy)
			return true
		}
		e.cx = e.trueX + e.trueW - 1
		e.at = len(e.display) - e.trueW + 1
		setCursor(e.cx, e.cy)
		e.Render()
		return true
	case termbox.KeyCtrlU:
		e.cx = e.trueX
		e.at = 0
		e.display = []rune("")
		setCursor(e.cx, e.cy)
		e.Render()
		return true
	case termbox.KeyArrowRight:
		// check to see if we have content on the right hand side
		if e.cx-e.trueX == len(e.display[e.at:]) {
			return true
		}
		e.cx++
		if e.cx > e.trueW+e.trueX-1 {
			e.cx = e.trueW + e.trueX - 1

			// check for end of string before moving at
			if len(e.display[e.at:]) == 0 {
				return true
			}
			e.at++
			e.Render()
			return true
		}
		setCursor(e.cx, e.cy)
		return true
	case termbox.KeyArrowLeft:
		e.cx--
		if e.cx < e.trueX {
			e.cx = e.trueX
			e.at--
			if e.at < 0 {
				e.at = 0
			}
			e.Render()
		}
		setCursor(e.cx, e.cy)
		return true
	case termbox.KeyDelete:
		inString = e.cx - e.trueX + e.at
		if len(e.display) == inString {
			return true
		}
		// remove from slice
		e.display = append(e.display[:inString],
			e.display[inString+1:]...)
		e.Render()
		return true
	case termbox.KeyBackspace, termbox.KeyBackspace2:
		inString = e.cx - e.trueX + e.at
		if inString <= 0 {
			return true
		}
		e.display = append(e.display[:inString-1],
			e.display[inString:]...)

		// cursor left magic
		if e.cx == e.trueX+1 {
			if e.at > e.trueW-1 {
				e.cx = e.trueW - 1
			} else {
				e.cx = e.at + e.trueX
			}
			if e.at >= e.cx {
				e.at -= e.cx
			}
		} else {
			e.cx--
		}
		setCursor(e.cx, e.cy)
		e.Render()
		return true
	case termbox.KeySpace:
		// use space
		ev.Ch = ' '
	case termbox.KeyEnter:
		*e.target = string(e.display)
		// return false and let the application decide if it wants
		// to consume the action
		return false
	}

	// normal runes are displayed and stored
	if ev.Ch != 0 && ev.Mod != 0 && ev.Key == 0 {
		// forward special
		return false
	} else if ev.Ch == 0 {
		return false
	}

	inString = e.cx - e.trueX + e.at
	e.display = insert(e.display, inString, ev.Ch)
	if e.cx < e.trueW+e.trueX-1 {
		e.cx++
		setCursor(e.cx, e.cy)
	} else {
		e.at++
	}

	e.Render()
	return true
}
// KeyHandler implements the interface.  This is called from queue context
// so be careful to not use blocking calls.