added ctrl-l keybind for arbitrary species+calltype labels
Dependencies
- [2]
4L2IWSLSmoved TUI-adjacent code from calls_classify.go to dedicated files within the same package - [3]
YVFPP5VJrefactor of tui/ first iteration
Change contents
- edit in tui/view.go at line 39
// Label dialog (when active)if m.labelMode {m.renderLabelDialog(&b)return tea.NewView(b.String())} - edit in tui/view.go at line 121
}// renderLabelDialog renders the label input dialogfunc (m Model) renderLabelDialog(b *strings.Builder) {before := m.labelText[:m.labelCursor]after := m.labelText[m.labelCursor:]inputLine := before + "█" + aftercharCount := fmt.Sprintf("%d/%d", len(m.labelText), maxLabelLength)content := fmt.Sprintf("Label (Species+CallType):\n%s\n%s\n%s", inputLine, charCount, labelHelpText)b.WriteString(commentBoxStyle.Render(content)) - edit in tui/update.go at line 45
}if m.labelMode {return m.handleLabelKey(msg) - edit in tui/update.go at line 122
if msg.String() == "ctrl+l" {m.labelText = m.state.GetCurrentSpeciesCallType()m.labelCursor = len(m.labelText)m.labelMode = truereturn true, m, nil} - edit in tui/update.go at line 353
}// handleLabelKey handles key presses in label modefunc (m Model) handleLabelKey(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) {key := msg.Key()// Enter: save labelif key.Code == tea.KeyEnter {return m.handleLabelEnter()}// Escape: cancelif key.Code == tea.KeyEscape || key.Code == tea.KeyEsc {m.labelMode = falsereturn m, nil}// Navigation and editing keysif handled := m.handleLabelKeyCode(key); handled {return m, nil}// Ctrl combosif handled := m.handleLabelCtrl(msg.String()); handled {return m, nil}// Printable ASCII character (space handled via KeySpace below)s := msg.String()if len(s) == 1 && s[0] >= 33 && s[0] <= 126 {if len(m.labelText) < maxLabelLength {m.labelText = m.labelText[:m.labelCursor] + s + m.labelText[m.labelCursor:]m.labelCursor++}}return m, nil - edit in tui/update.go at line 390
// handleLabelEnter handles Enter key in label mode.func (m Model) handleLabelEnter() (tea.Model, tea.Cmd) {m.labelMode = falseif m.labelText == "" {return m, nil} - edit in tui/update.go at line 398
species, callType := datafile.ParseSpeciesCallType(m.labelText)if species == "" {return m, nil}m.stopPlayer()m.state.ApplyBinding(&calls.BindingResult{Species: species, CallType: callType})if err := m.state.Save(); err != nil {m.err = err.Error()}return m.advanceOrQuit()}// handleLabelKeyCode handles navigation and editing keys in label mode.// Returns true if the key was consumed.func (m *Model) handleLabelKeyCode(key tea.Key) bool {switch key.Code {case tea.KeyLeft:if m.labelCursor > 0 {m.labelCursor--}return truecase tea.KeyRight:if m.labelCursor < len(m.labelText) {m.labelCursor++}return truecase tea.KeySpace:if len(m.labelText) < maxLabelLength {m.labelText = m.labelText[:m.labelCursor] + " " + m.labelText[m.labelCursor:]m.labelCursor++}return truecase tea.KeyBackspace:if m.labelCursor > 0 {m.labelText = m.labelText[:m.labelCursor-1] + m.labelText[m.labelCursor:]m.labelCursor--}return truecase tea.KeyDelete:if m.labelCursor < len(m.labelText) {m.labelText = m.labelText[:m.labelCursor] + m.labelText[m.labelCursor+1:]}return true}return false}// handleLabelCtrl handles ctrl-key combos in label mode.// Returns true if the key was consumed.func (m *Model) handleLabelCtrl(s string) bool {switch s {case "ctrl+u":m.labelText = ""m.labelCursor = 0return truecase "ctrl+a":m.labelCursor = 0return truecase "ctrl+e":m.labelCursor = len(m.labelText)return true}return false} - edit in tui/model.go at line 56
// Label dialog statelabelMode bool // true when label dialog is openlabelText string // current input textlabelCursor int // cursor position in label text - replacement in tui/keymap.go at line 4
const keyHelpText = "[esc]quit [,]prev [.]next [0]confirm [space]comment [ctrl+s]clip [ctrl+d]bookmark [ctrl+,]prev-bk [ctrl+.]next-bk [enter]play [shift+enter]½speed"const keyHelpText = "[esc]quit [,]prev [.]next [0]confirm [space]comment [ctrl+l]label [ctrl+s]clip [ctrl+d]bookmark [ctrl+,]prev-bk [ctrl+.]next-bk [enter]play [shift+enter]½speed" - replacement in tui/keymap.go at line 12
// Comment text limits.// Label dialog help text.const labelHelpText = "[enter]save [esc]cancel [←→]move [ctrl+u]clear [ctrl+a]start [ctrl+e]end"// Input text limits. - edit in tui/keymap.go at line 19
maxLabelLength = 64 - edit in tools/calls/classify_labels.go at line 58
}// GetCurrentSpeciesCallType returns the species+calltype string for the current// segment's first filter label, using the Species+CallType format.// Returns "" if no matching label exists.func (s *ClassifyState) GetCurrentSpeciesCallType() string {seg := s.CurrentSegment()if seg == nil {return ""}filterLabels := seg.GetFilterLabels(s.Config.Filter)if len(filterLabels) == 0 {return ""}l := filterLabels[0]if l.CallType != "" {return l.Species + "+" + l.CallType}return l.Species