Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

test: unit tests for pinned manager#1090

Merged
lazysegtree merged 13 commits into
yorukot:mainyorukot/superfile:mainfrom
Manaswa-S:tests/pinned-managerManaswa-S/superfile:tests/pinned-managerCopy head branch name to clipboard
Sep 23, 2025
Merged

test: unit tests for pinned manager#1090
lazysegtree merged 13 commits into
yorukot:mainyorukot/superfile:mainfrom
Manaswa-S:tests/pinned-managerManaswa-S/superfile:tests/pinned-managerCopy head branch name to clipboard

Conversation

@Manaswa-S

@Manaswa-S Manaswa-S commented Sep 21, 2025

Copy link
Copy Markdown
Contributor

Extents #1082

Adds unit tests for PinnedManager.

Tests for:

     pinnedMgr.Load
     pinnedMgr.Save
     pinnedMgr.Toggle
     pinnedMgr.Clean

Summary by CodeRabbit

  • Tests
    • Added comprehensive test coverage for sidebar pinning behavior, including loading, saving, toggling, and cleaning scenarios.
    • Validates behavior with empty, invalid, and mixed data, and simulates file-system errors to ensure robust error handling.
    • Improves reliability of persistence and state management under real-world conditions.
  • Chores
    • No user-facing changes; internal quality and stability improvements only.

@vercel

vercel Bot commented Sep 21, 2025

Copy link
Copy Markdown

@Manaswa-S is attempting to deploy a commit to the yorukot's project Team on Vercel.

A member of the Team first needs to authorize it.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@Manaswa-S Manaswa-S changed the title Tests/pinned manager test: unit tests for pinned manager Sep 21, 2025
codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@Manaswa-S

Copy link
Copy Markdown
Contributor Author

Extremely sorry for the PR chaos everyone. Got some last minute OS specific errors due to oversight. Should be fixed now.

@yorukot

yorukot commented Sep 22, 2025

Copy link
Copy Markdown
Owner

That is totally fine

@yorukot

yorukot commented Sep 22, 2025

Copy link
Copy Markdown
Owner

@CodeRabbit Full Review

@coderabbitai

coderabbitai Bot commented Sep 22, 2025

Copy link
Copy Markdown
Contributor
✅ Actions performed

Full review triggered.

@coderabbitai

coderabbitai Bot commented Sep 22, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds a new test file for PinnedManager covering Load, Save, Toggle, and Clean behaviors, including success paths, empty inputs, invalid data, non-existent paths, and simulated I/O failures using temporary directories and JSON persistence.

Changes

Cohort / File(s) Summary of Changes
PinnedManager tests
src/internal/ui/sidebar/pinned_test.go
Introduces comprehensive unit tests for PinnedManager: validates Load with varied inputs, Save including failure scenarios, Toggle add/remove flows, and Clean filtering logic against filesystem existence and write errors.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

awaiting pr review

Poem

I pinned a path, then hopped to save,
Toggles danced—so bold, so brave.
Cleaned the burrow, stale bits gone,
Temp nests built, then moved along.
JSON crumbs mark trails I tread—
Tests all green, carrot-fed! 🥕🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "test: unit tests for pinned manager" succinctly and accurately describes the primary change in the changeset—adding unit tests for the PinnedManager. It is specific and concise, avoids extraneous details, and communicates the main intent to reviewers scanning history. Therefore it meets the PR title criteria.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
src/internal/ui/sidebar/pinned_test.go (2)

176-209: Avoid shared state across subtests in Toggle; make each subtest independent.

Reusing the same manager/file couples test order. If someone parallelizes subtests later, this will flake. Prefer a fresh file per case or reinit state inside each t.Run.

Example approach (sketch):

  • Move mgr creation into each subtest with a unique file: filepath.Join(pinnedDir, name+".json").
  • Seed state (Save) as needed before calling Toggle.

102-151: Small ergonomics: prefer helper(s) for repetitive directory/JSON setup.

Extract tiny helpers like makeDir(t, path), writeJSON(t, path, v), and asDirWriteTarget(t, path). This will reduce boilerplate and improve readability.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 89911f6 and d60bf32.

📒 Files selected for processing (1)
  • src/internal/ui/sidebar/pinned_test.go (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-20T01:40:50.053Z
Learnt from: lazysegtree
PR: yorukot/superfile#1081
File: src/internal/ui/sidebar/directory_utils.go:103-112
Timestamp: 2025-09-20T01:40:50.053Z
Learning: lazysegtree identified code duplication between removeNotExistingDirectories and TogglePinnedDirectory functions in src/internal/ui/sidebar/directory_utils.go, specifically 6 lines of JSON marshaling and file writing logic. He prefers to track such duplication fixes in separate GitHub issues and suggests either extracting common util functions or creating a PinnedDir manager for centralized Read/Write operations to PinnedFile.

Applied to files:

  • src/internal/ui/sidebar/pinned_test.go
🔇 Additional comments (3)
src/internal/ui/sidebar/pinned_test.go (3)

73-93: Good coverage and realistic FS setup for Load scenarios.

The table‑driven tests are clear and exercise empty, valid, and mixed data conditions. Nice use of TempDir/Join for isolation.


225-288: Good matrix for Clean, including save failures and empty input.

The success/partial/failure/empty coverage aligns with the earlier ask to centralize pin file R/W in a manager (see retrieved learnings). After fixing the ModTime path/logic, this will validate stability nicely.


164-223: Approve — Toggle behavior confirmed.

Toggle appends non-existent dirs but Load/Clean removes them on read, so the test's expectation (non-existent -> no pinned) is correct.

Comment thread src/internal/ui/sidebar/pinned_test.go
Comment thread src/internal/ui/sidebar/pinned_test.go Outdated
Comment on lines +111 to +115
rOnlyPath := filepath.Join(pinnedDir, "pinnedRonly.json")
file, err := os.OpenFile(rOnlyPath, os.O_CREATE|os.O_RDONLY, 0400)
require.NoError(t, err)
file.Close()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Make the “Write Failure” path deterministic across OSes (use a directory as the target).

Creating a read‑only file can behave differently across platforms (Windows ACLs). Targeting a directory guarantees EISDIR/permission errors on all OSes.

Apply this diff:

- rOnlyPath := filepath.Join(pinnedDir, "pinnedRonly.json")
- file, err := os.OpenFile(rOnlyPath, os.O_CREATE|os.O_RDONLY, 0400)
- require.NoError(t, err)
- file.Close()
+ // Use a directory as the "file" path to force a cross‑platform write failure.
+ dirAsFilePath := filepath.Join(pinnedDir, "as_dir_write_target")
+ err = os.Mkdir(dirAsFilePath, 0755)
+ require.NoError(t, err)
@@
-      name:      "Write Failure",
-      pinnedMgr: PinnedManager{filePath: rOnlyPath},
+      name:      "Write Failure",
+      pinnedMgr: PinnedManager{filePath: dirAsFilePath},
       noError:   false,
       toSave:    dirs,
       expected:  nil,

Also applies to: 145-150

Comment on lines +153 to +161
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
err := tt.pinnedMgr.Save(tt.toSave)
if tt.noError {
require.NoError(t, err)
assert.Equal(t, tt.expected, tt.pinnedMgr.Load())
}
})
}

@coderabbitai coderabbitai Bot Sep 22, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Assert the negative path: Save should return an error on failure.

Currently the failure branch isn’t asserted, so a silent success would go unnoticed.

Apply this diff:

 for _, tt := range testCases {
   t.Run(tt.name, func(t *testing.T) {
     err := tt.pinnedMgr.Save(tt.toSave)
     if tt.noError {
       require.NoError(t, err)
       assert.Equal(t, tt.expected, tt.pinnedMgr.Load())
-    }
+    } else {
+      require.Error(t, err)
+    }
   })
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
err := tt.pinnedMgr.Save(tt.toSave)
if tt.noError {
require.NoError(t, err)
assert.Equal(t, tt.expected, tt.pinnedMgr.Load())
}
})
}
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
err := tt.pinnedMgr.Save(tt.toSave)
if tt.noError {
require.NoError(t, err)
assert.Equal(t, tt.expected, tt.pinnedMgr.Load())
} else {
require.Error(t, err)
}
})
}
🤖 Prompt for AI Agents
In src/internal/ui/sidebar/pinned_test.go around lines 153 to 161, the test loop
only asserts the success path and does not verify the failure path; when
tt.noError is false the test should assert that Save returned an error. Update
the test to add an else branch that calls require.Error(t, err) (and optionally
assert that the pinned manager state remains unchanged if desired) so failures
are not silently ignored.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. This is valid. Lets do this

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lazysegtree Thanks for confirming! Here's the implementation to properly assert the error path:

for _, tt := range testCases {
    t.Run(tt.name, func(t *testing.T) {
        err := tt.pinnedMgr.Save(tt.toSave)
        if tt.noError {
            require.NoError(t, err)
            assert.Equal(t, tt.expected, tt.pinnedMgr.Load())
        } else {
            require.Error(t, err)
        }
    })
}

This ensures that when tt.noError is false, the test will fail if Save() doesn't return an error, making the test more robust and preventing silent failures from going unnoticed.


🧠 Learnings used
Learnt from: lazysegtree
PR: yorukot/superfile#1081
File: src/internal/ui/sidebar/directory_utils.go:103-112
Timestamp: 2025-09-20T01:40:50.053Z
Learning: lazysegtree identified code duplication between removeNotExistingDirectories and TogglePinnedDirectory functions in src/internal/ui/sidebar/directory_utils.go, specifically 6 lines of JSON marshaling and file writing logic. He prefers to track such duplication fixes in separate GitHub issues and suggests either extracting common util functions or creating a PinnedDir manager for centralized Read/Write operations to PinnedFile.

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#1013
File: src/internal/model_render.go:329-341
Timestamp: 2025-08-29T14:11:21.380Z
Learning: lazysegtree prefers to defer help menu rendering optimizations and other technical debt improvements to separate GitHub issues when the current PR scope has grown too large, maintaining focus on the primary refactoring objectives while tracking performance improvements for future work.

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#1044
File: src/internal/utils/file_utils.go:149-149
Timestamp: 2025-09-09T13:29:11.771Z
Learning: lazysegtree prefers to keep PR scope focused on the primary objectives and considers pre-existing technical debt issues as out of scope for migration/refactoring PRs, preferring to defer such issues to separate GitHub issues rather than expanding the current PR scope.

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.

Comment on lines +291 to +307
t.Run(tt.name, func(t *testing.T) {
before, err := os.Stat(pinnedFile)
if !errors.Is(err, fs.ErrNotExist) {
require.NoError(t, err)
}

cleaned := tt.pinnedMgr.Clean(tt.argDirs)

after, err := os.Stat(pinnedFile)
if !errors.Is(err, fs.ErrNotExist) {
require.NoError(t, err)
} else if before != nil && !tt.modified {
require.Equal(t, before.ModTime(), after.ModTime())
}

assert.Equal(t, tt.expected, cleaned)
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Clean test checks the wrong path and has brittle ModTime logic.

  • It stats pinnedFile regardless of which path the manager actually writes to (e.g., rOnlyPath).
  • It compares ModTime only when after Stat fails, and risks nil deref if reused elsewhere.

Apply this diff to check the correct file and only compare ModTime when both files exist:

-      before, err := os.Stat(pinnedFile)
-      if !errors.Is(err, fs.ErrNotExist) {
-        require.NoError(t, err)
-      }
-
-      cleaned := tt.pinnedMgr.Clean(tt.argDirs)
-
-      after, err := os.Stat(pinnedFile)
-      if !errors.Is(err, fs.ErrNotExist) {
-        require.NoError(t, err)
-      } else if before != nil && !tt.modified {
-        require.Equal(t, before.ModTime(), after.ModTime())
-      }
+      subjectPath := tt.pinnedMgr.filePath
+      // Seed file when we control it, so ModTime checks are meaningful on "no modification" cases.
+      if subjectPath == pinnedFile {
+        _ = tt.pinnedMgr.Save(tt.argDirs)
+      }
+
+      beforeInfo, beforeErr := os.Stat(subjectPath)
+
+      cleaned := tt.pinnedMgr.Clean(tt.argDirs)
+
+      afterInfo, afterErr := os.Stat(subjectPath)
+      if beforeErr == nil && afterErr == nil && !tt.modified {
+        require.Equal(t, beforeInfo.ModTime(), afterInfo.ModTime())
+      }
 
       assert.Equal(t, tt.expected, cleaned)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
t.Run(tt.name, func(t *testing.T) {
before, err := os.Stat(pinnedFile)
if !errors.Is(err, fs.ErrNotExist) {
require.NoError(t, err)
}
cleaned := tt.pinnedMgr.Clean(tt.argDirs)
after, err := os.Stat(pinnedFile)
if !errors.Is(err, fs.ErrNotExist) {
require.NoError(t, err)
} else if before != nil && !tt.modified {
require.Equal(t, before.ModTime(), after.ModTime())
}
assert.Equal(t, tt.expected, cleaned)
})
t.Run(tt.name, func(t *testing.T) {
subjectPath := tt.pinnedMgr.filePath
// Seed file when we control it, so ModTime checks are meaningful on "no modification" cases.
if subjectPath == pinnedFile {
_ = tt.pinnedMgr.Save(tt.argDirs)
}
beforeInfo, beforeErr := os.Stat(subjectPath)
cleaned := tt.pinnedMgr.Clean(tt.argDirs)
afterInfo, afterErr := os.Stat(subjectPath)
if beforeErr == nil && afterErr == nil && !tt.modified {
require.Equal(t, beforeInfo.ModTime(), afterInfo.ModTime())
}
assert.Equal(t, tt.expected, cleaned)
})
🤖 Prompt for AI Agents
In src/internal/ui/sidebar/pinned_test.go around lines 291-307, the test
currently stats the hardcoded pinnedFile and uses brittle ModTime logic; change
it to stat the manager's actual pinned-file path (use tt.pinnedMgr.Path() or the
manager method that returns the file path instead of pinnedFile) so you check
the file the manager actually writes, and only compare modification times when
both before and after os.Stat succeed (i.e., neither is nil and neither returned
fs.ErrNotExist); adjust error checks to handle fs.ErrNotExist properly and avoid
dereferencing nil before/after values.

Comment thread src/internal/ui/sidebar/pinned_test.go Outdated
Comment on lines +19 to +20
err := os.Mkdir(pinnedDir, 0755)
require.NoError(t, err)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(1) Lets not use this.
Use utils functions to keep it consistent with all tests.

Suggested change
err := os.Mkdir(pinnedDir, 0755)
require.NoError(t, err)
utils.SetupDirectories(t, pinnedDir)

Comment thread src/internal/ui/sidebar/pinned_test.go Outdated
Comment on lines +26 to +27
err = os.WriteFile(emptyPath, emptyBytes, 0644)
require.NoError(t, err)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as (1)

Use utils.SetupFilesWithData

Comment thread src/internal/ui/sidebar/pinned_test.go Outdated
Comment on lines +30 to +31
err = os.WriteFile(invalidPath, []byte("{ invalid json }"), 0644)
require.NoError(t, err)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as (1)

Check all other occurences too

Comment thread src/internal/ui/sidebar/pinned_test.go Outdated
},
{
name: "Invalid Format File",
pinnedMgr: PinnedManager{filePath: emptyPath},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was supposed to be invalidPath

This test is same as the above test.

Comment on lines +88 to +93
{
name: "Valid With One Non-Existent Directory",
pinnedMgr: PinnedManager{filePath: newNonexistentPath},
expected: cleanDirs,
},
}

@lazysegtree lazysegtree Sep 22, 2025

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add a test with a path of file that is invalid

something like

	{
			name:      "Invalid filePath",
			pinnedMgr: PinnedManager{filePath: filepath.Join(pinnedDir, "non_existing_file_path.json")},
			expected: []directory{},
		},
	}

Comment thread src/internal/ui/sidebar/pinned_test.go Outdated

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
before, err := os.Stat(pinnedFile)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be tt.pinnedMgr. filePath, I think, not pinnedFile

@lazysegtree lazysegtree left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rest looks good to me

codescene-delta-analysis[bot]

This comment was marked as outdated.

@Manaswa-S

Copy link
Copy Markdown
Contributor Author

Applied all changes as per your suggestions. @yorukot @lazysegtree
Directories used to mock write failures and branching introduced for failures.
ModTime logic improved, utils used for io ops, wrong paths changed and test case added.

Thx for catching these issues guys. Much appreciated.

@lazysegtree lazysegtree left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great. Thanks.

@lazysegtree
lazysegtree merged commit 2f8f065 into yorukot:main Sep 23, 2025
6 of 7 checks passed
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Oct 15, 2025
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 [#&#8203;963](yorukot/superfile#963) by @&#8203;lazysegtree
- feat: processbar improvements, package separation, better channel management [#&#8203;973](yorukot/superfile#973) by @&#8203;lazysegtree
- feat: enable lll and recvcheck linter, fix tests, more refactors [#&#8203;977](yorukot/superfile#977) by @&#8203;lazysegtree
- feat: Remove channel for notification models [#&#8203;979](yorukot/superfile#979) by @&#8203;lazysegtree
- feat: enable cyclop, funlen, gocognit, gocyclo linters, and refactor large functions [#&#8203;984](yorukot/superfile#984) by @&#8203;lazysegtree
- feat: Add a new hotkey to handle cd-on-quit whenever needed [#&#8203;924](yorukot/superfile#924) by @&#8203;ahmed-habbachi
- feat: added option to permanently delete files [#&#8203;987](yorukot/superfile#987) by @&#8203;hupender
- feat: Preview panel separation [#&#8203;1021](yorukot/superfile#1021) by @&#8203;lazysegtree
- feat: Add search functionality to help menu [#&#8203;1011](yorukot/superfile#1011) by @&#8203;iZarrios
- feat: Use zoxide lib [#&#8203;1036](yorukot/superfile#1036) by @&#8203;lazysegtree
- feat: Add zoxide directory tracking on navigation [#&#8203;1041](yorukot/superfile#1041) by @&#8203;lazysegtree
- feat: Zoxide integration [#&#8203;1039](yorukot/superfile#1039) by @&#8203;lazysegtree
- feat: Select mode with better feedback [#&#8203;1074](yorukot/superfile#1074) by @&#8203;lazysegtree
- feat: owner/group in the metadata [#&#8203;1093](yorukot/superfile#1093) by @&#8203;xelavopelk
- feat: Async zoxide [#&#8203;1104](yorukot/superfile#1104) by @&#8203;lazysegtree

##### Bug Fix
- fix: sorting in searchbar [#&#8203;985](yorukot/superfile#985) by @&#8203;hupender
- fix: Async rendering, Include clipboard check in paste items, and update linter configs [#&#8203;997](yorukot/superfile#997) by @&#8203;lazysegtree
- fix: Move utility functions to utils package [#&#8203;1012](yorukot/superfile#1012) by @&#8203;lazysegtree
- fix: Refactoring and separation of preview panel and searchbar in help menu [#&#8203;1013](yorukot/superfile#1013) by @&#8203;lazysegtree
- fix(filePanel): allow focusType to be set correctly [#&#8203;1033](yorukot/superfile#1033) by @&#8203;faisal-990
- fix(ci): Update gomod2nix.toml, allow pre release in version output, release 1.4.0-rc1, bug fixes, and improvements [#&#8203;1054](yorukot/superfile#1054) by @&#8203;lazysegtree
- fix(nix): resolve build failures in the nix flake [#&#8203;1068](yorukot/superfile#1068) by @&#8203;Frost-Phoenix
- fix: Retry the file deletion to prevent flakies (#&#8203;938) [#&#8203;1076](yorukot/superfile#1076) by @&#8203;lazysegtree
- fix(issue-1066): Fixed issue where enter was not searchable [#&#8203;1078](yorukot/superfile#1078) by @&#8203;Simpaqt
- fix(#&#8203;1073): Tech debt fix [#&#8203;1077](yorukot/superfile#1077) by @&#8203;Simpaqt
- fix: fix deleted directory not able to remove from pins (#&#8203;1067) [#&#8203;1081](yorukot/superfile#1081) by @&#8203;yorukot
- fix: fix child process spawning attached [#&#8203;1084](yorukot/superfile#1084) by @&#8203;guemidiborhane
- fix: always clear images when showing a FullScreenStyle [#&#8203;1094](yorukot/superfile#1094) by @&#8203;snikoletopoulos
- fix: Allow j and k keys in zoxide [#&#8203;1102](yorukot/superfile#1102) by @&#8203;lazysegtree
- fix: Zoxide improvements and 1.4.0-rc2 [#&#8203;1105](yorukot/superfile#1105) by @&#8203;lazysegtree
- fix: rename cursor beginning on wrong character because of multiple dots in name (#&#8203;813) [#&#8203;1112](yorukot/superfile#1112) by @&#8203;SyedAsadK
- fix: check and fix file panel scroll position on height changes [#&#8203;1095](yorukot/superfile#1095) by @&#8203;snikoletopoulos

##### Optimization
- perf(website): optimize font loading and asset organization [#&#8203;1089](yorukot/superfile#1089) by @&#8203;yorukot

##### Documentation
- docs: fix incorrect zoxide plugin config name [#&#8203;1049](yorukot/superfile#1049) by @&#8203;shree-xvi
- docs(hotkeys): Fix typo in vimHotkeys.toml comments [#&#8203;1080](yorukot/superfile#1080) by @&#8203;wleoncio
- docs: add section for core maintainers in README.md [#&#8203;1088](yorukot/superfile#1088) by @&#8203;yorukot
- chore: add winget install instruction to readme and website [#&#8203;943](yorukot/superfile#943) by @&#8203;claykom

##### Dependencies
- chore(deps): update dependency go to v1.25.0, golangci-lint to v2, golangci-lint actions to v8 [#&#8203;750](yorukot/superfile#750) by @&#8203;renovate[bot]
- chore(deps): update amannn/action-semantic-pull-request action to v6 [#&#8203;1006](yorukot/superfile#1006) by @&#8203;renovate[bot]
- chore(deps): update actions/first-interaction action to v3 [#&#8203;1005](yorukot/superfile#1005) by @&#8203;renovate[bot]
- chore(deps): update actions/checkout action to v5 [#&#8203;1004](yorukot/superfile#1004) by @&#8203;renovate[bot]
- chore(deps): bump astro from 5.10.1 to 5.12.8 [#&#8203;982](yorukot/superfile#982) by @&#8203;dependabot[bot]
- fix(deps): update module golang.org/x/mod to v0.27.0 [#&#8203;989](yorukot/superfile#989) by @&#8203;renovate[bot]
- fix(deps): update dependency @&#8203;expressive-code/plugin-collapsible-sections to v0.41.3 [#&#8203;990](yorukot/superfile#990) by @&#8203;renovate[bot]
- fix(deps): update dependency sharp to v0.34.3 [#&#8203;992](yorukot/superfile#992) by @&#8203;renovate[bot]
- fix(deps): update dependency @&#8203;expressive-code/plugin-line-numbers to v0.41.3 [#&#8203;991](yorukot/superfile#991) by @&#8203;renovate[bot]
- chore(deps): update dependency go to v1.25.0 [#&#8203;994](yorukot/superfile#994) by @&#8203;renovate[bot]
- fix(deps): update astro monorepo [#&#8203;995](yorukot/superfile#995) by @&#8203;renovate[bot]
- fix(deps): update dependency @&#8203;astrojs/starlight to ^0.35.0 [#&#8203;1000](yorukot/superfile#1000) by @&#8203;renovate[bot]
- fix(deps): update module github.com/urfave/cli/v3 to v3.4.1 [#&#8203;1001](yorukot/superfile#1001) by @&#8203;renovate[bot]
- fix(deps): update module golang.org/x/text to v0.28.0 [#&#8203;1003](yorukot/superfile#1003) by @&#8203;renovate[bot]

##### Misc
- chore: migrate from superfile.netlify.app to superfile.dev [#&#8203;1087](yorukot/superfile#1087) by @&#8203;yorukot
- refactor(filepanel): replace filePanelFocusType with isFocused boolean [#&#8203;1040](yorukot/superfile#1040) by @&#8203;faisal-990
- refactor(ansi): Migrate from github.com/charmbracelet/x/exp/term/ansi to github.com/charmbracelet/x/ansi [#&#8203;1044](yorukot/superfile#1044) by @&#8203;faisal-990
- refactor: common operation on pinned directory file using PinnedManager [#&#8203;1085](yorukot/superfile#1085) by @&#8203;Manaswa-S
- test: unit tests for pinned manager [#&#8203;1090](yorukot/superfile#1090) by @&#8203;Manaswa-S

</p>
</details> 

#### New Contributors
* @&#8203;hupender made their first contribution in yorukot/superfile#985
* @&#8203;ahmed-habbachi made their first contribution in yorukot/superfile#924
* @&#8203;iZarrios made their first contribution in yorukot/superfile#1011
* @&#8203;faisal-990 made their first contribution in yorukot/superfile#1033
* @&#8203;shree-xvi made their first contribution in yorukot/superfile#1049
* @&#8203;Simpaqt made their first contribution in yorukot/superfile#1078
* @&#8203;wleoncio made their first contribution in yorukot/superfile#1080
* @&#8203;guemidiborhane made their first contribution in yorukot/superfile#1084
* @&#8203;Manaswa-S made their first contribution in yorukot/superfile#1085
* @&#8203;xelavopelk made their first contribution in yorukot/superfile#1093
* @&#8203;snikoletopoulos made their first contribution in yorukot/superfile#1094
* @&#8203;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=-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.