Improve multicursor clipboard

Ref #1721
This commit is contained in:
Zachary Yedidia 2020-07-05 01:12:35 -04:00
parent 037c3c993f
commit 102ae04a16
4 changed files with 20 additions and 31 deletions

View File

@ -995,7 +995,7 @@ func (h *BufPane) CutLine() bool {
if clip, err := clipboard.Read(clipboard.ClipboardReg); err != nil { if clip, err := clipboard.Read(clipboard.ClipboardReg); err != nil {
InfoBar.Error(err) InfoBar.Error(err)
} else { } 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 { } 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 // Paste whatever is in the system clipboard into the buffer
// Delete and paste if the user has a selection // Delete and paste if the user has a selection
func (h *BufPane) Paste() bool { 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 { if err != nil {
InfoBar.Error(err) InfoBar.Error(err)
} else { } else {
@ -1151,7 +1151,7 @@ func (h *BufPane) Paste() bool {
// PastePrimary pastes from the primary clipboard (only use on linux) // PastePrimary pastes from the primary clipboard (only use on linux)
func (h *BufPane) PastePrimary() bool { 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 { if err != nil {
InfoBar.Error(err) InfoBar.Error(err)
} else { } else {

View File

@ -128,7 +128,7 @@ func (c *Cursor) End() {
func (c *Cursor) CopySelection(target clipboard.Register) { func (c *Cursor) CopySelection(target clipboard.Register) {
if c.HasSelection() { if c.HasSelection() {
if target != clipboard.PrimaryReg || c.buf.Settings["useprimary"].(bool) { 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())
} }
} }
} }

View File

@ -69,30 +69,30 @@ func Write(text string, r Register) error {
} }
// ReadMulti reads text from a clipboard register for a certain multi-cursor // 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) clip, err := Read(r)
if err != nil { if err != nil {
return "", err return "", err
} }
if ValidMulti(r, clip) { if ValidMulti(r, clip, ncursors) {
return multi.getText(r, num), nil return multi.getText(r, num), nil
} }
return clip, nil return clip, nil
} }
// WriteMulti writes text to a clipboard register for a certain multi-cursor // WriteMulti writes text to a clipboard register for a certain multi-cursor
func WriteMulti(text string, r Register, num int) error { func WriteMulti(text string, r Register, num int, ncursors int) error {
return writeMulti(text, r, num, CurrentMethod) return writeMulti(text, r, num, ncursors, CurrentMethod)
} }
// ValidMulti checks if the internal multi-clipboard is valid and up-to-date // ValidMulti checks if the internal multi-clipboard is valid and up-to-date
// with the system clipboard // with the system clipboard
func ValidMulti(r Register, clip string) bool { func ValidMulti(r Register, clip string, ncursors int) bool {
return multi.isValid(r, clip) return multi.isValid(r, clip, ncursors)
} }
func writeMulti(text string, r Register, num int, m Method) error { func writeMulti(text string, r Register, num int, ncursors int, m Method) error {
multi.writeText(text, r, num) multi.writeText(text, r, num, ncursors)
return write(multi.getAllText(r), r, m) return write(multi.getAllText(r), r, m)
} }

View File

@ -2,7 +2,6 @@ package clipboard
import ( import (
"bytes" "bytes"
"hash/fnv"
) )
// For storing multi cursor clipboard contents // For storing multi cursor clipboard contents
@ -19,7 +18,6 @@ func (c multiClipboard) getAllText(r Register) string {
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
for _, s := range content { for _, s := range content {
buf.WriteString(s) buf.WriteString(s)
buf.WriteByte('\n')
} }
return buf.String() return buf.String()
} }
@ -33,37 +31,28 @@ func (c multiClipboard) getText(r Register, num int) string {
return content[num] 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 // 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 // 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 // if it is safe to use the multi-clipboard for pasting instead of the system
// clipboard. // clipboard.
func (c multiClipboard) isValid(r Register, clipboard string) bool { func (c multiClipboard) isValid(r Register, clipboard string, ncursors int) bool {
content := c[r] content := c[r]
if content == nil { if content == nil || len(content) != ncursors {
return false 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] content := c[r]
if content == nil { if content == nil || len(content) != ncursors {
content = make([]string, num+1, num+1) content = make([]string, ncursors, ncursors)
c[r] = content c[r] = content
} }
if num >= cap(content) { if num >= ncursors {
newctnt := make([]string, num+1, num+1) return
copy(newctnt, content)
content = newctnt
c[r] = content
} }
content[num] = text content[num] = text