Fix reading clipboard internally for OSC52

This commit is contained in:
Zachary Yedidia
2020-07-04 20:54:27 -04:00
parent cf86f6848f
commit d8596919a6
7 changed files with 48 additions and 26 deletions

View File

@@ -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()

View File

@@ -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()
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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