Bump gocui

This updates gocui to include https://github.com/jesseduffield/gocui/pull/68 and
https://github.com/jesseduffield/gocui/pull/69, which changes views to not have
an extra blank line at the end when content ending in a newline character is
written to them. This makes text views more consistent with list views, which
don't have a blank line after the last list entry either.
This commit is contained in:
Stefan Haller 2025-01-07 17:33:51 +01:00
parent 13829d8ff7
commit ae53059ed2
10 changed files with 84 additions and 57 deletions

View file

@ -66,6 +66,11 @@ type View struct {
// true and viewLines to nil
viewLines []viewLine
// If the last character written was a newline, we don't write it but
// instead set pendingNewline to true. If more text is written, we write the
// newline then. This is to avoid having an extra blank at the end of the view.
pendingNewline bool
// writeMutex protects locks the write process
writeMutex sync.Mutex
@ -647,6 +652,9 @@ func (v *View) SetWritePos(x, y int) {
v.wx = x
v.wy = y
// Changing the write position makes a pending newline obsolete
v.pendingNewline = false
}
// WritePos returns the current write position of the view's internal buffer.
@ -690,7 +698,7 @@ func (v *View) makeWriteable(x, y int) {
v.lines = append(v.lines, nil)
}
}
// cell `x` must not be index-able (that's why `<`)
// cell `x` need not be index-able (that's why `<`)
// append should be used by `lines[y]` user if he wants to write beyond `x`
for len(v.lines[y]) < x {
if cap(v.lines[y]) > len(v.lines[y]) {
@ -726,14 +734,6 @@ func (v *View) writeCells(x, y int, cells []cell) {
v.lines[y] = line[:newLen]
}
// readCell gets cell at specified location (x, y)
func (v *View) readCell(x, y int) (cell, bool) {
if y < 0 || y >= len(v.lines) || x < 0 || x >= len(v.lines[y]) {
return cell{}, false
}
return v.lines[y][x], true
}
// Write appends a byte slice into the view's internal buffer. Because
// View implements the io.Writer interface, it can be passed as parameter
// of functions like fmt.Fprintf, fmt.Fprintln, io.Copy, etc. Clear must
@ -762,31 +762,43 @@ func (v *View) writeRunes(p []rune) {
// Fill with empty cells, if writing outside current view buffer
v.makeWriteable(v.wx, v.wy)
for _, r := range p {
finishLine := func() {
v.autoRenderHyperlinksInCurrentLine()
if v.wx >= len(v.lines[v.wy]) {
v.writeCells(v.wx, v.wy, []cell{{
chr: 0,
fgColor: 0,
bgColor: 0,
}})
}
}
advanceToNextLine := func() {
v.wx = 0
v.wy++
if v.wy >= len(v.lines) {
v.lines = append(v.lines, nil)
}
}
if v.pendingNewline {
advanceToNextLine()
v.pendingNewline = false
}
until := len(p)
if until > 0 && p[until-1] == '\n' {
v.pendingNewline = true
until--
}
for _, r := range p[:until] {
switch r {
case '\n':
v.autoRenderHyperlinksInCurrentLine()
if c, ok := v.readCell(v.wx+1, v.wy); !ok || c.chr == 0 {
v.writeCells(v.wx, v.wy, []cell{{
chr: 0,
fgColor: 0,
bgColor: 0,
}})
}
v.wx = 0
v.wy++
if v.wy >= len(v.lines) {
v.lines = append(v.lines, nil)
}
finishLine()
advanceToNextLine()
case '\r':
v.autoRenderHyperlinksInCurrentLine()
if c, ok := v.readCell(v.wx, v.wy); !ok || c.chr == 0 {
v.writeCells(v.wx, v.wy, []cell{{
chr: 0,
fgColor: 0,
bgColor: 0,
}})
}
finishLine()
v.wx = 0
default:
truncateLine, cells := v.parseInput(r, v.wx, v.wy)
@ -803,6 +815,10 @@ func (v *View) writeRunes(p []rune) {
}
}
if v.pendingNewline {
finishLine()
}
v.updateSearchPositions()
}