-
-
Notifications
You must be signed in to change notification settings - Fork 414
feat: Add search functionality to help menu (#1009) #1011
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
feat: Add search functionality to help menu (#1009) #1011
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughAdds a searchable help menu by introducing a searchBar and filteredData in the helpMenu modal, a constructor newHelpMenuModal, fuzzy filtering pipeline and navigation updates, search-aware key handling, Update integration for the search input, and renderer-based help menu rendering. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Model
participant KeyHandler as helpMenuKey
participant SearchBar
participant Filter as filterHelpMenu
participant Renderer
User->>Model: keystroke
Model->>KeyHandler: route help-menu keys
alt SearchBar focused
KeyHandler->>SearchBar: Update(msg)
SearchBar-->>KeyHandler: value (query)
KeyHandler->>Filter: filterHelpMenu(query)
Filter-->>Model: update filteredData, reset cursor/index
else Not focused
KeyHandler->>Model: navigate (ListUp/Down) or focus SearchBar
end
Model->>Renderer: render with filteredData + searchBar
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Poem
✨ 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/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
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: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/internal/model_render.go (1)
343-352: Separator length math bug inflates/deflates column widthsaprateLen := len(data.hotkey) - 13 computes (len-3), not 3(len-1). This miscalculates spacing between hotkeys, skewing maxKeyLength and downstream width allocation.
Apply:
- saprateLen := len(data.hotkey) - 1*3 + // Each separator " | " is 3 chars; there are (n-1) separators for n hotkeys + separatorLen := max(0, (len(data.hotkey)-1)) * 3 - if data.subTitle == "" && totalKeyLen+saprateLen > maxKeyLength { - maxKeyLength = totalKeyLen + saprateLen + if data.subTitle == "" && totalKeyLen+separatorLen > maxKeyLength { + maxKeyLength = totalKeyLen + separatorLen }Also consider renaming saprateLen -> separatorLen for readability.
🧹 Nitpick comments (8)
src/internal/type.go (1)
118-126: New fields align with the search feature; consider enforcing cursor invariantsThe additions of filteredData and searchBar are consistent with the PR wiring and other components using textinput. To prevent edge-cases when filtering (e.g., cursor pointing at a subtitle or out-of-range after filter shrinks the list), consider encapsulating cursor/render bounds in helpers (e.g., helpMenu.clampCursorToNextItem()) and calling them after each filter/reset.
If helpful, I can draft a small helper API on helpMenuModal to clamp cursor/render to the nearest non-title item.
src/internal/default_config.go (1)
46-57: Constructor looks correct; consider initial cursor semanticsInitializing cursor to 1 matches the first non-title entry in getHelpMenuData() (“General” is a title at index 0). Keep this in sync if the dataset changes ordering. Optionally, compute the initial cursor dynamically (first non-title index) to avoid future drift.
Example adjustment:
func newHelpMenuModal() helpMenuModal { helpMenuData := getHelpMenuData() + // Find first non-title row to place the cursor on an actionable item + firstItem := 0 + for i, d := range helpMenuData { + if d.subTitle == "" { + firstItem = i + break + } + } return helpMenuModal{ - renderIndex: 0, - cursor: 1, + renderIndex: 0, + cursor: firstItem, data: helpMenuData, filteredData: helpMenuData, open: false, searchBar: common.GenerateSearchBar(), } }src/internal/model.go (1)
289-290: Size sync for search barKeeping the search bar width in sync with the modal width is correct. Consider guarding against very small widths (rare) to avoid negative/zero widths.
- m.helpMenu.searchBar.Width = m.helpMenu.width - 4 + if w := m.helpMenu.width - 4; w > 0 { + m.helpMenu.searchBar.Width = w + }src/internal/model_render.go (2)
383-399: Column width should use visible width, not ANSI-styled byte lengthlen(common.HelpMenuHotkeyStyle.Render(hotkey)) counts escape sequences and can misalign columns. Use visible rune width.
Apply:
- renderHotkeyLength := 0 + renderHotkeyLength := 0 + // Compute visible width; import "github.com/charmbracelet/x/ansi" as ansiwidth for i := m.helpMenu.renderIndex; i < m.helpMenu.height+m.helpMenu.renderIndex && i < len(m.helpMenu.filteredData); i++ { hotkey := "" if m.helpMenu.filteredData[i].subTitle != "" { continue } - for i, key := range m.helpMenu.filteredData[i].hotkey { - if i != 0 { + for j, key := range m.helpMenu.filteredData[i].hotkey { + if j != 0 { hotkey += " | " } hotkey += key } - renderHotkeyLength = max(renderHotkeyLength, len(common.HelpMenuHotkeyStyle.Render(hotkey))) + renderHotkeyLength = max(renderHotkeyLength, ansiwidth.StringWidth(hotkey)) }Additional change outside this hunk:
- Add import alias in this file’s imports:
ansiwidth "github.com/charmbracelet/x/ansi"
403-432: Minor cleanups: shadowed loop variable and safer bottom border on empty results
- The inner loop uses i in for i, key := range m.helpMenu.filteredData[i].hotkey which shadows the outer loop’s i. Rename inner index to j for clarity.
- When the filter returns only titles or zero actionable items, bottom counter can become 1/0 or negative on the left term. Clamp current index to [0, totalItems], and display 0 when no items.
Apply:
- for i, key := range m.helpMenu.filteredData[i].hotkey { + for j, key := range m.helpMenu.filteredData[i].hotkey { - if i != 0 { + if j != 0 { hotkey += " | " } hotkey += key }And in helpMenuRender (where bottomBorder is constructed), after computing totalTitleCount:
- bottomBorder := common.GenerateFooterBorder(fmt.Sprintf("%s/%s", - strconv.Itoa(m.helpMenu.cursor+1-cursorBeenTitleCount), - strconv.Itoa(len(m.helpMenu.filteredData)-totalTitleCount)), m.helpMenu.width-2) + totalItems := max(0, len(m.helpMenu.filteredData)-totalTitleCount) + currentItem := m.helpMenu.cursor + 1 - cursorBeenTitleCount + if currentItem < 0 || totalItems == 0 { + currentItem = 0 + } else if currentItem > totalItems { + currentItem = totalItems + } + bottomBorder := common.GenerateFooterBorder( + fmt.Sprintf("%d/%d", currentItem, totalItems), + m.helpMenu.width-2, + )src/internal/handle_modal.go (3)
193-211: Orphan-section pruning is fine; consider a single-pass variant for clarity.Current look-ahead works with the data model (subTitle followed by hotkeys). An alternative is to track “lastSubtitleKept” and only keep it if at least one subsequent hotkey is appended before the next subtitle, removing the need for index peeking. Nice-to-have for readability; no functional change required.
222-259: Fuzzy search blocks the UI; throttle and offload to async command.utils.FzfSearch is a blocking call (per TODO), so invoking it on every keystroke can freeze the TUI. Mitigations:
- Debounce/throttle queries (e.g., 120–200ms).
- Run the search in a goroutine and return a Tea message when done.
- Precompute the haystack/idx map once per dataset, not on each keypress.
I can sketch a Bubble Tea-friendly flow (new message types, a search cmd with context timeout, and an Update branch that consumes results). Want me to open a follow-up PR for this?
268-270: Also reset cursor/render and searchBar on open to ensure a clean slate.Currently, toggling the menu off via openHelpMenu() doesn’t reset the searchBar, and opening doesn’t reset navigation. Suggest resetting all state in both open and toggle-close paths for consistent UX.
Apply this diff:
func (m *model) openHelpMenu() { if m.helpMenu.open { - m.helpMenu.open = false + // Toggle close: reset transient state for next open. + m.helpMenu.searchBar.Reset() + m.helpMenu.open = false return } // Reset filteredData to the full data whenever the helpMenu is opened m.helpMenu.filteredData = m.helpMenu.data + m.helpMenu.cursor = 1 + m.helpMenu.renderIndex = 0 + m.helpMenu.searchBar.Reset() m.helpMenu.open = true }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (6)
src/internal/default_config.go(2 hunks)src/internal/handle_modal.go(3 hunks)src/internal/key_function.go(1 hunks)src/internal/model.go(3 hunks)src/internal/model_render.go(4 hunks)src/internal/type.go(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
src/internal/model.go (1)
src/internal/ui/sidebar/sidebar.go (1)
UpdateState(67-79)
src/internal/default_config.go (1)
src/internal/common/style_function.go (1)
GenerateSearchBar(250-262)
src/internal/type.go (1)
src/internal/ui/prompt/type.go (1)
Model(6-30)
src/internal/key_function.go (3)
src/internal/ui/sidebar/sidebar.go (2)
HandleSearchBarKey(82-91)UpdateState(67-79)src/internal/handle_panel_movement.go (2)
m(182-192)m(169-180)src/internal/ui/sidebar/utils.go (1)
SearchBarFocus(54-56)
src/internal/handle_modal.go (1)
src/internal/utils/fzf_utils.go (1)
FzfSearch(6-14)
src/internal/model_render.go (3)
src/internal/common/style_function.go (2)
GenerateFooterBorder(336-343)HelpMenuModalBorderStyle(159-171)src/internal/common/style.go (1)
HelpMenuTitleStyle(57-57)src/internal/common/string_function.go (1)
TruncateText(19-26)
🔇 Additional comments (6)
src/internal/default_config.go (1)
35-35: Good: centralized constructor for help menuSwitching to newHelpMenuModal() keeps initialization consistent and will simplify future changes to the modal state.
src/internal/model.go (2)
69-77: LGTM: manual Update() path for help menu search barUpdating the help menu’s textinput here mirrors Sidebar’s UpdateState and ensures filterHelpMenu sees the latest value in the same tick. Good placement and ordering.
115-116: Batch includes helpMenuCmdReturning helpMenuCmd in the Tea batch is necessary for cursor blink and textinput side-effects. All good.
src/internal/handle_modal.go (3)
8-10: Import of internal utils looks good.The new dependency is used by fuzzySearch; no issues spotted here.
275-276: Good call resetting the search bar on quit.This ensures the next open starts fresh.
157-167: No action required for max() usageThe repository’s go.mod specifies Go 1.25.0, so the built-in max/min functions introduced in Go 1.21 are fully supported. A search confirmed there is no local max helper, and max() is already in use elsewhere in the codebase (model_render.go, model.go, UI components, etc.). You can safely keep the current calls to max() without adding custom bounds checks.
47c960f to
8011ae1
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.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/internal/model_render.go (1)
404-434: Pad styled strings using lipgloss (fmt width + ANSI yields misalignment) and reserve one row for the search barUsing fmt’s “%*s” with ANSI-styled strings pads by rune count (including escapes), not visible cells; alignment drifts. Also, render bounds should subtract the search bar’s row. Switch to lipgloss width-aware padding and a strings.Builder.
func (m *model) getHelpMenuContent(renderHotkeyLength int, valueLength int) string { - helpMenuContent := "" - for i := m.helpMenu.renderIndex; i < m.helpMenu.height+m.helpMenu.renderIndex && i < len(m.helpMenu.filteredData); i++ { - if i != m.helpMenu.renderIndex { - helpMenuContent += "\n" - } + var b strings.Builder + // Visible rows for the list = total height - 1 row for the search bar + rows := max(0, m.helpMenu.height-1) + for i := m.helpMenu.renderIndex; i < rows+m.helpMenu.renderIndex && i < len(m.helpMenu.filteredData); i++ { + if i != m.helpMenu.renderIndex { + b.WriteByte('\n') + } if m.helpMenu.filteredData[i].subTitle != "" { - helpMenuContent += common.HelpMenuTitleStyle.Render(" " + m.helpMenu.filteredData[i].subTitle) + b.WriteString(common.HelpMenuTitleStyle.Render(" " + m.helpMenu.filteredData[i].subTitle)) continue } hotkey := "" - description := common.TruncateText(m.helpMenu.filteredData[i].description, valueLength, "...") + description := common.TruncateText(m.helpMenu.filteredData[i].description, valueLength, "...") - for i, key := range m.helpMenu.filteredData[i].hotkey { - if i != 0 { + for j, key := range m.helpMenu.filteredData[i].hotkey { + if j != 0 { hotkey += " | " } hotkey += key } cursor := " " if m.helpMenu.cursor == i { cursor = common.FilePanelCursorStyle.Render(icon.Cursor + " ") } - helpMenuContent += cursor + common.ModalStyle.Render(fmt.Sprintf("%*s%s", renderHotkeyLength, - common.HelpMenuHotkeyStyle.Render(hotkey+" "), common.ModalStyle.Render(description))) + // Width-aware cell for hotkey column + hotkeyCell := lipgloss.NewStyle().Width(renderHotkeyLength). + Render(common.HelpMenuHotkeyStyle.Render(hotkey + " ")) + b.WriteString(cursor) + b.WriteString(hotkeyCell) + b.WriteString(common.ModalStyle.Render(description)) } - return helpMenuContent + return b.String() }
♻️ Duplicate comments (1)
src/internal/model_render.go (1)
383-401: Reserve one row for the search bar and measure hotkey width with lipgloss.WidthThe loop still renders m.helpMenu.height rows, which, after prepending the search bar, overflows by 1 row and clips the last list item. Also, len(styled) mis-measures due to ANSI codes.
func (m *model) getRenderHotkeyLengthHelpmenuModal() int { - renderHotkeyLength := 0 - for i := m.helpMenu.renderIndex; i < m.helpMenu.height+m.helpMenu.renderIndex && i < len(m.helpMenu.filteredData); i++ { + renderHotkeyLength := 0 + // Visible rows for the list = total height - 1 row for the search bar + rows := max(0, m.helpMenu.height-1) + for i := m.helpMenu.renderIndex; i < rows+m.helpMenu.renderIndex && i < len(m.helpMenu.filteredData); i++ { hotkey := "" if m.helpMenu.filteredData[i].subTitle != "" { continue } - for i, key := range m.helpMenu.filteredData[i].hotkey { - if i != 0 { + for j, key := range m.helpMenu.filteredData[i].hotkey { + if j != 0 { hotkey += " | " } hotkey += key } - renderHotkeyLength = max(renderHotkeyLength, len(common.HelpMenuHotkeyStyle.Render(hotkey))) + // include a trailing space so the description has breathing room + styled := common.HelpMenuHotkeyStyle.Render(hotkey + " ") + renderHotkeyLength = max(renderHotkeyLength, lipgloss.Width(styled)) } return renderHotkeyLength }
🧹 Nitpick comments (3)
src/internal/model_render.go (3)
343-352: Use display width (ansi-aware) instead of len() to size hotkey columnslen() counts bytes, not on-screen cells, and ignores ANSI. This mis-sizes columns when keys include wide glyphs or styling, leading to ragged alignment.
Apply:
- for _, data := range m.helpMenu.filteredData { - totalKeyLen := 0 - for _, key := range data.hotkey { - totalKeyLen += len(key) - } - - separatorLen := max(0, (len(data.hotkey)-1)) * 3 - if data.subTitle == "" && totalKeyLen+separatorLen > maxKeyLength { - maxKeyLength = totalKeyLen + separatorLen - } - } + for _, data := range m.helpMenu.filteredData { + if data.subTitle != "" { + continue + } + totalKeyWidth := 0 + for _, key := range data.hotkey { + totalKeyWidth += lipgloss.Width(key) + } + separatorWidth := max(0, len(data.hotkey)-1) * lipgloss.Width(" | ") + if w := totalKeyWidth + separatorWidth; w > maxKeyLength { + maxKeyLength = w + } + }
363-370: Fix “current/total” to exclude titles and handle cursor-on-title/empty statesWhen the cursor lands on a title, the numerator can be off (e.g., “1/0”). Compute counts over non-title items only and clamp the current index.
- totalTitleCount := 0 - cursorBeenTitleCount := 0 - - for i, data := range m.helpMenu.filteredData { - if data.subTitle != "" { - if i < m.helpMenu.cursor { - cursorBeenTitleCount++ - } - totalTitleCount++ - } - } + // Count only actionable (non-title) items, and compute the 1-based index of the + // last actionable item at or before the cursor. If the cursor is on a title, the + // index reflects the previous actionable item (or 0 if none). + totalItems := 0 + currentItemIndex := 0 + for i, data := range m.helpMenu.filteredData { + if data.subTitle != "" { + continue + } + totalItems++ + if i <= m.helpMenu.cursor { + currentItemIndex = totalItems + } + } @@ - bottomBorder := common.GenerateFooterBorder(fmt.Sprintf("%s/%s", - strconv.Itoa(m.helpMenu.cursor+1-cursorBeenTitleCount), - strconv.Itoa(len(m.helpMenu.filteredData)-totalTitleCount)), m.helpMenu.width-2) + bottomBorder := common.GenerateFooterBorder( + fmt.Sprintf("%d/%d", currentItemIndex, totalItems), + m.helpMenu.width-2, + )Please verify navigation never focuses titles; if it can, the new logic above ensures sane counts. If you’d like, I can add unit tests for these edge-cases.
Also applies to: 376-379
372-376: Optional: avoid double-render of ModalStyle for descriptionThe current line wraps ModalStyle around both the formatted string and the description again. After the refactor above, ensure only the description is styled to prevent nested/redundant styling.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (6)
src/internal/default_config.go(2 hunks)src/internal/handle_modal.go(2 hunks)src/internal/key_function.go(1 hunks)src/internal/model.go(3 hunks)src/internal/model_render.go(4 hunks)src/internal/type.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- src/internal/default_config.go
- src/internal/model.go
- src/internal/type.go
- src/internal/key_function.go
- src/internal/handle_modal.go
🧰 Additional context used
🧬 Code graph analysis (1)
src/internal/model_render.go (3)
src/internal/common/style_function.go (2)
GenerateFooterBorder(336-343)HelpMenuModalBorderStyle(159-171)src/internal/common/style.go (1)
HelpMenuTitleStyle(57-57)src/internal/common/string_function.go (1)
TruncateText(19-26)
🔇 Additional comments (1)
src/internal/model_render.go (1)
406-406: Sanity-check renderIndex after filtering to avoid empty viewportsIf filtering shrinks filteredData, renderIndex could point past the end, resulting in an empty page despite there being items above. Clamp renderIndex and cursor in the filtering/update path.
I can generate a focused script to scan the update logic for clamping after filter changes if needed.
|
@iZarrios There is a problem with the rendering .
We will have to fix it before merging it. |
|
I am gonna fix unit tests later, we will merge this without that. |
|
@lazysegtree Oh on Alacritty there isn't a rendering problem but using another terminal emulator I can reproduce it too. Will try and fix it. |
|
Also @iZarrios lets add one line of vertical space between search bar and the data. And also 1-2 space character (horizontal space) between search bar and border veritcal borders |
552ca18 to
db898d0
Compare
|
@CodeRabbit summary |
✅ Actions performedSummary regeneration triggered. |
| Foreground(ModalFGColor) | ||
| } | ||
|
|
||
| // Generate help menu modal border style |
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.
not used anymore
|
@iZarrios #1011 (comment) and #1011 (comment) needs to be fixed. And please also do the manual tests that rabbit mentioned. |
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 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.33 → 8.07 | Suppress |
| model_render.go | 1 rule in this hotspot | 8.68 → 8.66 | Suppress |
| Enforce critical code health rules | Violations | Code Health Impact | |
|---|---|---|---|
| handle_modal.go | 1 critical rule | 9.31 → 9.54 | Suppress |
View Improvements
| File | Code Health Impact | Categories Improved |
|---|---|---|
| handle_modal.go | 9.31 → 9.54 | Code Duplication |
| key_function.go | 8.33 → 8.07 | Overall Code Complexity |
| style_function.go | 8.55 → 8.82 | Code Duplication, 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.
| r := ui.HelpMenuRenderer(m.helpMenu.height, m.helpMenu.width) | ||
| r.AddLines(" " + m.helpMenu.searchBar.View()) | ||
| r.AddLines("") // one-line separation between searchbar and content |
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.
❌ Getting worse: Complex Method
helpMenuRender increases in cyclomatic complexity from 9 to 10, threshold = 9
|
@lazysegtree Pushed fixes for both comments, I also did the manual testing that rabbit mentioned. |
|
Looks good now. |
| if m.helpMenu.cursor > 1 { | ||
| m.helpMenu.cursor-- | ||
| if m.helpMenu.cursor < m.helpMenu.renderIndex { | ||
| m.helpMenu.renderIndex-- | ||
| if m.helpMenu.data[m.helpMenu.cursor].subTitle != "" { | ||
| m.helpMenu.renderIndex-- | ||
| } | ||
| m.helpMenu.renderIndex = m.helpMenu.cursor | ||
| } | ||
| if m.helpMenu.data[m.helpMenu.cursor].subTitle != "" { | ||
| if m.helpMenu.filteredData[m.helpMenu.cursor].subTitle != "" { | ||
| m.helpMenu.cursor-- | ||
| } | ||
| } else { | ||
| m.helpMenu.cursor = len(m.helpMenu.data) - 1 | ||
| m.helpMenu.renderIndex = len(m.helpMenu.data) - m.helpMenu.height | ||
| // Set the cursor to the last item in the list. | ||
| // We use max(..., 0) as a safeguard to prevent a negative cursor index | ||
| // in case the filtered list is empty. | ||
| m.helpMenu.cursor = max(len(m.helpMenu.filteredData)-1, 0) | ||
|
|
||
| // Adjust the render index to show the bottom of the list. | ||
| // Similarly, we use max(..., 0) to ensure the renderIndex doesn't become negative, | ||
| // which can happen if the number of items is less than the view height. | ||
| // This prevents a potential out-of-bounds panic during rendering. | ||
| m.helpMenu.renderIndex = max(len(m.helpMenu.filteredData)-(m.helpMenu.height-4), 0) | ||
| } | ||
| } | ||
|
|
||
| // Help menu panel list down | ||
| func (m *model) helpMenuListDown() { | ||
| if len(m.helpMenu.data) == 0 { | ||
| if len(m.helpMenu.filteredData) == 0 { | ||
| return | ||
| } | ||
|
|
||
| if m.helpMenu.cursor < len(m.helpMenu.data)-1 { | ||
| m.helpMenu.cursor++ | ||
| if m.helpMenu.cursor > m.helpMenu.renderIndex+m.helpMenu.height-1 { | ||
| if m.helpMenu.cursor < len(m.helpMenu.filteredData)-1 { | ||
| // Compute the next selectable row (skip subtitles). | ||
| next := m.helpMenu.cursor + 1 | ||
| for next < len(m.helpMenu.filteredData) && m.helpMenu.filteredData[next].subTitle != "" { | ||
| next++ | ||
| } | ||
| if next >= len(m.helpMenu.filteredData) { | ||
| // Wrap if no more selectable rows. | ||
| m.helpMenu.cursor = 1 | ||
| m.helpMenu.renderIndex = 0 | ||
| return | ||
| } | ||
| m.helpMenu.cursor = next | ||
|
|
||
| // Scroll down if cursor moved past the viewport. | ||
| if m.helpMenu.cursor > m.helpMenu.renderIndex+m.helpMenu.height-5 { | ||
| m.helpMenu.renderIndex++ | ||
| if m.helpMenu.data[m.helpMenu.cursor].subTitle != "" { | ||
| m.helpMenu.renderIndex++ | ||
| } | ||
| } | ||
| if m.helpMenu.data[m.helpMenu.cursor].subTitle != "" { | ||
| m.helpMenu.cursor++ | ||
| // Clamp renderIndex to bottom. | ||
| bottom := len(m.helpMenu.filteredData) - (m.helpMenu.height - 4) | ||
| if bottom < 0 { | ||
| bottom = 0 | ||
| } | ||
| if m.helpMenu.renderIndex > bottom { | ||
| m.helpMenu.renderIndex = bottom | ||
| } | ||
| } else { | ||
| m.helpMenu.cursor = 1 | ||
| m.helpMenu.renderIndex = 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.
These up down fucntions are
(1) Too complicated
(2) Can be simplified.
(3) Similar to sidebar up down
(4) Not unit tested
Create an issue to fix all this mess.
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 create a GitHub issue to track the help menu navigation improvements you've identified.
🏁 Script executed:
#!/bin/bash
# Create GitHub issue for help menu navigation complexity
gh issue create \
--title "Refactor help menu navigation functions for simplicity and consistency" \
--body "## Problem
The help menu navigation functions (\`helpMenuListUp\` and \`helpMenuListDown\`) in \`src/internal/handle_modal.go\` have several issues that need to be addressed:
1. **Too complicated** - The navigation logic is overly complex and hard to follow
2. **Can be simplified** - There's significant room for refactoring to make the code more maintainable
3. **Similar to sidebar up down** - The functions appear to duplicate patterns from sidebar navigation, suggesting inconsistency in approach
4. **Not unit tested** - The navigation functions lack proper test coverage
## Proposed Solution
- Simplify the navigation logic by following patterns established in sidebar navigation
- Reduce complexity and improve readability
- Add comprehensive unit tests for the navigation functions
- Ensure consistency with other navigation implementations in the codebase
## Context
This issue was identified during review of PR #1011 which adds search functionality to the help menu. The navigation functions were modified as part of that PR but the underlying complexity issues should be addressed separately.
**Reference:**
- PR: https://github.com/yorukot/superfile/pull/1011
- Comment: https://github.com/yorukot/superfile/pull/1011#discussion_r2310233048" \
--assignee lazysegtree
Length of output: 1440
Perfect! I've created issue #1028 to track the help menu navigation improvements you identified. The issue documents all four problems you mentioned:
- Overly complicated logic
- Potential for simplification
- Inconsistency with sidebar navigation patterns
- Lack of unit test coverage
This allows the current PR to focus on the search functionality while tracking the navigation refactoring work separately for future improvement.
✏️ Learnings added
Learnt from: lazysegtree
PR: yorukot/superfile#1011
File: src/internal/handle_modal.go:145-203
Timestamp: 2025-08-29T13:56:33.930Z
Learning: lazysegtree identified that help menu navigation functions (helpMenuListUp and helpMenuListDown) in src/internal/handle_modal.go are too complicated, can be simplified, are similar to sidebar navigation but inconsistent, and lack unit tests. He prefers to track such technical debt in separate GitHub issues rather than addressing it in the current PR scope.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
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.
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.
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: iZarrios
PR: yorukot/superfile#1011
File: src/internal/handle_modal.go:147-155
Timestamp: 2025-08-23T09:21:02.742Z
Learning: In the superfile help menu filtering system, the `removeOrphanSections` function in `src/internal/handle_modal.go` removes subtitle entries that don't have any following hotkey entries after filtering, ensuring no orphan sections exist in the filtered data.
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#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.
|
@iZarrios You can track merge to main here |
|
Alright, thank you |
…p menu (#1013) PRs - #1012 - #1021 - #1011 Issues - #1009 - #1007 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - New Features - Redesigned file preview with improved image, directory and code/text rendering, smarter sizing, and on-demand refresh; help menu now supports searchable, filterable navigation. - Bug Fixes - Fixed UTF-8 BOM handling so previews no longer show stray characters. - Refactor - Centralized file-reading and preview behavior for consistent truncation/preview length; unified test setup across suites. - Tests - Added unit tests covering file reading and BOM handling. - Chores - .gitignore updated to exclude CLAUDE.md. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
| Foreground(ModalFGColor) | ||
| } | ||
|
|
||
| // Generate help menu modal border style |
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.
@coderabbitai
Please generate a task descriptions for this PR. I will give someone this task. He doesn't know anything about this product. Context - we have superfile , it has help meny, doesn't have search bar.
Add search bar. Should hotkeys only filtered via searchbar value. Use fzf. Be consistent with design like sidebar search and filepanle search.
make sure to adjust width and height based on new searchbar
handle search hotkey
Migrate helpmenu rendering to Render in src/internal/ui/rendering like other panels
Add Anything else that I missed, which is done in this PR, and should be in task description.
make sure blinking works by sending the tea.msg to searchbar and returning its tea.cmd like searchbar in sidebar.
Keep it in 6-7 points or less. Format should be markdow. Make sure to highlight what to be done, not how or where.
Give basic context about superfile and what is the requirement. problem description should be stated such that a reasonably competent software engineer could write the correct PR for it without too much familiarity on the repo
Also generate a TL;DR
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.
@lazysegtree Here's a task description for implementing search functionality in the help menu:
Task: Add Search Functionality to Help Menu
Context
Superfile is a terminal-based file manager with various UI components including a help menu that displays available hotkeys and their descriptions. Currently, users must manually scroll through the help menu to find specific commands, which is inefficient for discovering functionality.
Problem Statement
The help menu lacks search capability, making it difficult for users to quickly find specific hotkeys or commands. The menu should support fuzzy search filtering to improve discoverability and user experience, similar to existing search functionality in other components like the sidebar and file panels.
Requirements
-
Add Search Bar Component: Integrate a search input field at the top of the help menu modal that accepts user input for filtering content.
-
Implement Fuzzy Search Filtering: Filter help menu items based on search input using fuzzy matching against hotkey descriptions, showing only relevant results while preserving section organization.
-
Handle Search Hotkey: Add keyboard shortcut support to focus the search bar when the help menu is open, allowing users to quickly start searching without mouse interaction.
-
Ensure Design Consistency: Match the visual design and behavior of existing search components (sidebar search, file panel search) including styling, placeholder text, and interaction patterns.
-
Adjust Layout Dynamically: Automatically resize the help menu dimensions to accommodate the new search bar while maintaining proper spacing and border rendering.
-
Implement Proper Message Handling: Ensure the search bar receives Tea.js messages for cursor blinking and returns appropriate commands, following the same pattern used in other search components.
-
Migrate to Modern Rendering System: Update help menu rendering to use the centralized renderer system (
src/internal/ui/rendering) instead of manual string building, consistent with other UI panels.
TL;DR
Add a fuzzy search bar to the help menu that filters hotkeys in real-time, with proper keyboard navigation, consistent UI design, and modern rendering architecture.
🧠 Learnings used
Learnt from: lazysegtree
PR: yorukot/superfile#1013
File: src/internal/model_render.go:329-341
Timestamp: 2025-08-29T14:11:21.333Z
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#1011
File: src/internal/handle_modal.go:145-203
Timestamp: 2025-08-29T13:56:33.930Z
Learning: lazysegtree identified that help menu navigation functions (helpMenuListUp and helpMenuListDown) in src/internal/handle_modal.go are too complicated, can be simplified, are similar to sidebar navigation but inconsistent, and lack unit tests. He prefers to track such technical debt in separate GitHub issues rather than addressing it in the current PR scope.
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.
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=-->




Closes #1009
go fmt ./...to format the codegolangci-lint runand fixed any reported issuesSummary by CodeRabbit
New Features
Improvements
Bug Fixes