22FIUBOFKBIV3WINZUSBKJO526K52HQV3V33B3DRS6CQWHU5HFPAC 63YLBK363Z4ZHO4MG7UAQE4EZ6DQUNVME2PJXBB7CQA2V6Y6YPZAC HHT7M27I3YKGGJOTVTMRVWXATDWUZKIVVLM7IVI7SJRB7FLT2DAQC IOGCFEJZXNXE2YP5F6Q2WXQ2EPBOA64JTQTSIZSCIF67WLF2QA6AC DBOROCRFD6A5SJBMFYFEJI5S5M77X4EFEK6KDQWA5QDMQJKIHRWQC ULWBYMSXYZEE7BJQ2B4HTX2JAABBNJWZTUFIQ56NF5RWXODXRTHQC YHDO5ELECDAMD4Q2LIFQQJA3QVEEMUP7VCUGHIH2UR6P5VKKMDYAC U6JEEU5O477ZOJ5UMRMOJSGPEJEU6Q7KMPKUSDF56CYVUJWL7QBQC EW7VBNMGWFBC73ZUDLB4LIK2HWFKA74ZUTUDG4J575ZQHEFHW4UQC FRY33K6EGWLU3F5NJJ66AT5RBV6OEOWSDKY3JH2CPKKGPAHOMM6AC W3A2EECCD23SVHJZN6MXPH2PAVFHH5CNFD2XHPQRRW6M4GUTG3FAC }return m, nil}return m, nil}// handleGotoKey handles key presses in goto modefunc (m Model) handleGotoKey(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) {key := msg.Key()// Enter: execute gotoif key.Code == tea.KeyEnter {if m.gotoInput == "" {m.gotoMode = falsereturn m, nil}fileNum := 0for _, ch := range m.gotoInput {if ch >= '0' && ch <= '9' {fileNum = fileNum*10 + int(ch-'0')}}if m.state.GotoFile(fileNum) {if m.state.Player != nil {m.state.Player.Stop()}m.gotoMode = falsereturn m, m.segmentChangeCmd()
// Backspace: remove last digitif key.Code == tea.KeyBackspace {if len(m.gotoInput) > 0 {m.gotoInput = m.gotoInput[:len(m.gotoInput)-1]}return m, nil}// Digits: append to inputs := msg.String()if len(s) == 1 && s[0] >= '0' && s[0] <= '9' {// Limit to reasonable number of digits (9 digits = 999,999,999 files)if len(m.gotoInput) < 9 {m.gotoInput += s}return m, nil}
b.WriteString(helpDarkStyle.Render(wrapText("[esc]quit [,]prev [.]next [space]comment [ctrl+d]bookmark [ctrl+,]prev-bk [ctrl+.]next-bk [enter]play [shift+enter]½speed", wrapWidth)))
b.WriteString(helpDarkStyle.Render(wrapText("[esc]quit [,]prev [.]next [space]comment [ctrl+g]goto [ctrl+d]bookmark [ctrl+,]prev-bk [ctrl+.]next-bk [enter]play [shift+enter]½speed", wrapWidth)))
}// TotalFiles returns the total number of data filesfunc (s *ClassifyState) TotalFiles() int {return len(s.DataFiles)}// GotoFile jumps to a specific file number (1-based), returns false if invalidfunc (s *ClassifyState) GotoFile(fileNum int) bool {idx := fileNum - 1if idx < 0 || idx >= len(s.DataFiles) {return false}s.FileIdx = idxs.SegmentIdx = 0return true
## [2026-03-29] Goto file feature for `calls classify` TUIAdded `ctrl+g` keybinding to jump directly to any file by number. The dialog acceptsa file number (1-based) and jumps to the first segment of that file.**Keybinding:** `ctrl+g` → type number → `enter` to jump, `esc` to cancel**Changes:**- `tools/calls_classify.go` — Added `TotalFiles()` and `GotoFile()` methods to `ClassifyState`- `tui/classify.go` — Added `gotoMode` and `gotoInput` state; `ctrl+g` keybinding;`handleGotoKey()` for digit/backspace/enter/esc handling; `renderGotoDialog()` for UI display