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 package main
33
34 import (
35 "bytes"
36 "errors"
37 "flag"
38 "fmt"
39 "io"
40 "os"
41 "os/exec"
42 "regexp"
43 "strconv"
44 "strings"
45
46 "github.com/gdamore/tcell/v2/terminfo"
47 )
48
49 type termcap struct {
50 name string
51 desc string
52 aliases []string
53 bools map[string]bool
54 nums map[string]int
55 strs map[string]string
56 }
57
58 func (tc *termcap) getnum(s string) int {
59 return (tc.nums[s])
60 }
61
62 func (tc *termcap) getflag(s string) bool {
63 return (tc.bools[s])
64 }
65
66 func (tc *termcap) getstr(s string) string {
67 return (tc.strs[s])
68 }
69
70 const (
71 NONE = iota
72 CTRL
73 ESC
74 )
75
76 var notaddressable = errors.New("terminal not cursor addressable")
77
78 func unescape(s string) string {
79
80
81
82
83 buf := &bytes.Buffer{}
84 esc := NONE
85
86 for i := 0; i < len(s); i++ {
87 c := s[i]
88 switch esc {
89 case NONE:
90 switch c {
91 case '\\':
92 esc = ESC
93 case '^':
94 esc = CTRL
95 default:
96 buf.WriteByte(c)
97 }
98 case CTRL:
99 buf.WriteByte(c ^ 1<<6)
100 esc = NONE
101 case ESC:
102 switch c {
103 case 'E', 'e':
104 buf.WriteByte(0x1b)
105 case '0', '1', '2', '3', '4', '5', '6', '7':
106 if i+2 < len(s) && s[i+1] >= '0' && s[i+1] <= '7' && s[i+2] >= '0' && s[i+2] <= '7' {
107 buf.WriteByte(((c - '0') * 64) + ((s[i+1] - '0') * 8) + (s[i+2] - '0'))
108 i = i + 2
109 } else if c == '0' {
110 buf.WriteByte(0)
111 }
112 case 'n':
113 buf.WriteByte('\n')
114 case 'r':
115 buf.WriteByte('\r')
116 case 't':
117 buf.WriteByte('\t')
118 case 'b':
119 buf.WriteByte('\b')
120 case 'f':
121 buf.WriteByte('\f')
122 case 's':
123 buf.WriteByte(' ')
124 case 'l':
125 panic("WTF: weird format: " + s)
126 default:
127 buf.WriteByte(c)
128 }
129 esc = NONE
130 }
131 }
132 return (buf.String())
133 }
134
135 func (tc *termcap) setupterm(name string) error {
136 cmd := exec.Command("infocmp", "-x", "-1", name)
137 output := &bytes.Buffer{}
138 cmd.Stdout = output
139
140 tc.strs = make(map[string]string)
141 tc.bools = make(map[string]bool)
142 tc.nums = make(map[string]int)
143
144 err := cmd.Run()
145 if err != nil {
146 return err
147 }
148
149
150
151
152
153
154 lines := strings.Split(output.String(), "\n")
155 for len(lines) > 0 && strings.HasPrefix(lines[0], "#") {
156 lines = lines[1:]
157 }
158
159
160 if lines[len(lines)-1] == "" {
161 lines = lines[:len(lines)-1]
162 }
163 header := lines[0]
164 if strings.HasSuffix(header, ",") {
165 header = header[:len(header)-1]
166 }
167 names := strings.Split(header, "|")
168 tc.name = names[0]
169 names = names[1:]
170 if len(names) > 0 {
171 tc.desc = names[len(names)-1]
172 names = names[:len(names)-1]
173 }
174 tc.aliases = names
175 for _, val := range lines[1:] {
176 if (!strings.HasPrefix(val, "\t")) ||
177 (!strings.HasSuffix(val, ",")) {
178 return (errors.New("malformed infocmp: " + val))
179 }
180
181 val = val[1:]
182 val = val[:len(val)-1]
183
184 if k := strings.SplitN(val, "=", 2); len(k) == 2 {
185 tc.strs[k[0]] = unescape(k[1])
186 } else if k := strings.SplitN(val, "#", 2); len(k) == 2 {
187 if u, err := strconv.ParseUint(k[1], 0, 0); err != nil {
188 return (err)
189 } else {
190 tc.nums[k[0]] = int(u)
191 }
192 } else {
193 tc.bools[val] = true
194 }
195 }
196 return nil
197 }
198
199
200
201
202
203
204 func getinfo(name string) (*terminfo.Terminfo, string, error) {
205 var tc termcap
206 if err := tc.setupterm(name); err != nil {
207 if err != nil {
208 return nil, "", err
209 }
210 }
211 t := &terminfo.Terminfo{}
212
213 t.Name = tc.name
214 if t.Name != name {
215 return t, "", nil
216 }
217 t.Aliases = tc.aliases
218 t.Colors = tc.getnum("colors")
219 t.Columns = tc.getnum("cols")
220 t.Lines = tc.getnum("lines")
221 t.Bell = tc.getstr("bel")
222 t.Clear = tc.getstr("clear")
223 t.EnterCA = tc.getstr("smcup")
224 t.ExitCA = tc.getstr("rmcup")
225 t.ShowCursor = tc.getstr("cnorm")
226 t.HideCursor = tc.getstr("civis")
227 t.AttrOff = tc.getstr("sgr0")
228 t.Underline = tc.getstr("smul")
229 t.Bold = tc.getstr("bold")
230 t.Blink = tc.getstr("blink")
231 t.Dim = tc.getstr("dim")
232 t.Italic = tc.getstr("sitm")
233 t.Reverse = tc.getstr("rev")
234 t.EnterKeypad = tc.getstr("smkx")
235 t.ExitKeypad = tc.getstr("rmkx")
236 t.SetFg = tc.getstr("setaf")
237 t.SetBg = tc.getstr("setab")
238 t.ResetFgBg = tc.getstr("op")
239 t.SetCursor = tc.getstr("cup")
240 t.CursorBack1 = tc.getstr("cub1")
241 t.CursorUp1 = tc.getstr("cuu1")
242 t.InsertChar = tc.getstr("ich1")
243 t.AutoMargin = tc.getflag("am")
244 t.KeyF1 = tc.getstr("kf1")
245 t.KeyF2 = tc.getstr("kf2")
246 t.KeyF3 = tc.getstr("kf3")
247 t.KeyF4 = tc.getstr("kf4")
248 t.KeyF5 = tc.getstr("kf5")
249 t.KeyF6 = tc.getstr("kf6")
250 t.KeyF7 = tc.getstr("kf7")
251 t.KeyF8 = tc.getstr("kf8")
252 t.KeyF9 = tc.getstr("kf9")
253 t.KeyF10 = tc.getstr("kf10")
254 t.KeyF11 = tc.getstr("kf11")
255 t.KeyF12 = tc.getstr("kf12")
256 t.KeyInsert = tc.getstr("kich1")
257 t.KeyDelete = tc.getstr("kdch1")
258 t.KeyBackspace = tc.getstr("kbs")
259 t.KeyHome = tc.getstr("khome")
260 t.KeyEnd = tc.getstr("kend")
261 t.KeyUp = tc.getstr("kcuu1")
262 t.KeyDown = tc.getstr("kcud1")
263 t.KeyRight = tc.getstr("kcuf1")
264 t.KeyLeft = tc.getstr("kcub1")
265 t.KeyPgDn = tc.getstr("knp")
266 t.KeyPgUp = tc.getstr("kpp")
267 t.KeyBacktab = tc.getstr("kcbt")
268 t.KeyExit = tc.getstr("kext")
269 t.KeyCancel = tc.getstr("kcan")
270 t.KeyPrint = tc.getstr("kprt")
271 t.KeyHelp = tc.getstr("khlp")
272 t.KeyClear = tc.getstr("kclr")
273 t.AltChars = tc.getstr("acsc")
274 t.EnterAcs = tc.getstr("smacs")
275 t.ExitAcs = tc.getstr("rmacs")
276 t.EnableAcs = tc.getstr("enacs")
277 t.StrikeThrough = tc.getstr("smxx")
278 t.Mouse = tc.getstr("kmous")
279
280 t.Modifiers = terminfo.ModifiersNone
281
282
283
284
285
286
287
288 if tc.getstr("kRIT") == "\x1b[1;2C" {
289 t.Modifiers = terminfo.ModifiersXTerm
290 } else {
291
292 t.KeyShfInsert = tc.getstr("kIC")
293 t.KeyShfDelete = tc.getstr("kDC")
294 t.KeyShfRight = tc.getstr("kRIT")
295 t.KeyShfLeft = tc.getstr("kLFT")
296 t.KeyShfHome = tc.getstr("kHOM")
297 t.KeyShfEnd = tc.getstr("kEND")
298 t.KeyF13 = tc.getstr("kf13")
299 t.KeyF14 = tc.getstr("kf14")
300 t.KeyF15 = tc.getstr("kf15")
301 t.KeyF16 = tc.getstr("kf16")
302 t.KeyF17 = tc.getstr("kf17")
303 t.KeyF18 = tc.getstr("kf18")
304 t.KeyF19 = tc.getstr("kf19")
305 t.KeyF20 = tc.getstr("kf20")
306 t.KeyF21 = tc.getstr("kf21")
307 t.KeyF22 = tc.getstr("kf22")
308 t.KeyF23 = tc.getstr("kf23")
309 t.KeyF24 = tc.getstr("kf24")
310 t.KeyF25 = tc.getstr("kf25")
311 t.KeyF26 = tc.getstr("kf26")
312 t.KeyF27 = tc.getstr("kf27")
313 t.KeyF28 = tc.getstr("kf28")
314 t.KeyF29 = tc.getstr("kf29")
315 t.KeyF30 = tc.getstr("kf30")
316 t.KeyF31 = tc.getstr("kf31")
317 t.KeyF32 = tc.getstr("kf32")
318 t.KeyF33 = tc.getstr("kf33")
319 t.KeyF34 = tc.getstr("kf34")
320 t.KeyF35 = tc.getstr("kf35")
321 t.KeyF36 = tc.getstr("kf36")
322 t.KeyF37 = tc.getstr("kf37")
323 t.KeyF38 = tc.getstr("kf38")
324 t.KeyF39 = tc.getstr("kf39")
325 t.KeyF40 = tc.getstr("kf40")
326 t.KeyF41 = tc.getstr("kf41")
327 t.KeyF42 = tc.getstr("kf42")
328 t.KeyF43 = tc.getstr("kf43")
329 t.KeyF44 = tc.getstr("kf44")
330 t.KeyF45 = tc.getstr("kf45")
331 t.KeyF46 = tc.getstr("kf46")
332 t.KeyF47 = tc.getstr("kf47")
333 t.KeyF48 = tc.getstr("kf48")
334 t.KeyF49 = tc.getstr("kf49")
335 t.KeyF50 = tc.getstr("kf50")
336 t.KeyF51 = tc.getstr("kf51")
337 t.KeyF52 = tc.getstr("kf52")
338 t.KeyF53 = tc.getstr("kf53")
339 t.KeyF54 = tc.getstr("kf54")
340 t.KeyF55 = tc.getstr("kf55")
341 t.KeyF56 = tc.getstr("kf56")
342 t.KeyF57 = tc.getstr("kf57")
343 t.KeyF58 = tc.getstr("kf58")
344 t.KeyF59 = tc.getstr("kf59")
345 t.KeyF60 = tc.getstr("kf60")
346 t.KeyF61 = tc.getstr("kf61")
347 t.KeyF62 = tc.getstr("kf62")
348 t.KeyF63 = tc.getstr("kf63")
349 t.KeyF64 = tc.getstr("kf64")
350 }
351
352
353
354
355
356
357 if t.KeyShfRight == "\x1b[c" && t.KeyShfLeft == "\x1b[d" {
358 t.KeyShfUp = "\x1b[a"
359 t.KeyShfDown = "\x1b[b"
360 t.KeyCtrlUp = "\x1b[Oa"
361 t.KeyCtrlDown = "\x1b[Ob"
362 t.KeyCtrlRight = "\x1b[Oc"
363 t.KeyCtrlLeft = "\x1b[Od"
364 }
365 if t.KeyShfHome == "\x1b[7$" && t.KeyShfEnd == "\x1b[8$" {
366 t.KeyCtrlHome = "\x1b[7^"
367 t.KeyCtrlEnd = "\x1b[8^"
368 }
369
370
371
372
373
374
375
376 if tc.getflag("Tc") {
377
378 t.TrueColor = true
379 } else if tc.getflag("RGB") {
380
381
382
383 t.TrueColor = true
384 t.SetBg = "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m"
385 t.SetFg = "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m"
386 }
387
388
389 if t.Colors < 8 || t.SetFg == "" {
390 t.Colors = 0
391 }
392 if t.SetCursor == "" {
393 return nil, "", notaddressable
394 }
395
396
397
398 t.PadChar = tc.getstr("pad")
399 if t.PadChar == "" {
400 if !tc.getflag("npc") {
401 t.PadChar = "\u0000"
402 }
403 }
404
405
406
407 if strings.HasPrefix(t.SetFg, "\x1b[") &&
408 strings.HasPrefix(t.SetBg, "\x1b[") &&
409 strings.HasSuffix(t.SetFg, "m") &&
410 strings.HasSuffix(t.SetBg, "m") {
411 fg := t.SetFg[:len(t.SetFg)-1]
412 r := regexp.MustCompile("%p1")
413 bg := r.ReplaceAllString(t.SetBg[2:], "%p2")
414 t.SetFgBg = fg + ";" + bg
415 }
416
417 return t, tc.desc, nil
418 }
419
420 func dotGoAddInt(w io.Writer, n string, i int) {
421 if i == 0 {
422
423 return
424 }
425 fmt.Fprintf(w, "\t\t%-13s %d,\n", n+":", i)
426 }
427 func dotGoAddStr(w io.Writer, n string, s string) {
428 if s == "" {
429 return
430 }
431 fmt.Fprintf(w, "\t\t%-13s %q,\n", n+":", s)
432 }
433 func dotGoAddFlag(w io.Writer, n string, b bool) {
434 if !b {
435
436 return
437 }
438 fmt.Fprintf(w, "\t\t%-13s true,\n", n+":")
439 }
440
441 func dotGoAddArr(w io.Writer, n string, a []string) {
442 if len(a) == 0 {
443 return
444 }
445 fmt.Fprintf(w, "\t\t%-13s []string{", n+":")
446 did := false
447 for _, b := range a {
448 if did {
449 fmt.Fprint(w, ", ")
450 }
451 did = true
452 fmt.Fprintf(w, "%q", b)
453 }
454 fmt.Fprintln(w, "},")
455 }
456
457 func dotGoHeader(w io.Writer, packname, tipackname string) {
458 fmt.Fprintln(w, "// Generated automatically. DO NOT HAND-EDIT.")
459 fmt.Fprintln(w, "")
460 fmt.Fprintf(w, "package %s\n", packname)
461 fmt.Fprintln(w, "")
462 fmt.Fprintf(w, "import \"%s\"\n", tipackname)
463 fmt.Fprintln(w, "")
464 }
465
466 func dotGoTrailer(w io.Writer) {
467 }
468
469 func dotGoInfo(w io.Writer, terms []*TData) {
470
471 fmt.Fprintln(w, "func init() {")
472 for _, t := range terms {
473 fmt.Fprintf(w, "\n\t// %s\n", t.Desc)
474 fmt.Fprintln(w, "\tterminfo.AddTerminfo(&terminfo.Terminfo{")
475 dotGoAddStr(w, "Name", t.Name)
476 dotGoAddArr(w, "Aliases", t.Aliases)
477 dotGoAddInt(w, "Columns", t.Columns)
478 dotGoAddInt(w, "Lines", t.Lines)
479 dotGoAddInt(w, "Colors", t.Colors)
480 dotGoAddStr(w, "Bell", t.Bell)
481 dotGoAddStr(w, "Clear", t.Clear)
482 dotGoAddStr(w, "EnterCA", t.EnterCA)
483 dotGoAddStr(w, "ExitCA", t.ExitCA)
484 dotGoAddStr(w, "ShowCursor", t.ShowCursor)
485 dotGoAddStr(w, "HideCursor", t.HideCursor)
486 dotGoAddStr(w, "AttrOff", t.AttrOff)
487 dotGoAddStr(w, "Underline", t.Underline)
488 dotGoAddStr(w, "Bold", t.Bold)
489 dotGoAddStr(w, "Dim", t.Dim)
490 dotGoAddStr(w, "Italic", t.Italic)
491 dotGoAddStr(w, "Blink", t.Blink)
492 dotGoAddStr(w, "Reverse", t.Reverse)
493 dotGoAddStr(w, "EnterKeypad", t.EnterKeypad)
494 dotGoAddStr(w, "ExitKeypad", t.ExitKeypad)
495 dotGoAddStr(w, "SetFg", t.SetFg)
496 dotGoAddStr(w, "SetBg", t.SetBg)
497 dotGoAddStr(w, "SetFgBg", t.SetFgBg)
498 dotGoAddStr(w, "ResetFgBg", t.ResetFgBg)
499 dotGoAddStr(w, "PadChar", t.PadChar)
500 dotGoAddStr(w, "AltChars", t.AltChars)
501 dotGoAddStr(w, "EnterAcs", t.EnterAcs)
502 dotGoAddStr(w, "ExitAcs", t.ExitAcs)
503 dotGoAddStr(w, "EnableAcs", t.EnableAcs)
504 dotGoAddStr(w, "SetFgRGB", t.SetFgRGB)
505 dotGoAddStr(w, "SetBgRGB", t.SetBgRGB)
506 dotGoAddStr(w, "SetFgBgRGB", t.SetFgBgRGB)
507 dotGoAddStr(w, "StrikeThrough", t.StrikeThrough)
508 dotGoAddStr(w, "Mouse", t.Mouse)
509 dotGoAddStr(w, "SetCursor", t.SetCursor)
510 dotGoAddStr(w, "CursorBack1", t.CursorBack1)
511 dotGoAddStr(w, "CursorUp1", t.CursorUp1)
512 dotGoAddStr(w, "KeyUp", t.KeyUp)
513 dotGoAddStr(w, "KeyDown", t.KeyDown)
514 dotGoAddStr(w, "KeyRight", t.KeyRight)
515 dotGoAddStr(w, "KeyLeft", t.KeyLeft)
516 dotGoAddStr(w, "KeyInsert", t.KeyInsert)
517 dotGoAddStr(w, "KeyDelete", t.KeyDelete)
518 dotGoAddStr(w, "KeyBackspace", t.KeyBackspace)
519 dotGoAddStr(w, "KeyHome", t.KeyHome)
520 dotGoAddStr(w, "KeyEnd", t.KeyEnd)
521 dotGoAddStr(w, "KeyPgUp", t.KeyPgUp)
522 dotGoAddStr(w, "KeyPgDn", t.KeyPgDn)
523 dotGoAddStr(w, "KeyF1", t.KeyF1)
524 dotGoAddStr(w, "KeyF2", t.KeyF2)
525 dotGoAddStr(w, "KeyF3", t.KeyF3)
526 dotGoAddStr(w, "KeyF4", t.KeyF4)
527 dotGoAddStr(w, "KeyF5", t.KeyF5)
528 dotGoAddStr(w, "KeyF6", t.KeyF6)
529 dotGoAddStr(w, "KeyF7", t.KeyF7)
530 dotGoAddStr(w, "KeyF8", t.KeyF8)
531 dotGoAddStr(w, "KeyF9", t.KeyF9)
532 dotGoAddStr(w, "KeyF10", t.KeyF10)
533 dotGoAddStr(w, "KeyF11", t.KeyF11)
534 dotGoAddStr(w, "KeyF12", t.KeyF12)
535
536
537 dotGoAddStr(w, "KeyF13", t.KeyF13)
538 dotGoAddStr(w, "KeyF14", t.KeyF14)
539 dotGoAddStr(w, "KeyF15", t.KeyF15)
540 dotGoAddStr(w, "KeyF16", t.KeyF16)
541 dotGoAddStr(w, "KeyF17", t.KeyF17)
542 dotGoAddStr(w, "KeyF18", t.KeyF18)
543 dotGoAddStr(w, "KeyF19", t.KeyF19)
544 dotGoAddStr(w, "KeyF20", t.KeyF20)
545 dotGoAddStr(w, "KeyF21", t.KeyF21)
546 dotGoAddStr(w, "KeyF22", t.KeyF22)
547 dotGoAddStr(w, "KeyF23", t.KeyF23)
548 dotGoAddStr(w, "KeyF24", t.KeyF24)
549 dotGoAddStr(w, "KeyF25", t.KeyF25)
550 dotGoAddStr(w, "KeyF26", t.KeyF26)
551 dotGoAddStr(w, "KeyF27", t.KeyF27)
552 dotGoAddStr(w, "KeyF28", t.KeyF28)
553 dotGoAddStr(w, "KeyF29", t.KeyF29)
554 dotGoAddStr(w, "KeyF30", t.KeyF30)
555 dotGoAddStr(w, "KeyF31", t.KeyF31)
556 dotGoAddStr(w, "KeyF32", t.KeyF32)
557 dotGoAddStr(w, "KeyF33", t.KeyF33)
558 dotGoAddStr(w, "KeyF34", t.KeyF34)
559 dotGoAddStr(w, "KeyF35", t.KeyF35)
560 dotGoAddStr(w, "KeyF36", t.KeyF36)
561 dotGoAddStr(w, "KeyF37", t.KeyF37)
562 dotGoAddStr(w, "KeyF38", t.KeyF38)
563 dotGoAddStr(w, "KeyF39", t.KeyF39)
564 dotGoAddStr(w, "KeyF40", t.KeyF40)
565 dotGoAddStr(w, "KeyF41", t.KeyF41)
566 dotGoAddStr(w, "KeyF42", t.KeyF42)
567 dotGoAddStr(w, "KeyF43", t.KeyF43)
568 dotGoAddStr(w, "KeyF44", t.KeyF44)
569 dotGoAddStr(w, "KeyF45", t.KeyF45)
570 dotGoAddStr(w, "KeyF46", t.KeyF46)
571 dotGoAddStr(w, "KeyF47", t.KeyF47)
572 dotGoAddStr(w, "KeyF48", t.KeyF48)
573 dotGoAddStr(w, "KeyF49", t.KeyF49)
574 dotGoAddStr(w, "KeyF50", t.KeyF50)
575 dotGoAddStr(w, "KeyF51", t.KeyF51)
576 dotGoAddStr(w, "KeyF52", t.KeyF52)
577 dotGoAddStr(w, "KeyF53", t.KeyF53)
578 dotGoAddStr(w, "KeyF54", t.KeyF54)
579 dotGoAddStr(w, "KeyF55", t.KeyF55)
580 dotGoAddStr(w, "KeyF56", t.KeyF56)
581 dotGoAddStr(w, "KeyF57", t.KeyF57)
582 dotGoAddStr(w, "KeyF58", t.KeyF58)
583 dotGoAddStr(w, "KeyF59", t.KeyF59)
584 dotGoAddStr(w, "KeyF60", t.KeyF60)
585 dotGoAddStr(w, "KeyF61", t.KeyF61)
586 dotGoAddStr(w, "KeyF62", t.KeyF62)
587 dotGoAddStr(w, "KeyF63", t.KeyF63)
588 dotGoAddStr(w, "KeyF64", t.KeyF64)
589 dotGoAddStr(w, "KeyCancel", t.KeyCancel)
590 dotGoAddStr(w, "KeyPrint", t.KeyPrint)
591 dotGoAddStr(w, "KeyExit", t.KeyExit)
592 dotGoAddStr(w, "KeyHelp", t.KeyHelp)
593 dotGoAddStr(w, "KeyClear", t.KeyClear)
594 dotGoAddStr(w, "KeyBacktab", t.KeyBacktab)
595 dotGoAddStr(w, "KeyShfLeft", t.KeyShfLeft)
596 dotGoAddStr(w, "KeyShfRight", t.KeyShfRight)
597 dotGoAddStr(w, "KeyShfUp", t.KeyShfUp)
598 dotGoAddStr(w, "KeyShfDown", t.KeyShfDown)
599 dotGoAddStr(w, "KeyShfHome", t.KeyShfHome)
600 dotGoAddStr(w, "KeyShfEnd", t.KeyShfEnd)
601 dotGoAddStr(w, "KeyShfInsert", t.KeyShfInsert)
602 dotGoAddStr(w, "KeyShfDelete", t.KeyShfDelete)
603 dotGoAddStr(w, "KeyCtrlUp", t.KeyCtrlUp)
604 dotGoAddStr(w, "KeyCtrlDown", t.KeyCtrlDown)
605 dotGoAddStr(w, "KeyCtrlRight", t.KeyCtrlRight)
606 dotGoAddStr(w, "KeyCtrlLeft", t.KeyCtrlLeft)
607 dotGoAddStr(w, "KeyCtrlHome", t.KeyCtrlHome)
608 dotGoAddStr(w, "KeyCtrlEnd", t.KeyCtrlEnd)
609 dotGoAddInt(w, "Modifiers", t.Modifiers)
610 dotGoAddFlag(w, "TrueColor", t.TrueColor)
611 dotGoAddFlag(w, "AutoMargin", t.AutoMargin)
612 dotGoAddStr(w, "InsertChar", t.InsertChar)
613 dotGoAddStr(w, "CursorDefault", t.CursorDefault)
614 dotGoAddStr(w, "CursorBlinkingBlock", t.CursorBlinkingBlock)
615 dotGoAddStr(w, "CursorSteadyBlock", t.CursorSteadyBlock)
616 dotGoAddStr(w, "CursorBlinkingUnderline", t.CursorBlinkingUnderline)
617 dotGoAddStr(w, "CursorSteadyUnderline", t.CursorSteadyUnderline)
618 dotGoAddStr(w, "CursorBlinkingBar", t.CursorBlinkingBar)
619 dotGoAddStr(w, "CursorSteadyBar", t.CursorSteadyBar)
620 fmt.Fprintln(w, "\t})")
621 }
622 fmt.Fprintln(w, "}")
623 }
624
625 var packname = ""
626 var tipackname = "github.com/gdamore/tcell/v2/terminfo"
627
628 func dotGoFile(fname string, terms []*TData) error {
629 w := os.Stdout
630 var e error
631 if fname != "-" && fname != "" {
632 if w, e = os.Create(fname); e != nil {
633 return e
634 }
635 }
636 if packname == "" {
637 packname = strings.Replace(terms[0].Name, "-", "_", -1)
638 }
639 dotGoHeader(w, packname, tipackname)
640 dotGoInfo(w, terms)
641 dotGoTrailer(w)
642 if w != os.Stdout {
643 w.Close()
644 }
645 cmd := exec.Command("go", "fmt", fname)
646 cmd.Run()
647 return nil
648 }
649
650 type TData struct {
651 Desc string
652
653 terminfo.Terminfo
654 }
655
656 func main() {
657 gofile := ""
658 nofatal := false
659 quiet := false
660 all := false
661
662 flag.StringVar(&gofile, "go", "", "generate go source in named file")
663 flag.StringVar(&tipackname, "I", tipackname, "import package path")
664 flag.StringVar(&packname, "P", packname, "package name (go source)")
665 flag.BoolVar(&nofatal, "nofatal", false, "errors are not fatal")
666 flag.BoolVar(&quiet, "quiet", false, "suppress error messages")
667 flag.BoolVar(&all, "all", false, "load all terminals from terminfo")
668 flag.Parse()
669 var e error
670
671 args := flag.Args()
672 if len(args) == 0 {
673 args = []string{os.Getenv("TERM")}
674 }
675
676 tdata := make([]*TData, 0)
677
678 for _, term := range args {
679 if t, desc, e := getinfo(term); e != nil {
680 if all && e == notaddressable {
681 continue
682 }
683 if !quiet {
684 fmt.Fprintf(os.Stderr,
685 "Failed loading %s: %v\n", term, e)
686 }
687 if !nofatal {
688 os.Exit(1)
689 }
690 } else {
691 tdata = append(tdata, &TData{
692 Desc: desc,
693 Terminfo: *t,
694 })
695 }
696 }
697
698 if len(tdata) == 0 {
699
700 os.Exit(0)
701 }
702
703 e = dotGoFile(gofile, tdata)
704 if e != nil {
705 fmt.Fprintf(os.Stderr, "Failed %s: %v", gofile, e)
706 os.Exit(1)
707 }
708 }
709
View as plain text