From 2aef9eb77f52940298c7165f4a84c78439d6352f Mon Sep 17 00:00:00 2001 From: theimpostor Date: Thu, 22 Aug 2024 19:45:21 -0500 Subject: Break up screen copy operation into chunks --- main.go | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index 0f31819..806075e 100644 --- a/main.go +++ b/main.go @@ -117,6 +117,39 @@ func identifyTerm() { } } +// Breaks up every 250 bytes with a screen dcs end + start sequence +// Based on: https://github.com/chromium/hterm/blob/6846a85f9579a8dfdef4405cc50d9fb17d8944aa/etc/osc52.sh#L23 +const chunkSize = 250 + +type chunkingWriter struct { + bytesWritten int64 + writer io.Writer +} + +func (w *chunkingWriter) Write(p []byte) (n int, err error) { + slog.Debug(fmt.Sprintf("chunkingWriter got %d bytes", len(p))) + + for err == nil && len(p) > 0 { + bytesWritten := 0 + chunksWritten := w.bytesWritten / chunkSize + nextChunkBoundary := (chunksWritten + 1) * chunkSize + + if w.bytesWritten+int64(len(p)) < nextChunkBoundary { + bytesWritten, err = w.writer.Write(p) + } else { + bytesWritten, err = w.writer.Write(p[:nextChunkBoundary-w.bytesWritten]) + if err == nil { + _, err = w.writer.Write([]byte("\x1b\\\x1bP")) + } + } + w.bytesWritten += int64(bytesWritten) + n += bytesWritten + p = p[bytesWritten:] + } + + return +} + func copy(fnames []string) error { // copy if isTmux { @@ -156,8 +189,13 @@ func copy(fnames []string) error { defer closetty(tty) // Open buffered output, using default max OSC52 length as buffer size - // TODO limit size - out := bufio.NewWriterSize(tty, 1000000) + var out *bufio.Writer + if isScreen { + // TODO: stdout or tty? + out = bufio.NewWriterSize(&chunkingWriter{writer: os.Stdout}, 1000000) + } else { + out = bufio.NewWriterSize(tty, 1000000) + } // Start OSC52 fmt.Fprint(out, oscOpen) -- cgit v1.2.3