handleChipKey gives chips atomic-token semantics: Backspace/Delete at a boundary removes the whole chip, ←/→ jumps across it, and a cursor inside a chip is snapped to a boundary first. Returns (handled, updated).
(msg tea.KeyMsg)
| 219 | // boundary removes the whole chip, ←/→ jumps across it, and a cursor inside a |
| 220 | // chip is snapped to a boundary first. Returns (handled, updated). |
| 221 | func (p promptInput) handleChipKey(msg tea.KeyMsg) (bool, promptInput) { |
| 222 | if len(p.spans) == 0 { |
| 223 | return false, p |
| 224 | } |
| 225 | cur := p.snapCursorOutOfChip() |
| 226 | switch msg.Type { |
| 227 | case tea.KeyBackspace: |
| 228 | if chip, ok := p.chipAtBoundary(cur, false); ok { |
| 229 | p.deleteSpan(chip) |
| 230 | return true, p |
| 231 | } |
| 232 | case tea.KeyDelete: |
| 233 | if chip, ok := p.chipAtBoundary(cur, true); ok { |
| 234 | p.deleteSpan(chip) |
| 235 | return true, p |
| 236 | } |
| 237 | case tea.KeyLeft: |
| 238 | if chip, ok := p.chipAtBoundary(cur, false); ok { |
| 239 | p.setCursorRuneOffset(chip.start) |
| 240 | return true, p |
| 241 | } |
| 242 | case tea.KeyRight: |
| 243 | if chip, ok := p.chipAtBoundary(cur, true); ok { |
| 244 | p.setCursorRuneOffset(chip.end) |
| 245 | return true, p |
| 246 | } |
| 247 | } |
| 248 | return false, p |
| 249 | } |
| 250 | |
| 251 | // insertChip splices a chip label in at the cursor, recording the new span at |
| 252 | // the right ORDER position so the following reconcile() walks the labels |
no test coverage detected