Skip to content

Commit

Permalink
Improve column's overflow
Browse files Browse the repository at this point in the history
Add the start position to the COLUMN judgment.
Make variable names easier to understand for refactoring.
Add Comment.
  • Loading branch information
noborus committed Sep 17, 2024
1 parent f373308 commit 557cd58
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 85 deletions.
41 changes: 22 additions & 19 deletions oviewer/convert_align.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,47 +129,50 @@ func (a *align) convertDelm(src contents) contents {
func (a *align) convertWidth(src contents) contents {
dst := make(contents, 0, len(src))

s := 0
start := 0
for c := 0; c < len(a.orgWidths); c++ {
e := findColumnEnd(src, a.orgWidths, c) + 1
e = min(e, len(src))
end := findColumnEnd(src, a.orgWidths, c, start) + 1
end = min(end, len(src))

if a.isShrink(c) {
dst = appendShrink(dst, nil)
dst = append(dst, SpaceContent)
a.maxWidths[c] = runewidth.RuneWidth(Shrink)
s = e
start = end
continue
}

ss := countLeftSpaces(src, s)
ee := countRightSpaces(src, e)
if ss >= ee {
s = e
tStart := findStartWithTrim(src, start)
tEnd := findEndWidthTrim(src, end)
// If the column width is 0, skip.
if tStart >= tEnd {
start = end
continue
}
addSpace := 0

padding := 0
if c < len(a.maxWidths) {
addSpace = (a.maxWidths[c] - (ee - ss))
padding = (a.maxWidths[c] - (tEnd - tStart))
}
s = e
start = end

if a.isRightAlign(c) {
// Add left space to align columns.
dst = appendSpaces(dst, addSpace)
dst = appendSpaces(dst, padding)
// Add content.
dst = append(dst, src[ss:ee]...)
dst = append(dst, src[tStart:tEnd]...)
} else {
// Add content.
dst = append(dst, src[ss:ee]...)
dst = append(dst, src[tStart:tEnd]...)
// Add right space to align columns.
dst = appendSpaces(dst, addSpace)
dst = appendSpaces(dst, padding)
}
dst = append(dst, SpaceContent)

}

// Add the remaining content.
if !a.isShrink(len(a.orgWidths)) {
dst = append(dst, src[s:]...)
dst = append(dst, src[start:]...)
return dst
}
dst = appendShrink(dst, nil)
Expand Down Expand Up @@ -206,13 +209,13 @@ func (a *align) isRightAlign(col int) bool {
return false
}

func countLeftSpaces(lc contents, s int) int {
func findStartWithTrim(lc contents, s int) int {
for ; s < len(lc) && lc[s].mainc == ' '; s++ {
}
return s
}

func countRightSpaces(lc contents, e int) int {
func findEndWidthTrim(lc contents, e int) int {
for ; e > 0 && lc[e-1].mainc == ' '; e-- {
}
return e
Expand Down
84 changes: 55 additions & 29 deletions oviewer/prepare_draw.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ func maxWidthsWidth(lc contents, maxWidths []int, widths []int, rightCount []int
}
s := 0
for i := 0; i < len(widths); i++ {
e := findColumnEnd(lc, widths, i) + 1
e := findColumnEnd(lc, widths, i, s) + 1
width, addRight := trimWidth(lc[s:e])
if len(maxWidths) <= i {
maxWidths = append(maxWidths, width)
Expand Down Expand Up @@ -470,10 +470,7 @@ func (root *Root) columnDelimiterHighlight(line LineC) {
switch {
case c == 0 && lStart == 0:
iStart = lStart
iEnd = indexes[0][1] - len(m.ColumnDelimiter)
if iEnd < 0 {
iEnd = 0
}
iEnd = max(indexes[0][1]-len(m.ColumnDelimiter), 0)
case c < len(indexes):
iStart = iEnd + 1
iEnd = indexes[c][0]
Expand Down Expand Up @@ -504,13 +501,12 @@ func (root *Root) columnWidthHighlight(line LineC) {

numC := len(root.StyleColumnRainbow)

start := 0
start, end := 0, 0
for c := 0; c < len(indexes)+1; c++ {
end := 0
if m.Converter == convAlign {
end = alignColumnEnd(line.lc, m.alignConv.maxWidths, c, start)
} else {
end = findColumnEnd(line.lc, indexes, c)
end = findColumnEnd(line.lc, indexes, c, start)
}

if m.ColumnRainbow {
Expand All @@ -524,41 +520,71 @@ func (root *Root) columnWidthHighlight(line LineC) {
}

// findColumnEnd returns the position of the end of a column.
func findColumnEnd(lc contents, indexes []int, n int) int {
func findColumnEnd(lc contents, indexes []int, n int, start int) int {
// If the column index is out of bounds, return the length of the contents.
if len(indexes) <= n {
return len(lc)
}
width := indexes[n]
if width >= len(lc) {

columnEnd := indexes[n]
// The end of the right end returns the length of the contents.
if columnEnd >= len(lc) {
return len(lc)
}

if lc[width].mainc == ' ' {
return width
// If the character at the end of the column is a space, return the end of the column.
if lc[columnEnd].mainc == ' ' {
return columnEnd
}

f := width
for ; f < len(lc) && lc[f].mainc != ' '; f++ {
}
b := width
for ; b > 0 && lc[b].mainc != ' '; b-- {
}
// Column overflow.
lCount, lPos := countToNextSpaceLeft(lc, columnEnd)
rCount, rPos := countToNextSpaceRight(lc, columnEnd)

if b == indexes[n] {
return f
// Is the column omitted?
if lPos == columnEnd {
return rPos
}

// Check the position of the next column.
if n < len(indexes)-1 {
if f == indexes[n+1] {
return b
}
if b == indexes[n] {
return f
// If the next column is reached, return the position shifted to the left.
if rPos == indexes[n+1] {
return lPos
}
if b > indexes[n] && b < indexes[n+1] {
return b
// If the position is between the end of the column and the start of the next column,
// return the position shifted to the left.
if lPos > columnEnd && lPos < indexes[n+1] {
return lPos
}
}
return f
// It overflows on the left side.
if lPos > start && rCount > lCount {
return lPos
}

// It overflows on the right side.
return rPos
}

// countToNextSpaceLeft counts the number of positions to the next space character to the left.
func countToNextSpaceLeft(lc contents, start int) (int, int) {
count := 0
i := start
for ; i >= 0 && lc[i].mainc != ' '; i-- {
count++
}
return count, i
}

// countToNextSpaceRight counts the number of positions to the next space character to the right.
func countToNextSpaceRight(lc contents, start int) (int, int) {
count := 0
i := start
for ; i < len(lc) && lc[i].mainc != ' '; i++ {
count++
}
return count, i
}

// alignColumnEnd returns the position of the end of a column.
Expand Down
86 changes: 49 additions & 37 deletions oviewer/prepare_draw_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -850,9 +850,10 @@ func TestRoot_sectionNum(t *testing.T) {

func Test_findColumnEnd(t *testing.T) {
type args struct {
str string
pos []int
n int
str string
pos []int
n int
start int
}
tests := []struct {
name string
Expand All @@ -862,107 +863,118 @@ func Test_findColumnEnd(t *testing.T) {
{
name: "Test findColumnEnd1Over",
args: args{
str: "012345678901234567890123",
pos: []int{7, 15},
n: 0,
str: "012345678901234567890123",
pos: []int{7, 15},
n: 0,
start: 0,
},
want: 24,
},
{
name: "Test findColumnEnd2",
args: args{
str: "header1 header2 header3",
pos: []int{7, 15},
n: 0,
str: "header1 header2 header3",
pos: []int{7, 15},
n: 0,
start: 0,
},
want: 7,
},
{
name: "Test findColumnEnd3",
args: args{
str: "1 2 3",
pos: []int{7, 15},
n: 0,
str: "1 2 3",
pos: []int{7, 15},
n: 0,
start: 0,
},
want: 7,
},
{
name: "Test findColumnEnd4",
args: args{
str: " 1 2 3",
pos: []int{7, 15},
n: 0,
str: " 1 2 3",
pos: []int{7, 15},
n: 0,
start: 0,
},
want: 7,
},
{
name: "Test findColumnEnd6Over1",
args: args{
str: "123 456789012 345678901234",
pos: []int{7, 15},
n: 0,
str: "123 456789012 345678901234",
pos: []int{7, 15},
n: 0,
start: 0,
},
want: 5,
},
{
name: "Test findColumnEnd6Over2",
args: args{
str: "123 456789012 345678901234",
pos: []int{7, 15},
n: 1,
str: "123 456789012 345678901234",
pos: []int{7, 15},
n: 1,
start: 6,
},
want: 15,
},
{
name: "Test findColumnEnd7Over1",
args: args{
str: "abedefghi jkujik mnoopqr",
pos: []int{7, 15},
n: 0,
str: "abedefghi jkujik mnoopqr",
pos: []int{7, 15},
n: 0,
start: 0,
},
want: 9,
},
{
name: "Test findColumnEnd7Over2",
args: args{
str: "abedefghi jkujikl mnoopqr",
pos: []int{7, 15},
n: 1,
str: "abedefghi jkujikl mnoopqr",
pos: []int{7, 15},
n: 1,
start: 0,
},
want: 17,
},
{
name: "Test findColumnEnd8Over1",
args: args{
str: "abedefghi jkujikl mnoopqr",
pos: []int{7, 15},
n: 0,
str: "abedefghi jkujikl mnoopqr",
pos: []int{7, 15},
n: 0,
start: 0,
},
want: 9,
},
{
name: "Test findColumnEnd8Over2",
args: args{
str: "あいうえお かきくけこ さしすせそ",
pos: []int{7, 15},
n: 1,
str: "あいうえお かきくけこ さしすせそ",
pos: []int{10, 15},
n: 1,
start: 10,
},
want: 21,
},
{
name: "Test findColumnEnd9Over",
args: args{
str: "abedefg hijkujiklmnoopqrstuvxyz",
pos: []int{7, 15},
n: 1,
str: "abedefg hijkujiklmnoopqrstuvxyz",
pos: []int{7, 15},
n: 1,
start: 7,
},
want: 31,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
lc := StrToContents(tt.args.str, 8)
if got := findColumnEnd(lc, tt.args.pos, tt.args.n); got != tt.want {
if got := findColumnEnd(lc, tt.args.pos, tt.args.n, tt.args.start); got != tt.want {
t.Errorf("findColumnEnd() = %v, want %v", got, tt.want)
}
})
Expand Down

0 comments on commit 557cd58

Please sign in to comment.