diff --git a/cmd/micro/micro.go b/cmd/micro/micro.go index 723e11b7..53e232f0 100644 --- a/cmd/micro/micro.go +++ b/cmd/micro/micro.go @@ -27,7 +27,6 @@ import ( var ( // Event channel - events chan tcell.Event autosave chan bool // Command line flags @@ -321,7 +320,7 @@ func main() { action.InfoBar.Error(clipErr, " or change 'clipboard' option") } - events = make(chan tcell.Event) + screen.Events = make(chan tcell.Event) // Here is the event loop which runs in a separate thread go func() { @@ -330,7 +329,7 @@ func main() { e := screen.Screen.PollEvent() screen.Unlock() if e != nil { - events <- e + screen.Events <- e } } }() @@ -343,7 +342,7 @@ func main() { // wait for initial resize event select { - case event := <-events: + case event := <-screen.Events: action.Tabs.HandleEvent(event) case <-time.After(10 * time.Millisecond): // time out after 10ms @@ -396,7 +395,7 @@ func DoEvent() { } ulua.Lock.Unlock() case <-shell.CloseTerms: - case event = <-events: + case event = <-screen.Events: case <-screen.DrawChan(): for len(screen.DrawChan()) > 0 { <-screen.DrawChan() diff --git a/cmd/micro/micro_test.go b/cmd/micro/micro_test.go index ec99b248..0a52bc8f 100644 --- a/cmd/micro/micro_test.go +++ b/cmd/micro/micro_test.go @@ -20,7 +20,7 @@ var tempDir string var sim tcell.SimulationScreen func init() { - events = make(chan tcell.Event, 8) + screen.Events = make(chan tcell.Event, 8) } func startup(args []string) (tcell.SimulationScreen, error) { @@ -106,7 +106,7 @@ func handleEvent() { e := screen.Screen.PollEvent() screen.Unlock() if e != nil { - events <- e + screen.Events <- e } DoEvent() } diff --git a/internal/action/actions.go b/internal/action/actions.go index 5d7b31e0..b1ed974e 100644 --- a/internal/action/actions.go +++ b/internal/action/actions.go @@ -1142,8 +1142,9 @@ func (h *BufPane) Paste() bool { clip, err := clipboard.Read(clipboard.ClipboardReg) if err != nil { InfoBar.Error(err) + } else { + h.paste(clip) } - h.paste(clip) h.Relocate() return true } @@ -1153,8 +1154,9 @@ func (h *BufPane) PastePrimary() bool { clip, err := clipboard.Read(clipboard.PrimaryReg) if err != nil { InfoBar.Error(err) + } else { + h.paste(clip) } - h.paste(clip) h.Relocate() return true } diff --git a/internal/clipboard/clipboard.go b/internal/clipboard/clipboard.go index 3a7dd004..9fad3571 100644 --- a/internal/clipboard/clipboard.go +++ b/internal/clipboard/clipboard.go @@ -70,8 +70,14 @@ 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) { - s := multi.getText(r, num) - return s, nil + clip, err := Read(r) + if err != nil { + return "", err + } + if ValidMulti(r, clip) { + return multi.getText(r, num), nil + } + return clip, nil } // WriteMulti writes text to a clipboard register for a certain multi-cursor @@ -81,12 +87,8 @@ func WriteMulti(text string, r Register, num int) error { // ValidMulti checks if the internal multi-clipboard is valid and up-to-date // with the system clipboard -func ValidMulti(r Register, ncursors int) bool { - clip, err := Read(r) - if err != nil { - return false - } - return multi.isValid(r, ncursors, clip) +func ValidMulti(r Register, clip string) bool { + return multi.isValid(r, clip) } func writeMulti(text string, r Register, num int, m Method) error { @@ -112,11 +114,9 @@ func read(r Register, m Method) (string, error) { case ClipboardReg: // terminal paste works by sending an esc sequence to the // terminal to trigger a paste event - err := terminal.read("clipboard") - return "", err + return terminal.read("clipboard") case PrimaryReg: - err := terminal.read("primary") - return "", err + return terminal.read("primary") default: return internal.read(r), nil } diff --git a/internal/clipboard/multi.go b/internal/clipboard/multi.go index 25a19321..47cc43eb 100644 --- a/internal/clipboard/multi.go +++ b/internal/clipboard/multi.go @@ -43,9 +43,9 @@ func hash(s string) uint32 { // 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, ncursors int, clipboard string) bool { +func (c multiClipboard) isValid(r Register, clipboard string) bool { content := c[r] - if content == nil || len(content) != ncursors { + if content == nil { return false } diff --git a/internal/clipboard/terminal.go b/internal/clipboard/terminal.go index 37b37dc3..fca42967 100644 --- a/internal/clipboard/terminal.go +++ b/internal/clipboard/terminal.go @@ -1,13 +1,31 @@ package clipboard -import "github.com/zyedidia/micro/v2/internal/screen" +import ( + "errors" + "time" + + "github.com/zyedidia/micro/v2/internal/screen" + "github.com/zyedidia/tcell" +) type terminalClipboard struct{} var terminal terminalClipboard -func (t terminalClipboard) read(reg string) error { - return screen.Screen.GetClipboard(reg) +func (t terminalClipboard) read(reg string) (string, error) { + screen.Screen.GetClipboard(reg) + // wait at most 200ms for response + for { + select { + case event := <-screen.Events: + e, ok := event.(*tcell.EventPaste) + if ok { + return e.Text(), nil + } + case <-time.After(200 * time.Millisecond): + return "", errors.New("No clipboard received from terminal") + } + } } func (t terminalClipboard) write(text, reg string) error { diff --git a/internal/screen/screen.go b/internal/screen/screen.go index 9093d8f9..a8fdc6df 100644 --- a/internal/screen/screen.go +++ b/internal/screen/screen.go @@ -18,6 +18,9 @@ import ( // same time too. var Screen tcell.Screen +// Events is the channel of tcell events +var Events chan (tcell.Event) + // The lock is necessary since the screen is polled on a separate thread var lock sync.Mutex