+// DoTextEvent runs a text event
+func (eh *EventHandler) DoTextEvent(t *TextEvent, useUndo bool) {
+ oldl := eh.buf.LinesNum()
+
+ if useUndo {
+ eh.Execute(t)
+ } else {
+ ExecuteTextEvent(t, eh.buf)
+ }
+
+ if len(t.Deltas) != 1 {
+ return
+ }
+
+ text := t.Deltas[0].Text
+ start := t.Deltas[0].Start
+ lastnl := -1
+ var endX int
+ var textX int
+ if t.EventType == TextEventInsert {
+ linecount := eh.buf.LinesNum() - oldl
+ textcount := utf8.RuneCount(text)
+ lastnl = bytes.LastIndex(text, []byte{'\n'})
+ if lastnl >= 0 {
+ endX = utf8.RuneCount(text[lastnl+1:])
+ textX = endX
+ } else {
+ endX = start.X + textcount
+ textX = textcount
+ }
+ t.Deltas[0].End = clamp(Loc{endX, start.Y + linecount}, eh.buf.LineArray)
+ }
+ end := t.Deltas[0].End
+
+ for _, c := range eh.cursors {
+ move := func(loc Loc) Loc {
+ if t.EventType == TextEventInsert {
+ if start.Y != loc.Y && loc.GreaterThan(start) {
+ loc.Y += end.Y - start.Y
+ } else if loc.Y == start.Y && loc.GreaterEqual(start) {
+ loc.Y += end.Y - start.Y
+ if lastnl >= 0 {
+ loc.X += textX - start.X
+ } else {
+ loc.X += textX
+ }
+ }
+ return loc
+ } else {
+ if loc.Y != end.Y && loc.GreaterThan(end) {
+ loc.Y -= end.Y - start.Y
+ } else if loc.Y == end.Y && loc.GreaterEqual(end) {
+ loc = loc.MoveLA(-DiffLA(start, end, eh.buf.LineArray), eh.buf.LineArray)
+ }
+ return loc
+ }
+ }
+ c.Loc = move(c.Loc)
+ c.CurSelection[0] = move(c.CurSelection[0])
+ c.CurSelection[1] = move(c.CurSelection[1])
+ c.OrigSelection[0] = move(c.OrigSelection[0])
+ c.OrigSelection[1] = move(c.OrigSelection[1])
+ c.Relocate()
+ c.LastVisualX = c.GetVisualX()
+ }
+}
+