refactor(picker_ui): split monolithic picker_ui.lua into focused submodules#564
Open
thuan1412 wants to merge 2 commits into
Open
refactor(picker_ui): split monolithic picker_ui.lua into focused submodules#564thuan1412 wants to merge 2 commits into
thuan1412 wants to merge 2 commits into
Conversation
…odules Break the ~2535-line picker_ui.lua into 8 modules under lua/fff/picker_ui/: - state_manager.lua: pure data store for all picker state - ui_creator.lua: buffers, windows, keymaps, autocmds - search_manager.lua: search execution, pagination, query history - renderer.lua: list rendering, combo separator, scrollbar, empty state - preview_manager.lua: preview debounce, title, update/clear - navigation.lua: cursor movement, pagination wrap, preview scrolling - layout_manager.lua: relayout on VimResized, close/cleanup - init.lua: coordinator wiring all submodules via init(P) pattern Move picker_ui.lua to picker_ui/init.lua for clean module resolution. Also removes unused scrollbar import in ui_creator.lua and need-check-nil diagnostic suppression comments in preview_manager.lua (nil was already handled by the guard check).
a8eccf3 to
9a89cad
Compare
Contributor
Author
|
CI has passed. Should we YOLO and merge it @dmtrKovalenko ? 😆 Otherwise, the PR will get conflict when change is made to to picker_ui.lua |
Owner
|
let's do a few changes to it if you don't mind, I can do them myself:
I don't think the files can be called managers - if you wish to call them like this you should restructure them to actually keep the state inside. I would say that all the functions from the layout_manager and preview_manager should be splitted between the preview.lua/layout.lua and state_manager.lua
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Break the ~2535-line picker_ui.lua into 8 modules under lua/fff/picker_ui/:
Move picker_ui.lua to picker_ui/init.lua for clean module resolution.
Also removes unused scrollbar import in ui_creator.lua and need-check-nil diagnostic suppression comments in preview_manager.lua (nil was already handled by the guard check).
Resolve: #560
Screen.Recording.2026-06-03.at.20.40.14.mov
The code is AI generated. Below are plan generated by AI
Click to expand
Picker UI Refactoring Plan
Overview
Split the 2535-line
picker_ui.luainto 8 smaller, focused modules under apicker_ui/directory, following the existing pattern used bylua/fff/file_picker/.Current State
lua/fff/picker_ui.lualua/fff/picker_ui/Refactoring Strategy
All extracted modules live under
lua/fff/picker_ui/and are required viarequire('fff.picker_ui.<module>'). The top-levelpicker_ui.luaremains the public entry point — it coordinates the submodules and preserves the existing public API.Module Directory Layout
Phase 1: State Management Module
File:
lua/fff/picker_ui/state_manager.luaLines to extract: 41-100, 1946-2200 (selection functions, close reset logic)
Content:
toggle_select,send_to_quickfix)reset_state,reset_history_state)clear_selections,get_selected_items)Public API:
M.reset_state()- Complete state resetM.clear_selections()- Clear all selectionsM.toggle_selection()- Toggle item selectionM.send_to_quickfix()- Send selections to quickfixM.get_selected_items()- Get selected itemsPhase 2: UI Creation Module
File:
lua/fff/picker_ui/ui_creator.luaLines to extract: 140-380, 570-650 (focus functions)
Content:
create_ui)setup_buffers)setup_windows)setup_keymaps)Public API:
M.create_ui()- Main UI creationM.setup_buffers()- Buffer configurationM.setup_windows()- Window configurationM.setup_keymaps()- Keybinding setupM.focus_list_win()- Focus list windowM.focus_preview_win()- Focus preview windowPhase 3: Search and Results Module
File:
lua/fff/picker_ui/search_manager.luaLines to extract: 650-950, 1700-1850 (search and pagination logic)
Content:
update_results,update_results_sync)load_page_at_index,load_next_page)Public API:
M.perform_search()- Execute searchM.load_page_at_index()- Load specific pageM.load_next_page()- Load next pageM.load_previous_page()- Load previous pageM.get_current_results()- Get current resultsPhase 4: Rendering System Module
File:
lua/fff/picker_ui/renderer.luaLines to extract: 950-1400
Content:
render_list)build_render_context)finalize_render)format_file_display)render_grep_empty_state)Public API:
M.render_filtered_items()- Render filtered itemsM.build_render_context()- Build rendering contextM.format_file_display()- Format file displayM.render_grep_empty_state()- Render empty statePhase 5: Preview System Module
File:
lua/fff/picker_ui/preview_manager.luaLines to extract: 1400-1700, 1850-1950 (preview functions)
Content:
update_preview,update_preview_smart)update_preview_debounced)update_preview_title)clear_preview)Public API:
M.update_preview()- Update previewM.update_preview_smart()- Smart preview updateM.update_preview_debounced()- Debounced preview updateM.clear_preview()- Clear previewM.update_preview_title()- Update preview titlePhase 6: Navigation Module
File:
lua/fff/picker_ui/navigation.luaLines to extract: 1950-2100, 1700-1850 (movement functions)
Content:
move_up,move_down)wrap_to_first,wrap_to_last)Public API:
M.navigate_up()- Navigate upM.navigate_down()- Navigate downM.wrap_to_first()- Wrap to first itemM.wrap_to_last()- Wrap to last itemM.handle_mouse_click()- Handle mouse clicksPhase 7: Layout and Window Module
File:
lua/fff/picker_ui/layout_manager.luaLines to extract: 2200-2400
Content:
relayout)Public API:
M.handle_resize()- Handle window resizeM.cleanup_windows()- Cleanup windowsM.recalculate_layout()- Recalculate layoutM.close_preview()- Close preview windowPhase 8: Main Module Refactoring
File:
lua/fff/picker_ui.lua(update existing file)Changes:
lua/fff/picker_ui/Public API (preserved):
M.open(opts)- Main entry pointM.open_with_callback(query, callback, opts)- Callback-based openingM.close()- Cleanup and closeM.relayout()- Handle window resizingM.toggle_debug()- Toggle debug modeM.cycle_grep_modes()- Cycle through grep search modesKey Principles
1. Preserve Public API
M.open,M.close, etc.) remain unchanged2. Module Cohesion
3. Testability
4. Maintainability
5. Gradual Migration
Implementation Timeline with Verification
Week 1: Foundation
Week 2: Core Functionality
Week 3: Advanced Features
Week 4: Final Integration
Verification Strategy
Verification Types
1. Unit Testing
2. Integration Testing
3. End-to-End Testing
4. Performance Testing
Phase-by-Phase Verification Steps
Phase 1: State Management Module
Verification Checklist:
reset_state()clears all state properlytoggle_selection()toggles file/grep selectionssend_to_quickfix()builds correct quickfix listsTest Cases:
Phase 2: UI Creation Module
Verification Checklist:
create_ui()creates all windows and buffersTest Cases:
Phase 3: Search and Results Module
Verification Checklist:
Test Cases:
Phase 4: Rendering System Module
Verification Checklist:
Test Cases:
Phase 5: Preview System Module
Verification Checklist:
Test Cases:
Phase 6: Navigation Module
Verification Checklist:
Test Cases:
Phase 7: Layout and Window Module
Verification Checklist:
Test Cases:
Phase 8: Main Module Refactoring
Verification Checklist:
Test Cases:
Automated Testing Framework
Test Structure
Test Commands
Continuous Integration
Pre-Merge Checks
Quality Gates
Rollback Strategy
If Verification Fails
Automated Rollback Scripts
Risk Mitigation
High-Risk Areas
Mitigation Strategies
Success Metrics
Code Quality Metrics
Maintainability Metrics
Team Collaboration
Post-Refactoring Activities
Documentation
Testing
Monitoring
Conclusion
This refactoring plan transforms a monolithic 2535-line file into 8 focused modules of 200-300 lines each. The result will be:
The phase-based approach ensures manageable risk while delivering significant improvements in code organization and maintainability.