mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-10-06 14:06:32 -04:00
Report a wrapped selection by the lines of content it covers
A test asks which lines of a view are selected; a wrapping view's cursor and range anchor answer in view lines, which count the segments each line is drawn as. Going through the segment-to-line mapping keeps the answer in the terms the question was asked in, and a line the selection covers several segments of is reported once. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
0ae23b15a1
commit
0bce007abe
+26
-3
@@ -1985,11 +1985,12 @@ func (v *View) SelectedLine() string {
|
||||
v.writeMutex.Lock()
|
||||
defer v.writeMutex.Unlock()
|
||||
|
||||
if len(v.buf.lines) == 0 {
|
||||
idx, ok := v.bufferLineForViewLine(v.SelectedLineIdx())
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
return v.lineContentAtIdx(v.SelectedLineIdx())
|
||||
return v.lineContentAtIdx(idx)
|
||||
}
|
||||
|
||||
// expected to only be used in tests
|
||||
@@ -2004,8 +2005,17 @@ func (v *View) SelectedLines() []string {
|
||||
startIdx, endIdx := v.SelectedLineRange()
|
||||
|
||||
lines := make([]string, 0, endIdx-startIdx+1)
|
||||
previous := -1
|
||||
for i := startIdx; i <= endIdx; i++ {
|
||||
lines = append(lines, v.lineContentAtIdx(i))
|
||||
// The selection is in view lines, which count the segments a wrapped line
|
||||
// is drawn as; a line the selection covers several segments of is still
|
||||
// the one line it is.
|
||||
idx, ok := v.bufferLineForViewLine(i)
|
||||
if !ok || idx == previous {
|
||||
continue
|
||||
}
|
||||
previous = idx
|
||||
lines = append(lines, v.lineContentAtIdx(idx))
|
||||
}
|
||||
|
||||
return lines
|
||||
@@ -2015,6 +2025,19 @@ func (v *View) lineContentAtIdx(idx int) string {
|
||||
return v.buf.lines[idx].cells.String()
|
||||
}
|
||||
|
||||
// bufferLineForViewLine maps a view line index, which counts the wrapped
|
||||
// segments of the lines it draws, to the index of the line of content it is a
|
||||
// segment of. Only call this with a lock on writeMutex.
|
||||
func (v *View) bufferLineForViewLine(y int) (int, bool) {
|
||||
v.refreshViewLinesIfNeeded()
|
||||
|
||||
if y < 0 || y >= len(v.viewLines) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return v.viewLines[y].linesY, true
|
||||
}
|
||||
|
||||
func (v *View) SelectedPoint() (int, int) {
|
||||
cx, cy := v.Cursor()
|
||||
ox, oy := v.Origin()
|
||||
|
||||
@@ -837,15 +837,9 @@ func TestSelectedLinesOfWrappedContent(t *testing.T) {
|
||||
|
||||
// The cursor on the wrapped line's second half is on that line.
|
||||
v.FocusPoint(0, 3, false)
|
||||
/* EXPECTED:
|
||||
assert.Equal(t, "a line that wraps", v.SelectedLine())
|
||||
ACTUAL: */
|
||||
assert.Equal(t, "four", v.SelectedLine())
|
||||
|
||||
// A range over both halves of the wrapped line covers one line of content.
|
||||
v.SetRangeSelectStart(2)
|
||||
/* EXPECTED:
|
||||
assert.Equal(t, []string{"a line that wraps"}, v.SelectedLines())
|
||||
ACTUAL: */
|
||||
assert.Equal(t, []string{"a line that wraps", "four"}, v.SelectedLines())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user