]> git.lizzy.rs Git - micro.git/blobdiff - internal/display/tabwindow.go
Fix weird behavior of JumpToMatchingBrace in some ill cases (#1966)
[micro.git] / internal / display / tabwindow.go
index 3d25a42caa646b54e927e46049dd7c953727473f..8e31922c9aa4511fda83822146f81574e2f3b268 100644 (file)
@@ -1,42 +1,45 @@
 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"
-       "github.com/zyedidia/micro/internal/util"
+       "github.com/zyedidia/tcell/v2"
+       "github.com/zyedidia/micro/v2/internal/buffer"
+       "github.com/zyedidia/micro/v2/internal/config"
+       "github.com/zyedidia/micro/v2/internal/screen"
+       "github.com/zyedidia/micro/v2/internal/util"
 )
 
 type TabWindow struct {
        Names   []string
        active  int
        Y       int
-       width   int
+       Width   int
        hscroll int
 }
 
 func NewTabWindow(w int, y int) *TabWindow {
        tw := new(TabWindow)
-       tw.width = w
+       tw.Width = w
        tw.Y = y
        return tw
 }
 
+func (w *TabWindow) Resize(width, height int) {
+       w.Width = width
+}
+
 func (w *TabWindow) LocFromVisual(vloc buffer.Loc) int {
        x := -w.hscroll
 
        for i, n := range w.Names {
                x++
-               s := utf8.RuneCountInString(n)
+               s := util.CharacterCountInString(n)
                if vloc.Y == w.Y && vloc.X < x+s {
                        return i
                }
                x += s
                x += 3
-               if x >= w.width {
+               if x >= w.Width {
                        break
                }
        }
@@ -45,13 +48,18 @@ func (w *TabWindow) LocFromVisual(vloc buffer.Loc) int {
 
 func (w *TabWindow) Scroll(amt int) {
        w.hscroll += amt
-       w.hscroll = util.Clamp(w.hscroll, 0, w.TotalSize()-w.width)
+       s := w.TotalSize()
+       w.hscroll = util.Clamp(w.hscroll, 0, s-w.Width)
+
+       if s-w.Width <= 0 {
+               w.hscroll = 0
+       }
 }
 
 func (w *TabWindow) TotalSize() int {
        sum := 2
        for _, n := range w.Names {
-               sum += utf8.RuneCountInString(n) + 4
+               sum += runewidth.StringWidth(n) + 4
        }
        return sum - 4
 }
@@ -64,25 +72,54 @@ func (w *TabWindow) SetActive(a int) {
        w.active = a
        x := 2
        s := w.TotalSize()
+
        for i, n := range w.Names {
-               c := utf8.RuneCountInString(n)
+               c := util.CharacterCountInString(n)
                if i == a {
-                       if x+c >= w.hscroll+w.width {
-                               w.hscroll = util.Clamp(x+c+1-w.width, 0, s-w.width)
+                       if x+c >= w.hscroll+w.Width {
+                               w.hscroll = util.Clamp(x+c+1-w.Width, 0, s-w.Width)
                        } else if x < w.hscroll {
-                               w.hscroll = util.Clamp(x-4, 0, s-w.width)
+                               w.hscroll = util.Clamp(x-4, 0, s-w.Width)
                        }
                        break
                }
                x += c + 4
        }
+
+       if s-w.Width <= 0 {
+               w.hscroll = 0
+       }
 }
 
 func (w *TabWindow) Display() {
        x := -w.hscroll
        done := false
 
-       draw := func(r rune, n int) {
+       globalTabReverse := config.GetGlobalOption("tabreverse").(bool)
+       globalTabHighlight := config.GetGlobalOption("tabhighlight").(bool)
+
+       // xor of reverse and tab highlight to get tab character (as in filename and surrounding characters) reverse state
+       tabCharHighlight := (globalTabReverse || globalTabHighlight) && !(globalTabReverse && globalTabHighlight)
+
+       reverseStyles := func(reverse bool) (tcell.Style, tcell.Style) {
+               tabBarStyle := config.DefStyle.Reverse(reverse)
+               if style, ok := config.Colorscheme["tabbar"]; ok {
+                       tabBarStyle = style
+               }
+               tabBarActiveStyle := tabBarStyle
+               if style, ok := config.Colorscheme["tabbar.active"]; ok {
+                       tabBarActiveStyle = style
+               }
+               return tabBarStyle, tabBarActiveStyle
+       }
+       
+       draw := func(r rune, n int, active bool, reversed bool) {
+               tabBarStyle, tabBarActiveStyle := reverseStyles(reversed)
+               
+               style := tabBarStyle
+               if active {
+                       style = tabBarActiveStyle
+               }
                for i := 0; i < n; i++ {
                        rw := runewidth.RuneWidth(r)
                        for j := 0; j < rw; j++ {
@@ -90,14 +127,14 @@ func (w *TabWindow) Display() {
                                if j > 0 {
                                        c = ' '
                                }
-                               if x == w.width-1 && !done {
-                                       screen.Screen.SetContent(w.width-1, w.Y, '>', nil, config.DefStyle.Reverse(true))
+                               if x == w.Width-1 && !done {
+                                       screen.SetContent(w.Width-1, w.Y, '>', nil, tabBarStyle)
                                        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))
+                                       screen.SetContent(0, w.Y, '<', nil, tabBarStyle)
+                               } else if x >= 0 && x < w.Width {
+                                       screen.SetContent(x, w.Y, c, nil, style)
                                }
                                x++
                        }
@@ -106,28 +143,33 @@ func (w *TabWindow) Display() {
 
        for i, n := range w.Names {
                if i == w.active {
-                       draw('[', 1)
+                       draw('[', 1, true, tabCharHighlight)
                } else {
-                       draw(' ', 1)
+                       draw(' ', 1, false, tabCharHighlight)
                }
+               
                for _, c := range n {
-                       draw(c, 1)
+                       draw(c, 1, i == w.active, tabCharHighlight)
                }
+               
                if i == len(w.Names)-1 {
                        done = true
                }
+               
                if i == w.active {
-                       draw(']', 1)
-                       draw(' ', 2)
+                       draw(']', 1, true, tabCharHighlight)
+                       draw(' ', 2, true, globalTabReverse)
                } else {
-                       draw(' ', 3)
+                       draw(' ', 1, false, tabCharHighlight)
+                       draw(' ', 2, false, globalTabReverse)
                }
-               if x >= w.width {
+               
+               if x >= w.Width {
                        break
                }
        }
 
-       if x < w.width {
-               draw(' ', w.width-x)
+       if x < w.Width {
+               draw(' ', w.Width-x, false, globalTabReverse)
        }
 }