From 47a129b70f620802a4a21137a56146da927a230e Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Sat, 15 Jun 2019 16:54:53 -0400 Subject: [PATCH] Unicode support improvement --- internal/display/infowindow.go | 9 ++++++++- internal/display/statusline.go | 28 ++++++++++++++++++++++++---- internal/display/tabwindow.go | 26 ++++++++++++++++---------- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/internal/display/infowindow.go b/internal/display/infowindow.go index 40519433..3c1c5151 100644 --- a/internal/display/infowindow.go +++ b/internal/display/infowindow.go @@ -99,7 +99,14 @@ func (i *InfoWindow) displayBuffer() { } - screen.Screen.SetContent(vlocX, i.Y, r, nil, style) + rw := runewidth.RuneWidth(r) + for j := 0; j < rw; j++ { + c := r + if j > 0 { + c = ' ' + } + screen.Screen.SetContent(vlocX, i.Y, c, nil, style) + } vlocX++ } nColsBeforeStart-- diff --git a/internal/display/statusline.go b/internal/display/statusline.go index b48406cd..79e090f2 100644 --- a/internal/display/statusline.go +++ b/internal/display/statusline.go @@ -3,14 +3,17 @@ package display import ( "bytes" "fmt" + "log" "path" "regexp" "strconv" "unicode/utf8" + runewidth "github.com/mattn/go-runewidth" "github.com/zyedidia/micro/internal/buffer" "github.com/zyedidia/micro/internal/config" "github.com/zyedidia/micro/internal/screen" + "github.com/zyedidia/micro/internal/util" ) // StatusLine represents the information line at the bottom @@ -95,19 +98,36 @@ func (s *StatusLine) Display() { statusLineStyle = style } - leftLen := utf8.RuneCount(leftText) - rightLen := utf8.RuneCount(rightText) + leftLen := util.StringWidth(leftText, utf8.RuneCount(leftText), 1) + rightLen := util.StringWidth(rightText, utf8.RuneCount(rightText), 1) winX := s.win.X for x := 0; x < s.win.Width; x++ { if x < leftLen { r, size := utf8.DecodeRune(leftText) leftText = leftText[size:] - screen.Screen.SetContent(winX+x, y, r, nil, statusLineStyle) + rw := runewidth.RuneWidth(r) + for j := 0; j < rw; j++ { + c := r + if j > 0 { + c = ' ' + x++ + } + log.Println(x, string(c)) + screen.Screen.SetContent(winX+x, y, c, nil, statusLineStyle) + } } else if x >= s.win.Width-rightLen && x < rightLen+s.win.Width-rightLen { r, size := utf8.DecodeRune(rightText) rightText = rightText[size:] - screen.Screen.SetContent(winX+x, y, r, nil, statusLineStyle) + rw := runewidth.RuneWidth(r) + for j := 0; j < rw; j++ { + c := r + if j > 0 { + c = ' ' + x++ + } + screen.Screen.SetContent(winX+x, y, c, nil, statusLineStyle) + } } else { screen.Screen.SetContent(winX+x, y, ' ', nil, statusLineStyle) } diff --git a/internal/display/tabwindow.go b/internal/display/tabwindow.go index 698dbf84..d3e9553b 100644 --- a/internal/display/tabwindow.go +++ b/internal/display/tabwindow.go @@ -3,6 +3,7 @@ package display import ( "unicode/utf8" + runewidth "github.com/mattn/go-runewidth" "github.com/zyedidia/micro/internal/buffer" "github.com/zyedidia/micro/internal/config" "github.com/zyedidia/micro/internal/screen" @@ -77,24 +78,29 @@ func (w *TabWindow) SetActive(a int) { } } -// TODO: handle files with character width >=2 - func (w *TabWindow) Display() { x := -w.hscroll done := false draw := func(r rune, n int) { for i := 0; i < n; i++ { - if x == w.width-1 && !done { - screen.Screen.SetContent(w.width-1, w.Y, '>', nil, config.DefStyle.Reverse(true)) + rw := runewidth.RuneWidth(r) + for j := 0; j < rw; j++ { + c := r + if j > 0 { + c = ' ' + } + if x == w.width-1 && !done { + screen.Screen.SetContent(w.width-1, w.Y, '>', nil, config.DefStyle.Reverse(true)) + x++ + break + } else if x == 0 && w.hscroll > 0 { + screen.Screen.SetContent(0, w.Y, '<', nil, config.DefStyle.Reverse(true)) + } else if x >= 0 && x < w.width { + screen.Screen.SetContent(x, w.Y, c, nil, config.DefStyle.Reverse(true)) + } x++ - break - } else if x == 0 && w.hscroll > 0 { - screen.Screen.SetContent(0, w.Y, '<', nil, config.DefStyle.Reverse(true)) - } else if x >= 0 && x < w.width { - screen.Screen.SetContent(x, w.Y, r, nil, config.DefStyle.Reverse(true)) } - x++ } }