feat: add goto interactive modal for quick navigation#1347
feat: add goto interactive modal for quick navigation#1347robert-zaremba wants to merge 3 commits intoyorukot:mainfrom
Conversation
Add a new "Goto Interactive" modal that allows users to quickly navigate to files and directories with fuzzy search and autocomplete. Features: - Fuzzy search filtering for files and directories in current directory - Tab autocomplete to navigate into directories or autocomplete filenames - Support for ".." to navigate to parent directory - Keyboard navigation with up/down arrows and page up/down - Looping navigation through results - Shows ".." in the results list when parent directory exists - Pressing Enter on a file opens it, on a directory navigates into it - Wider modal window (240 chars initial, 80 chars minimum) for better visibility - Title changed to "Goto:" with truncated path display (suffix instead of prefix) - Hotkey binding: press 'g' to open the modal Implementation: - New package: src/internal/ui/gotointeractive/ - Added to main model with proper integration - Config hotkey: open_goto_interactive = ['g', ''] - Comprehensive test coverage Signed-off-by: Robert Zaremba <robert@zaremba.ch>
📝 WalkthroughWalkthroughAdds an interactive "goto" modal component and integrates it into the main model, exposes a new hotkey binding to open it, and introduces the gotointeractive package (types, model, utils, render, tests) plus wiring in core model, key handling, defaults, and hotkey configs. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Input as "Input Handler"
participant Main as "Main Model"
participant Goto as "GotoModal"
participant FS as "FileSystem"
User->>Input: press hotkey (g)
Input->>Main: dispatch OpenGotoInteractive
Main->>Goto: SetCurrentPath(current panel) + Open()
Goto->>Goto: GetQueryCmd() (initial query)
User->>Input: type query
Input->>Goto: HandleUpdate(KeyMsg)
Goto->>FS: ReadDir/Stat(currentPath)
FS-->>Goto: entries
Goto->>Goto: filterResults + updateResults
Goto-->>Main: send UpdateMsg(results)
Main->>Goto: Apply(UpdateMsg)
User->>Input: navigate / confirm
Input->>Goto: HandleUpdate(KeyMsg)
Goto->>Main: return ModelAction (open/cd)
Main->>Main: applyGotoModalAction()
Main->>Goto: Close()
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@src/internal/ui/gotointeractive/model.go`:
- Around line 186-196: GetQueryCmd currently captures the receiver m and calls
m.filterResults(query) later, which can produce results that are filtered
against a changed m.currentPath; to fix, capture the current path at command
creation (e.g., path := m.currentPath) and either call a refactored
filterResults(query, path) or pass the captured path into NewUpdateMsg so Apply
can verify both query and path staleness; update filterResults to accept a path
parameter (or make it a standalone function) and add path validation in Apply
(compare msg.path to m.currentPath) to drop stale results.
In `@src/internal/ui/gotointeractive/utils.go`:
- Line 50: Update the slog.Warn call that currently logs "Goto initialized with
too less maxHeight" (in src/internal/ui/gotointeractive/utils.go) to use correct
grammar by replacing the message with "Goto initialized with insufficient
maxHeight"; locate the slog.Warn invocation (search for slog.Warn("Goto
initialized with too less maxHeight", "maxHeight", maxHeight)) and change only
the human-readable message text, leaving the "maxHeight" key and maxHeight
variable intact.
- Around line 41-42: The warning message string passed to slog.Warn in the Goto
initialization should be corrected for grammar: update the call in the block
that sets width to GotoMinWidth (the slog.Warn invocation referencing "width"
and variable width) to use a clearer phrase such as "insufficient width" or "too
little width" instead of "too less width" while keeping the same structured
field ("width", width).
🧹 Nitpick comments (3)
src/internal/ui/gotointeractive/render.go (2)
43-55: Consider caching directory status to avoid repeatedos.Statcalls during render.The
os.Statcall insiderenderVisibleResultsexecutes for each visible item on every render frame. With 15 visible results, this means 15 syscalls per render, which could cause UI lag especially on slow filesystems or network mounts.Consider determining
isDirstatus when results are filtered (infilterResults) and storing it alongside the result strings, or caching the stat results.💡 Suggested approach
Store results as a struct with name and isDir fields instead of just strings:
type resultItem struct { name string isDir bool }Then populate
isDironce infilterResultsusingentry.IsDir()from theos.DirEntrywhich is already available there without additional syscalls.
16-20: Minor: ANSI-aware width calculation for title truncation.
len(m.headline)returns byte length, but the headline contains icon characters (nerd font glyphs) which may have different display widths. Consider usingansi.StringWidth(m.headline)for accurate width calculation, consistent with howTruncateTextBeginninghandles ANSI width internally.💡 Proposed fix
- availableWidth := m.width - len(m.headline) - 3 //nolint:mnd // Space for " - " separator + availableWidth := m.width - ansi.StringWidth(m.headline) - 3 //nolint:mnd // Space for " - " separatorYou'll need to import
"github.com/charmbracelet/x/ansi".src/internal/ui/gotointeractive/model.go (1)
215-260: Consider refactoringfilterResultsto reduce code duplication.The function has two similar code paths: one when a parent directory exists (lines 217-244) and one when at root (lines 246-259). Both perform the same directory reading and filtering logic, just with different handling of the ".." entry.
♻️ Proposed simplification
func (m *Model) filterResults(query string) []string { parentDir := filepath.Dir(m.currentPath) - if parentDir != m.currentPath { - hasParent := true - if query != "" { - queryLower := strings.ToLower(query) - hasParent = strings.Contains(strings.ToLower(".."), queryLower) - } - - entries, err := os.ReadDir(m.currentPath) - if err != nil { - if hasParent { - return []string{".."} - } - return []string{} - } - - results := make([]string, 0, len(entries)+1) - if hasParent { - results = append(results, "..") - } - - for _, entry := range entries { - name := entry.Name() - if query == "" || strings.Contains(strings.ToLower(name), strings.ToLower(query)) { - results = append(results, name) - } - } - return results - } - + hasParent := parentDir != m.currentPath + queryLower := strings.ToLower(query) + entries, err := os.ReadDir(m.currentPath) if err != nil { + if hasParent && (query == "" || strings.Contains("..", queryLower)) { + return []string{".."} + } return []string{} } - queryLower := strings.ToLower(query) - results := make([]string, 0, len(entries)) + results := make([]string, 0, len(entries)+1) + if hasParent && (query == "" || strings.Contains("..", queryLower)) { + results = append(results, "..") + } + for _, entry := range entries { name := entry.Name() - if strings.Contains(strings.ToLower(name), queryLower) { + if query == "" || strings.Contains(strings.ToLower(name), queryLower) { results = append(results, name) } } return results }
There was a problem hiding this comment.
Pull request overview
Adds a new “Goto” interactive modal (opened via the g hotkey) to quickly navigate/open items in the current panel using a searchable, keyboard-navigable result list.
Changes:
- Adds
open_goto_interactivehotkey to the default and vim-like hotkey TOML configs and wires it into the hotkeys struct. - Introduces a new
gotointeractiveUI package (model, rendering, navigation/filtering logic, basic tests). - Integrates the modal into the main application model (state, sizing, update loop, overlay rendering, and key dispatch).
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/superfile_config/vimHotkeys.toml | Adds default vim-like binding for open_goto_interactive. |
| src/superfile_config/hotkeys.toml | Adds default binding for open_goto_interactive. |
| src/internal/ui/gotointeractive/consts.go | Adds modal sizing and rendering constants + prompt helper. |
| src/internal/ui/gotointeractive/type.go | Defines Model and async UpdateMsg type for goto queries. |
| src/internal/ui/gotointeractive/utils.go | Adds open/close/state + dimension/result accessors. |
| src/internal/ui/gotointeractive/model.go | Implements input handling, filtering, navigation, and async query command plumbing. |
| src/internal/ui/gotointeractive/render.go | Implements modal rendering of input + results list with scroll indicators. |
| src/internal/ui/gotointeractive/model_test.go | Adds initial unit tests for construction/open/close/dimensions/update msg. |
| src/internal/type.go | Adds gotoModal field to the main model struct and imports the package. |
| src/internal/model.go | Routes goto UpdateMsg, sizes the modal, handles modal updates, and renders it as an overlay. |
| src/internal/key_function.go | Adds g hotkey handling to open the goto modal. |
| src/internal/handle_panel_movement.go | Adds gotoModalOpen() helper to set path from focused panel and open modal. |
| src/internal/default_config.go | Initializes the goto modal in the default model config. |
| src/internal/common/config_type.go | Adds OpenGotoInteractive to the hotkeys config struct for TOML parsing. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/internal/ui/gotointeractive/render.go`:
- Around line 15-22: The availableWidth calculation uses m.width (total modal
width) but ignores left/right border chars; update the logic in render.go so
availableWidth is computed from the content width (either subtract 2 for
borders: availableWidth := m.width - 2 - headlineWidth - separatorWidth, or read
the content width provided by PromptRenderer when BorderRequired = true), and
then use that adjusted availableWidth before calling
common.TruncateTextBeginning on titlePath; update any related variables (m.width
usage in this block) to reference the content width instead of the total width.
🧹 Nitpick comments (3)
src/internal/ui/gotointeractive/utils.go (1)
66-69: Consider whetherupdateResults()should return atea.Cmdfor consistency.
SetCurrentPathcallsupdateResults()synchronously, which performs file I/O. While this may be acceptable for the current use case, other path-changing operations likehandleGoUp()in model.go also callupdateResults()synchronously. If directory reads become slow (network mounts, large directories), this could block the UI.For now this is fine given the interactive modal context, but worth noting for future async refactoring if performance issues arise.
src/internal/ui/gotointeractive/model.go (1)
280-285: Minor: RedundantToLoweron constant string "..".The string
".."contains no alphabetic characters, sostrings.ToLower("..")is always"..".📝 Proposed simplification
if hasParent { queryLower := strings.ToLower(query) - if strings.Contains(strings.ToLower(".."), queryLower) { + if strings.Contains("..", queryLower) { results = append(results, Result{Name: "..", IsDir: true}) } }src/internal/ui/gotointeractive/render.go (1)
69-84: Consider showing both scroll indicators simultaneously when applicable.Currently, if
m.renderIndex > 0(more results above), a section is added before the "above" indicator. Then if there are also more results below, no new section is added (line 79-81 check). However, both indicators could be shown together when the user is in the middle of the list.The current logic appears correct for this case, but verify that both indicators display when scrolled to the middle of a long list.
#!/bin/bash # Check if there are tests covering scroll indicator behavior rg -n "renderScrollIndicators|More results" src/internal/ui/gotointeractive/
| separator := " " | ||
| headlineWidth := lipgloss.Width(m.headline) | ||
| separatorWidth := lipgloss.Width(separator) | ||
| availableWidth := m.width - headlineWidth - separatorWidth | ||
| titlePath := m.currentPath | ||
| if lipgloss.Width(titlePath) > availableWidth { | ||
| titlePath = common.TruncateTextBeginning(titlePath, availableWidth, "...") | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, find the PromptRenderer struct definition and understand m.width
fd render.go src/internal/ui/gotointeractive/Repository: yorukot/superfile
Length of output: 102
🏁 Script executed:
# Search for PromptRenderer struct definition and width field
rg -n "type PromptRenderer\|m.width\|type.*Renderer" src/internal/ui/gotointeractive/ -A 5 -B 2Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Check how the render function sets m.width and if borders are added
cat -n src/internal/ui/gotointeractive/render.goRepository: yorukot/superfile
Length of output: 2762
🏁 Script executed:
# Look for border rendering in the PromptRenderer
rg -n "border\|Border\|lipgloss" src/internal/ui/gotointeractive/render.go -A 2 -B 2Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Find PromptRenderer function definition
rg -n "func PromptRenderer" src/internal/ui/ -A 5Repository: yorukot/superfile
Length of output: 528
🏁 Script executed:
# Find Model struct definition in gotointeractive
rg -n "type Model struct" src/internal/ui/gotointeractive/ -A 10Repository: yorukot/superfile
Length of output: 729
🏁 Script executed:
# Look at rendering.Renderer struct and SetBorderTitle
rg -n "SetBorderTitle\|type Renderer" src/internal/ui/rendering/ -A 5Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Check how Model.width is initialized
rg -n "m.width\s*=" src/internal/ui/gotointeractive/ -B 3 -A 1Repository: yorukot/superfile
Length of output: 439
🏁 Script executed:
# Look at DefaultRendererConfig to understand how width is handled with borders
rg -n "DefaultRendererConfig\|func.*RendererConfig" src/internal/ui/rendering/ -A 10Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Check the rendering.Renderer implementation for border handling
rg -n "type Renderer struct" src/internal/ui/rendering/ -A 20Repository: yorukot/superfile
Length of output: 1683
🏁 Script executed:
# Look at SetBorderTitle and Render methods
rg -n "func.*SetBorderTitle\|func.*Render\(\)" src/internal/ui/rendering/ -A 8 | head -50Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Look at full context around m.width initialization in utils.go
sed -n '35,55p' src/internal/ui/gotointeractive/utils.goRepository: yorukot/superfile
Length of output: 565
🏁 Script executed:
# Check what GotoMinWidth and modalInputPadding are
rg -n "GotoMinWidth\|modalInputPadding" src/internal/ui/gotointeractive/Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Search for constants in gotointeractive package
rg -n "GotoMinWidth\|modalInputPadding\|const" src/internal/ui/gotointeractive/ -B 1 -A 1 | head -40Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Look at the complete rendering.Renderer initialization and border handling
cat -n src/internal/ui/rendering/renderer.go | head -80Repository: yorukot/superfile
Length of output: 3222
🏁 Script executed:
# Search for how border width affects content width in Renderer
rg -n "contentWidth\|GetBorder\|borderWidth" src/internal/ui/rendering/ -A 3Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Check the Render function of Renderer to see how borders are applied
rg -n "func.*\(r \*Renderer\).*Render" src/internal/ui/rendering/renderer.go -A 20Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Search for DefaultRendererConfig function
rg -n "func DefaultRendererConfig" src/internal/ui/rendering/ -A 20Repository: yorukot/superfile
Length of output: 1608
🏁 Script executed:
# Look for where contentWidth is calculated from totalWidth
rg -n "contentWidth\s*=" src/internal/ui/rendering/ -B 2 -A 2Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Check the BorderConfig.GetBorder method mentioned in the learnings
rg -n "GetBorder\|contentWidth" src/internal/ui/rendering/border.go -B 3 -A 5Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Look at how the Renderer.Render() method applies borders
rg -n "func \(r \*Renderer\) Render" src/internal/ui/rendering/renderer.go -A 30Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Look at the full border.go file to understand border width handling
cat -n src/internal/ui/rendering/border.goRepository: yorukot/superfile
Length of output: 5481
🏁 Script executed:
# Look at NewRenderer function to see how contentWidth is set
sed -n '108,200p' src/internal/ui/rendering/renderer.goRepository: yorukot/superfile
Length of output: 1516
🏁 Script executed:
# Search for any place where contentWidth or border width subtraction happens
rg -n "contentWidth|totalWidth.*2|totalWidth.*border" src/internal/ui/rendering/Repository: yorukot/superfile
Length of output: 1462
🏁 Script executed:
# Check if SetBorderTitle enables borders
rg -n "func.*SetBorderTitle\|SetBorderTitle" src/internal/ui/rendering/ -A 10Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Look at the spf_renderers.go to see if borders are explicitly set in PromptRenderer
cat -n src/internal/ui/spf_renderers.go | sed -n '84,110p'Repository: yorukot/superfile
Length of output: 1160
🏁 Script executed:
# Check if borders are applied elsewhere in the code
rg -n "BorderRequired.*true\|SetBorder\|Border.*true" src/internal/ui/gotointeractive/Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Check the constants for border width
rg -n "borderCornerWidth\|borderDividerWidth\|borderPaddingWidth\|minTitleWidth" src/internal/ui/rendering/ | head -20Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Search for constants definition
rg -n "const.*borderCornerWidth|const.*borderDividerWidth" src/internal/ui/rendering/Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Check if m.width is ever adjusted for borders in gotointeractive
rg -n "m.width\|SetWidth" src/internal/ui/gotointeractive/ -B 2 -A 2Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Look at the constants file to understand the dimensions
cat -n src/internal/ui/rendering/consts.goRepository: yorukot/superfile
Length of output: 128
🏁 Script executed:
# Find where the border constants are defined
rg -n "borderCornerWidth\|borderDividerWidth" src/ -B 2 -A 1Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# List all files in rendering directory
fd . src/internal/ui/rendering/ -type fRepository: yorukot/superfile
Length of output: 231
🏁 Script executed:
# Look at render_core.go which was mentioned in the search results
cat -n src/internal/ui/rendering/renderer_core.goRepository: yorukot/superfile
Length of output: 5453
🏁 Script executed:
# Look for how m.width is set and documented
rg -n "width.*int\|SetWidth" src/internal/ui/gotointeractive/ -B 2 -A 2 | head -40Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Check the complete render.go to see all width calculations
cat -n src/internal/ui/gotointeractive/render.go | grep -E "width|Width" -nRepository: yorukot/superfile
Length of output: 674
🏁 Script executed:
# Look at lines 45-55 to see the other width calculation in renderVisibleResults
sed -n '45,70p' src/internal/ui/gotointeractive/render.goRepository: yorukot/superfile
Length of output: 794
🏁 Script executed:
# Verify if contentWidth is exposed or used anywhere in gotointeractive
rg -n "contentWidth\|GetContentWidth\|GetWidth" src/internal/ui/gotointeractive/Repository: yorukot/superfile
Length of output: 43
🏁 Script executed:
# Search for constant definitions in border.go
head -100 src/internal/ui/rendering/border.go | tail -50Repository: yorukot/superfile
Length of output: 1863
🏁 Script executed:
# Look for constant definitions
rg -n "const|borderCornerWidth|borderDividerWidth|borderPaddingWidth" src/internal/ui/rendering/border.goRepository: yorukot/superfile
Length of output: 503
🏁 Script executed:
# Check if there are any constants in other files that might define border widths
rg -n "^const" src/internal/ui/rendering/Repository: yorukot/superfile
Length of output: 212
🏁 Script executed:
# Look at end of border.go for constant definitions
tail -50 src/internal/ui/rendering/border.goRepository: yorukot/superfile
Length of output: 1643
🏁 Script executed:
# Look at the constants.go file
cat -n src/internal/ui/rendering/constants.goRepository: yorukot/superfile
Length of output: 849
Account for border width when calculating available width for title path.
The availableWidth calculation on line 18 uses m.width directly, but m.width is the total modal width including the left and right border characters (2 characters total). Since PromptRenderer sets BorderRequired = true, the actual content width available for the title is m.width - 2. The calculation should be:
availableWidth := m.width - 2 - headlineWidth - separatorWidth
Alternatively, have PromptRenderer return the content width separately so it can be used for width calculations in the modal, similar to how the sidebar component (from retrieved learnings) distinguishes between SidebarWidth (content) and total width (including borders).
🤖 Prompt for AI Agents
In `@src/internal/ui/gotointeractive/render.go` around lines 15 - 22, The
availableWidth calculation uses m.width (total modal width) but ignores
left/right border chars; update the logic in render.go so availableWidth is
computed from the content width (either subtract 2 for borders: availableWidth
:= m.width - 2 - headlineWidth - separatorWidth, or read the content width
provided by PromptRenderer when BorderRequired = true), and then use that
adjusted availableWidth before calling common.TruncateTextBeginning on
titlePath; update any related variables (m.width usage in this block) to
reference the content width instead of the total width.
There was a problem hiding this comment.
I can solve the problem above if there is a consensus to merge this feature
There was a problem hiding this comment.
@robert-zaremba, thank you for your willingness to address this issue!
The border width calculation fix is indeed important for correct text truncation in the modal title. Since the PromptRenderer sets BorderRequired = true, the 2-character border width (left + right) should be subtracted from m.width when calculating availableWidth. Without this, the title path could be truncated prematurely or overflow.
I'd recommend proceeding with the fix now—it's a straightforward adjustment that will make the feature render correctly:
availableWidth := m.width - 2 - headlineWidth - separatorWidthThis will ensure your goto modal is merge-ready and displays the title path with accurate truncation. The feature looks solid overall, and addressing this rendering detail will polish it nicely.
🧠 Learnings used
Learnt from: lazysegtree
Repo: yorukot/superfile PR: 781
File: src/internal/ui/rendering/border.go:104-114
Timestamp: 2025-04-28T04:02:28.747Z
Learning: The BorderConfig.GetBorder method in src/internal/ui/rendering/border.go already protects against negative availWidth values through the condition `actualWidth >= cnt*4` which ensures that availWidth is at least 1.
Learnt from: lazysegtree
Repo: yorukot/superfile PR: 1227
File: src/internal/common/config_type.go:94-94
Timestamp: 2025-12-25T04:09:23.241Z
Learning: In the superfile sidebar component (src/internal/ui/sidebar/), the SidebarWidth configuration value represents the sidebar content width excluding borders, while the minWidth = 7 constant in consts.go represents the minimum total width including borders. The actual sidebar width is computed as SidebarWidth + BorderPadding in sidebar.go's New() function.
Learnt from: lazysegtree
Repo: yorukot/superfile PR: 1044
File: src/internal/ui/rendering/truncate.go:6-6
Timestamp: 2025-09-09T14:23:14.164Z
Learning: The truncate test failure in src/internal/ui/rendering/truncate_test.go during the ANSI package migration from experimental to stable was caused by a truncation bug in the experimental package. The experimental package incorrectly truncated strings even when input length equaled maxWidth (e.g., "1234" with maxWidth=4 became "1..."), while the stable package correctly only truncates when input exceeds maxWidth. The test expectation was based on the buggy behavior and needs to be corrected.
Learnt from: lazysegtree
Repo: yorukot/superfile PR: 825
File: src/internal/ui/rendering/renderer_core.go:95-108
Timestamp: 2025-05-22T04:42:07.369Z
Learning: In src/internal/ui/rendering/renderer_core.go, when truncating rendered output that exceeds the maximum height, we should drop all remaining lines after reaching totalHeight without adding an ellipsis or other truncation indicator, as the goal is to have exactly totalHeight lines.
Learnt from: lazysegtree
Repo: yorukot/superfile PR: 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.
Learnt from: lazysegtree
Repo: yorukot/superfile PR: 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
Repo: yorukot/superfile PR: 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
Repo: yorukot/superfile PR: 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.
|
Hey @robert-zaremba, first of all, sorry for the late review, and thanks for your effort on this PR! I have a quick question: what is the difference between the go-to panel and the search functionality? Also, what are the intended use cases for the goto panel? |
Summary
Adds a new modal accessible via the 'g' hotkey that provides:
Usage
gto open the Goto modalKey Features
Navigation
Visual
Hotkey
gto open the modalEscorCtrl+Cto closeEnterto confirm selectionSummary by CodeRabbit