Skip to content

Commit

Permalink
Merge pull request #483 from noborus/fix-column-delimiter
Browse files Browse the repository at this point in the history
Fixed delimiter width calculation
  • Loading branch information
noborus authored Jan 12, 2024
2 parents fdcf9c8 + 04d89e3 commit 06feaa0
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 30 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ require (
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.18.2
github.com/ulikunitz/xz v0.5.11
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc
golang.org/x/exp v0.0.0-20240110193028-0dcbfd608b1e
golang.org/x/sync v0.6.0
golang.org/x/term v0.16.0
)
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM=
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
golang.org/x/exp v0.0.0-20240110193028-0dcbfd608b1e h1:723BNChdd0c2Wk6WOE320qGBiPtYx0F0Bbm1kriShfE=
golang.org/x/exp v0.0.0-20240110193028-0dcbfd608b1e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
Expand Down
4 changes: 3 additions & 1 deletion oviewer/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ import (
func (root *Root) toggleWrapMode() {
m := root.Doc
m.WrapMode = !m.WrapMode

// Move cursor to correct position
x, err := root.Doc.optimalX(m.columnCursor)
x, err := m.optimalX(m.columnCursor)
if err != nil {
root.setMessageLog(err.Error())
return
}
// Move if off screen
if x < m.x || x > m.x+(root.scr.vWidth-root.scr.startX) {
Expand Down
45 changes: 23 additions & 22 deletions oviewer/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,10 @@ func (input *Input) keyEvent(evKey *tcell.EventKey) bool {
if input.cursorX <= 0 {
return false
}
pos := stringWidth(input.value, input.cursorX)
pos := countToCursor(input.value, input.cursorX)
runes := []rune(input.value)
input.value = string(runes[:pos])
input.cursorX = runeWidth(input.value)
input.cursorX = stringWidth(input.value)
next := pos + 1
for ; next < len(runes); next++ {
if runewidth.RuneWidth(runes[next]) != 0 {
Expand All @@ -127,7 +127,7 @@ func (input *Input) keyEvent(evKey *tcell.EventKey) bool {
}
input.value += string(runes[next:])
case tcell.KeyDelete:
pos := stringWidth(input.value, input.cursorX)
pos := countToCursor(input.value, input.cursorX)
runes := []rune(input.value)
dp := 1
if input.cursorX == 0 {
Expand All @@ -147,27 +147,27 @@ func (input *Input) keyEvent(evKey *tcell.EventKey) bool {
if input.cursorX <= 0 {
return false
}
pos := stringWidth(input.value, input.cursorX)
pos := countToCursor(input.value, input.cursorX)
runes := []rune(input.value)
input.cursorX = runeWidth(string(runes[:pos]))
input.cursorX = stringWidth(string(runes[:pos]))
if pos > 0 && runes[pos-1] == '\t' {
input.cursorX--
}
case tcell.KeyRight:
pos := stringWidth(input.value, input.cursorX+1)
pos := countToCursor(input.value, input.cursorX+1)
runes := []rune(input.value)
if len(runes) > pos {
input.cursorX = runeWidth(string(runes[:pos+1]))
input.cursorX = stringWidth(string(runes[:pos+1]))
}
case tcell.KeyTAB:
pos := stringWidth(input.value, input.cursorX+1)
pos := countToCursor(input.value, input.cursorX+1)
runes := []rune(input.value)
input.value = string(runes[:pos])
input.value += "\t"
input.cursorX += 2
input.value += string(runes[pos:])
case tcell.KeyRune:
pos := stringWidth(input.value, input.cursorX+1)
pos := countToCursor(input.value, input.cursorX+1)
runes := []rune(input.value)
input.value = string(runes[:pos])
r := evKey.Rune()
Expand Down Expand Up @@ -209,44 +209,45 @@ func (root *Root) inputPrevious() {
input := root.input
input.value = input.Event.Up(input.value)
runes := []rune(input.value)
input.cursorX = runeWidth(string(runes))
input.cursorX = stringWidth(string(runes))
}

// inputNext searches the next history.
func (root *Root) inputNext() {
input := root.input
input.value = input.Event.Down(input.value)
runes := []rune(input.value)
input.cursorX = runeWidth(string(runes))
input.cursorX = stringWidth(string(runes))
}

// stringWidth returns the number of characters in the input.
func stringWidth(str string, cursor int) int {
// stringWidth returns the number of widths of the input.
// Tab is 2 characters.
func stringWidth(str string) int {
width := 0
i := 0
for _, r := range str {
width += runewidth.RuneWidth(r)
if r == '\t' {
width += 2
}
if width >= cursor {
return i
}
i++
}
return i
return width
}

// runeWidth returns the number of widths of the input.
func runeWidth(str string) int {
// countToCursor returns the number of characters in the input.
func countToCursor(str string, cursor int) int {
width := 0
i := 0
for _, r := range str {
width += runewidth.RuneWidth(r)
if r == '\t' {
width += 2
}
if width >= cursor {
return i
}
i++
}
return width
return i
}

// Eventer is a generic interface for inputs.
Expand Down
2 changes: 1 addition & 1 deletion oviewer/mouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func (root *Root) getClipboard(_ context.Context) {
return
}

pos := stringWidth(input.value, input.cursorX+1)
pos := countToCursor(input.value, input.cursorX+1)
runes := []rune(input.value)
input.value = string(runes[:pos])
input.value += str
Expand Down
21 changes: 18 additions & 3 deletions oviewer/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"regexp"
"strings"

"github.com/mattn/go-runewidth"
"golang.org/x/exp/constraints"
)

Expand Down Expand Up @@ -90,11 +91,25 @@ func allStringIndex(s string, substr string) [][]int {
return nil
}
var result [][]int
width := wordWidth(substr)
for pos, offSet := strings.Index(s, substr), 0; pos != -1; {
s = s[pos+len(substr):]
result = append(result, []int{pos + offSet, pos + offSet + len(substr)})
offSet += pos + len(substr)
s = s[pos+width:]
result = append(result, []int{pos + offSet, pos + offSet + width})
offSet += pos + width
pos = strings.Index(s, substr)
}
return result
}

// wordWidth returns the width of the word.
func wordWidth(str string) int {
width := 0
for _, r := range str {
w := runewidth.RuneWidth(r)
if w == 0 {
w = 1
}
width += w
}
return width
}
36 changes: 36 additions & 0 deletions oviewer/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,42 @@ func Test_allIndex(t *testing.T) {
{3, 4},
},
},
{
name: "test2",
args: args{
s: "a|b|c",
substr: "|",
reg: nil,
},
want: [][]int{
{1, 2},
{3, 4},
},
},
{
name: "testTab",
args: args{
s: "a b c",
substr: " ",
reg: nil,
},
want: [][]int{
{1, 2},
{3, 4},
},
},
{
name: "testUnicode",
args: args{
s: "a│b│c",
substr: "│",
reg: nil,
},
want: [][]int{
{1, 2},
{5, 6},
},
},
{
name: "testRegex",
args: args{
Expand Down

0 comments on commit 06feaa0

Please sign in to comment.