Skip to content

Commit 922d2c4

Browse files
Adding tabbarchars option for customizing tabbar visuals
1 parent 4c81246 commit 922d2c4

File tree

4 files changed

+109
-15
lines changed

4 files changed

+109
-15
lines changed

internal/config/settings.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ var DefaultGlobalOnlySettings = map[string]any{
129129
"savehistory": true,
130130
"scrollbarchar": "|",
131131
"sucmd": "sudo",
132+
"tabbarchars": "div= ,active=[],inactive= ",
132133
"tabhighlight": false,
133134
"tabreverse": false,
134135
"xterm": false,

internal/display/tabwindow.go

Lines changed: 92 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"github.com/zyedidia/micro/v2/internal/config"
77
"github.com/zyedidia/micro/v2/internal/screen"
88
"github.com/zyedidia/micro/v2/internal/util"
9+
"strings"
10+
"unicode/utf8"
911
)
1012

1113
type TabWindow struct {
@@ -29,15 +31,26 @@ func (w *TabWindow) Resize(width, height int) {
2931

3032
func (w *TabWindow) LocFromVisual(vloc buffer.Loc) int {
3133
x := -w.hscroll
32-
34+
tabactiverunes, tabinactiverunes, tabdivrunes := GetTabRunes()
3335
for i, n := range w.Names {
34-
x++
36+
if i == w.active {
37+
x += len(tabactiverunes) / 2
38+
} else {
39+
x += len(tabinactiverunes) / 2
40+
}
41+
3542
s := util.CharacterCountInString(n)
3643
if vloc.Y == w.Y && vloc.X < x+s {
3744
return i
3845
}
3946
x += s
40-
x += 3
47+
48+
if i == w.active {
49+
x += len(tabactiverunes) - len(tabactiverunes)/2
50+
} else {
51+
x += len(tabinactiverunes) - len(tabinactiverunes)/2
52+
}
53+
x += len(tabdivrunes)
4154
if x >= w.Width {
4255
break
4356
}
@@ -90,6 +103,39 @@ func (w *TabWindow) SetActive(a int) {
90103
}
91104
}
92105

106+
func GetTabRunes() ([]rune, []rune, []rune) {
107+
var tabactivechars string
108+
var tabinactivechars string
109+
var tabdivchars string
110+
for _, entry := range strings.Split(config.GetGlobalOption("tabbarchars").(string), ",") {
111+
split := strings.SplitN(entry, "=", 2)
112+
if len(split) < 2 {
113+
continue
114+
}
115+
key, val := split[0], split[1]
116+
switch key {
117+
case "active":
118+
tabactivechars = val
119+
case "inactive":
120+
tabinactivechars = val
121+
case "div":
122+
tabdivchars = val
123+
}
124+
}
125+
126+
if utf8.RuneCountInString(tabactivechars) < 2 {
127+
tabactivechars = ""
128+
}
129+
if utf8.RuneCountInString(tabinactivechars) < 2 {
130+
tabinactivechars = ""
131+
}
132+
133+
tabactiverunes := []rune(tabactivechars)
134+
tabinactiverunes := []rune(tabinactivechars)
135+
tabdivrunes := []rune(tabdivchars)
136+
return tabactiverunes, tabinactiverunes, tabdivrunes
137+
}
138+
93139
func (w *TabWindow) Display() {
94140
x := -w.hscroll
95141
done := false
@@ -111,12 +157,27 @@ func (w *TabWindow) Display() {
111157
if style, ok := config.Colorscheme["tabbar.active"]; ok {
112158
tabBarActiveStyle = style
113159
}
160+
tabBarInactiveStyle := tabBarStyle
161+
if style, ok := config.Colorscheme["tabbar.inactive"]; ok {
162+
tabBarInactiveStyle = style
163+
}
164+
tabBarDivStyle := tabBarStyle
165+
if style, ok := config.Colorscheme["tabbar.div"]; ok {
166+
tabBarDivStyle = style
167+
}
114168

115-
draw := func(r rune, n int, active bool, tab bool) {
169+
draw := func(r rune, n int, active bool, tab bool, div bool) {
116170
style := tabBarStyle
117-
if active {
118-
style = tabBarActiveStyle
171+
if tab {
172+
if active {
173+
style = tabBarActiveStyle
174+
} else {
175+
style = tabBarInactiveStyle
176+
}
177+
} else if div {
178+
style = tabBarDivStyle
119179
}
180+
120181
for i := 0; i < n; i++ {
121182
rw := runewidth.RuneWidth(r)
122183
for j := 0; j < rw; j++ {
@@ -138,27 +199,44 @@ func (w *TabWindow) Display() {
138199
}
139200
}
140201

202+
tabactiverunes, tabinactiverunes, tabdivrunes := GetTabRunes()
203+
leftactiverunes := tabactiverunes[0 : len(tabactiverunes)/2]
204+
rightactiverunes := tabactiverunes[len(tabactiverunes)/2:]
205+
206+
leftinactiverunes := tabinactiverunes[0 : len(tabinactiverunes)/2]
207+
rightinactiverunes := tabinactiverunes[len(tabinactiverunes)/2:]
208+
141209
for i, n := range w.Names {
142210
if i == w.active {
143-
draw('[', 1, true, true)
211+
for j := 0; j < len(leftactiverunes); j++ {
212+
draw(leftactiverunes[j], 1, true, true, false)
213+
}
144214
} else {
145-
draw(' ', 1, false, true)
215+
for j := 0; j < len(leftinactiverunes); j++ {
216+
draw(leftinactiverunes[j], 1, false, true, false)
217+
}
146218
}
147219

148220
for _, c := range n {
149-
draw(c, 1, i == w.active, true)
221+
draw(c, 1, i == w.active, true, false)
150222
}
151223

152224
if i == len(w.Names)-1 {
153225
done = true
154226
}
155227

156228
if i == w.active {
157-
draw(']', 1, true, true)
158-
draw(' ', 2, true, false)
229+
for j := 0; j < len(rightactiverunes); j++ {
230+
draw(rightactiverunes[j], 1, true, true, false)
231+
}
159232
} else {
160-
draw(' ', 1, false, true)
161-
draw(' ', 2, false, false)
233+
for j := 0; j < len(rightinactiverunes); j++ {
234+
draw(rightinactiverunes[j], 1, false, true, false)
235+
}
236+
}
237+
238+
for j := 0; j < len(tabdivrunes); j++ {
239+
draw(tabdivrunes[j], 1, false, false, true)
162240
}
163241

164242
if x >= w.Width {
@@ -167,6 +245,6 @@ func (w *TabWindow) Display() {
167245
}
168246

169247
if x < w.Width {
170-
draw(' ', w.Width-x, false, globalTabReverse)
248+
draw(' ', w.Width-x, false, false, false)
171249
}
172250
}

runtime/help/colors.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ color support comes in three flavors.
4040
same regardless of the configured 16-color palette. However, the color
4141
range is fairly limited due to the small number of colors available.
4242
Default 256-color colorschemes include `monokai`, `twilight`, `zenburn`,
43-
`darcula` and more.
43+
`dracula` and more.
4444

4545
* true-color: Some terminals support displaying "true color" with 16 million
4646
colors using standard RGB values. This mode will be able to support
@@ -179,6 +179,8 @@ Here is a list of the colorscheme groups that you can use:
179179
* statusline.suggestions (Color of the autocomplete suggestions menu)
180180
* tabbar (Color of the tabbar that lists open files)
181181
* tabbar.active (Color of the active tab in the tabbar)
182+
* tabbar.inactive (Color of the inactive tabs in the tabbar)
183+
* tabbar.div (Color of the space/divider between each tab in the tabbar)
182184
* indent-char (Color of the character which indicates tabs if the option is
183185
enabled)
184186
* line-number

runtime/help/options.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,19 @@ Here are the available options:
460460

461461
default value: `true`
462462

463+
* `tabbarchars`: sets what visual characters to be shown for various tabbar options.
464+
This option is specified in the form of `key1=value1,key2=value2,...`.
465+
466+
Here are the list of keys:
467+
- `active`: the opening and closing tab characters for the current active tab,
468+
where the values are splitted in half for opening and closing characters.
469+
For example, value of `[[]]` will have `[[` as opening characters and
470+
`]]` as closing characters.
471+
- `div`: the characters to be filled between each tab.
472+
- `inactive`: the opening and closing tab characters for the inactive tabs.
473+
where the values are splitted in half for opening and closing characters.
474+
475+
default value: `div= ,active=[],inactive= `
463476

464477
* `tabhighlight`: highlighting the current active tab by using the inverted tab bar color.
465478
Has no effect if `tabbar.active` is present in the current colorscheme.

0 commit comments

Comments
 (0)