-
Notifications
You must be signed in to change notification settings - Fork 5
Fix fidget plugin flashing and improve message formatting #61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Use Red's timer API instead of global setTimeout/clearTimeout - Add proper debouncing to prevent creating multiple render timers - Track removal timers separately to ensure proper cleanup - Add error handling for async timer operations - Increase poll rate from 10ms to 100ms to reduce timer pressure - Add renderScheduled flag to prevent race conditions
- Increase poll rate to 500ms to avoid hitting timer limit - Add documentation about current timer implementation limitations - The root cause is that Red's timer implementation doesn't properly execute callbacks - This is a temporary workaround until the timer system is improved
- Add TimeoutCallback variant to PluginRequest enum - Modify op_set_timeout to send callback requests via ACTION_DISPATCHER - Update JavaScript setTimeout to store callbacks and return timer IDs - Add event listener for timeout:callback events - Fix clearTimeout to properly clean up callbacks - Add timer test plugin to validate functionality - Update fidget plugin to use 100ms poll rate now that timers work The timer system now properly executes callbacks when timers fire, fixing the 'Too many timers' error and enabling plugins to use timers effectively.
- Add timer_stats module to track timer usage per plugin - Implement 'dt' debug command to dump timer statistics - Add DumpTimers action to the debug command set - Export timer_stats module for use in editor - This helps identify plugins that are using excessive timers The 'dt' command can be used in command mode to see which plugins are creating timers and how many are active vs cleared.
Document the timer system improvements including: - Problem description and root causes - Implementation details of the fix - Usage examples for plugin developers - Debugging instructions - Future improvement ideas
The previous timer implementation relied on tokio tasks that weren't being polled properly due to the plugin runtime architecture. This caused timers to never fire, preventing the fidget plugin from displaying progress notifications. Changes: - Replace tokio-based timers with timestamp-based approach - Poll for expired timers in main editor event loop every 10ms - Add debug logging to track timer lifecycle - Update fidget plugin with additional logging and refresh trigger The timer callbacks now work reliably, allowing plugins like fidget to update the display on a regular schedule. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
- Add new PluginOverlay system with separate render buffers - Implement dirty region tracking to avoid unnecessary redraws - Add overlay positioning with bottom-right alignment (fidget.nvim style) - Create new plugin API methods: createOverlay, updateOverlay, removeOverlay - Refactor fidget plugin to use overlay system instead of direct buffer rendering - Messages now appear in bottom-right corner and stack upwards - Eliminate visual flashing by rendering to overlay buffers This provides a much smoother visual experience for LSP progress notifications, similar to how fidget.nvim works in Neovim. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
The renderTimer variable was removed during the overlay system refactor but a reference to it remained in the LSP progress handler, causing a runtime error. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
- Add cleaner message formatting similar to fidget.nvim - Extract titles from LSP tokens (e.g., "rustAnalyzer/Indexing" → "Indexing") - Add spinner animation for in-progress tasks - Add done checkmark icon for completed tasks - Format rust-analyzer messages more cleanly (e.g., "Indexing: 17/21 (unicode_width)") - Remove redundant information from progress displays The messages now appear much cleaner and more readable, matching the style of fidget.nvim's progress notifications. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
- Spinner now appears only on the last in-progress message - Positioned on the right side of the text instead of left - Completed tasks still show checkmark on the left - Provides cleaner visual hierarchy with active task indicator 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
- Fix double spaces in progress messages - Maintain proper capitalization for common terms (Fetching, Building, Loading) - Handle special cases like 'buildArtifacts' → 'build-artifacts' - Improve right-alignment rendering in overlay system - Use proper Unicode character counting for text positioning 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
- Add width calculation based on editor size - Truncate messages from the left side when they exceed available width - Add ellipsis (...) at the beginning of truncated messages - Ensures messages stay within editor bounds and remain right-aligned 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
- Add Default derive for OverlayManager instead of manual implementation - Add Default derive for TimerUsage instead of manual implementation - Follows clippy's recommendations for cleaner, more idiomatic code 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
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.
Pull Request Overview
This pull request fixes the fidget plugin’s visual flashing issues and improves message formatting by introducing a plugin overlay system and integrating a refined timer management mechanism. Key changes include:
- A new overlay API with create, update, and remove operations for flicker‐free overlay rendering
- A reworked timer system that replaces the old timeout tracking with a polling-based callback mechanism and adds timer statistics
- Updates to the fidget plugin and editor integration to use the new overlay and timer APIs
Reviewed Changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/plugin/timer_stats.rs | Adds timer usage tracking with creation and clearing statistics |
| src/plugin/runtime.rs | Reworks timeout handling with a polling mechanism and adds overlay ops |
| src/plugin/runtime.js | Updates JS timer functions and overlay API integration |
| src/plugin/overlay.rs | Implements overlay rendering and positioning logic |
| src/plugin/mod.rs | Exports new overlay and timer modules |
| src/editor/rendering.rs / src/editor.rs | Incorporates overlay updates and timer callback processing into the editor |
| plugins/fidget.js | Enhances the fidget plugin with clean message formatting and spinner animation |
| examples/timer-test.js | Provides tests validating timer callback functionality |
| docs/TIMER_IMPROVEMENTS.md | Documents updated timer and overlay implementations |
| .hookman/hooks/pre-push.toml & ci.yml | Minor CI and pre-push hook updates |
Comments suppressed due to low confidence (1)
src/plugin/runtime.js:187
- [nitpick] Consider adding additional error handling or a retry mechanism in the animation loop to avoid the spinner animation stopping unexpectedly if red.setTimeout fails. This can help maintain a smoother user interface experience.
animationTimer = await red.setTimeout(() => animate(), 100);
Summary
Problem
The fidget plugin was experiencing severe visual flashing issues where LSP progress messages would flicker constantly during rust-analyzer operations. Messages were also poorly formatted with redundant information.
Solution
Created a Plugin Overlay System
PluginOverlaystructure with separate render buffersNew Plugin API
red.createOverlay(id, config)- Create positioned overlaysred.updateOverlay(id, lines)- Update overlay contentred.removeOverlay(id)- Remove overlaysImproved Message Formatting
Test plan
cargo build🤖 Generated with Claude Code