Here I give a brief overview of what Charm CLI is and how to get started with the basics.
Charm CLI a framework Go lang CLI applications. Charm offers a variety of different libraries and apps you can use to integrate into your application.
Build terminal user interfaces.
Style your terminal.
Back-end for your commandline applications.
Create SSH apps.
The Bubble Tea component toolkit.
Stylesheet drivern markdown renderer.
Physics-based animation library.
Script GIFs of the terminal with code.
Self-hostable Git server which runs its own SSH service and SSH-accessible terminal user interface.
Render markdown on the commpand line.
Personal key value store via command line.
Colourful logging library
Example: building a shopping list for command line via Bubble Tea
mkdir [folder-name]
cd [folder-name]
go mode init [folder-name]
touch main.go
// main.go
package main
import (
"fmt"
"os"
tea "github.com/charmbracelet/bubbletea"
)
// neeed methods init (reutrn initial command for application run), update (handle incokming events and update model accordingly) and view (render UI based on data in model)
// init
type mode struct {
choices []string // list of items
cursor int // which item cursor is pointing at
selected map[int]struct{} // item selected
}
func initialMode() model {
return model{
choices: []string{"Buy apples", "Buy pears", "Buy bananas"},
selected: make(map[int]struct{})
}
}
func (m model) Init() tea.Cmd {
retur nil
}
// update
func (m model) Update(msg tea.Msg) (tea.Model, tea.cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "ctrl+c", "q":
return m, tea.Quit // m is the model
case "up", "k":
if m.cursor > 0 {
m.cursor --
}
case "down", "j":
if m.cursor < len(m.choices)-1 {
m.cursor++
}
case "enter", " ":
_, ok := m.selected[m.cursor]
if ok {
delete(m.selected, m.cursor)
} else {
m.selected[m.cursor] = struct{}{}
}
}
}
return m, nil
}
// view - this is where lipgloss would be used
func (m model) View() string {
s := "What should we buy at the market? \n\n"
for i, choice := range m.choices {
// is cursor pointing at this choice
cursor := " " // no cursor - empty current index
if m.cursor == i {
cursor = ">"
}
// is this choice selected?
checked := " " // not selected
if _, ok := m.selected[i]; ok{
checked = "x"
}
// render the row
s+= fmt.Sprintf("%s [%s] %s\n", cursor, checked, choice)
}
s += "\nPress q to quit \n"
return s
}
func main() {
p := tea.NewProgram(iniialModel())
if err := p.Start(); err != nil {
fmt.Printf("Error: %v", err)
os.Exit(1)
}
}
go run .