Skip to content

Commit

Permalink
initial support for wide-chars (JP, CN...)
Browse files Browse the repository at this point in the history
Thanks @ujun. Fixes #51, at least so it looks.
  • Loading branch information
akavel committed Aug 11, 2023
1 parent 2fad5ae commit 73a3761
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 29 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ Calum MacRae <[email protected]>
Ghislain Rodrigues <[email protected]>
Mateusz Czapliński <[email protected]>
Rohan Verma <[email protected]>
Uchino Jun <[email protected]>
11 changes: 5 additions & 6 deletions bufview_draw_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ func Test_BufView_DrawTo(t *testing.T) {
喝茶
睡觉`),
want: TestScreen{
Wide{'吃', 2}, Wide{'饭', 2}, Endline{8},
Wide{'喝', 2}, Wide{'茶', 2}, Endline{8},
Wide{'睡', 2}, Wide{'觉', 2}, Endline{8},
Wide{'吃', 2}, Wide{'饭', 2}, Endline{6},
Wide{'喝', 2}, Wide{'茶', 2}, Endline{6},
Wide{'睡', 2}, Wide{'觉', 2}, Endline{6},
Rows{W: 10, H: 7},
},
},
Expand All @@ -46,10 +46,9 @@ func Test_BufView_DrawTo(t *testing.T) {
region := Region{
W: 10,
H: 10,
SetCell: func(x, y int, style tcell.Style, ch rune) {
scr.SetCell(x, y, style, ch)
SetContent: func(x, y int, mainc rune, combc []rune, style tcell.Style) {
scr.SetContent(x, y, mainc, combc, style)
},
// SetContent: func(dx, dy int, mainc rune, combc []rune
}

for _, tt := range tests {
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ require (
require (
github.com/gdamore/encoding v1.0.0 // indirect
github.com/lucasb-eyer/go-colorful v1.0.3 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/text v0.3.4 // indirect
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
47 changes: 25 additions & 22 deletions up.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"github.com/gdamore/tcell"
"github.com/gdamore/tcell/terminfo"
"github.com/mattn/go-isatty"
"github.com/mattn/go-runewidth"
"github.com/spf13/pflag"
)

Expand Down Expand Up @@ -242,7 +243,7 @@ func main() {
commandEditor.DrawTo(TuiRegion(tui, 1, 0, w-1, 1), style,
func(x, y int) { tui.ShowCursor(x+1, 0) })
commandOutput.DrawTo(TuiRegion(tui, 0, 1, w, h-1))
drawText(TuiRegion(tui, 0, h-1, w, 1), whiteOnBlue, message)
drawText(TuiRegion(tui, 0, h-1, w, 1), 0, whiteOnBlue, []rune(message))
tui.Show()

// Handle UI events
Expand Down Expand Up @@ -364,22 +365,18 @@ func (e *Editor) String() string { return string(e.value) }

func (e *Editor) DrawTo(region Region, style tcell.Style, setcursor func(x, y int)) {
// Draw prompt & the edited value - use white letters on blue background
for i, ch := range e.prompt {
region.SetCell(i, 0, style, ch)
}
for i, ch := range e.value {
region.SetCell(len(e.prompt)+i, 0, style, ch)
}
wprompt := drawText(region, 0, style, e.prompt)
wvalue := drawText(region, wprompt, style, e.value)

// Clear remains of last value if needed
for i := len(e.value); i < e.lastw; i++ {
region.SetCell(len(e.prompt)+i, 0, tcell.StyleDefault, ' ')
for i := wvalue; i < e.lastw; i++ {
region.SetContent(wprompt+i, 0, ' ', nil, tcell.StyleDefault)
}
e.lastw = len(e.value)
e.lastw = wvalue

// Show cursor if requested
if setcursor != nil {
setcursor(len(e.prompt)+e.cursor, 0)
setcursor(wprompt+runewidth.StringWidth(string(e.value[:e.cursor])), 0)
}
}

Expand Down Expand Up @@ -501,10 +498,11 @@ func (v *BufView) DrawTo(region Region) {
} else {
x -= v.X
}
// FIXME: properly handle runes of runewidth >= 2
if x >= region.W {
x, ch = region.W-1, '»'
}
region.SetCell(x, y, tcell.StyleDefault, ch)
region.SetContent(x, y, ch, nil, tcell.StyleDefault)
}
endline := func(x, y int) {
x = max(0, x-v.X)
Expand All @@ -513,7 +511,7 @@ func (v *BufView) DrawTo(region Region) {
}
lclip = false
for ; x < region.W; x++ {
region.SetCell(x, y, tcell.StyleDefault, ' ')
region.SetContent(x, y, ' ', nil, tcell.StyleDefault)
}
}

Expand Down Expand Up @@ -541,10 +539,12 @@ func (v *BufView) DrawTo(region Region) {
}
drawch(x, y, ' ')
}
// FIXME: is below line correct?
x++
default:
drawch(x, y, ch)
x += runewidth.RuneWidth(ch)
}
x++
}
for ; y < region.H; y++ {
endline(x, y)
Expand Down Expand Up @@ -698,7 +698,7 @@ func (b *Buf) DrawStatus(region Region, style tcell.Style) {
}
b.mu.Unlock()

region.SetCell(0, 0, style, status)
region.SetContent(0, 0, status, nil, style)
}

func (b *Buf) NewReader(blocking bool) io.Reader {
Expand Down Expand Up @@ -848,19 +848,19 @@ fallback_print:
}

type Region struct {
W, H int
SetCell func(x, y int, style tcell.Style, ch rune)
W, H int
SetContent func(x, y int, mainc rune, combc []rune, style tcell.Style)
}

func TuiRegion(tui tcell.Screen, x, y, w, h int) Region {
return Region{
W: w, H: h,
SetCell: func(dx, dy int, style tcell.Style, ch rune) {
SetContent: func(dx, dy int, mainc rune, combc []rune, style tcell.Style) {
if dx >= 0 && dx < w && dy >= 0 && dy < h {
if *noColors {
style = tcell.StyleDefault
}
tui.SetCell(x+dx, y+dy, style, ch)
tui.SetContent(x+dx, y+dy, mainc, combc, style)
}
},
}
Expand All @@ -871,8 +871,11 @@ var (
whiteOnDBlue = tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.ColorNavy)
)

func drawText(region Region, style tcell.Style, text string) {
for x, ch := range text {
region.SetCell(x, 0, style, ch)
func drawText(region Region, x int, style tcell.Style, text []rune) int {
w := 0
for _, ch := range text {
region.SetContent(x+w, 0, ch, nil, style)
w += runewidth.RuneWidth(ch)
}
return w
}

0 comments on commit 73a3761

Please sign in to comment.