Skip to content

Commit 3b1b406

Browse files
committed
first commit
0 parents  commit 3b1b406

File tree

3 files changed

+247
-0
lines changed

3 files changed

+247
-0
lines changed

go.mod

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module kancli-demo
2+
3+
go 1.19
4+
5+
require github.com/charmbracelet/bubbles v0.13.0
6+
7+
require (
8+
github.com/atotto/clipboard v0.1.4 // indirect
9+
github.com/charmbracelet/bubbletea v0.21.0 // indirect
10+
github.com/charmbracelet/lipgloss v0.5.0 // indirect
11+
github.com/containerd/console v1.0.3 // indirect
12+
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
13+
github.com/mattn/go-isatty v0.0.14 // indirect
14+
github.com/mattn/go-runewidth v0.0.13 // indirect
15+
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect
16+
github.com/muesli/cancelreader v0.2.0 // indirect
17+
github.com/muesli/reflow v0.3.0 // indirect
18+
github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739 // indirect
19+
github.com/rivo/uniseg v0.2.0 // indirect
20+
github.com/sahilm/fuzzy v0.1.0 // indirect
21+
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
22+
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
23+
)

go.sum

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
2+
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
3+
github.com/charmbracelet/bubbles v0.13.0 h1:zP/ROH3wJEBqZWKIsD50ZKKlx3ydLInq3LdD/Nrlb8w=
4+
github.com/charmbracelet/bubbles v0.13.0/go.mod h1:bbeTiXwPww4M031aGi8UK2HT9RDWoiNibae+1yCMtcc=
5+
github.com/charmbracelet/bubbletea v0.21.0 h1:f3y+kanzgev5PA916qxmDybSHU3N804uOnKnhRPXTcI=
6+
github.com/charmbracelet/bubbletea v0.21.0/go.mod h1:GgmJMec61d08zXsOhqRC/AiOx4K4pmz+VIcRIm1FKr4=
7+
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
8+
github.com/charmbracelet/lipgloss v0.5.0 h1:lulQHuVeodSgDez+3rGiuxlPVXSnhth442DATR2/8t8=
9+
github.com/charmbracelet/lipgloss v0.5.0/go.mod h1:EZLha/HbzEt7cYqdFPovlqy5FZPj0xFhg5SaqxScmgs=
10+
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
11+
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
12+
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
13+
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
14+
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
15+
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
16+
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
17+
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
18+
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
19+
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
20+
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
21+
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
22+
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b h1:1XF24mVaiu7u+CFywTdcDo2ie1pzzhwjt6RHqzpMU34=
23+
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
24+
github.com/muesli/cancelreader v0.2.0 h1:SOpr+CfyVNce341kKqvbhhzQhBPyJRXQaCtn03Pae1Q=
25+
github.com/muesli/cancelreader v0.2.0/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
26+
github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ=
27+
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
28+
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
29+
github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs=
30+
github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739 h1:QANkGiGr39l1EESqrE0gZw0/AJNYzIvoGLhIoVYtluI=
31+
github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs=
32+
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
33+
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
34+
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
35+
github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI=
36+
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
37+
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
38+
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
39+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
40+
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
41+
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c=
42+
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
43+
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
44+
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=

main.go

+180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"github.com/charmbracelet/bubbles/list"
8+
tea "github.com/charmbracelet/bubbletea"
9+
"github.com/charmbracelet/lipgloss"
10+
)
11+
12+
type status int
13+
14+
const divisor = 4
15+
16+
const (
17+
todo status = iota
18+
inProgress
19+
done
20+
)
21+
22+
/* STYLING */
23+
var (
24+
columnStyle = lipgloss.NewStyle().
25+
Padding(1, 2).
26+
Border(lipgloss.HiddenBorder())
27+
focusedStyle = lipgloss.NewStyle().
28+
Padding(1, 2).
29+
Border(lipgloss.RoundedBorder()).
30+
BorderForeground(lipgloss.Color("62"))
31+
helpStyle = lipgloss.NewStyle().
32+
Foreground(lipgloss.Color("241"))
33+
)
34+
35+
/* CUSTOM ITEM */
36+
37+
type Task struct {
38+
status status
39+
title string
40+
description string
41+
}
42+
43+
// implement the list.Item interface
44+
func (t Task) FilterValue() string {
45+
return t.title
46+
}
47+
48+
func (t Task) Title() string {
49+
return t.title
50+
}
51+
52+
func (t Task) Description() string {
53+
return t.description
54+
}
55+
56+
/* MAIN MODEL */
57+
58+
type Model struct {
59+
loaded bool
60+
focused status
61+
lists []list.Model
62+
err error
63+
quitting bool
64+
}
65+
66+
func New() *Model {
67+
return &Model{}
68+
}
69+
70+
func (m *Model) Next() {
71+
if m.focused == done {
72+
m.focused = todo
73+
} else {
74+
m.focused++
75+
}
76+
}
77+
78+
func (m *Model) Prev() {
79+
if m.focused == todo {
80+
m.focused = done
81+
} else {
82+
m.focused--
83+
}
84+
}
85+
86+
func (m *Model) initLists(width, height int) {
87+
defaultList := list.New([]list.Item{}, list.NewDefaultDelegate(), width/divisor, height-divisor)
88+
defaultList.SetShowHelp(false)
89+
m.lists = []list.Model{defaultList, defaultList, defaultList}
90+
91+
// Init To Do
92+
m.lists[todo].Title = "To Do"
93+
m.lists[todo].SetItems([]list.Item{
94+
Task{status: todo, title: "buy milk", description: "strawberry milk"},
95+
Task{status: todo, title: "eat sushi", description: "negitoro roll, miso soup, rice"},
96+
Task{status: todo, title: "fold laundry", description: "or wear wrinkly t-shirts"},
97+
})
98+
// Init in progress
99+
m.lists[inProgress].Title = "In Progress"
100+
m.lists[inProgress].SetItems([]list.Item{
101+
Task{status: todo, title: "write code", description: "don't worry, it's Go"},
102+
})
103+
// Init done
104+
m.lists[done].Title = "Done"
105+
m.lists[done].SetItems([]list.Item{
106+
Task{status: todo, title: "stay cool", description: "as a cucumber"},
107+
})
108+
}
109+
110+
func (m Model) Init() tea.Cmd {
111+
return nil
112+
}
113+
114+
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
115+
switch msg := msg.(type) {
116+
case tea.WindowSizeMsg:
117+
if !m.loaded {
118+
m.initLists(msg.Width, msg.Height)
119+
m.loaded = true
120+
}
121+
case tea.KeyMsg:
122+
switch msg.String() {
123+
case "ctrl+c", "q":
124+
m.quitting = true
125+
return m, tea.Quit
126+
case "left", "h":
127+
m.Prev()
128+
case "right", "l":
129+
m.Next()
130+
}
131+
}
132+
var cmd tea.Cmd
133+
m.lists[m.focused], cmd = m.lists[m.focused].Update(msg)
134+
return m, cmd
135+
}
136+
137+
func (m Model) View() string {
138+
if m.quitting {
139+
return ""
140+
}
141+
if m.loaded {
142+
todoView := m.lists[todo].View()
143+
inProgView := m.lists[inProgress].View()
144+
doneView := m.lists[done].View()
145+
switch m.focused {
146+
case inProgress:
147+
return lipgloss.JoinHorizontal(
148+
lipgloss.Left,
149+
columnStyle.Render(todoView),
150+
focusedStyle.Render(inProgView),
151+
columnStyle.Render(doneView),
152+
)
153+
case done:
154+
return lipgloss.JoinHorizontal(
155+
lipgloss.Left,
156+
columnStyle.Render(todoView),
157+
columnStyle.Render(inProgView),
158+
focusedStyle.Render(doneView),
159+
)
160+
default:
161+
return lipgloss.JoinHorizontal(
162+
lipgloss.Left,
163+
focusedStyle.Render(todoView),
164+
columnStyle.Render(inProgView),
165+
columnStyle.Render(doneView),
166+
)
167+
}
168+
} else {
169+
return "loading..."
170+
}
171+
}
172+
173+
func main() {
174+
m := New()
175+
p := tea.NewProgram(m)
176+
if err := p.Start(); err != nil {
177+
fmt.Println(err)
178+
os.Exit(1)
179+
}
180+
}

0 commit comments

Comments
 (0)