Skip to content

Commit

Permalink
Merge pull request #631 from noborus/change-column-delimiter
Browse files Browse the repository at this point in the history
Change the specifications of column by delimiter
  • Loading branch information
noborus authored Sep 29, 2024
2 parents 9ce1f13 + 84a8b1b commit 2c77138
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 161 deletions.
4 changes: 3 additions & 1 deletion oviewer/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,8 @@ func (root *Root) esFormat(ctx context.Context) {
// setDelimiter sets the delimiter string.
func (root *Root) setDelimiter(input string) {
root.Doc.setDelimiter(input)
root.Doc.optimalCursor(root.scr, root.Doc.columnCursor)
root.Doc.columnCursor = max(root.Doc.columnStart, root.Doc.columnCursor)
root.setMessagef("Set delimiter %s", input)
}

Expand Down Expand Up @@ -796,7 +798,7 @@ func (m *Document) isColumnShrink(cursor int) (bool, error) {
if m.Converter != convAlign {
return false, ErrNotAlignMode
}
if cursor >= len(m.alignConv.columnAttrs) {
if cursor < 0 || cursor >= len(m.alignConv.columnAttrs) {
return false, ErrNoColumnSelected
}
return m.alignConv.columnAttrs[cursor].shrink, nil
Expand Down
2 changes: 1 addition & 1 deletion oviewer/action_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,7 @@ func TestRoot_ColumnDelimiterWrapMode(t *testing.T) {
wrapMode: false,
},
want: want{
x: 2,
x: 10,
columnCursor: 1,
wrapMode: true,
},
Expand Down
124 changes: 58 additions & 66 deletions oviewer/convert_align.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ func newAlignConverter(widthF bool) *align {
}
}

// convert converts only escape sequence codes to display characters and returns them as is.
// convert aligns the columns.
// convert also shrinks and right-aligns the columns.
// (It only processes escape sequences until the end of the line is reached.)
// Returns true if it is an escape sequence and a non-printing character.
func (a *align) convert(st *parseState) bool {
if len(st.lc) == 0 {
Expand Down Expand Up @@ -80,47 +82,29 @@ func (a *align) convertDelm(src contents) contents {
if len(indexes) == 0 {
return src
}
delmWidth := runewidth.StringWidth(a.delimiter)
dst := make(contents, 0, len(src))

s := 0
for c := 0; c < len(indexes); c++ {
e := pos.x(indexes[c][0])
width := e - s
if width <= 0 {
break
}

// shrink column.
if a.isShrink(c) {
if s == 0 {
dst = appendShrink(dst, nil)
} else {
dst = appendShrink(dst, src[s:s+delmWidth])
}
s = e
continue
}

addSpace := 0
if c < len(a.maxWidths) {
addSpace = ((a.maxWidths[c] + 1) - width)
}

if a.isRightAlign(c) {
dst = appendSpaces(dst, addSpace)
dst = append(dst, src[s:e]...)
start := pos.x(0)
for columnNum := 0; columnNum < len(indexes); columnNum++ {
end := pos.x(indexes[columnNum][0]) // Start of the delimiter.
delmEnd := pos.x(indexes[columnNum][1])
if a.isShrink(columnNum) {
// shrink column.
dst = appendShrink(dst)
} else {
dst = append(dst, src[s:e]...)
dst = appendSpaces(dst, addSpace)
// content column.
dst = a.appendColumn(dst, columnNum, src[start:end])
}
s = e
// Add the delimiter.
dst = append(dst, src[end:delmEnd]...)
start = delmEnd
}
if !a.isShrink(len(indexes)) {
dst = append(dst, src[s:]...)

// Add the remaining content.
if a.isShrink(len(indexes)) {
dst = appendShrink(dst)
return dst
}
dst = appendShrink(dst, src[s:s+delmWidth])
dst = append(dst, src[start:]...)
return dst
}

Expand All @@ -130,65 +114,73 @@ func (a *align) convertWidth(src contents) contents {
dst := make(contents, 0, len(src))

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

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

// content column.
tStart := findStartWithTrim(src, start)
tEnd := findEndWidthTrim(src, end)
// If the column width is 0, skip.
if tStart >= tEnd {
start = end
continue
}

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

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

// Add the remaining content.
if !a.isShrink(len(a.orgWidths)) {
dst = append(dst, src[start:]...)
if a.isShrink(len(a.orgWidths)) {
dst = appendShrink(dst)
return dst
}
dst = appendShrink(dst, nil)
dst = append(dst, src[start:]...)
return dst
}

func appendShrink(lc contents, delm contents) contents {
lc = append(lc, delm...)
// appendColumn adds column content to the lc.
func (a *align) appendColumn(lc contents, columnNum int, column contents) contents {
padding := 0
if columnNum < len(a.maxWidths) {
padding = (a.maxWidths[columnNum] - len(column))
}

if a.isRightAlign(columnNum) {
// Add left space to align columns.
lc = appendPaddings(lc, padding)
// Add content.
lc = append(lc, column...)
return lc
}
// Add content.
lc = append(lc, column...)
// Add right space to align columns.
lc = appendPaddings(lc, padding)
return lc
}

// appendShrink adds a shrink column to the lc.
func appendShrink(lc contents) contents {
lc = append(lc, ShrinkContent)
if ShrinkContent.width > 1 {
lc = append(lc, SpaceContent)
lc = append(lc, DefaultContent)
}
return lc
}

func appendSpaces(lc contents, num int) contents {
// appendPaddings adds spaces to the lc.
func appendPaddings(lc contents, num int) contents {
for i := 0; i < num; i++ {
lc = append(lc, SpaceContent)
}
Expand Down
62 changes: 55 additions & 7 deletions oviewer/convert_align_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package oviewer

import (
"reflect"
"regexp"
"testing"
)
Expand Down Expand Up @@ -29,7 +30,7 @@ func Test_align_convert(t *testing.T) {
name: "convertAlignDelm",
fields: fields{
es: newESConverter(),
maxWidths: []int{1, 2},
maxWidths: []int{2, 2},
WidthF: false,
delimiter: ",",
count: 0,
Expand Down Expand Up @@ -180,7 +181,7 @@ func Test_align_convertDelm(t *testing.T) {
name: "convertAlignDelm1",
fields: fields{
es: newESConverter(),
maxWidths: []int{1, 2},
maxWidths: []int{2, 2},
WidthF: false,
delimiter: ",",
count: 0,
Expand All @@ -194,7 +195,7 @@ func Test_align_convertDelm(t *testing.T) {
name: "convertAlignDelm2",
fields: fields{
es: newESConverter(),
maxWidths: []int{1, 2, 2, 2, 2, 2},
maxWidths: []int{2, 2, 2, 2, 2, 2},
WidthF: false,
delimiter: ",",
count: 0,
Expand All @@ -208,7 +209,7 @@ func Test_align_convertDelm(t *testing.T) {
name: "convertAlignDelmShrink1",
fields: fields{
es: newESConverter(),
maxWidths: []int{1, 2, 2, 2, 2, 2},
maxWidths: []int{2, 2, 2, 2, 2, 2},
columns: []columnAttribute{
{shrink: false, rightAlign: false},
{shrink: true, rightAlign: false},
Expand All @@ -229,7 +230,7 @@ func Test_align_convertDelm(t *testing.T) {
name: "convertAlignDelmShrink2",
fields: fields{
es: newESConverter(),
maxWidths: []int{1, 2, 2, 2, 2, 2},
maxWidths: []int{2, 2, 2, 2, 2, 2},
columns: []columnAttribute{
{shrink: true, rightAlign: false},
{shrink: false, rightAlign: false},
Expand All @@ -250,7 +251,7 @@ func Test_align_convertDelm(t *testing.T) {
name: "convertAlignDelmShrink3",
fields: fields{
es: newESConverter(),
maxWidths: []int{1, 2, 2, 2, 2, 2},
maxWidths: []int{2, 2, 2, 2, 2, 2},
columns: []columnAttribute{
{shrink: false, rightAlign: false},
{shrink: false, rightAlign: false},
Expand All @@ -272,7 +273,7 @@ func Test_align_convertDelm(t *testing.T) {
name: "convertAlignDelmRight",
fields: fields{
es: newESConverter(),
maxWidths: []int{1, 2, 2, 2, 2, 2},
maxWidths: []int{2, 2, 2, 2, 2, 2},
columns: []columnAttribute{
{shrink: false, rightAlign: true},
{shrink: false, rightAlign: false},
Expand Down Expand Up @@ -533,3 +534,50 @@ func Test_align_isRightAlign(t *testing.T) {
})
}
}

func Test_appendShrink(t *testing.T) {
type args struct {
lc contents
}
type fields struct {
shrink rune
}
tests := []struct {
name string
fields fields
args args
want contents
}{
{
name: "appendShrink1",
fields: fields{
shrink: '.',
},
args: args{
lc: StrToContents("abc", 8),
},
want: StrToContents("abc.", 8),
},
{
name: "appendShrink2",
fields: fields{
shrink: '略',
},
args: args{
lc: StrToContents("abc", 8),
},
want: StrToContents("abc略", 8),
},
}
for _, tt := range tests {
SetShrinkContent(tt.fields.shrink)
t.Cleanup(func() {
SetShrinkContent(Shrink)
})
t.Run(tt.name, func(t *testing.T) {
if got := appendShrink(tt.args.lc); !reflect.DeepEqual(got, tt.want) {
t.Errorf("appendShrink() = %v, want %v", got, tt.want)
}
})
}
}
3 changes: 3 additions & 0 deletions oviewer/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ type Document struct {
// columnCursor is the number of columns.
columnCursor int

// columnStart is the starting position of the column 0 or 1.
columnStart int

// lastSearchLN is the last search line number.
lastSearchLN int
// showGotoF displays the specified line if it is true.
Expand Down
Loading

0 comments on commit 2c77138

Please sign in to comment.