mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-11-01 08:28:06 -06:00
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:
1 parent
cbfa22cfbe
commit
3f64902a11
2 files changed
+59
-7
No files matched your search
+40
-7
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in new issue
Block a user