]> git.lizzy.rs Git - micro.git/blob - internal/display/tabwindow.go
Fix v2 import path for go mod
[micro.git] / internal / display / tabwindow.go
1 package display
2
3 import (
4         "unicode/utf8"
5
6         runewidth "github.com/mattn/go-runewidth"
7         "github.com/zyedidia/micro/v2/internal/buffer"
8         "github.com/zyedidia/micro/v2/internal/config"
9         "github.com/zyedidia/micro/v2/internal/screen"
10         "github.com/zyedidia/micro/v2/internal/util"
11 )
12
13 type TabWindow struct {
14         Names   []string
15         active  int
16         Y       int
17         Width   int
18         hscroll int
19 }
20
21 func NewTabWindow(w int, y int) *TabWindow {
22         tw := new(TabWindow)
23         tw.Width = w
24         tw.Y = y
25         return tw
26 }
27
28 func (w *TabWindow) Resize(width, height int) {
29         w.Width = width
30 }
31
32 func (w *TabWindow) LocFromVisual(vloc buffer.Loc) int {
33         x := -w.hscroll
34
35         for i, n := range w.Names {
36                 x++
37                 s := utf8.RuneCountInString(n)
38                 if vloc.Y == w.Y && vloc.X < x+s {
39                         return i
40                 }
41                 x += s
42                 x += 3
43                 if x >= w.Width {
44                         break
45                 }
46         }
47         return -1
48 }
49
50 func (w *TabWindow) Scroll(amt int) {
51         w.hscroll += amt
52         s := w.TotalSize()
53         w.hscroll = util.Clamp(w.hscroll, 0, s-w.Width)
54
55         if s-w.Width <= 0 {
56                 w.hscroll = 0
57         }
58 }
59
60 func (w *TabWindow) TotalSize() int {
61         sum := 2
62         for _, n := range w.Names {
63                 sum += runewidth.StringWidth(n) + 4
64         }
65         return sum - 4
66 }
67
68 func (w *TabWindow) Active() int {
69         return w.active
70 }
71
72 func (w *TabWindow) SetActive(a int) {
73         w.active = a
74         x := 2
75         s := w.TotalSize()
76
77         for i, n := range w.Names {
78                 c := utf8.RuneCountInString(n)
79                 if i == a {
80                         if x+c >= w.hscroll+w.Width {
81                                 w.hscroll = util.Clamp(x+c+1-w.Width, 0, s-w.Width)
82                         } else if x < w.hscroll {
83                                 w.hscroll = util.Clamp(x-4, 0, s-w.Width)
84                         }
85                         break
86                 }
87                 x += c + 4
88         }
89
90         if s-w.Width <= 0 {
91                 w.hscroll = 0
92         }
93 }
94
95 func (w *TabWindow) Display() {
96         x := -w.hscroll
97         done := false
98
99         tabBarStyle := config.DefStyle.Reverse(true)
100         if style, ok := config.Colorscheme["tabbar"]; ok {
101                 tabBarStyle = style
102         }
103
104         draw := func(r rune, n int) {
105                 for i := 0; i < n; i++ {
106                         rw := runewidth.RuneWidth(r)
107                         for j := 0; j < rw; j++ {
108                                 c := r
109                                 if j > 0 {
110                                         c = ' '
111                                 }
112                                 if x == w.Width-1 && !done {
113                                         screen.SetContent(w.Width-1, w.Y, '>', nil, tabBarStyle)
114                                         x++
115                                         break
116                                 } else if x == 0 && w.hscroll > 0 {
117                                         screen.SetContent(0, w.Y, '<', nil, tabBarStyle)
118                                 } else if x >= 0 && x < w.Width {
119                                         screen.SetContent(x, w.Y, c, nil, tabBarStyle)
120                                 }
121                                 x++
122                         }
123                 }
124         }
125
126         for i, n := range w.Names {
127                 if i == w.active {
128                         draw('[', 1)
129                 } else {
130                         draw(' ', 1)
131                 }
132                 for _, c := range n {
133                         draw(c, 1)
134                 }
135                 if i == len(w.Names)-1 {
136                         done = true
137                 }
138                 if i == w.active {
139                         draw(']', 1)
140                         draw(' ', 2)
141                 } else {
142                         draw(' ', 3)
143                 }
144                 if x >= w.Width {
145                         break
146                 }
147         }
148
149         if x < w.Width {
150                 draw(' ', w.Width-x)
151         }
152 }