mirror of
https://github.com/walles/moar.git
synced 2024-11-22 11:45:50 +03:00
Simplify last-cell-on-a-row-is-wide handling
By doing the clipping in SetCell(). This is less intrusive than doing it in renderLine().
This commit is contained in:
parent
5bddefafe1
commit
189e622658
@ -40,26 +40,33 @@ func (screen *FakeScreen) Clear() {
|
||||
}
|
||||
}
|
||||
|
||||
func (screen *FakeScreen) SetCell(column int, row int, cell StyledRune) int {
|
||||
func (screen *FakeScreen) SetCell(column int, row int, styledRune StyledRune) int {
|
||||
// This method's contents has been copied from UnixScreen.Clear()
|
||||
|
||||
if column < 0 {
|
||||
return cell.Width()
|
||||
return styledRune.Width()
|
||||
}
|
||||
if row < 0 {
|
||||
return cell.Width()
|
||||
return styledRune.Width()
|
||||
}
|
||||
|
||||
width, height := screen.Size()
|
||||
if column >= width {
|
||||
return cell.Width()
|
||||
return styledRune.Width()
|
||||
}
|
||||
if row >= height {
|
||||
return cell.Width()
|
||||
return styledRune.Width()
|
||||
}
|
||||
screen.cells[row][column] = cell
|
||||
|
||||
return cell.Width()
|
||||
if column+styledRune.Width() > width {
|
||||
// This cell is too wide for the screen, write a space instead
|
||||
screen.cells[row][column] = NewStyledRune(' ', styledRune.Style)
|
||||
return styledRune.Width()
|
||||
}
|
||||
|
||||
screen.cells[row][column] = styledRune
|
||||
|
||||
return styledRune.Width()
|
||||
}
|
||||
|
||||
func (screen *FakeScreen) Show() {
|
||||
@ -88,5 +95,5 @@ func (screen *FakeScreen) Events() chan Event {
|
||||
}
|
||||
|
||||
func (screen *FakeScreen) GetRow(row int) []StyledRune {
|
||||
return withoutHiddenRunes(screen.cells[row], screen.width)
|
||||
return withoutHiddenRunes(screen.cells[row])
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ type Screen interface {
|
||||
Clear()
|
||||
|
||||
// Returns the width of the rune just added, in number of columns
|
||||
SetCell(column int, row int, cell StyledRune) int
|
||||
SetCell(column int, row int, styledRune StyledRune) int
|
||||
|
||||
// Render our contents into the terminal window
|
||||
Show()
|
||||
@ -623,24 +623,31 @@ func parseTerminalBgColorResponse(responseBytes []byte) *Color {
|
||||
return &color
|
||||
}
|
||||
|
||||
func (screen *UnixScreen) SetCell(column int, row int, cell StyledRune) int {
|
||||
func (screen *UnixScreen) SetCell(column int, row int, styledRune StyledRune) int {
|
||||
if column < 0 {
|
||||
return cell.Width()
|
||||
return styledRune.Width()
|
||||
}
|
||||
if row < 0 {
|
||||
return cell.Width()
|
||||
return styledRune.Width()
|
||||
}
|
||||
|
||||
width, height := screen.Size()
|
||||
if column >= width {
|
||||
return cell.Width()
|
||||
return styledRune.Width()
|
||||
}
|
||||
if row >= height {
|
||||
return cell.Width()
|
||||
return styledRune.Width()
|
||||
}
|
||||
screen.cells[row][column] = cell
|
||||
|
||||
return cell.Width()
|
||||
if column+styledRune.Width() > width {
|
||||
// This cell is too wide for the screen, write a space instead
|
||||
screen.cells[row][column] = NewStyledRune(' ', styledRune.Style)
|
||||
return styledRune.Width()
|
||||
}
|
||||
|
||||
screen.cells[row][column] = styledRune
|
||||
|
||||
return styledRune.Width()
|
||||
}
|
||||
|
||||
func (screen *UnixScreen) Clear() {
|
||||
@ -656,21 +663,16 @@ func (screen *UnixScreen) Clear() {
|
||||
|
||||
// A cell is considered hidden if it's preceded by a wide character that spans
|
||||
// multiple columns.
|
||||
//
|
||||
// Also, if the last cell on the screen is a wide character that would span the
|
||||
// screen border, it will be considered hidden as well.
|
||||
func withoutHiddenRunes(runes []StyledRune, screenWidth int) []StyledRune {
|
||||
func withoutHiddenRunes(runes []StyledRune) []StyledRune {
|
||||
result := make([]StyledRune, 0, len(runes))
|
||||
renderedWidth := 0
|
||||
for _, char := range runes {
|
||||
charWidth := char.Width()
|
||||
if renderedWidth+charWidth > screenWidth {
|
||||
// This character would span the screen border
|
||||
break
|
||||
|
||||
for i := 0; i < len(runes); i++ {
|
||||
if i > 0 && runes[i-1].Width() == 2 {
|
||||
// This is a hidden rune
|
||||
continue
|
||||
}
|
||||
|
||||
result = append(result, char)
|
||||
renderedWidth += charWidth
|
||||
result = append(result, runes[i])
|
||||
}
|
||||
|
||||
return result
|
||||
@ -678,8 +680,8 @@ func withoutHiddenRunes(runes []StyledRune, screenWidth int) []StyledRune {
|
||||
|
||||
// Returns the rendered line, plus how many information carrying cells went into
|
||||
// it
|
||||
func renderLine(row []StyledRune, screenWidth int, terminalColorCount ColorCount) (string, int) {
|
||||
row = withoutHiddenRunes(row, screenWidth)
|
||||
func renderLine(row []StyledRune, terminalColorCount ColorCount) (string, int) {
|
||||
row = withoutHiddenRunes(row)
|
||||
|
||||
// Strip trailing whitespace
|
||||
lastSignificantCellIndex := len(row) - 1
|
||||
@ -746,9 +748,8 @@ func (screen *UnixScreen) showNLines(height int, clearFirst bool) {
|
||||
builder.WriteString("\x1b[1;1H")
|
||||
}
|
||||
|
||||
screenWidth, _ := screen.Size()
|
||||
for row := 0; row < height; row++ {
|
||||
rendered, lineLength := renderLine(screen.cells[row], screenWidth, screen.terminalColorCount)
|
||||
rendered, lineLength := renderLine(screen.cells[row], screen.terminalColorCount)
|
||||
builder.WriteString(rendered)
|
||||
|
||||
wasLastLine := row == (height - 1)
|
||||
|
@ -65,7 +65,7 @@ func TestRenderLine(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
rendered, count := renderLine(row, 100, ColorCount16)
|
||||
rendered, count := renderLine(row, ColorCount16)
|
||||
assert.Equal(t, count, 2)
|
||||
reset := "[m"
|
||||
reversed := "[7m"
|
||||
@ -80,7 +80,7 @@ func TestRenderLine(t *testing.T) {
|
||||
func TestRenderLineEmpty(t *testing.T) {
|
||||
row := []StyledRune{}
|
||||
|
||||
rendered, count := renderLine(row, 100, ColorCount16)
|
||||
rendered, count := renderLine(row, ColorCount16)
|
||||
assert.Equal(t, count, 0)
|
||||
|
||||
// All lines are expected to stand on their own, so we always need to clear
|
||||
@ -96,7 +96,7 @@ func TestRenderLineLastReversed(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
rendered, count := renderLine(row, 100, ColorCount16)
|
||||
rendered, count := renderLine(row, ColorCount16)
|
||||
assert.Equal(t, count, 1)
|
||||
reset := "[m"
|
||||
reversed := "[7m"
|
||||
@ -114,7 +114,7 @@ func TestRenderLineLastNonSpace(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
rendered, count := renderLine(row, 100, ColorCount16)
|
||||
rendered, count := renderLine(row, ColorCount16)
|
||||
assert.Equal(t, count, 1)
|
||||
reset := "[m"
|
||||
clearToEol := "[K"
|
||||
@ -135,7 +135,7 @@ func TestRenderLineLastReversedPlusTrailingSpace(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
rendered, count := renderLine(row, 100, ColorCount16)
|
||||
rendered, count := renderLine(row, ColorCount16)
|
||||
assert.Equal(t, count, 1)
|
||||
reset := "[m"
|
||||
reversed := "[7m"
|
||||
@ -157,7 +157,7 @@ func TestRenderLineOnlyTrailingSpaces(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
rendered, count := renderLine(row, 100, ColorCount16)
|
||||
rendered, count := renderLine(row, ColorCount16)
|
||||
assert.Equal(t, count, 0)
|
||||
|
||||
// All lines are expected to stand on their own, so we always need to clear
|
||||
@ -173,7 +173,7 @@ func TestRenderLineLastReversedSpaces(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
rendered, count := renderLine(row, 100, ColorCount16)
|
||||
rendered, count := renderLine(row, ColorCount16)
|
||||
assert.Equal(t, count, 1)
|
||||
reset := "[m"
|
||||
reversed := "[7m"
|
||||
@ -190,7 +190,7 @@ func TestRenderLineNonPrintable(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
rendered, count := renderLine(row, 100, ColorCount16)
|
||||
rendered, count := renderLine(row, ColorCount16)
|
||||
assert.Equal(t, count, 1)
|
||||
reset := "[m"
|
||||
white := "[37m"
|
||||
@ -211,7 +211,7 @@ func TestRenderHyperlinkAtEndOfLine(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
rendered, count := renderLine(row, 100, ColorCount16)
|
||||
rendered, count := renderLine(row, ColorCount16)
|
||||
assert.Equal(t, count, 1)
|
||||
|
||||
assert.Equal(t,
|
||||
@ -236,7 +236,7 @@ func TestMultiCharHyperlink(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
rendered, count := renderLine(row, 100, ColorCount16)
|
||||
rendered, count := renderLine(row, ColorCount16)
|
||||
assert.Equal(t, count, 3)
|
||||
|
||||
assert.Equal(t,
|
||||
|
Loading…
Reference in New Issue
Block a user