Conversation
* feat: copy resource ID/ARN to clipboard (y/Y keys) (#59) - Add clipboard package with OSC52 + tmux/screen passthrough - y: copy resource ID, Y: copy ARN - Works in list view and detail view - Flash message shows copy confirmation * fix: add missing docs and feedback for clipboard feature - Add y/Y keybindings to help_view.go and README.md - Add NoARNMsg for user feedback when ARN unavailable - Add inline comment for CopiedMsg.Value field * refactor: consolidate UnwrapResource calls in clipboard handler * fix: add cursor bounds check and unify handler pattern - Add cursor >= 0 check to prevent potential panic on negative cursor - Unify all handlers to Pattern A (positive check) - Affected: handleMark, handleEnter, handleAction, handleCopyID, handleCopyARN * refactor: unify y/Y switch cases in detail_view * test: improve clipboard test coverage and add OSC52 debug logging - Add debug logging for OSC52 write failures - Verify command execution returns correct CopiedMsg - Test Label and Value fields in all copy functions * docs: add godoc comments and extract flash duration constant - Add package and function documentation to clipboard package - Add debug logging for native clipboard write failures - Extract flashDuration constant (2s) in app.go * test: add view handler tests for clipboard y/Y keys - Add TestResourceBrowserCopyID/ARN/ARNNoARN/EmptyList - Add TestDetailViewCopyID/ARN/ARNNoARN - Add arn field to mockResource for testing
This comment was marked as resolved.
This comment was marked as resolved.
Code Review - PR #94: Clipboard Copy Feature (y/Y keys)✅ Overall AssessmentThis is a high-quality PR that implements clipboard functionality with excellent attention to detail. The implementation is clean, well-tested, and follows good software engineering practices. 🎯 Strengths
🔍 Observations & Suggestions1. Test Coverage Enhancement (Minor)The tests verify that commands are returned but don't verify the actual message content in some cases: internal/view/resource_browser_test.go:629-632 msg := cmd()
if msg == nil {
t.Fatal("Expected message from clipboard command")
}Suggestion: Verify the actual message type and content: msg := cmd()
copiedMsg, ok := msg.(clipboard.CopiedMsg)
if !ok {
t.Fatalf("expected CopiedMsg, got %T", msg)
}
if copiedMsg.Label != "ID" {
t.Errorf("expected Label 'ID', got %q", copiedMsg.Label)
}
if copiedMsg.Value != "i-1234567890abcdef0" {
t.Errorf("expected Value 'i-1234567890abcdef0', got %q", copiedMsg.Value)
}This same pattern applies to:
2. OSC52 Edge Case (Very Minor)internal/clipboard/clipboard.go:52 if _, err := os.Stdout.WriteString(seq); err != nil {
log.Debug("OSC52 clipboard write failed", "error", err)
}This is fine, but in very rare cases where stdout is closed/redirected, this could fail silently. Current approach is good (debug logging), but you might consider:
Current behavior is acceptable - the dual-write approach means if OSC52 fails, native clipboard likely succeeds and vice versa. 3. Empty String Edge Case (Theoretical)internal/view/resource_browser_input.go:289-290 resource := dao.UnwrapResource(r.filtered[cursor])
return r, clipboard.CopyID(resource.GetID())If if id := resource.GetID(); id != "" {
return r, clipboard.CopyID(id)
}
return r, nil // or show error messageThis is probably unnecessary given AWS resource constraints, but worth considering if other resource types are added. 4. Message Field Usageinternal/clipboard/clipboard.go:20 Value string // The copied value (retained for future use: logging, undo)The
Current approach is fine - it's low cost and enables future features. 🔒 Security Review✅ No security concerns identified
⚡ Performance Review✅ No performance concerns
📦 Dependencies✅ Dependency management is correct The 🎨 Code Style✅ Consistent with codebase patterns
📝 Minor Nitpicks (Optional)
✨ Recommendations
🏆 SummaryApprove with minor suggestions for future improvement. This PR demonstrates:
Great work on this feature! 🎉 Review Score: 9/10
|
Summary
ykey to copy resource ID to clipboardYkey to copy resource ARN to clipboardChanges
internal/clipboardpackageCloses #59