TUI IDE multiplexer?!
golang
tui
ide
1package main
2
3import (
4 "fmt"
5 "slices"
6 "strings"
7
8 "github.com/godbus/dbus/v5"
9 "github.com/godbus/dbus/v5/introspect"
10 "github.com/rivo/tview"
11)
12
13const statusIntro = `
14<node>
15 <interface name="net.kettek.Aight.Status">
16 <method name="UpdateItem">
17 <arg name="ID" direction="in" type="s"/>
18 <arg name="Name" direction="in" type="s"/>
19 <arg name="Value" direction="in" type="s"/>
20 </method>
21 <method name="RemoveItem">
22 <arg name="ID" direction="in" type="s"/>
23 </method>
24 <method name="Refresh"></method>
25 </interface>` + introspect.IntrospectDataString + `
26</node>
27`
28
29// TODO: Make configurable.
30var statusItemString = "[::b]%s[::B]%s\t"
31
32type StatusItem struct {
33 ID string // If ID is set, only one instance of this item may exist and any calls to Add will just overwrite.
34 Name string
35 Value string
36}
37
38type Status struct {
39 *tview.TextView
40 items []StatusItem
41}
42
43func NewStatus() *Status {
44 view := tview.NewTextView().
45 SetWrap(false).
46 SetScrollable(true).
47 SetDynamicColors(true)
48
49 status := &Status{
50 TextView: view,
51 }
52
53 return status
54}
55
56func (s *Status) AddToConn(conn *dbus.Conn) error {
57 if err := app.Conn.Export(s, "/status", "net.kettek.Aight.Status"); err != nil {
58 return err
59 }
60 if err := app.Conn.Export(introspect.Introspectable(statusIntro), "/status", "org.freedesktop.DBus.Introspectable"); err != nil {
61 return err
62 }
63
64 // Add DBUS connection ID to the statusbar.
65 s.Add(StatusItem{"DBUS", "DBUS", conn.Names()[0]})
66 return nil
67}
68
69func (s *Status) RemoveFromConn(conn *dbus.Conn) {
70 conn.Export(nil, "/status", "org.freedesktop.DBus.Introspectable")
71 conn.Export(nil, "/status", "net.kettek.Aight.Status")
72}
73
74func (s *Status) Add(items ...StatusItem) {
75 for _, v := range items {
76 if v.ID != "" {
77 index := slices.IndexFunc(s.items, func(item StatusItem) bool {
78 return item.ID == v.ID
79 })
80 if index != -1 {
81 s.items[index] = v
82 continue
83 }
84 }
85 s.items = append(s.items, v)
86 }
87 s.Refresh()
88}
89
90func (s *Status) UpdateItem(id, name, value string) *dbus.Error {
91 s.Add(StatusItem{id, name, value})
92 return nil
93}
94
95func (s *Status) RemoveItem(id string) *dbus.Error {
96 if index := slices.IndexFunc(s.items, func(s StatusItem) bool {
97 return s.ID == id
98 }); index != -1 {
99 s.items = append(s.items[:index], s.items[index+1:]...)
100 return nil
101 }
102 return s.Refresh()
103}
104
105func (s *Status) Refresh() *dbus.Error {
106 var t strings.Builder
107 for _, item := range s.items {
108 fmt.Fprintf(&t, statusItemString, item.Name, item.Value)
109 }
110 s.SetText(t.String())
111 return nil
112}