package main import tea "github.com/charmbracelet/bubbletea" func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.WindowSizeMsg: m.win_h = msg.Height m.win_w = msg.Width case tea.KeyMsg: switch m.mode { case NormalMode: return m, m.input.Handle(&m, msg.String()) case InsertMode: switch msg.String() { case "ctrl+c", "ctrl+d": return m, tea.Quit case "esc": // Allow i to step back, but a to stay put if m.cursor.x > 0 { m.cursor.x-- } m.mode = NormalMode case "enter": y := m.cursor.y x := m.cursor.x // Simple case, at end, just create a line if x == len(m.lines[y]) { m.lines = append(m.lines[:y+1], append([]string{""}, m.lines[y+1:]...)...) // otherwise, splice } else { l := m.lines[y] m.lines[y] = l[:x] m.lines = append(m.lines[:y+1], append([]string{l[x:]}, m.lines[y+1:]...)...) } m.cursor.y++ m.cursor.x = 0 case "backspace": x := m.cursor.x y := m.cursor.y l := m.lines[y] if m.cursor.x > 0 { m.lines[y] = l[:x-1] + l[x:] m.cursor.x-- } else if m.cursor.y > 0 { new_x := len(m.lines[y-1]) m.lines[y-1] = m.lines[y-1] + l m.lines = append(m.lines[:y], m.lines[y+1:]...) m.cursor.y-- m.cursor.x = new_x } case "left": if m.cursor.x > 0 { m.cursor.x-- } case "right": if m.cursor.x < len(m.lines[m.cursor.y]) { m.cursor.x++ } case "up": if m.cursor.y > 0 { m.cursor.y-- } if m.cursor.x > len(m.lines[m.cursor.y])-1 { m.cursor.x = len(m.lines[m.cursor.y]) } case "down": if m.cursor.y < len(m.lines)-1 { m.cursor.y++ } if m.cursor.x > len(m.lines[m.cursor.y])-1 { m.cursor.x = len(m.lines[m.cursor.y]) } default: x := m.cursor.x y := m.cursor.y l := m.lines[y] ch := msg.String() if x < len(l) { m.lines[y] = l[:x] + ch + l[x:] } else { m.lines[y] = l + ch } m.cursor.x += len(ch) } case CommandMode: switch msg.String() { case "esc": m.mode = NormalMode m.command = "" default: m.command += msg.String() } } } return m, nil }