From 102ae04a16f4832021ea1263d9f72f35fdbc9b17 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Sun, 5 Jul 2020 01:12:35 -0400 Subject: [PATCH] Improve multicursor clipboard Ref #1721 --- internal/action/actions.go | 6 +++--- internal/buffer/cursor.go | 2 +- internal/clipboard/clipboard.go | 16 ++++++++-------- internal/clipboard/multi.go | 27 ++++++++------------------- 4 files changed, 20 insertions(+), 31 deletions(-) diff --git a/internal/action/actions.go b/internal/action/actions.go index a8732630..e7470056 100644 --- a/internal/action/actions.go +++ b/internal/action/actions.go @@ -995,7 +995,7 @@ func (h *BufPane) CutLine() bool { if clip, err := clipboard.Read(clipboard.ClipboardReg); err != nil { InfoBar.Error(err) } else { - clipboard.WriteMulti(clip+string(h.Cursor.GetSelection()), clipboard.ClipboardReg, h.Cursor.Num) + clipboard.WriteMulti(clip+string(h.Cursor.GetSelection()), clipboard.ClipboardReg, h.Cursor.Num, h.Buf.NumCursors()) } } } else if time.Since(h.lastCutTime)/time.Second > 10*time.Second || h.freshClip == false { @@ -1139,7 +1139,7 @@ func (h *BufPane) MoveLinesDown() bool { // Paste whatever is in the system clipboard into the buffer // Delete and paste if the user has a selection func (h *BufPane) Paste() bool { - clip, err := clipboard.ReadMulti(clipboard.ClipboardReg, h.Cursor.Num) + clip, err := clipboard.ReadMulti(clipboard.ClipboardReg, h.Cursor.Num, h.Buf.NumCursors()) if err != nil { InfoBar.Error(err) } else { @@ -1151,7 +1151,7 @@ func (h *BufPane) Paste() bool { // PastePrimary pastes from the primary clipboard (only use on linux) func (h *BufPane) PastePrimary() bool { - clip, err := clipboard.ReadMulti(clipboard.PrimaryReg, h.Cursor.Num) + clip, err := clipboard.ReadMulti(clipboard.PrimaryReg, h.Cursor.Num, h.Buf.NumCursors()) if err != nil { InfoBar.Error(err) } else { diff --git a/internal/buffer/cursor.go b/internal/buffer/cursor.go index 2aaf02bd..aa3daf02 100644 --- a/internal/buffer/cursor.go +++ b/internal/buffer/cursor.go @@ -128,7 +128,7 @@ func (c *Cursor) End() { func (c *Cursor) CopySelection(target clipboard.Register) { if c.HasSelection() { if target != clipboard.PrimaryReg || c.buf.Settings["useprimary"].(bool) { - clipboard.WriteMulti(string(c.GetSelection()), target, c.Num) + clipboard.WriteMulti(string(c.GetSelection()), target, c.Num, c.buf.NumCursors()) } } } diff --git a/internal/clipboard/clipboard.go b/internal/clipboard/clipboard.go index 9fad3571..6c68c40f 100644 --- a/internal/clipboard/clipboard.go +++ b/internal/clipboard/clipboard.go @@ -69,30 +69,30 @@ func Write(text string, r Register) error { } // ReadMulti reads text from a clipboard register for a certain multi-cursor -func ReadMulti(r Register, num int) (string, error) { +func ReadMulti(r Register, num, ncursors int) (string, error) { clip, err := Read(r) if err != nil { return "", err } - if ValidMulti(r, clip) { + if ValidMulti(r, clip, ncursors) { return multi.getText(r, num), nil } return clip, nil } // WriteMulti writes text to a clipboard register for a certain multi-cursor -func WriteMulti(text string, r Register, num int) error { - return writeMulti(text, r, num, CurrentMethod) +func WriteMulti(text string, r Register, num int, ncursors int) error { + return writeMulti(text, r, num, ncursors, CurrentMethod) } // ValidMulti checks if the internal multi-clipboard is valid and up-to-date // with the system clipboard -func ValidMulti(r Register, clip string) bool { - return multi.isValid(r, clip) +func ValidMulti(r Register, clip string, ncursors int) bool { + return multi.isValid(r, clip, ncursors) } -func writeMulti(text string, r Register, num int, m Method) error { - multi.writeText(text, r, num) +func writeMulti(text string, r Register, num int, ncursors int, m Method) error { + multi.writeText(text, r, num, ncursors) return write(multi.getAllText(r), r, m) } diff --git a/internal/clipboard/multi.go b/internal/clipboard/multi.go index 42c84363..18836c86 100644 --- a/internal/clipboard/multi.go +++ b/internal/clipboard/multi.go @@ -2,7 +2,6 @@ package clipboard import ( "bytes" - "hash/fnv" ) // For storing multi cursor clipboard contents @@ -19,7 +18,6 @@ func (c multiClipboard) getAllText(r Register) string { buf := &bytes.Buffer{} for _, s := range content { buf.WriteString(s) - buf.WriteByte('\n') } return buf.String() } @@ -33,37 +31,28 @@ func (c multiClipboard) getText(r Register, num int) string { return content[num] } -func hash(s string) uint32 { - h := fnv.New32a() - h.Write([]byte(s)) - return h.Sum32() -} - // isValid checks if the text stored in this multi-clipboard is the same as the // text stored in the system clipboard (provided as an argument), and therefore // if it is safe to use the multi-clipboard for pasting instead of the system // clipboard. -func (c multiClipboard) isValid(r Register, clipboard string) bool { +func (c multiClipboard) isValid(r Register, clipboard string, ncursors int) bool { content := c[r] - if content == nil { + if content == nil || len(content) != ncursors { return false } - return hash(clipboard) == hash(c.getAllText(r)) + return clipboard == c.getAllText(r) } -func (c multiClipboard) writeText(text string, r Register, num int) { +func (c multiClipboard) writeText(text string, r Register, num int, ncursors int) { content := c[r] - if content == nil { - content = make([]string, num+1, num+1) + if content == nil || len(content) != ncursors { + content = make([]string, ncursors, ncursors) c[r] = content } - if num >= cap(content) { - newctnt := make([]string, num+1, num+1) - copy(newctnt, content) - content = newctnt - c[r] = content + if num >= ncursors { + return } content[num] = text