]> git.lizzy.rs Git - micro.git/blobdiff - internal/buffer/eventhandler.go
fix eofnewline not running on files with 1 rune (#1535)
[micro.git] / internal / buffer / eventhandler.go
index 6eb546bde0d8f4f44e59dfb3eb0acdf3cb3859aa..4e4243a07953488adcf8310ec1104964e1752c3f 100644 (file)
@@ -1,6 +1,7 @@
 package buffer
 
 import (
+       "bytes"
        "time"
        "unicode/utf8"
 
@@ -116,27 +117,47 @@ func (eh *EventHandler) Insert(start Loc, textStr string) {
 
 // InsertBytes creates an insert text event and executes it
 func (eh *EventHandler) InsertBytes(start Loc, text []byte) {
+       start = clamp(start, eh.buf.LineArray)
        e := &TextEvent{
                C:         *eh.cursors[eh.active],
                EventType: TextEventInsert,
                Deltas:    []Delta{{text, start, Loc{0, 0}}},
                Time:      time.Now(),
        }
+       oldl := eh.buf.LinesNum()
        eh.Execute(e)
+       linecount := eh.buf.LinesNum() - oldl
        textcount := utf8.RuneCount(text)
-       e.Deltas[0].End = start.MoveLA(textcount, eh.buf.LineArray)
+       lastnl := bytes.LastIndex(text, []byte{'\n'})
+       var endX int
+       var textX int
+       if lastnl >= 0 {
+               endX = utf8.RuneCount(text[lastnl+1:])
+               textX = endX
+       } else {
+               endX = start.X + textcount
+               textX = textcount
+       }
+
+       e.Deltas[0].End = clamp(Loc{endX, start.Y + linecount}, eh.buf.LineArray)
        end := e.Deltas[0].End
 
        for _, c := range eh.cursors {
                move := func(loc Loc) Loc {
-                       if start.Y != end.Y && loc.GreaterThan(start) {
+                       if start.Y != loc.Y && loc.GreaterThan(start) {
                                loc.Y += end.Y - start.Y
                        } else if loc.Y == start.Y && loc.GreaterEqual(start) {
-                               loc = loc.MoveLA(textcount, eh.buf.LineArray)
+                               loc.Y += end.Y - start.Y
+                               if lastnl >= 0 {
+                                       loc.X += textX - start.X
+                               } else {
+                                       loc.X += textX
+                               }
                        }
                        return loc
                }
                c.Loc = move(c.Loc)
+               c.Relocate()
                c.CurSelection[0] = move(c.CurSelection[0])
                c.CurSelection[1] = move(c.CurSelection[1])
                c.OrigSelection[0] = move(c.OrigSelection[0])
@@ -147,6 +168,8 @@ func (eh *EventHandler) InsertBytes(start Loc, text []byte) {
 
 // Remove creates a remove text event and executes it
 func (eh *EventHandler) Remove(start, end Loc) {
+       start = clamp(start, eh.buf.LineArray)
+       end = clamp(end, eh.buf.LineArray)
        e := &TextEvent{
                C:         *eh.cursors[eh.active],
                EventType: TextEventRemove,
@@ -157,7 +180,7 @@ func (eh *EventHandler) Remove(start, end Loc) {
 
        for _, c := range eh.cursors {
                move := func(loc Loc) Loc {
-                       if start.Y != end.Y && loc.GreaterThan(end) {
+                       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)