-
-
Notifications
You must be signed in to change notification settings - Fork 414
feat: Remove channel for notification models #979
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThis change refactors modal and notification handling by removing legacy channel-based and warnModal systems in favor of a new Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Model
participant NotifyModal
participant BubbleTea
User->>Model: Presses key (e.g., delete, paste, quit)
Model->>Model: Validates operation (e.g., paste validation)
alt Validation fails
Model->>BubbleTea: Returns tea.Cmd to open NotifyModal with warning
BubbleTea->>NotifyModal: Opens modal with title/content/action
User->>NotifyModal: Confirms or cancels via keypress
NotifyModal->>Model: Triggers confirm/cancel action via tea.Cmd
else Validation passes
Model->>Model: Proceeds with operation
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes Possibly related PRs
Suggested labels
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (15)
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
9af59c5 to
0833aff
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Health Improved
(3 files improve in Code Health)
Gates Failed
Prevent hotspot decline
(3 hotspots with String Heavy Function Arguments, Bumpy Road Ahead, Complex Method)
Enforce critical code health rules
(1 file with Bumpy Road Ahead)
Gates Passed
1 Quality Gates Passed
See analysis details in CodeScene
Reason for failure
| Prevent hotspot decline | Violations | Code Health Impact | |
|---|---|---|---|
| main.go | 1 rule in this hotspot | 9.43 → 9.22 | Suppress |
| key_function.go | 1 rule in this hotspot | 8.29 → 8.20 | Suppress |
| handle_file_operations.go | 2 rules in this hotspot | 7.89 → 8.28 | Suppress |
| Enforce critical code health rules | Violations | Code Health Impact | |
|---|---|---|---|
| handle_file_operations.go | 1 critical rule | 7.89 → 8.28 | Suppress |
View Improvements
| File | Code Health Impact | Categories Improved |
|---|---|---|
| main.go | 9.43 → 9.22 | Large Method |
| handle_file_operation_test.go | 8.31 → 8.32 | Large Method |
| handle_file_operations.go | 7.89 → 8.28 | Complex Method, Complex Conditional, Bumpy Road Ahead, Overall Code Complexity |
| model.go | 8.02 → 8.20 | Complex Method |
| key_function.go | 8.29 → 8.20 | Bumpy Road Ahead |
Quality Gate Profile: The Bare Minimum
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.
| "time" | ||
|
|
||
| variable "github.com/yorukot/superfile/src/config" | ||
| "github.com/yorukot/superfile/src/internal/ui/notify" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| "time" | ||
|
|
||
| variable "github.com/yorukot/superfile/src/config" | ||
| "github.com/yorukot/superfile/src/internal/ui/notify" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Health Improved
(2 files improve in Code Health)
Gates Failed
Prevent hotspot decline
(2 hotspots with Bumpy Road Ahead, String Heavy Function Arguments, Complex Method)
Enforce critical code health rules
(1 file with Bumpy Road Ahead)
Gates Passed
1 Quality Gates Passed
See analysis details in CodeScene
Reason for failure
| Prevent hotspot decline | Violations | Code Health Impact | |
|---|---|---|---|
| key_function.go | 1 rule in this hotspot | 8.29 → 8.20 | Suppress |
| handle_file_operations.go | 2 rules in this hotspot | 7.88 → 8.28 | Suppress |
| Enforce critical code health rules | Violations | Code Health Impact | |
|---|---|---|---|
| handle_file_operations.go | 1 critical rule | 7.88 → 8.28 | Suppress |
View Improvements
| File | Code Health Impact | Categories Improved |
|---|---|---|
| handle_file_operations.go | 7.88 → 8.28 | Complex Method, Complex Conditional, Bumpy Road Ahead, Overall Code Complexity |
| key_function.go | 8.29 → 8.20 | Bumpy Road Ahead |
| model.go | 8.02 → 8.20 | Complex Method |
Quality Gate Profile: The Bare Minimum
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.
0833aff to
bb07cfc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Health Improved
(2 files improve in Code Health)
Gates Failed
Prevent hotspot decline
(3 hotspots with String Heavy Function Arguments, Code Duplication, Primitive Obsession)
Gates Passed
2 Quality Gates Passed
See analysis details in CodeScene
Reason for failure
| Prevent hotspot decline | Violations | Code Health Impact | |
|---|---|---|---|
| key_function.go | 1 rule in this hotspot | 8.29 → 7.86 | Suppress |
| function.go | 1 rule in this hotspot | 7.77 → 7.53 | Suppress |
| handle_file_operations.go | 1 rule in this hotspot | 7.88 → 8.35 | Suppress |
View Improvements
| File | Code Health Impact | Categories Improved |
|---|---|---|
| handle_file_operations.go | 7.88 → 8.35 | Complex Method, Complex Conditional, Bumpy Road Ahead, Overall Code Complexity |
| key_function.go | 8.29 → 7.86 | Bumpy Road Ahead, Overall Code Complexity |
| model.go | 8.02 → 8.20 | Complex Method |
| function.go | 7.77 → 7.53 | Overall Code Complexity, String Heavy Function Arguments |
Quality Gate Profile: The Bare Minimum
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.
src/internal/key_function.go
Outdated
| func (m *model) handleNotifyModelCancel() tea.Cmd { | ||
| m.notifyModel.Close() | ||
| switch m.notifyModel.GetConfirmAction() { | ||
| case notify.RenameAction: | ||
| m.cancelRename() | ||
| case notify.QuitAction: | ||
| m.modelQuitState = notQuitting | ||
| case notify.DeleteAction, notify.NoAction: | ||
| // Do nothing | ||
| default: | ||
| slog.Error("Unknown type of action", "action", m.notifyModel.GetConfirmAction()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are similar. But there is no clean way to refactor this.
The functionality these two method's offer is very different.
| } | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❌ New issue: Primitive Obsession
In this module, 84.2% of all function arguments are primitive types, threshold = 40.0%
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/internal/key_function.go (1)
208-221: Helper methods provide clear separation of concerns.While codescene flagged code duplication, the
handleNotifyModelCancelandhandleNotifyModelConfirmmethods have distinct logic for different action types. The structure similarity is acceptable given their different responsibilities.Also applies to: 223-236
🧹 Nitpick comments (2)
src/internal/ui/notify/model.go (1)
39-39: Track the code duplication issue.The TODO comment correctly identifies code duplication with
typingModalRender. Based on the learnings about tracking technical debt, this should be addressed in a separate PR to maintain focus on the current refactoring.Consider creating a GitHub issue to track this technical debt for future refactoring, following the pattern mentioned in the learnings.
src/internal/handle_file_operations.go (1)
217-226: Excellent separation of validation and execution.The new
validatePasteOperationfunction centralizes all paste validation logic, making the code more maintainable and testable. The error messages are descriptive and help users understand why operations fail.Also applies to: 227-247
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
src/internal/common/predefined_variable.go(2 hunks)src/internal/function.go(1 hunks)src/internal/handle_file_operations.go(5 hunks)src/internal/handle_modal.go(0 hunks)src/internal/key_function.go(8 hunks)src/internal/model.go(6 hunks)src/internal/model_msg.go(2 hunks)src/internal/model_render.go(0 hunks)src/internal/model_test.go(2 hunks)src/internal/type.go(3 hunks)src/internal/ui/notify/model.go(1 hunks)src/internal/ui/notify/type.go(1 hunks)
💤 Files with no reviewable changes (2)
- src/internal/handle_modal.go
- src/internal/model_render.go
🧰 Additional context used
🧠 Learnings (25)
📓 Common learnings
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/default_config.go:16-16
Timestamp: 2025-07-27T15:35:25.617Z
Learning: In yorukot/superfile, deleteItemWarn() only displays a warning modal via the channelMessage system and does not perform actual file deletion. The actual deletion happens when the user confirms the modal, which triggers getDeleteCmd() that returns a tea.Cmd. The architecture intentionally separates UI modal operations (using channelMessage/goroutines) from file I/O operations (using tea.Cmd pattern), creating clean separation of concerns between UI state management and file operations.
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/default_config.go:16-16
Timestamp: 2025-07-27T15:35:25.617Z
Learning: deleteItemWarn() in yorukot/superfile only displays a warning modal via channel messaging and does not perform actual file deletion. The actual deletion happens through getDeleteCmd() which returns a tea.Cmd. The architectural pattern separates UI modal operations (using channels/goroutines) from file I/O operations (using tea.Cmd), which is intentional and appropriate.
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/default_config.go:16-16
Timestamp: 2025-07-27T15:35:25.617Z
Learning: In yorukot/superfile, deleteItemWarn() only displays a warning modal via the channelMessage system and does not perform actual file deletion. The actual deletion happens when the user confirms the modal, which triggers getDeleteCmd() that returns a tea.Cmd. The architecture intentionally separates UI modal operations (using channelMessage/goroutines) from file I/O operations (using tea.Cmd pattern), creating clean separation of concerns between UI state management and file operations.
Learnt from: lazysegtree
PR: yorukot/superfile#0
File: :0-0
Timestamp: 2025-04-12T12:25:06.352Z
Learning: PR #770 "Sidebar code separation" is a refactoring and code reorganization effort with no new features. It involves moving code, updating import paths, renaming functions to follow PascalCase convention, and consolidating sidebar-related functionality into a dedicated package.
Learnt from: lazysegtree
PR: yorukot/superfile#969
File: src/internal/key_function.go:40-40
Timestamp: 2025-08-03T09:34:55.721Z
Learning: In yorukot/superfile, lazysegtree prefers that individual components like modals should implement interfaces directly and handle their own cancel/confirm logic, rather than using external handler objects. This follows the existing pattern where components like sidebarModel are self-contained and don't depend on the main model object.
Learnt from: lazysegtree
PR: yorukot/superfile#965
File: src/internal/config_function.go:8-8
Timestamp: 2025-07-29T03:42:36.581Z
Learning: When reviewing large refactoring PRs that introduce new async patterns (like moving from global channels to dedicated processbar channels), always check for incomplete refactoring where critical functionality like navigation depends on data structures that are no longer being populated, as this often leads to completely broken features.
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/default_config.go:16-16
Timestamp: 2025-07-27T07:40:51.938Z
Learning: lazysegtree prefers simpler implementation approaches when the alternatives are significantly more complex, even if the alternatives might be architecturally cleaner, prioritizing maintainability and avoiding over-engineering.
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/default_config.go:16-16
Timestamp: 2025-07-27T07:40:51.938Z
Learning: lazysegtree prefers simpler implementation approaches when the alternatives are significantly more complex, even if the alternatives might be architecturally cleaner, prioritizing maintainability and avoiding over-engineering.
Learnt from: lazysegtree
PR: yorukot/superfile#969
File: src/internal/key_function.go:40-40
Timestamp: 2025-08-03T09:34:55.721Z
Learning: lazysegtree emphasizes proper dependency direction in software architecture, preferring that low-level components (like modal handlers) should not depend on high-level components (like the main model object). He also prioritizes performance considerations, noting that creating objects on every keypress in hot code paths like key handling is inefficient and should be avoided.
Learnt from: lazysegtree
PR: yorukot/superfile#973
File: src/internal/ui/processbar/model_update.go:7-27
Timestamp: 2025-08-03T14:49:31.221Z
Learning: lazysegtree prefers to keep test-only code simple without adding production-level concerns like goroutine synchronization, cancellation contexts, or complex lifecycle management, even when such patterns might prevent potential issues, since the complexity isn't justified for test utilities.
Learnt from: lazysegtree
PR: yorukot/superfile#950
File: src/internal/ui/metadata/README.md:7-7
Timestamp: 2025-07-24T03:46:29.516Z
Learning: lazysegtree prefers to defer comprehensive unit testing to separate PRs when the current PR has grown too large, maintaining focus on the primary refactoring objectives while tracking testing requirements in dedicated GitHub issues.
Learnt from: lazysegtree
PR: yorukot/superfile#967
File: src/internal/key_function.go:45-47
Timestamp: 2025-08-02T11:47:07.713Z
Learning: lazysegtree prefers to track technical debt and architectural improvements in dedicated GitHub issues when they are identified during PR reviews but are beyond the scope of the current PR, particularly for complex refactoring needs like input handling architecture that would require significant changes.
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/handle_file_operations.go:567-570
Timestamp: 2025-07-27T08:49:09.687Z
Learning: lazysegtree prefers to defer technical debt issues like model mutation concerns to later PRs when the current PR has already grown too large, maintaining focus on the primary objectives while acknowledging the need to track such issues for future work.
Learnt from: lazysegtree
PR: yorukot/superfile#970
File: src/internal/ui/processbar/model.go:11-26
Timestamp: 2025-08-02T17:00:37.262Z
Learning: lazysegtree prefers to track memory leak issues and feature enhancements via dedicated GitHub issues when identified during PR reviews but are beyond the current PR scope, particularly for processbar-related improvements like cleanup mechanisms and keyboard shortcuts.
Learnt from: lazysegtree
PR: yorukot/superfile#906
File: src/internal/file_panel.go:11-14
Timestamp: 2025-07-12T05:32:53.131Z
Learning: lazysegtree is concerned about the efficiency impact of adding bounds checking to frequently called methods like getSelectedItem() in file panels, preferring to defer such changes to consider performance implications.
Learnt from: lazysegtree
PR: yorukot/superfile#935
File: website/src/content/docs/changelog.md:17-26
Timestamp: 2025-07-15T10:32:28.063Z
Learning: In the superfile changelog (website/src/content/docs/changelog.md), lazysegtree prefers to maintain the existing heading format with main version headings using # and sub-sections using #### (Update, Bug fix, Optimization, etc.) consistently throughout all releases, prioritizing established format consistency over strict markdown heading hierarchy compliance.
📚 Learning: the `addorupdateprocess` method in the processbar.model type (src/internal/ui/processbar/model.go) h...
Learnt from: lazysegtree
PR: yorukot/superfile#970
File: src/internal/ui/processbar/model_test.go:67-67
Timestamp: 2025-08-02T16:56:18.390Z
Learning: The `AddOrUpdateProcess` method in the processbar.Model type (src/internal/ui/processbar/model.go) has a void return type and doesn't return any values, so there's no return value to check in tests or other code.
Applied to files:
src/internal/model_test.gosrc/internal/type.go
📚 Learning: in yorukot/superfile, deleteitemwarn() only displays a warning modal via the channelmessage system a...
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/default_config.go:16-16
Timestamp: 2025-07-27T15:35:25.617Z
Learning: In yorukot/superfile, deleteItemWarn() only displays a warning modal via the channelMessage system and does not perform actual file deletion. The actual deletion happens when the user confirms the modal, which triggers getDeleteCmd() that returns a tea.Cmd. The architecture intentionally separates UI modal operations (using channelMessage/goroutines) from file I/O operations (using tea.Cmd pattern), creating clean separation of concerns between UI state management and file operations.
Applied to files:
src/internal/model_test.gosrc/internal/ui/notify/model.gosrc/internal/type.gosrc/internal/model.gosrc/internal/model_msg.gosrc/internal/key_function.gosrc/internal/handle_file_operations.go
📚 Learning: lazysegtree prefers to keep test-only code simple without adding production-level concerns like goro...
Learnt from: lazysegtree
PR: yorukot/superfile#973
File: src/internal/ui/processbar/model_update.go:7-27
Timestamp: 2025-08-03T14:49:31.221Z
Learning: lazysegtree prefers to keep test-only code simple without adding production-level concerns like goroutine synchronization, cancellation contexts, or complex lifecycle management, even when such patterns might prevent potential issues, since the complexity isn't justified for test utilities.
Applied to files:
src/internal/model_test.go
📚 Learning: when reviewing large refactoring prs that change async patterns (like moving from goroutines to tea....
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/default_config.go:16-16
Timestamp: 2025-07-27T15:32:06.922Z
Learning: When reviewing large refactoring PRs that change async patterns (like moving from goroutines to tea.Cmd), always check for incomplete refactoring where some call sites still use the old pattern while others use the new pattern, as this often leads to compilation errors and architectural inconsistencies.
Applied to files:
src/internal/function.gosrc/internal/model.gosrc/internal/key_function.gosrc/internal/handle_file_operations.go
📚 Learning: when race conditions or other issues that are unrelated to the current pr's focus are identified dur...
Learnt from: lazysegtree
PR: yorukot/superfile#781
File: src/internal/model_render.go:254-256
Timestamp: 2025-04-28T04:27:33.074Z
Learning: When race conditions or other issues that are unrelated to the current PR's focus are identified during review, lazysegtree prefers creating separate GitHub issues to track them rather than addressing them in the current PR. This helps maintain PR focus and scope.
Applied to files:
src/internal/function.go
📚 Learning: when reviewing large refactoring prs that introduce new async patterns (like moving from global chan...
Learnt from: lazysegtree
PR: yorukot/superfile#965
File: src/internal/config_function.go:8-8
Timestamp: 2025-07-29T03:42:36.581Z
Learning: When reviewing large refactoring PRs that introduce new async patterns (like moving from global channels to dedicated processbar channels), always check for incomplete refactoring where critical functionality like navigation depends on data structures that are no longer being populated, as this often leads to completely broken features.
Applied to files:
src/internal/function.go
📚 Learning: before suggesting the creation of new constants for string literals, always check if a constant alre...
Learnt from: yorukot
PR: yorukot/superfile#841
File: src/internal/model_render.go:334-334
Timestamp: 2025-06-04T09:58:25.572Z
Learning: Before suggesting the creation of new constants for string literals, always check if a constant already exists in the codebase, especially in common packages like `src/internal/common/predefined_variable.go`.
Applied to files:
src/internal/common/predefined_variable.gosrc/internal/handle_file_operations.go
📚 Learning: in go packages, constants and variables should only be exported (capitalized) if they need to be acc...
Learnt from: lazysegtree
PR: yorukot/superfile#770
File: src/internal/ui/sidebar/consts.go:16-16
Timestamp: 2025-04-12T14:02:46.575Z
Learning: In Go packages, constants and variables should only be exported (capitalized) if they need to be accessed from outside their package. In the sidebar package, constants like `sideBarInitialHeight` should remain unexported as they're only used within the package.
Applied to files:
src/internal/common/predefined_variable.go
📚 Learning: in yorukot/superfile, lazysegtree prefers that individual components like modals should implement in...
Learnt from: lazysegtree
PR: yorukot/superfile#969
File: src/internal/key_function.go:40-40
Timestamp: 2025-08-03T09:34:55.721Z
Learning: In yorukot/superfile, lazysegtree prefers that individual components like modals should implement interfaces directly and handle their own cancel/confirm logic, rather than using external handler objects. This follows the existing pattern where components like sidebarModel are self-contained and don't depend on the main model object.
Applied to files:
src/internal/ui/notify/model.gosrc/internal/model.gosrc/internal/key_function.gosrc/internal/handle_file_operations.go
📚 Learning: deleteitemwarn() in yorukot/superfile only displays a warning modal via channel messaging and does n...
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/default_config.go:16-16
Timestamp: 2025-07-27T15:35:25.617Z
Learning: deleteItemWarn() in yorukot/superfile only displays a warning modal via channel messaging and does not perform actual file deletion. The actual deletion happens through getDeleteCmd() which returns a tea.Cmd. The architectural pattern separates UI modal operations (using channels/goroutines) from file I/O operations (using tea.Cmd), which is intentional and appropriate.
Applied to files:
src/internal/ui/notify/model.gosrc/internal/type.gosrc/internal/model.gosrc/internal/key_function.gosrc/internal/handle_file_operations.go
📚 Learning: in the sidebar component of yorukot/superfile, the partial list rendering in render.go is intentiona...
Learnt from: lazysegtree
PR: yorukot/superfile#770
File: src/internal/ui/sidebar/render.go:0-0
Timestamp: 2025-04-12T13:51:24.691Z
Learning: In the sidebar component of yorukot/superfile, the partial list rendering in render.go is intentional. The sidebar implements scrolling functionality where ListUp/ListDown methods in navigation.go update cursor position and renderIndex to show the appropriate portion of the directory list based on available space.
Applied to files:
src/internal/type.gosrc/internal/model_msg.gosrc/internal/key_function.gosrc/internal/handle_file_operations.go
📚 Learning: the project standardized on using one ansi package import (github.com/charmbracelet/x/exp/term/ansi)...
Learnt from: lazysegtree
PR: yorukot/superfile#825
File: src/internal/model_render.go:0-0
Timestamp: 2025-05-22T04:50:02.071Z
Learning: The project standardized on using one ANSI package import (github.com/charmbracelet/x/exp/term/ansi) to avoid binary bloat and potential incompatibilities.
Applied to files:
src/internal/type.gosrc/internal/model_msg.gosrc/internal/key_function.gosrc/internal/handle_file_operations.go
📚 Learning: in the processbar package (src/internal/ui/processbar/model.go), the progress.width field is modifie...
Learnt from: lazysegtree
PR: yorukot/superfile#973
File: src/internal/ui/processbar/model.go:118-120
Timestamp: 2025-08-03T15:07:56.341Z
Learning: In the processbar package (src/internal/ui/processbar/model.go), the Progress.Width field is modified temporarily during rendering on a copy of the process data, and this modification is intentionally not persisted to the stored process data since it's only needed for display purposes during the render call.
Applied to files:
src/internal/type.go
📚 Learning: in the superfile codebase, hotkey configuration validation happens in the loadhotkeysfile() function...
Learnt from: lazysegtree
PR: yorukot/superfile#752
File: src/internal/ui/prompt/model.go:14-17
Timestamp: 2025-04-04T04:02:58.343Z
Learning: In the superfile codebase, hotkey configuration validation happens in the LoadHotkeysFile() function, which ensures that all hotkey slices are non-empty and contain valid values. If validation fails, the application exits early with an error message, eliminating the need for runtime checks when accessing slice elements.
Applied to files:
src/internal/model.gosrc/internal/key_function.go
📚 Learning: the project standardized on using one ansi package import (either github.com/charmbracelet/x/ansi or...
Learnt from: lazysegtree
PR: yorukot/superfile#825
File: src/internal/model_render.go:0-0
Timestamp: 2025-05-22T04:50:02.071Z
Learning: The project standardized on using one ANSI package import (either github.com/charmbracelet/x/ansi or github.com/charmbracelet/x/exp/term/ansi) to avoid binary bloat and potential incompatibilities.
Applied to files:
src/internal/model_msg.gosrc/internal/handle_file_operations.go
📚 Learning: pattern to watch for: defer file.close() inside loops (for, range, filepath.walk callbacks) causes r...
Learnt from: lazysegtree
PR: yorukot/superfile#821
File: src/internal/file_operations_compress.go:0-0
Timestamp: 2025-06-05T12:42:45.139Z
Learning: Pattern to watch for: defer file.Close() inside loops (for, range, filepath.Walk callbacks) causes resource leaks by accumulating file descriptors until function exits. Should be replaced with explicit Close() calls immediately after file operations with proper error handling.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in pr #767 for yorukot/superfile, the focus is on moving code (especially sidebar-related functional...
Learnt from: lazysegtree
PR: yorukot/superfile#0
File: :0-0
Timestamp: 2025-04-12T12:00:32.688Z
Learning: In PR #767 for yorukot/superfile, the focus is on moving code (especially sidebar-related functionality) to a more organized structure without changing functionality. Pre-existing issues should be ignored since the purpose is code reorganization, not fixing existing problems.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in the superfile codebase, yorukot prefers to maintain consistent code structure patterns (like usin...
Learnt from: yorukot
PR: yorukot/superfile#887
File: src/internal/key_function.go:258-263
Timestamp: 2025-06-16T14:14:39.966Z
Learning: In the superfile codebase, yorukot prefers to maintain consistent code structure patterns (like using switch statements in key handling functions) even when it triggers linter warnings, prioritizing code consistency and future extensibility over linter compliance.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: the superfile application includes shell capabilities where users directly input commands to be exec...
Learnt from: lazysegtree
PR: yorukot/superfile#752
File: src/internal/ui/prompt/tokenize.go:66-80
Timestamp: 2025-04-03T16:09:55.483Z
Learning: The superfile application includes shell capabilities where users directly input commands to be executed on their own systems. As with standard shells, the responsibility for command safety lies with the user, not the application.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in the superfile bash installer (website/public/install.sh), lazysegtree maintains the same principl...
Learnt from: lazysegtree
PR: yorukot/superfile#953
File: website/public/install.sh:42-42
Timestamp: 2025-07-21T08:49:44.628Z
Learning: In the superfile bash installer (website/public/install.sh), lazysegtree maintains the same principle as the PowerShell installer - users should supply correct environment variable values (SPF_INSTALL_VERSION without leading 'v') rather than adding validation code to handle malformed input, following the philosophy that users should provide properly formatted values.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in the ui renderer functions of superfile, errors are deliberately handled at the renderer creation ...
Learnt from: lazysegtree
PR: yorukot/superfile#781
File: src/internal/ui/spf_renderers.go:25-31
Timestamp: 2025-04-28T04:03:54.192Z
Learning: In the UI renderer functions of Superfile, errors are deliberately handled at the renderer creation level (logging and fallback to empty renderer) rather than propagating them up the call stack. This is an intentional architectural decision to limit error propagation in the UI layer.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in the superfile changelog (website/src/content/docs/changelog.md), lazysegtree prefers to maintain ...
Learnt from: lazysegtree
PR: yorukot/superfile#935
File: website/src/content/docs/changelog.md:17-26
Timestamp: 2025-07-15T10:32:28.063Z
Learning: In the superfile changelog (website/src/content/docs/changelog.md), lazysegtree prefers to maintain the existing heading format with main version headings using # and sub-sections using #### (Update, Bug fix, Optimization, etc.) consistently throughout all releases, prioritizing established format consistency over strict markdown heading hierarchy compliance.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in superfile, during the initial config loading phase (loadtomlfile calls), slog redirection to log ...
Learnt from: lazysegtree
PR: yorukot/superfile#881
File: src/internal/utils/file_utils.go:104-104
Timestamp: 2025-06-24T03:11:07.797Z
Learning: In superfile, during the initial config loading phase (LoadTomlFile calls), slog redirection to log files hasn't been set up yet, so slog.Error messages still go to stdout/stderr and should include errorPrefix for proper terminal styling.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in the superfile codebase, structs that need to be serialized to/from json have exported fields (cap...
Learnt from: lazysegtree
PR: yorukot/superfile#770
File: src/internal/ui/sidebar/consts.go:5-8
Timestamp: 2025-04-12T14:00:54.846Z
Learning: In the superfile codebase, structs that need to be serialized to/from JSON have exported fields (capitalized names like `Name` and `Location`) even when the variables of those structs are unexported. This is because Go's JSON marshaling/unmarshaling can only access exported struct fields.
Applied to files:
src/internal/handle_file_operations.go
🧬 Code Graph Analysis (3)
src/internal/ui/notify/model.go (4)
src/internal/ui/notify/type.go (2)
ConfirmActionType(3-3)NoAction(9-9)src/internal/common/predefined_variable.go (6)
ModalOkayInputText(46-46)ModalConfirmInputText(44-44)ModalInputSpacingText(47-47)ModalCancelInputText(45-45)ModalHeight(22-22)ModalWidth(21-21)src/internal/common/style_function.go (1)
ModalBorderStyle(123-125)src/internal/model_render.go (1)
warnModalRender(311-318)
src/internal/model.go (3)
src/internal/ui/notify/model.go (1)
New(14-21)src/internal/ui/notify/type.go (1)
QuitAction(8-8)src/internal/ui/processbar/model_update.go (1)
ListenForChannelUpdates(8-27)
src/internal/model_msg.go (1)
src/internal/ui/notify/model.go (1)
Model(7-12)
🔇 Additional comments (19)
src/internal/function.go (1)
365-370: LGTM!This helper function provides a clean abstraction for operation naming and supports the refactored notification system mentioned in the PR objectives.
src/internal/model_test.go (1)
122-122: LGTM!The test assertions correctly reflect the updated quit confirmation state machine, changing from
confirmToQuittoquitConfirmationInitiatedas part of the architectural refactoring to the new notification modal system.Also applies to: 133-133
src/internal/ui/notify/type.go (1)
3-10: LGTM!Well-designed enumeration type that provides a clean foundation for the new notification modal system. The constants are appropriately named and the use of
iotafollows Go best practices.src/internal/common/predefined_variable.go (2)
44-48: LGTM!Well-organized addition of modal styling variables that follow the existing naming pattern and support the new notification modal system.
91-95: LGTM!Proper initialization of the modal styling variables using existing lipgloss styles and hotkey configuration. The styling approach is consistent with the existing codebase patterns.
src/internal/model_msg.go (1)
8-8: LGTM!Proper addition of the notify package import to support the new notification modal architecture.
src/internal/type.go (2)
7-7: LGTM! Clean architectural improvement.The migration from local modal types to the external
notify.Modelpackage improves modularity and follows proper separation of concerns. The field rename fromnotifyModaltonotifyModelalso improves naming consistency.Also applies to: 78-78
59-60: Good improvement to quit state naming.The renamed constants
quitConfirmationInitiatedandquitConfirmationReceivedare more descriptive than the previousconfirmToQuit, making the state machine flow clearer.src/internal/ui/notify/model.go (2)
1-22: Well-structured notification modal implementation.The
Modelstruct and constructor follow good encapsulation practices. The separation of concerns aligns with the learnings about individual components handling their own logic.
40-49: Render method correctly handles different action types.The conditional rendering based on
confirmActiontype appropriately shows different input key instructions, maintaining consistent UI behavior.src/internal/key_function.go (3)
121-121: Excellent refactoring to command-based architecture.All key handling functions now consistently return
tea.Cmd, properly returningnilwhen no command is needed. This aligns perfectly with the Bubble Tea framework patterns and the architectural direction to replace channel-based messaging.Also applies to: 127-127, 139-139, 151-151, 159-159, 168-168, 182-182
196-206: Clean modal key handling implementation.The renamed
notifyModelOpenKeyfunction properly delegates to helper methods and includes error logging for invalid keypresses, improving debuggability.
260-260: Consistent handling of rename conflicts.The
renamingKeymethod properly returns the command fromwarnModalForRenaming()when conflicts exist, maintaining the command-based flow.Also applies to: 262-262
src/internal/model.go (3)
17-17: Successful migration to notify modal system.The integration with the new
notify.Modelis clean and consistent throughout. All modal state checks and rendering properly use the newnotifyModelfield with its methods.Also applies to: 282-282, 304-305, 541-545
336-340: Improved quit confirmation state machine.The refactored quit flow with clearer state names (
quitConfirmationInitiated,quitConfirmationReceived) and proper integration with the notify modal system makes the logic more maintainable.Also applies to: 342-345, 446-449
52-58: Clean removal of channel-based messaging.Excellent removal of the global channel state and associated goroutine spawning. The comment acknowledging the previous issue (#946) shows awareness of the architectural improvement.
Also applies to: 104-104, 111-112
src/internal/handle_file_operations.go (3)
60-70: Clean refactoring to command-based modal creation.The
warnModalForRenamingfunction now properly returns atea.Cmdthat creates a notification modal, following the architectural pattern of separating UI operations from business logic.
155-175: Well-structured delete confirmation flow.The
getDeleteTriggerCmdfunction properly:
- Validates preconditions before creating the command
- Customizes messages based on trash availability
- Returns a command that creates the appropriate notification modal
253-254: Good use of helper functions for consistency.The refactored
executePasteOperationproperly uses:
icon.GetCopyOrCutIcon()for consistent icon displaygetCopyOrCutOperationName()for operation naming
This improves code maintainability and consistency.Also applies to: 257-259, 281-281
src/internal/key_function.go
Outdated
| func (m *model) handleNotifyModelCancel() tea.Cmd { | ||
| m.notifyModel.Close() | ||
| switch m.notifyModel.GetConfirmAction() { | ||
| case notify.RenameAction: | ||
| m.cancelRename() | ||
| case notify.QuitAction: | ||
| m.modelQuitState = notQuitting | ||
| case notify.DeleteAction, notify.NoAction: | ||
| // Do nothing | ||
| default: | ||
| slog.Error("Unknown type of action", "action", m.notifyModel.GetConfirmAction()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are similar. But there is no clean way to refactor this.
The functionality these two method's offer is very different.
bb07cfc to
8b9e9ae
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Health Improved
(3 files improve in Code Health)
Gates Failed
Prevent hotspot decline
(2 hotspots with String Heavy Function Arguments, Primitive Obsession)
Gates Passed
2 Quality Gates Passed
See analysis details in CodeScene
Reason for failure
| Prevent hotspot decline | Violations | Code Health Impact | |
|---|---|---|---|
| function.go | 1 rule in this hotspot | 7.77 → 7.53 | Suppress |
| handle_file_operations.go | 1 rule in this hotspot | 7.88 → 8.35 | Suppress |
View Improvements
| File | Code Health Impact | Categories Improved |
|---|---|---|
| handle_file_operations.go | 7.88 → 8.35 | Complex Method, Complex Conditional, Bumpy Road Ahead, Overall Code Complexity |
| key_function.go | 8.29 → 8.36 | Bumpy Road Ahead, Overall Code Complexity |
| model.go | 8.02 → 8.20 | Complex Method |
| function.go | 7.77 → 7.53 | Overall Code Complexity, String Heavy Function Arguments |
Quality Gate Profile: The Bare Minimum
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.
8b9e9ae to
f6a0fc7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Health Improved
(3 files improve in Code Health)
Gates Failed
Prevent hotspot decline
(2 hotspots with String Heavy Function Arguments, Primitive Obsession)
Gates Passed
2 Quality Gates Passed
See analysis details in CodeScene
Reason for failure
| Prevent hotspot decline | Violations | Code Health Impact | |
|---|---|---|---|
| function.go | 1 rule in this hotspot | 7.77 → 7.53 | Suppress |
| handle_file_operations.go | 1 rule in this hotspot | 7.88 → 8.35 | Suppress |
View Improvements
| File | Code Health Impact | Categories Improved |
|---|---|---|
| handle_file_operations.go | 7.88 → 8.35 | Complex Method, Complex Conditional, Bumpy Road Ahead, Overall Code Complexity |
| key_function.go | 8.29 → 8.36 | Bumpy Road Ahead |
| model.go | 8.02 → 8.20 | Complex Method |
| function.go | 7.77 → 7.53 | Overall Code Complexity, String Heavy Function Arguments |
Quality Gate Profile: The Bare Minimum
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Health Improved
(3 files improve in Code Health)
Gates Failed
Prevent hotspot decline
(2 hotspots with String Heavy Function Arguments, Primitive Obsession)
Gates Passed
2 Quality Gates Passed
See analysis details in CodeScene
Reason for failure
| Prevent hotspot decline | Violations | Code Health Impact | |
|---|---|---|---|
| function.go | 1 rule in this hotspot | 7.77 → 7.53 | Suppress |
| handle_file_operations.go | 1 rule in this hotspot | 7.88 → 8.35 | Suppress |
View Improvements
| File | Code Health Impact | Categories Improved |
|---|---|---|
| handle_file_operations.go | 7.88 → 8.35 | Complex Method, Complex Conditional, Bumpy Road Ahead, Overall Code Complexity |
| key_function.go | 8.29 → 8.36 | Bumpy Road Ahead |
| model.go | 8.02 → 8.20 | Complex Method |
| function.go | 7.77 → 7.53 | Overall Code Complexity, String Heavy Function Arguments |
Quality Gate Profile: The Bare Minimum
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.
| "time" | ||
|
|
||
| variable "github.com/yorukot/superfile/src/config" | ||
| "github.com/yorukot/superfile/src/internal/ui/notify" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❌ New issue: String Heavy Function Arguments
In this module, 50.0% of all arguments to its 20 functions are strings. The threshold for string arguments is 39.0%
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/internal/handle_file_operations.go (1)
60-70: LGTM! Consider updating the TODO comment.The refactor from channel messaging to tea.Cmd is architecturally sound and consistent with the new notification modal system. The request ID management using
m.ioReqCntis simpler and appropriate.The TODO comment on line 59 should be updated or removed since this change actually implements the tea.Cmd approach it suggests.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/internal/handle_file_operations.go(6 hunks)
🧰 Additional context used
🧠 Learnings (19)
📓 Common learnings
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/default_config.go:16-16
Timestamp: 2025-07-27T07:40:51.938Z
Learning: lazysegtree prefers simpler implementation approaches when the alternatives are significantly more complex, even if the alternatives might be architecturally cleaner, prioritizing maintainability and avoiding over-engineering.
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/default_config.go:16-16
Timestamp: 2025-07-27T07:40:51.938Z
Learning: lazysegtree prefers simpler implementation approaches when the alternatives are significantly more complex, even if the alternatives might be architecturally cleaner, prioritizing maintainability and avoiding over-engineering.
Learnt from: lazysegtree
PR: yorukot/superfile#969
File: src/internal/key_function.go:40-40
Timestamp: 2025-08-03T09:34:55.721Z
Learning: lazysegtree emphasizes proper dependency direction in software architecture, preferring that low-level components (like modal handlers) should not depend on high-level components (like the main model object). He also prioritizes performance considerations, noting that creating objects on every keypress in hot code paths like key handling is inefficient and should be avoided.
Learnt from: lazysegtree
PR: yorukot/superfile#973
File: src/internal/ui/processbar/model_update.go:7-27
Timestamp: 2025-08-03T14:49:31.221Z
Learning: lazysegtree prefers to keep test-only code simple without adding production-level concerns like goroutine synchronization, cancellation contexts, or complex lifecycle management, even when such patterns might prevent potential issues, since the complexity isn't justified for test utilities.
Learnt from: lazysegtree
PR: yorukot/superfile#950
File: src/internal/ui/metadata/README.md:7-7
Timestamp: 2025-07-24T03:46:29.516Z
Learning: lazysegtree prefers to defer comprehensive unit testing to separate PRs when the current PR has grown too large, maintaining focus on the primary refactoring objectives while tracking testing requirements in dedicated GitHub issues.
Learnt from: lazysegtree
PR: yorukot/superfile#967
File: src/internal/key_function.go:45-47
Timestamp: 2025-08-02T11:47:07.713Z
Learning: lazysegtree prefers to track technical debt and architectural improvements in dedicated GitHub issues when they are identified during PR reviews but are beyond the scope of the current PR, particularly for complex refactoring needs like input handling architecture that would require significant changes.
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/handle_file_operations.go:567-570
Timestamp: 2025-07-27T08:49:09.687Z
Learning: lazysegtree prefers to defer technical debt issues like model mutation concerns to later PRs when the current PR has already grown too large, maintaining focus on the primary objectives while acknowledging the need to track such issues for future work.
Learnt from: lazysegtree
PR: yorukot/superfile#970
File: src/internal/ui/processbar/model.go:11-26
Timestamp: 2025-08-02T17:00:37.262Z
Learning: lazysegtree prefers to track memory leak issues and feature enhancements via dedicated GitHub issues when identified during PR reviews but are beyond the current PR scope, particularly for processbar-related improvements like cleanup mechanisms and keyboard shortcuts.
Learnt from: lazysegtree
PR: yorukot/superfile#906
File: src/internal/file_panel.go:11-14
Timestamp: 2025-07-12T05:32:53.131Z
Learning: lazysegtree is concerned about the efficiency impact of adding bounds checking to frequently called methods like getSelectedItem() in file panels, preferring to defer such changes to consider performance implications.
Learnt from: lazysegtree
PR: yorukot/superfile#935
File: website/src/content/docs/changelog.md:17-26
Timestamp: 2025-07-15T10:32:28.063Z
Learning: In the superfile changelog (website/src/content/docs/changelog.md), lazysegtree prefers to maintain the existing heading format with main version headings using # and sub-sections using #### (Update, Bug fix, Optimization, etc.) consistently throughout all releases, prioritizing established format consistency over strict markdown heading hierarchy compliance.
📚 Learning: in yorukot/superfile, deleteitemwarn() only displays a warning modal via the channelmessage system a...
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/default_config.go:16-16
Timestamp: 2025-07-27T15:35:25.617Z
Learning: In yorukot/superfile, deleteItemWarn() only displays a warning modal via the channelMessage system and does not perform actual file deletion. The actual deletion happens when the user confirms the modal, which triggers getDeleteCmd() that returns a tea.Cmd. The architecture intentionally separates UI modal operations (using channelMessage/goroutines) from file I/O operations (using tea.Cmd pattern), creating clean separation of concerns between UI state management and file operations.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: deleteitemwarn() in yorukot/superfile only displays a warning modal via channel messaging and does n...
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/default_config.go:16-16
Timestamp: 2025-07-27T15:35:25.617Z
Learning: deleteItemWarn() in yorukot/superfile only displays a warning modal via channel messaging and does not perform actual file deletion. The actual deletion happens through getDeleteCmd() which returns a tea.Cmd. The architectural pattern separates UI modal operations (using channels/goroutines) from file I/O operations (using tea.Cmd), which is intentional and appropriate.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in bubble tea applications, when functions like warnmodalforrenaming() capture state (like m.ioreqcn...
Learnt from: lazysegtree
PR: yorukot/superfile#979
File: src/internal/common/predefined_variable.go:44-44
Timestamp: 2025-08-05T11:51:37.626Z
Learning: In Bubble Tea applications, when functions like warnModalForRenaming() capture state (like m.ioReqCnt) and increment it before returning a tea.Cmd, the increment happens synchronously in the calling context (typically Update()), not inside the returned tea.Cmd function. Since Update() is called synchronously by the Bubble Tea runtime, there are no race conditions in this pattern.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: when reviewing large refactoring prs that change async patterns (like moving from goroutines to tea....
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/default_config.go:16-16
Timestamp: 2025-07-27T15:32:06.922Z
Learning: When reviewing large refactoring PRs that change async patterns (like moving from goroutines to tea.Cmd), always check for incomplete refactoring where some call sites still use the old pattern while others use the new pattern, as this often leads to compilation errors and architectural inconsistencies.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: before suggesting the creation of new constants for string literals, always check if a constant alre...
Learnt from: yorukot
PR: yorukot/superfile#841
File: src/internal/model_render.go:334-334
Timestamp: 2025-06-04T09:58:25.572Z
Learning: Before suggesting the creation of new constants for string literals, always check if a constant already exists in the codebase, especially in common packages like `src/internal/common/predefined_variable.go`.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: pattern to watch for: defer file.close() inside loops (for, range, filepath.walk callbacks) causes r...
Learnt from: lazysegtree
PR: yorukot/superfile#821
File: src/internal/file_operations_compress.go:0-0
Timestamp: 2025-06-05T12:42:45.139Z
Learning: Pattern to watch for: defer file.Close() inside loops (for, range, filepath.Walk callbacks) causes resource leaks by accumulating file descriptors until function exits. Should be replaced with explicit Close() calls immediately after file operations with proper error handling.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in pr #767 for yorukot/superfile, the focus is on moving code (especially sidebar-related functional...
Learnt from: lazysegtree
PR: yorukot/superfile#0
File: :0-0
Timestamp: 2025-04-12T12:00:32.688Z
Learning: In PR #767 for yorukot/superfile, the focus is on moving code (especially sidebar-related functionality) to a more organized structure without changing functionality. Pre-existing issues should be ignored since the purpose is code reorganization, not fixing existing problems.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in the superfile codebase, yorukot prefers to maintain consistent code structure patterns (like usin...
Learnt from: yorukot
PR: yorukot/superfile#887
File: src/internal/key_function.go:258-263
Timestamp: 2025-06-16T14:14:39.966Z
Learning: In the superfile codebase, yorukot prefers to maintain consistent code structure patterns (like using switch statements in key handling functions) even when it triggers linter warnings, prioritizing code consistency and future extensibility over linter compliance.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: the superfile application includes shell capabilities where users directly input commands to be exec...
Learnt from: lazysegtree
PR: yorukot/superfile#752
File: src/internal/ui/prompt/tokenize.go:66-80
Timestamp: 2025-04-03T16:09:55.483Z
Learning: The superfile application includes shell capabilities where users directly input commands to be executed on their own systems. As with standard shells, the responsibility for command safety lies with the user, not the application.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in the superfile bash installer (website/public/install.sh), lazysegtree maintains the same principl...
Learnt from: lazysegtree
PR: yorukot/superfile#953
File: website/public/install.sh:42-42
Timestamp: 2025-07-21T08:49:44.628Z
Learning: In the superfile bash installer (website/public/install.sh), lazysegtree maintains the same principle as the PowerShell installer - users should supply correct environment variable values (SPF_INSTALL_VERSION without leading 'v') rather than adding validation code to handle malformed input, following the philosophy that users should provide properly formatted values.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in the ui renderer functions of superfile, errors are deliberately handled at the renderer creation ...
Learnt from: lazysegtree
PR: yorukot/superfile#781
File: src/internal/ui/spf_renderers.go:25-31
Timestamp: 2025-04-28T04:03:54.192Z
Learning: In the UI renderer functions of Superfile, errors are deliberately handled at the renderer creation level (logging and fallback to empty renderer) rather than propagating them up the call stack. This is an intentional architectural decision to limit error propagation in the UI layer.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in the superfile changelog (website/src/content/docs/changelog.md), lazysegtree prefers to maintain ...
Learnt from: lazysegtree
PR: yorukot/superfile#935
File: website/src/content/docs/changelog.md:17-26
Timestamp: 2025-07-15T10:32:28.063Z
Learning: In the superfile changelog (website/src/content/docs/changelog.md), lazysegtree prefers to maintain the existing heading format with main version headings using # and sub-sections using #### (Update, Bug fix, Optimization, etc.) consistently throughout all releases, prioritizing established format consistency over strict markdown heading hierarchy compliance.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in the sidebar component of yorukot/superfile, the partial list rendering in render.go is intentiona...
Learnt from: lazysegtree
PR: yorukot/superfile#770
File: src/internal/ui/sidebar/render.go:0-0
Timestamp: 2025-04-12T13:51:24.691Z
Learning: In the sidebar component of yorukot/superfile, the partial list rendering in render.go is intentional. The sidebar implements scrolling functionality where ListUp/ListDown methods in navigation.go update cursor position and renderIndex to show the appropriate portion of the directory list based on available space.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in yorukot/superfile, lazysegtree prefers that individual components like modals should implement in...
Learnt from: lazysegtree
PR: yorukot/superfile#969
File: src/internal/key_function.go:40-40
Timestamp: 2025-08-03T09:34:55.721Z
Learning: In yorukot/superfile, lazysegtree prefers that individual components like modals should implement interfaces directly and handle their own cancel/confirm logic, rather than using external handler objects. This follows the existing pattern where components like sidebarModel are self-contained and don't depend on the main model object.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in superfile, during the initial config loading phase (loadtomlfile calls), slog redirection to log ...
Learnt from: lazysegtree
PR: yorukot/superfile#881
File: src/internal/utils/file_utils.go:104-104
Timestamp: 2025-06-24T03:11:07.797Z
Learning: In superfile, during the initial config loading phase (LoadTomlFile calls), slog redirection to log files hasn't been set up yet, so slog.Error messages still go to stdout/stderr and should include errorPrefix for proper terminal styling.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: the project standardized on using one ansi package import (github.com/charmbracelet/x/exp/term/ansi)...
Learnt from: lazysegtree
PR: yorukot/superfile#825
File: src/internal/model_render.go:0-0
Timestamp: 2025-05-22T04:50:02.071Z
Learning: The project standardized on using one ANSI package import (github.com/charmbracelet/x/exp/term/ansi) to avoid binary bloat and potential incompatibilities.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: the project standardized on using one ansi package import (either github.com/charmbracelet/x/ansi or...
Learnt from: lazysegtree
PR: yorukot/superfile#825
File: src/internal/model_render.go:0-0
Timestamp: 2025-05-22T04:50:02.071Z
Learning: The project standardized on using one ANSI package import (either github.com/charmbracelet/x/ansi or github.com/charmbracelet/x/exp/term/ansi) to avoid binary bloat and potential incompatibilities.
Applied to files:
src/internal/handle_file_operations.go
📚 Learning: in the superfile codebase, structs that need to be serialized to/from json have exported fields (cap...
Learnt from: lazysegtree
PR: yorukot/superfile#770
File: src/internal/ui/sidebar/consts.go:5-8
Timestamp: 2025-04-12T14:00:54.846Z
Learning: In the superfile codebase, structs that need to be serialized to/from JSON have exported fields (capitalized names like `Name` and `Location`) even when the variables of those structs are unexported. This is because Go's JSON marshaling/unmarshaling can only access exported struct fields.
Applied to files:
src/internal/handle_file_operations.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Build and Test (ubuntu-latest)
- GitHub Check: Analyze (go)
🔇 Additional comments (5)
src/internal/handle_file_operations.go (5)
15-15: LGTM!The addition of the notify package import is consistent with the architectural migration from channel-based messaging to the new notification modal system.
155-175: LGTM!The refactor from
deleteItemWarntogetDeleteTriggerCmdis well-implemented. The function name better reflects its purpose, and the tea.Cmd pattern is correctly applied. The logic for distinguishing between trash and permanent delete operations is preserved and properly reflected in the modal content.
227-247: LGTM! Excellent separation of concerns.Extracting paste validation into a dedicated function improves testability and maintainability. The validation logic is comprehensive, covering all edge cases:
- Prevents no-op cut operations into the same directory
- Prevents circular paste operations
- Uses
isAncestorcheck to prevent pasting into subdirectoriesThe descriptive error messages will help users understand why paste operations fail.
217-221: LGTM!The integration with
validatePasteOperationis clean and follows the established error handling pattern. UsingNoActionfor error notifications is appropriate since these are informational messages requiring no user action.
253-303: LGTM! Good improvements with one potential behavioral change.The refactoring improves the function significantly:
- Added debug logging for better troubleshooting
- Cleaner function signature with discrete parameters
- Consistent use of
icon.GetCopyOrCutIconhelper- Better separation of concerns
Note that line 294 now sets
p.Done = p.Totalon success instead of incrementing for each item. This changes progress tracking behavior - progress will only update at the end rather than incrementally during the operation.Verify that this change in progress tracking behavior is intentional and doesn't negatively impact user experience.
| return p.State | ||
| } | ||
|
|
||
| func getTotalFilesCnt(copyItems []string) int { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was removed in earlier PRs, but this caused unexepcted behaviour.
https://github.com/yorukot/superfile/pull/973/files#diff-122e33672bc3c4cc7d30c6a5a205e075296636dc64704ec03e9f4228474e25e0L316
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Health Improved
(4 files improve in Code Health)
Gates Failed
Prevent hotspot decline
(2 hotspots with String Heavy Function Arguments, Primitive Obsession)
Gates Passed
2 Quality Gates Passed
See analysis details in CodeScene
Reason for failure
| Prevent hotspot decline | Violations | Code Health Impact | |
|---|---|---|---|
| function.go | 1 rule in this hotspot | 7.77 → 7.53 | Suppress |
| handle_file_operations.go | 1 rule in this hotspot | 7.88 → 8.35 | Suppress |
View Improvements
| File | Code Health Impact | Categories Improved |
|---|---|---|
| handle_file_operations.go | 7.88 → 8.35 | Complex Method, Complex Conditional, Bumpy Road Ahead, Overall Code Complexity |
| key_function.go | 8.29 → 8.36 | Bumpy Road Ahead |
| model.go | 8.02 → 8.20 | Complex Method |
| function.go | 7.77 → 7.53 | Overall Code Complexity, String Heavy Function Arguments |
| handle_file_operation_test.go | 8.32 → 8.34 | Large Method, Bumpy Road Ahead |
| test_utils.go | 9.39 → 9.10 | Primitive Obsession |
Quality Gate Profile: The Bare Minimum
Want more control? Customize Code Health rules or catch issues early with our IDE extension and CLI tool.
| } | ||
|
|
||
| // This is needed for blink, etc to work | ||
| m.updateFilePanelsState(msg, &cmd) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was causing a bug, where the cmd from above methods will get overwritten.
took me hours to find.
|
@coderabbitai summary |
✅ Actions performedSummary regeneration triggered. |
| subTwo + "\n\n" + subThree + "\n\n" + subFour + "\n\n") | ||
| } | ||
|
|
||
| func (m *model) warnModalRender() string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please create an issue proposing unifying all overlay models . Dont tell what to do, but what is the problem.
- We have six overlay modals, Typing Model, Prompt Modal, Help Menu Modal, Notify Modal, Sort OptionModal, FirstUseModal.
- Their input handling is all scattered accross the code.
- Their rendering has duplicated code
- There is no way we are guranteeing only one modal being open at a time
We should
- unify their code somehow
Please add more info, if I have missed, about the problems, and what should we target to achieve.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
@lazysegtree I'll analyze the codebase to gather comprehensive information about the modal unification problem and create a detailed issue.
Based on my analysis of the codebase, I'll now create a comprehensive GitHub issue describing the modal unification problems.
@lazysegtree I've created a comprehensive GitHub issue that identifies the modal unification problems in detail. The issue covers:
Key Problems Identified:
- Scattered input handling across 6 different modal types with inconsistent patterns
- Significant code duplication in rendering logic, borders, and styling
- No coordination mechanism to ensure only one modal is open at a time
- Inconsistent state management patterns across different modals
- Testing complexity due to fragmented implementations
Additional Issues Found:
- Mixed architectural patterns after recent refactoring (notify package vs old patterns)
- Manual spacing/newline management in each render function
- Different lifecycle management approaches
- Potential UI conflicts from simultaneous modal states
The issue focuses on describing the problems and their impact on development rather than prescribing solutions, as requested. It should help guide future architectural decisions for unifying the modal system.
🏁 Script executed:
#!/bin/bash
# Find all modal-related functions and structures to understand the current implementation
echo "=== Modal rendering functions ==="
rg -n "func.*[Mm]odal.*[Rr]ender" --type=go
echo -e "\n=== Modal struct definitions ==="
rg -n "type.*[Mm]odal.*struct" --type=go
echo -e "\n=== Modal fields in main model ==="
rg -nA5 -B5 "Modal.*\{|modal.*:" src/internal/type.go
echo -e "\n=== Modal-related key handling ==="
rg -n "[Mm]odal.*[Kk]ey" --type=go
echo -e "\n=== Modal open/close logic ==="
rg -n "\.open.*=|IsOpen\(\)" --type=go
echo -e "\n=== Modal state management ==="
rg -n "focus.*[Mm]odal|[Mm]odal.*focus" --type=go
Length of output: 6453
🏁 Script executed:
#!/bin/bash
# Look for modal-related constants and enums
echo "=== Modal-related constants and types ==="
rg -n "const.*[Mm]odal|type.*[Mm]odal" --type=go
echo -e "\n=== Modal initialization patterns ==="
rg -n "New.*[Mm]odal|[Mm]odal.*New" --type=go
echo -e "\n=== Modal update handling ==="
rg -n "Update.*[Mm]odal|[Mm]odal.*Update" --type=go -A3 -B3
echo -e "\n=== Modal message types ==="
rg -n "Msg.*[Mm]odal|[Mm]odal.*Msg" --type=go
Length of output: 5895
🏁 Script executed:
#!/bin/bash
# Count the different modal implementations and their complexity
echo "=== Modal complexity analysis ==="
echo "Files containing modal logic:"
fd -e go -x grep -l -i modal {} \; | wc -l
echo -e "\nModal-related functions count:"
rg -c "func.*[Mm]odal" --type=go | head -10
echo -e "\n=== Specific modal types found ==="
rg -n "typing[Mm]odal|prompt[Mm]odal|help[Mm]enu|notify[Mm]odal|sort.*[Mm]odal|introduce[Mm]odal|firstUse" --type=go | head -20
echo -e "\n=== Modal rendering duplication patterns ==="
rg -n "Modal.*Render|Border.*Style.*Modal" --type=go | head -15
Length of output: 4173
🏁 Script executed:
#!/bin/bash
gh issue create \
--title "Architecture: Unify overlay modal system to eliminate code duplication and improve maintainability" \
--body "## Problem Statement
The current modal system in superfile suffers from significant architectural inconsistencies and code duplication that makes the codebase harder to maintain and prone to bugs.
## Current Modal Types
We currently have **six different overlay modal implementations**:
1. **Typing Modal** - for creating files/directories
2. **Prompt Modal** - for user prompts and confirmations
3. **Help Menu Modal** - for displaying keyboard shortcuts
4. **Notify Modal** - for notifications and warnings (recently refactored)
5. **Sort Options Modal** - for file sorting preferences
6. **First Use Modal** - for initial user introduction
## Key Problems
### 1. Scattered Input Handling Logic
Each modal implements its own input handling in different locations across the codebase:
- Key handling is spread across multiple functions (\`mainKey\`, \`normalAndBrowserModeKey\`, \`notifyModelOpenKey\`, etc.)
- No consistent pattern for modal navigation, confirmation, or cancellation
- Modal-specific keypresses are handled in different ways, making it difficult to maintain consistent UX
### 2. Duplicated Rendering Code
Modal rendering shows significant code duplication:
- Each modal reimplements similar border styling, sizing, and positioning logic
- Common UI elements like confirm/cancel buttons are recreated multiple times
- Inconsistent styling patterns across different modals
- Manual newline and spacing management in each render function
### 3. No Modal State Coordination
Currently there's **no mechanism to guarantee only one modal is open at a time**:
- Multiple modals could theoretically be opened simultaneously
- No central modal state management
- Risk of UI conflicts and undefined behavior when multiple overlays are active
- Difficult to track which modal currently has focus
### 4. Inconsistent State Management
Each modal manages its state differently:
- Some use boolean \`open\` fields, others use more complex state machines
- Different initialization and cleanup patterns
- Inconsistent update/message handling approaches
- No unified lifecycle management
### 5. Testing and Debugging Complexity
The scattered implementation makes testing difficult:
- Each modal requires separate test setup and teardown
- No consistent way to test modal interactions
- Debugging modal-related issues requires knowledge of multiple different patterns
## Impact on Development
This architectural fragmentation:
- **Increases development time** for new modal features
- **Creates maintenance burden** when fixing modal-related bugs
- **Introduces inconsistencies** in user experience
- **Makes code reviews harder** due to different patterns across modals
- **Complicates testing** of modal interactions
## Target Achievements
A unified modal system should achieve:
- **Single source of truth** for modal state management
- **Consistent input handling** patterns across all modal types
- **Reusable rendering components** to eliminate duplication
- **Guaranteed exclusivity** - only one modal active at a time
- **Simplified testing** through standardized modal interfaces
- **Easier maintenance** through centralized modal logic
- **Consistent UX patterns** across all overlay interactions
## Current Technical Debt
The recent refactoring work (PR #979) shows progress toward unification with the new \`notify\` package, but this only addresses one modal type. The remaining five modals still follow the old scattered patterns, creating a mixed architectural approach that needs completion.
Related to: #979
Reported by: @lazysegtree" \
--assignee lazysegtree
Length of output: 3767
✅ Issue created successfully!
I've created GitHub issue #999 that comprehensively documents the modal unification problem. The analysis revealed some additional details beyond what you initially mentioned:
Additional Problems Identified:
- 17 files currently contain modal logic, showing how scattered the implementation really is
- Mixed architectural patterns - the recent
notifypackage from PR feat: Remove channel for notification models #979 usesIsOpen()methods while older modals use boolean.openfields - Manual spacing management - each modal manually handles newlines and spacing (see TODO comment in
typineModalRender) - No focus management - no system to track which modal currently has focus
- Complex testing setup - each modal type requires different test patterns and setup
Scale of Duplication:
- Border styling is reimplemented across
ModalBorderStyle,FirstUseModal,HelpMenuModalBorderStyle,SortOptionsModalBorderStyle - Button rendering for confirm/cancel is duplicated with manual hotkey insertion
- Positioning logic using
PlaceOverlayis repeated for each modal type
The issue focuses on problems and target achievements rather than solutions, as requested. It should provide a solid foundation for planning the architectural unification work while maintaining your preference for solution-agnostic problem statements.
🧬 Code Graph Analysis Results
Here are the snippets from the provided code that are most relevant to understanding/assessing the overlay modals mentioned in your comment. I’ve included the exact code for short items and concise descriptions (docstring-style) for longer items, with their source file and approximate line ranges.
-
Source: src/internal/model_render.go
-
Typing modal render (TypineModalRender)
-
File: src/internal/model_render.go
-
Approx. lines: 285-305
-
Code:
func (m *model) typineModalRender() string {
previewPath := filepath.Join(m.typingModal.location, m.typingModal.textInput.Value())fileLocation := common.FilePanelTopDirectoryIconStyle.Render(" "+icon.Directory+icon.Space) +
common.FilePanelTopPathStyle.Render(common.TruncateTextBeginning(previewPath, common.ModalWidth-4, "...")) + "\n"confirm := common.ModalConfirm.Render(" (" + common.Hotkeys.ConfirmTyping[0] + ") Create ")
cancel := common.ModalCancel.Render(" (" + common.Hotkeys.CancelTyping[0] + ") Cancel ")tip := confirm +
lipgloss.NewStyle().Background(common.ModalBGColor).Render(" ") +
cancelvar err string
if m.typingModal.errorMesssage != "" {
err = "\n\n" + common.ModalErrorStyle.Render(m.typingModal.errorMesssage)
}
// TODO : Move this all to rendering package to avoid specifying newlines manually
return common.ModalBorderStyle(common.ModalHeight, common.ModalWidth).
Render(fileLocation + "\n" + m.typingModal.textInput.View() + "\n\n" + tip + err)
}
-
-
First-use modal render (IntroduceModalRender)
- File: src/internal/model_render.go
- Approx. lines: 307-336
- Code:
func (m *model) introduceModalRender() string {
title := common.SidebarTitleStyle.Render(" Thanks for using superfile!!") +
common.ModalStyle.Render("\n You can read the following information before starting to use it!")
vimUserWarn := common.ProcessErrorStyle.Render(" ** Very importantly ** If you are a Vim/Nvim user, go to:\n" +
" https://superfile.netlify.app/configure/custom-hotkeys/ to change your hotkey settings!")
subOne := common.SidebarTitleStyle.Render(" (1)") +
common.ModalStyle.Render(" If this is your first time, make sure you read:\n"+
" https://superfile.netlify.app/getting-started/tutorial/")
subTwo := common.SidebarTitleStyle.Render(" (2)") +
common.ModalStyle.Render(" If you forget the relevant keys during use,\n"+
" you can press "?" (shift+/) at any time to query the keys!")
subThree := common.SidebarTitleStyle.Render(" (3)") +
common.ModalStyle.Render(" For more customization you can refer to:\n"+
" https://superfile.netlify.app/")
subFour := common.SidebarTitleStyle.Render(" (4)") +
common.ModalStyle.Render(" Thank you again for using superfile.\n"+
" If you have any questions, please feel free to ask at:\n"+
" https://github.com/yorukot/superfile\n"+
" Of course, you can always open a new issue to share your idea \n"+
" or report a bug!")
return common.FirstUseModal(m.helpMenu.height, m.helpMenu.width).
Render(title + "\n\n" + vimUserWarn + "\n\n" + subOne + "\n\n" +
subTwo + "\n\n" + subThree + "\n\n" + subFour + "\n\n")
}
-
Prompt modal render (PromptModalRender)
- File: src/internal/model_render.go
- Approx. lines: 338-342
- Code:
func (m *model) promptModalRender() string {
return m.promptModal.Render()
}
-
Help Menu modal render (HelpMenuRender) - overview
- File: src/internal/model_render.go
- Approx. lines: 344-515 (long function)
- Description:
- Builds and renders the Help Menu modal content by iterating m.helpMenu.data, computing maximum hotkey string width to align columns, and assembling lines with either subtitles or hotkey/description rows. It tracks cursor position and rendering index (m.helpMenu.cursor, m.helpMenu.renderIndex, m.helpMenu.height). It then creates a bottom border string via GenerateFooterBorder and returns the final string using common.HelpMenuModalBorderStyle. No explicit error handling is shown; it’s a formatting/rendering routine.
-
Sort Options modal render (SortOptionsRender)
-
File: src/internal/model_render.go
-
Approx. lines: 516-534 (shorter function)
-
Code:
func (m *model) sortOptionsRender() string {
panel := m.fileModel.filePanels[m.filePanelFocusIndex]
sortOptionsContent := common.ModalTitleStyle.Render(" Sort Options") + "\n\n"
for i, option := range panel.sortOptions.data.options {
cursor := " "
if i == panel.sortOptions.cursor {
cursor = common.FilePanelCursorStyle.Render(icon.Cursor)
}
sortOptionsContent += cursor + common.ModalStyle.Render(" "+option) + "\n"
}
bottomBorder := common.GenerateFooterBorder(fmt.Sprintf("%s/%s", strconv.Itoa(panel.sortOptions.cursor+1),
strconv.Itoa(len(panel.sortOptions.data.options))), panel.sortOptions.width-2)return common.SortOptionsModalBorderStyle(panel.sortOptions.height, panel.sortOptions.width,
bottomBorder).Render(sortOptionsContent)
}
-
-
Notes:
- These modal render functions rely on shared modal styling helpers (ModalBorderStyle, FirstUseModal, HelpMenuModalBorderStyle, SortOptionsModalBorderStyle) defined in the style utilities. See the style-related snippets below for exact implementations.
-
-
Source: src/internal/common/style_function.go
-
FullScreenStyle
- File: src/internal/common/style_function.go
- Lines: 188-195
- Code:
func FullScreenStyle(height int, width int) lipgloss.Style {
return lipgloss.NewStyle().
Height(height).
Width(width).
Align(lipgloss.Center, lipgloss.Center).
Background(FullScreenBGColor).
Foreground(FullScreenFGColor)
}
-
ModalBorderStyle
- File: src/internal/common/style_function.go
- Lines: 123-125
- Code:
func ModalBorderStyle(height int, width int) lipgloss.Style {
return modalBorderStyleWithAlign(height, width, lipgloss.Center)
}
-
FirstUseModal
- File: src/internal/common/style_function.go
- Lines: 145-155
- Code:
func FirstUseModal(height int, width int) lipgloss.Style {
border := GenerateBorder()
return lipgloss.NewStyle().Height(height).
Width(width).
Align(lipgloss.Left, lipgloss.Center).
Border(border).
BorderForeground(ModalBorderActiveColor).
BorderBackground(ModalBGColor).
Background(ModalBGColor).
Foreground(ModalFGColor)
}
-
HelpMenuModalBorderStyle
-
File: src/internal/common/style_function.go
-
Lines: 158-170
-
Code:
func HelpMenuModalBorderStyle(height int, width int, borderBottom string) lipgloss.Style {
border := GenerateBorder()
border.Bottom = borderBottomreturn lipgloss.NewStyle().
Border(border).
BorderForeground(ModalBorderActiveColor).
BorderBackground(ModalBGColor).
Width(width).
Height(height).
Background(ModalBGColor).
Foreground(ModalFGColor)
}
-
-
SortOptionsModalBorderStyle
-
File: src/internal/common/style_function.go
-
Lines: 173-185
-
Code:
func SortOptionsModalBorderStyle(height int, width int, borderBottom string) lipgloss.Style {
border := GenerateBorder()
border.Bottom = borderBottomreturn lipgloss.NewStyle().
Border(border).
BorderForeground(ModalBorderActiveColor).
BorderBackground(ModalBGColor).
Width(width).
Height(height).
Background(ModalBGColor).
Foreground(ModalFGColor)
}
-
-
GenerateFooterBorder
- File: src/internal/common/style_function.go
- Lines: 335-342
- Code:
func GenerateFooterBorder(countString string, width int) string {
repeatCount := width - len(countString)
if repeatCount < 0 {
repeatCount = 0
}
return strings.Repeat(Config.BorderBottom, repeatCount) + Config.BorderMiddleRight +
countString + Config.BorderMiddleLeft
}
-
FilePreviewBox
- File: src/internal/common/style_function.go
- Lines: 38-42
- Code:
func FilePreviewBox(height int, width int) lipgloss.Style {
return lipgloss.NewStyle().
Width(width).
Height(height).Background(FilePanelBGColor)
}
-
-
Source: src/internal/common/predefined_variable.go
- Modal dimensions (ModalWidth, ModalHeight)
- File: src/internal/common/predefined_variable.go
- Lines: 24-25
- Code:
ModalWidth = 60
ModalHeight = 7
- Modal dimensions (ModalWidth, ModalHeight)
-
Source: src/internal/common/string_function.go
-
TruncateText
-
File: src/internal/common/string_function.go
-
Lines: 19-26
-
Code:
func TruncateText(text string, maxChars int, tails string) string {
truncatedText := ansi.Truncate(text, maxChars-len(tails), "")
if text != truncatedText {
return truncatedText + tails
}return text
}
-
-
TruncateTextBeginning
-
File: src/internal/common/string_function.go
-
Lines: 28-47
-
Code:
func TruncateTextBeginning(text string, maxChars int, tails string) string {
if ansi.StringWidth(text) <= maxChars {
return text
}truncatedRunes := []rune(text)
truncatedWidth := ansi.StringWidth(string(truncatedRunes))
for truncatedWidth > maxChars {
truncatedRunes = truncatedRunes[1:]
truncatedWidth = ansi.StringWidth(string(truncatedRunes))
}if len(truncatedRunes) > len(tails) {
truncatedRunes = append([]rune(tails), truncatedRunes[len(tails):]...)
}return string(truncatedRunes)
}
-
-
PrettierName
- File: src/internal/common/string_function.go
- Lines: 61-74
- Code:
func PrettierName(name string, width int, isDir bool, isSelected bool, bgColor lipgloss.Color) string {
style := GetElementIcon(name, isDir, Config.Nerdfont)
if isSelected {
return StringColorRender(lipgloss.Color(style.Color), bgColor).
Background(bgColor).
Render(style.Icon+" ") +
FilePanelItemSelectedStyle.
Render(TruncateText(name, width, "..."))
}
return StringColorRender(lipgloss.Color(style.Color), bgColor).
Background(bgColor).
Render(style.Icon+" ") +
FilePanelStyle.Render(TruncateText(name, width, "..."))
}
-
-
Source: src/internal/common/default_config.go (context for config types)
- Config and Hotkeys types presence (relevant for modal input/keys)
- File: src/internal/common/default_config.go
- Line ranges:
- Config ConfigType (line 11)
- Hotkeys HotkeysType (line 12)
- Theme ThemeType (line 10)
Note: The above reflect the snippets most relevant to understanding how the six overlay modals are implemented and styled, including the input/exit cues, rendering borders, and width/height constraints used when unifying or refactoring the overlays. If you want, I can trim or add additional nearby snippets for specific parts (e.g., more of helpMenuRender) for deeper review.
🧠 Learnings used
Learnt from: lazysegtree
PR: yorukot/superfile#775
File: src/internal/common/style_function.go:240-243
Timestamp: 2025-04-27T17:04:47.888Z
Learning: lazysegtree plans to refactor textinput.Model creation in the future to fix the code duplication issue that caused a bug where the sidebar search model was created without setting the Width property.
Learnt from: lazysegtree
PR: yorukot/superfile#969
File: src/internal/key_function.go:40-40
Timestamp: 2025-08-03T09:34:55.721Z
Learning: In yorukot/superfile, lazysegtree prefers that individual components like modals should implement interfaces directly and handle their own cancel/confirm logic, rather than using external handler objects. This follows the existing pattern where components like sidebarModel are self-contained and don't depend on the main model object.
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/default_config.go:16-16
Timestamp: 2025-07-27T07:40:51.938Z
Learning: lazysegtree prefers simpler implementation approaches when the alternatives are significantly more complex, even if the alternatives might be architecturally cleaner, prioritizing maintainability and avoiding over-engineering.
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/default_config.go:16-16
Timestamp: 2025-07-27T07:40:51.938Z
Learning: lazysegtree prefers simpler implementation approaches when the alternatives are significantly more complex, even if the alternatives might be architecturally cleaner, prioritizing maintainability and avoiding over-engineering.
Learnt from: lazysegtree
PR: yorukot/superfile#969
File: src/internal/key_function.go:40-40
Timestamp: 2025-08-03T09:34:55.721Z
Learning: lazysegtree emphasizes proper dependency direction in software architecture, preferring that low-level components (like modal handlers) should not depend on high-level components (like the main model object). He also prioritizes performance considerations, noting that creating objects on every keypress in hot code paths like key handling is inefficient and should be avoided.
Learnt from: lazysegtree
PR: yorukot/superfile#985
File: src/internal/model.go:0-0
Timestamp: 2025-08-11T01:49:30.040Z
Learning: lazysegtree prefers maintaining code correctness through proper design and invariants rather than adding defensive bounds checks at every slice access point, viewing such defensive programming as "duct taping" that can mask actual bugs instead of fixing them at their source.
Learnt from: lazysegtree
PR: yorukot/superfile#973
File: src/internal/ui/processbar/model_update.go:7-27
Timestamp: 2025-08-03T14:49:31.221Z
Learning: lazysegtree prefers to keep test-only code simple without adding production-level concerns like goroutine synchronization, cancellation contexts, or complex lifecycle management, even when such patterns might prevent potential issues, since the complexity isn't justified for test utilities.
Learnt from: lazysegtree
PR: yorukot/superfile#950
File: src/internal/ui/metadata/README.md:7-7
Timestamp: 2025-07-24T03:46:29.516Z
Learning: lazysegtree prefers to defer comprehensive unit testing to separate PRs when the current PR has grown too large, maintaining focus on the primary refactoring objectives while tracking testing requirements in dedicated GitHub issues.
Learnt from: lazysegtree
PR: yorukot/superfile#967
File: src/internal/key_function.go:45-47
Timestamp: 2025-08-02T11:47:07.713Z
Learning: lazysegtree prefers to track technical debt and architectural improvements in dedicated GitHub issues when they are identified during PR reviews but are beyond the scope of the current PR, particularly for complex refactoring needs like input handling architecture that would require significant changes.
Learnt from: lazysegtree
PR: yorukot/superfile#963
File: src/internal/handle_file_operations.go:567-570
Timestamp: 2025-07-27T08:49:09.687Z
Learning: lazysegtree prefers to defer technical debt issues like model mutation concerns to later PRs when the current PR has already grown too large, maintaining focus on the primary objectives while acknowledging the need to track such issues for future work.
Learnt from: lazysegtree
PR: yorukot/superfile#924
File: src/internal/model_test.go:147-168
Timestamp: 2025-08-09T02:52:22.516Z
Learning: In superfile tests, lazysegtree prefers tests that accurately mimic the actual production behavior, including file operations like creating and deleting the LastDir file, rather than isolating such operations to temporary locations when the real behavior involves modifying/deleting those specific files.
Learnt from: lazysegtree
PR: yorukot/superfile#970
File: src/internal/ui/processbar/model.go:11-26
Timestamp: 2025-08-02T17:00:37.262Z
Learning: lazysegtree prefers to track memory leak issues and feature enhancements via dedicated GitHub issues when identified during PR reviews but are beyond the current PR scope, particularly for processbar-related improvements like cleanup mechanisms and keyboard shortcuts.
This MR contains the following updates: | Package | Update | Change | |---|---|---| | [yorukot/superfile](https://github.com/yorukot/superfile) | minor | `v1.3.3` -> `v1.4.0` | MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot). **Proposed changes to behavior should be submitted there as MRs.** --- ### Release Notes <details> <summary>yorukot/superfile (yorukot/superfile)</summary> ### [`v1.4.0`](https://github.com/yorukot/superfile/releases/tag/v1.4.0) [Compare Source](yorukot/superfile@v1.3.3...v1.4.0) Hey folks. Releasing v1.4.0 with many new features, improvements, and bug fixes. We have an async file preview now, a zoxide panel, and various new features improving UX. #### Install: [**Click me to know how to install**](https://github.com/yorukot/superfile?tab=readme-ov-file#installation) #### Highlights - We have the Zoxide Panel now. Ensure zoxide is installed on your system, set `zoxide_support` to `true` in the config, and press `z` to use zoxide. <img width="645" height="295" alt="Image" src="https://github.com/user-attachments/assets/238f6549-5318-49d1-a3a0-14cf8a686955" /> - File previewing is now async, meaning reduced lag while scrolling through images, or on slow systems. - Many bug fixes. See 'Detailed Change Summary' ##### Internal Updates - Most file operations are now truly async with the usage of the recommended `tea.Cmd` pattern. - Enabled many new linters to improve code quality. - Moved golangci-lint to v2. Now developers don't need to keep the old v1 in their systems. - Refactored file preview in its own package for better maintainability and readability. - Fixed flaky unit tests. #### Detailed Change Summary <details><summary>Details</summary> <p> ##### Update - feat: File operation via tea cmd [#​963](yorukot/superfile#963) by @​lazysegtree - feat: processbar improvements, package separation, better channel management [#​973](yorukot/superfile#973) by @​lazysegtree - feat: enable lll and recvcheck linter, fix tests, more refactors [#​977](yorukot/superfile#977) by @​lazysegtree - feat: Remove channel for notification models [#​979](yorukot/superfile#979) by @​lazysegtree - feat: enable cyclop, funlen, gocognit, gocyclo linters, and refactor large functions [#​984](yorukot/superfile#984) by @​lazysegtree - feat: Add a new hotkey to handle cd-on-quit whenever needed [#​924](yorukot/superfile#924) by @​ahmed-habbachi - feat: added option to permanently delete files [#​987](yorukot/superfile#987) by @​hupender - feat: Preview panel separation [#​1021](yorukot/superfile#1021) by @​lazysegtree - feat: Add search functionality to help menu [#​1011](yorukot/superfile#1011) by @​iZarrios - feat: Use zoxide lib [#​1036](yorukot/superfile#1036) by @​lazysegtree - feat: Add zoxide directory tracking on navigation [#​1041](yorukot/superfile#1041) by @​lazysegtree - feat: Zoxide integration [#​1039](yorukot/superfile#1039) by @​lazysegtree - feat: Select mode with better feedback [#​1074](yorukot/superfile#1074) by @​lazysegtree - feat: owner/group in the metadata [#​1093](yorukot/superfile#1093) by @​xelavopelk - feat: Async zoxide [#​1104](yorukot/superfile#1104) by @​lazysegtree ##### Bug Fix - fix: sorting in searchbar [#​985](yorukot/superfile#985) by @​hupender - fix: Async rendering, Include clipboard check in paste items, and update linter configs [#​997](yorukot/superfile#997) by @​lazysegtree - fix: Move utility functions to utils package [#​1012](yorukot/superfile#1012) by @​lazysegtree - fix: Refactoring and separation of preview panel and searchbar in help menu [#​1013](yorukot/superfile#1013) by @​lazysegtree - fix(filePanel): allow focusType to be set correctly [#​1033](yorukot/superfile#1033) by @​faisal-990 - fix(ci): Update gomod2nix.toml, allow pre release in version output, release 1.4.0-rc1, bug fixes, and improvements [#​1054](yorukot/superfile#1054) by @​lazysegtree - fix(nix): resolve build failures in the nix flake [#​1068](yorukot/superfile#1068) by @​Frost-Phoenix - fix: Retry the file deletion to prevent flakies (#​938) [#​1076](yorukot/superfile#1076) by @​lazysegtree - fix(issue-1066): Fixed issue where enter was not searchable [#​1078](yorukot/superfile#1078) by @​Simpaqt - fix(#​1073): Tech debt fix [#​1077](yorukot/superfile#1077) by @​Simpaqt - fix: fix deleted directory not able to remove from pins (#​1067) [#​1081](yorukot/superfile#1081) by @​yorukot - fix: fix child process spawning attached [#​1084](yorukot/superfile#1084) by @​guemidiborhane - fix: always clear images when showing a FullScreenStyle [#​1094](yorukot/superfile#1094) by @​snikoletopoulos - fix: Allow j and k keys in zoxide [#​1102](yorukot/superfile#1102) by @​lazysegtree - fix: Zoxide improvements and 1.4.0-rc2 [#​1105](yorukot/superfile#1105) by @​lazysegtree - fix: rename cursor beginning on wrong character because of multiple dots in name (#​813) [#​1112](yorukot/superfile#1112) by @​SyedAsadK - fix: check and fix file panel scroll position on height changes [#​1095](yorukot/superfile#1095) by @​snikoletopoulos ##### Optimization - perf(website): optimize font loading and asset organization [#​1089](yorukot/superfile#1089) by @​yorukot ##### Documentation - docs: fix incorrect zoxide plugin config name [#​1049](yorukot/superfile#1049) by @​shree-xvi - docs(hotkeys): Fix typo in vimHotkeys.toml comments [#​1080](yorukot/superfile#1080) by @​wleoncio - docs: add section for core maintainers in README.md [#​1088](yorukot/superfile#1088) by @​yorukot - chore: add winget install instruction to readme and website [#​943](yorukot/superfile#943) by @​claykom ##### Dependencies - chore(deps): update dependency go to v1.25.0, golangci-lint to v2, golangci-lint actions to v8 [#​750](yorukot/superfile#750) by @​renovate[bot] - chore(deps): update amannn/action-semantic-pull-request action to v6 [#​1006](yorukot/superfile#1006) by @​renovate[bot] - chore(deps): update actions/first-interaction action to v3 [#​1005](yorukot/superfile#1005) by @​renovate[bot] - chore(deps): update actions/checkout action to v5 [#​1004](yorukot/superfile#1004) by @​renovate[bot] - chore(deps): bump astro from 5.10.1 to 5.12.8 [#​982](yorukot/superfile#982) by @​dependabot[bot] - fix(deps): update module golang.org/x/mod to v0.27.0 [#​989](yorukot/superfile#989) by @​renovate[bot] - fix(deps): update dependency @​expressive-code/plugin-collapsible-sections to v0.41.3 [#​990](yorukot/superfile#990) by @​renovate[bot] - fix(deps): update dependency sharp to v0.34.3 [#​992](yorukot/superfile#992) by @​renovate[bot] - fix(deps): update dependency @​expressive-code/plugin-line-numbers to v0.41.3 [#​991](yorukot/superfile#991) by @​renovate[bot] - chore(deps): update dependency go to v1.25.0 [#​994](yorukot/superfile#994) by @​renovate[bot] - fix(deps): update astro monorepo [#​995](yorukot/superfile#995) by @​renovate[bot] - fix(deps): update dependency @​astrojs/starlight to ^0.35.0 [#​1000](yorukot/superfile#1000) by @​renovate[bot] - fix(deps): update module github.com/urfave/cli/v3 to v3.4.1 [#​1001](yorukot/superfile#1001) by @​renovate[bot] - fix(deps): update module golang.org/x/text to v0.28.0 [#​1003](yorukot/superfile#1003) by @​renovate[bot] ##### Misc - chore: migrate from superfile.netlify.app to superfile.dev [#​1087](yorukot/superfile#1087) by @​yorukot - refactor(filepanel): replace filePanelFocusType with isFocused boolean [#​1040](yorukot/superfile#1040) by @​faisal-990 - refactor(ansi): Migrate from github.com/charmbracelet/x/exp/term/ansi to github.com/charmbracelet/x/ansi [#​1044](yorukot/superfile#1044) by @​faisal-990 - refactor: common operation on pinned directory file using PinnedManager [#​1085](yorukot/superfile#1085) by @​Manaswa-S - test: unit tests for pinned manager [#​1090](yorukot/superfile#1090) by @​Manaswa-S </p> </details> #### New Contributors * @​hupender made their first contribution in yorukot/superfile#985 * @​ahmed-habbachi made their first contribution in yorukot/superfile#924 * @​iZarrios made their first contribution in yorukot/superfile#1011 * @​faisal-990 made their first contribution in yorukot/superfile#1033 * @​shree-xvi made their first contribution in yorukot/superfile#1049 * @​Simpaqt made their first contribution in yorukot/superfile#1078 * @​wleoncio made their first contribution in yorukot/superfile#1080 * @​guemidiborhane made their first contribution in yorukot/superfile#1084 * @​Manaswa-S made their first contribution in yorukot/superfile#1085 * @​xelavopelk made their first contribution in yorukot/superfile#1093 * @​snikoletopoulos made their first contribution in yorukot/superfile#1094 * @​SyedAsadK made their first contribution in yorukot/superfile#1112 **Full Changelog**: <yorukot/superfile@v1.3.3...v1.4.0> </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS4xNDYuMCIsInVwZGF0ZWRJblZlciI6IjQxLjE0Ni4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiXX0=-->
Summary by CodeRabbit
New Features
Refactor
Bug Fixes
Tests