Fix file-level annotation input overflow and Enter-to-edit#27
Fix file-level annotation input overflow and Enter-to-edit#27
Conversation
Add prefixWidth parameter to newAnnotationInput so file-level annotations use the correct width subtraction (12) matching the wider "💬 file: " prefix, instead of the line-level value (6) which caused terminal overflow. Related to #26
In handleEnterKey, check cursorOnFileAnnotationLine() before falling through to startAnnotation(). When on a file annotation line (diffCursor == -1), dispatch to startFileAnnotation() instead. Related to #26
There was a problem hiding this comment.
Pull request overview
Fixes inconsistencies between file-level (A) and line-level (a) annotations by correcting the annotation input width calculation and enabling Enter-to-edit on the file-annotation header line.
Changes:
- Parameterized annotation input width calculation to account for different rendered prefixes (line vs file).
- Updated Enter-key handling to start file-level annotation editing when the cursor is on the file-annotation line.
- Added regression tests covering width differences and Enter-to-edit behavior for file annotations.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| ui/model.go | Routes Enter on the file-annotation header line to startFileAnnotation() so Enter edits file annotations. |
| ui/annotate.go | Updates newAnnotationInput to accept a caller-provided prefix width and applies distinct offsets for line vs file annotations. |
| ui/model_test.go | Adds tests for file-vs-line input widths and Enter-to-edit behavior on file annotation lines. |
| docs/plans/completed/20260405-fix-file-annotation-bugs.md | Documents the investigation and implemented fix steps for the two bugs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ui/model.go
Outdated
| if m.cursorOnFileAnnotationLine() { | ||
| cmd := m.startFileAnnotation() | ||
| m.viewport.SetContent(m.renderDiff()) | ||
| return m, cmd | ||
| } | ||
| cmd := m.startAnnotation() |
There was a problem hiding this comment.
handleEnterKey now duplicates the same SetContent(renderDiff()) + return in both branches. Consider selecting the command (startFileAnnotation vs startAnnotation) first and then calling SetContent once to keep this handler easier to maintain.
| if m.cursorOnFileAnnotationLine() { | |
| cmd := m.startFileAnnotation() | |
| m.viewport.SetContent(m.renderDiff()) | |
| return m, cmd | |
| } | |
| cmd := m.startAnnotation() | |
| var cmd tea.Cmd | |
| if m.cursorOnFileAnnotationLine() { | |
| cmd = m.startFileAnnotation() | |
| } else { | |
| cmd = m.startAnnotation() | |
| } |
|
|
||
| **Files:** | ||
| - Modify: `ui/annotate.go` | ||
| - Modify: `ui/diffview.go` |
There was a problem hiding this comment.
This completed plan claims ui/diffview.go was modified in Task 1’s file list, but this PR doesn’t actually change that file. Consider updating the file list (or adjusting the text) so the plan accurately reflects what was changed.
| - Modify: `ui/diffview.go` |
| // newAnnotationInput creates and focuses a text input for annotation editing. | ||
| func (m *Model) newAnnotationInput(placeholder string) (textinput.Model, tea.Cmd) { | ||
| // prefixWidth accounts for the visible prefix characters (cursor col + emoji + label + margin). | ||
| func (m *Model) newAnnotationInput(placeholder string, prefixWidth int) (textinput.Model, tea.Cmd) { | ||
| ti := textinput.New() | ||
| ti.Placeholder = placeholder | ||
| cmd := ti.Focus() | ||
| ti.CharLimit = 500 | ||
| ti.Width = max(10, m.diffContentWidth()-6) // cursor col + emoji prefix "💬 " + border margin | ||
| ti.Width = max(10, m.diffContentWidth()-prefixWidth) |
There was a problem hiding this comment.
prefixWidth values are still hard-coded (6, 12), which can drift from the actual rendered prefixes if the label/emoji changes again. Consider computing it from the exact prefix strings via lipgloss.Width(...) (optionally plus a named padding constant) and clarifying the comment since diffContentWidth() already excludes the cursor bar.
Fixes #26
Two bugs where file-level annotations (
Akey) behaved differently from line-level annotations:1. Input width overflow -
newAnnotationInputsubtracted a fixed 6 chars for the prefix, but file-level annotations render a wider"💬 file: "prefix. ChangednewAnnotationInputto accept aprefixWidthparameter so each caller passes the correct offset.2. Enter key didn't edit file annotations -
handleEnterKeyalways calledstartAnnotation()which returned nil whendiffCursor == -1(file annotation line). Added acursorOnFileAnnotationLine()check to dispatch tostartFileAnnotation()instead.