Collect the records of a line when the line has been written

Under a diff renderer that states which diff line each row shows, such
as delta, moving the selection by change block in a diff of 300,000
lines lags noticeably. One reason is that the queries about the lines
of the main view collect the records of every row from the row's
cells, going through every cell of every row. Under delta, a row has
about 130 cells.

Collect the records of a line once, when the write cursor moves on to
the next line, and take them from there. A line that is written to
again is read from its cells until it has been finished again.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan HallerandClaude Opus 5.5 committed 2026-10-14 08:41:50 +02:00
1 parent cbfa22cfbe
commit 3f64902a11
2 files changed
+59 -7

No files matched your search

+40 -7
View File
@@ -754,6 +754,15 @@ type lineType struct {
// which they hold as the overwrite it caused. nil while the cells spell the
// line as it was written, as they do for most lines.
asWritten []byte
// metadata holds the OSC 1717 records that the line's cells carry, each once, in
// the order they first appear. They are collected when the write cursor moves on
// to the next line, so that a reader can take them from here instead of going
// through every cell of every line. metadataCollected is false until then, and
// again once anything is written to the line; a reader then takes them from the
// cells.
metadata []string
metadataCollected bool
}
// textAsWritten returns the line's text as its writer wrote it, escape sequences
@@ -766,6 +775,34 @@ func (l *lineType) textAsWritten() string {
return l.cells.String()
}
// diffLineMetadata returns the OSC 1717 records that the line's cells carry (see
// lineType.metadata).
func (l *lineType) diffLineMetadata() []string {
if l.metadataCollected {
return l.metadata
}
return metadataOfCells(l.cells)
}
// collectMetadata keeps the records that the line's cells carry, for readers to take
// without going through the cells (see lineType.metadata).
func (l *lineType) collectMetadata() {
l.metadata = metadataOfCells(l.cells)
l.metadataCollected = true
}
// metadataOfCells returns the OSC 1717 records that the given cells carry, each once,
// in the order they first appear.
func metadataOfCells(cells []cell) []string {
var metadata []string
for _, c := range cells {
if c.metadata != "" && !slices.Contains(metadata, c.metadata) {
metadata = append(metadata, c.metadata)
}
}
return metadata
}
// trailingFillAttributes describes the fg/bg colors that draw() should
// use for cells past the end of a wrapped segment's content. On a source
// line this records what the writer asked for via '\x1b[K' (and so opts
@@ -1153,6 +1190,7 @@ func (b *viewBuffer) writeCells(cells []cell) {
}
}
b.lines[b.wy].cells = line[:newLen]
b.lines[b.wy].metadataCollected = false
b.wx += len(cells)
}
@@ -1244,6 +1282,7 @@ func (b *viewBuffer) write(v *View, p []byte) {
}
advanceToNextLine := func() {
b.lines[b.wy].collectMetadata()
b.seekWrite(0, b.wy+1)
if b.wy >= len(b.lines) {
b.lines = append(b.lines, lineType{})
@@ -2170,13 +2209,7 @@ func diffLineContentsFrom(buf *viewBuffer, from int) []DiffLineContent {
contents := make([]DiffLineContent, len(lines))
for i := range lines {
line := &lines[i]
var metadata []string
for _, c := range line.cells {
if c.metadata != "" && !slices.Contains(metadata, c.metadata) {
metadata = append(metadata, c.metadata)
}
}
contents[i] = DiffLineContent{Text: line.textAsWritten(), Metadata: metadata}
contents[i] = DiffLineContent{Text: line.textAsWritten(), Metadata: line.diffLineMetadata()}
}
return contents
}
+19
View File
@@ -335,6 +335,25 @@ func TestDiffLineContentsWithRecordsCoveringNoCell(t *testing.T) {
}, v.DiffLineContents())
}
func TestDiffLineContentsOfARewrittenLine(t *testing.T) {
v := NewView("name", 0, 0, 80, 10, OutputNormal)
v.writeString(strings.Join([]string{
osc1717("1;c;1;;foo.txt") + "line1",
osc1717("1;c;2;;foo.txt") + "line2",
"last line",
}, "\n"))
// The records of a line that is written again are the ones it is written with,
// even when the line's earlier records were taken from it already.
v.OverwriteLines(0, osc1717("1;a;7;;bar.txt")+"new1")
assert.Equal(t, []DiffLineContent{
{Text: "new1", Metadata: []string{"1;a;7;;bar.txt"}},
{Text: "line2", Metadata: []string{"1;c;2;;foo.txt"}},
{Text: "last line"},
}, v.DiffLineContents())
}
func TestDiffLineContentsSwallowsHandshake(t *testing.T) {
v := NewView("name", 0, 0, 80, 10, OutputNormal)