apiStatusScreen := NewAPIStatusScreen()
return RootScreen().SwitchScreen(&apiStatusScreen)
- case 6:
+ case 6:
+ shellScreen := NewShellScreenModel()
+ return RootScreen().SwitchScreen(&shellScreen)
+
+ case 7:
return m, tea.Quit
}
c := m.OptionChoice
// Top bar styling
-
roundLabelCorner := ui.RoundLabelCornerStyle.Render("")
labelArrow := ui.LabelArrowStyle.Render("")
titleBlock := ui.TitleStyle.Render(" Repoman CLI ")
ui.TopBarLeftStyle.Width((m.Width / 2 ) - 1).Render(roundLabelCorner + titleBlock + labelArrow),
ui.TopBarRightStyle.Width((m.Width / 2 ) - 1).Render(rightTopBarBlock)))
- _, topBarBlockHeight := lipgloss.Size(topBarBlock)
+ topBarBlockHeight := lipgloss.Height(topBarBlock)
// Footer styling
copyrightBlock := ui.SubtleStyle.Render("2024 Copyright - Repoman")
ui.FooterLeftStyle.Width((m.Width / 2 ) - 1).Render(copyrightBlock),
ui.FooterRightStyle.Width((m.Width / 2 ) - 1).Render(helpBlock)))
- _, footerBlockHeight := lipgloss.Size(footerBlock)
+ footerBlockHeight := lipgloss.Height(footerBlock)
// Menu options
var mainMenuBlock string
--- /dev/null
+package screens
+
+// A simple program demonstrating the text area component from the Bubbles
+// component library.
+
+import (
+ "fmt"
+ "strings"
+ "os"
+ "github.com/repoman-cli/ui"
+ "github.com/charmbracelet/bubbles/textarea"
+ "github.com/charmbracelet/bubbles/viewport"
+ tea "github.com/charmbracelet/bubbletea"
+ "github.com/charmbracelet/lipgloss"
+)
+
+
+type (
+ errMsg error
+)
+
+type RepomanShellModel struct {
+ viewport viewport.Model
+ messages []string
+ textarea textarea.Model
+ senderStyle lipgloss.Style
+ err error
+ Width int
+ Height int
+ topBar string
+}
+
+func NewShellScreenModel() RepomanShellModel {
+ // Get terminal size
+ w, h, err := ui.GetWindowSize()
+ if err != nil {
+ fmt.Printf("Could not get terminal window size.")
+ os.Exit(1)
+ }
+
+ // Top bar styling
+ roundLabelCorner := ui.RoundLabelCornerStyle.Render("")
+ labelArrow := ui.LabelArrowStyle.Render("")
+ titleBlock := ui.TitleStyle.Render(" Repoman CLI ")
+ rightTopBarBlock := ui.TopBarRightLabel.Render(" Repoman Shell ")
+
+ topBarBlock := ui.TopBarStyle.Render(lipgloss.JoinHorizontal(lipgloss.Center,
+ ui.TopBarLeftStyle.Width((w / 2 ) - 1).Render(roundLabelCorner + titleBlock + labelArrow),
+ ui.TopBarRightStyle.Width((w / 2 ) - 1).Render(rightTopBarBlock)))
+
+ topBarBlockHeight := lipgloss.Height(topBarBlock)
+
+ ta := textarea.New()
+ ta.Placeholder = "Type in a command or enter 'help' if you are lost"
+ ta.Focus()
+
+ ta.Prompt = "┃ repoman $ ❯ "
+ ta.CharLimit = 280
+
+ ta.SetWidth(w)
+ ta.SetHeight(1)
+
+ // Remove cursor line styling
+ ta.FocusedStyle.CursorLine = lipgloss.NewStyle()
+
+ ta.ShowLineNumbers = false
+
+ vp := viewport.New(w, h - topBarBlockHeight - 1)
+ vp.SetContent(ui.SubtleStyle.Render(`This is not Bash, Zshhh or some type of fish `))
+
+ ta.KeyMap.InsertNewline.SetEnabled(false)
+
+ return RepomanShellModel{
+ textarea: ta,
+ messages: []string{},
+ viewport: vp,
+ senderStyle: lipgloss.NewStyle().Foreground(lipgloss.Color("5")),
+ err: nil,
+ Width: w,
+ Height: h,
+ topBar: topBarBlock,
+ }
+}
+
+func (m *RepomanShellModel) Init() tea.Cmd {
+ return textarea.Blink
+}
+
+func (m *RepomanShellModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+ var (
+ tiCmd tea.Cmd
+ vpCmd tea.Cmd
+ )
+
+ m.textarea, tiCmd = m.textarea.Update(msg)
+ m.viewport, vpCmd = m.viewport.Update(msg)
+
+ switch msg := msg.(type) {
+ case tea.KeyMsg:
+ switch msg.Type {
+ case tea.KeyCtrlC, tea.KeyEsc:
+ fmt.Println(m.textarea.Value())
+ return m, tea.Quit
+
+ case tea.KeyEnter:
+ m, cmd := parseCmd(m, m.textarea.Value())
+ return m, cmd
+ case tea.KeyCtrlL:
+ m.messages = []string{}
+ m.viewport.SetContent("$ ❯ ")
+ }
+
+ // We handle errors just like any other message
+ case errMsg:
+ m.err = msg
+ return m, nil
+
+ case tea.WindowSizeMsg:
+ w, h, _ := ui.GetWindowSize()
+ m.Width = w
+ m.Height = h
+ m.textarea.SetWidth(w)
+ m.viewport = viewport.New(w, h - lipgloss.Height(m.topBar) - 1)
+ m.viewport.SetContent(strings.Join(m.messages, "\n"))
+ }
+
+ return m, tea.Batch(tiCmd, vpCmd)
+}
+
+func (m *RepomanShellModel) View() string {
+
+ // Top bar styling
+ roundLabelCorner := ui.RoundLabelCornerStyle.Render("")
+ labelArrow := ui.LabelArrowStyle.Render("")
+ titleBlock := ui.TitleStyle.Render(" Repoman CLI ")
+ rightTopBarBlock := ui.TopBarRightLabel.Render(" Repoman Shell ")
+
+ topBarBlock := ui.TopBarStyle.Render(lipgloss.JoinHorizontal(lipgloss.Center,
+ ui.TopBarLeftStyle.Width((m.Width / 2 ) - 1).Render(roundLabelCorner + titleBlock + labelArrow),
+ ui.TopBarRightStyle.Width((m.Width / 2 ) - 1).Render(rightTopBarBlock)))
+
+ m.topBar = topBarBlock
+
+ return lipgloss.PlaceHorizontal(m.Width, lipgloss.Center, lipgloss.JoinVertical(lipgloss.Left, m.topBar, m.viewport.View(), m.textarea.View()))
+}
+
+
+func parseCmd(m *RepomanShellModel, cmd string) (tea.Model, tea.Cmd){
+ var cmdReturn string
+ if cmd != "" {
+ switch cmd {
+ case "help", "?":
+ cmdReturn = "Well I can't help you neither buddy"
+ m.messages = append(m.messages, m.senderStyle.Render(fmt.Sprintf("$ ❯ %s\n%s", m.textarea.Value(), cmdReturn)))
+
+ case "menu", "quit":
+ mainMenuModel := MainMenu()
+ return RootScreen().SwitchScreen(&mainMenuModel)
+
+ case "exit":
+ return m, tea.Quit
+
+ default:
+ m.messages = append(m.messages, m.senderStyle.Render("$ ❯ Unknown command: " + m.textarea.Value()))
+
+ }
+ } else {
+ m.messages = append(m.messages, m.senderStyle.Render("$ ❯ "))
+ }
+
+ m.viewport.SetContent(strings.Join(m.messages, "\n"))
+ m.textarea.Reset()
+ m.viewport.GotoBottom()
+
+ return m, nil
+}