-
Notifications
You must be signed in to change notification settings - Fork 3
/
utils.go
145 lines (124 loc) · 2.57 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package main
import (
"fmt"
"os"
"strings"
"unicode"
"unicode/utf8"
"github.com/gdamore/tcell"
"github.com/go-errors/errors"
runewidth "github.com/mattn/go-runewidth"
)
func fatalError(err error) {
if err != nil {
fatal(err.Error())
}
}
func fatal(message string) {
if screen != nil {
screen.Fini()
screen = nil
}
fmt.Printf("%v\n", message)
os.Exit(1)
}
func handlePanics() {
if err := recover(); err != nil {
fatal(fmt.Sprintf("ry fatal error:\n%v\n%s", err, errors.Wrap(err, 2).ErrorStack()))
}
}
func write(style tcell.Style, x, y int, str string) int {
s := screen
i := 0
var deferred []rune
dwidth := 0
for _, r := range str {
// Handle tabs
if r == '\t' {
// TODO setting
tabWidth := int(configGetNumber("tab_width", nil))
// Print first tab char
s.SetContent(x+i, y, '>', nil, style.Foreground(tcell.ColorAqua))
i++
// Add space till we reach tab column or tabWidth
for j := 0; j < tabWidth-1 || i%tabWidth == tabWidth-1; j++ {
s.SetContent(x+i, y, ' ', nil, style)
i++
}
deferred = nil
continue
}
switch runewidth.RuneWidth(r) {
case 0:
if len(deferred) == 0 {
deferred = append(deferred, ' ')
dwidth = 1
}
case 1:
if len(deferred) != 0 {
s.SetContent(x+i, y, deferred[0], deferred[1:], style)
i += dwidth
}
deferred = nil
dwidth = 1
case 2:
if len(deferred) != 0 {
s.SetContent(x+i, y, deferred[0], deferred[1:], style)
i += dwidth
}
deferred = nil
dwidth = 2
}
deferred = append(deferred, r)
}
if len(deferred) != 0 {
s.SetContent(x+i, y, deferred[0], deferred[1:], style)
i += dwidth
}
// i is the real width of what we just outputed
return i
}
func listContainsString(list []string, search string) bool {
for _, item := range list {
if item == search {
return true
}
}
return false
}
func padr(str string, length int, padding rune) string {
for utf8.RuneCountInString(str) < length {
str = str + string(padding)
}
return str
}
func padl(str string, length int, padding rune) string {
for utf8.RuneCountInString(str) < length {
str = string(padding) + str
}
return str
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func isWord(r rune) bool {
return unicode.IsLetter(r) || unicode.IsNumber(r) || strings.ContainsRune("_", r)
}
func isSpace(r rune) bool {
return r == ' ' || r == '\t' || r == '\n'
}
func isAlpha(r rune) bool {
return (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z')
}
func isNum(r rune) bool {
return r >= '0' && r <= '9'
}