Fix performance issue causing input delays during character typing#40
Fix performance issue causing input delays during character typing#40
Conversation
Co-authored-by: maorun <2291503+maorun@users.noreply.github.com>
Co-authored-by: maorun <2291503+maorun@users.noreply.github.com>
There was a problem hiding this comment.
Pull Request Overview
This PR resolves a critical performance issue where the Code::Stats plugin caused significant input delays during character typing in Neovim. The problem was caused by expensive TreeSitter operations and XP processing being triggered on every keypress.
- Optimized event handling by replacing per-character
InsertCharPreevents with less frequentInsertLeaveand debouncedTextChangedIevents - Implemented intelligent language detection caching with position-based invalidation to avoid redundant TreeSitter API calls
- Added XP processing batching to reduce overhead from level calculations and notifications
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| lua/maorun/code-stats/pulse.lua | Implements XP batching system with timer-based processing to reduce per-keystroke overhead |
| lua/maorun/code-stats/language-detection.lua | Adds intelligent caching for language detection with position-aware cache invalidation and fast-path optimization |
| lua/maorun/code-stats/events.lua | Replaces frequent InsertCharPre events with InsertLeave and debounced TextChangedI for better performance |
| lua/maorun/code-stats/config.lua | Adds configurable performance settings for debouncing, batching, and caching timeouts |
| README.md | Documents the new performance optimization features and configuration options |
lua/maorun/code-stats/pulse.lua
Outdated
| if not pulse.batch_timer then | ||
| local batch_delay = cs_config.config.performance.xp_batch_delay_ms | ||
| pulse.batch_timer = vim.fn.timer_start(batch_delay, function() | ||
| process_pending_xp() |
There was a problem hiding this comment.
The timer callback function does not handle potential errors during XP processing. If process_pending_xp() throws an error, the timer will silently fail and pending XP data may be lost. Wrap the callback in a pcall to handle errors gracefully.
| process_pending_xp() | |
| local ok, err = pcall(process_pending_xp) | |
| if not ok then | |
| logging.error("Error during XP batch processing: " .. tostring(err)) | |
| end |
| if | ||
| language_cache.buffer == current_buffer | ||
| and language_cache.filetype == current_filetype | ||
| and language_cache.timestamp + cache_timeout > current_time | ||
| and math.abs(language_cache.last_line - line) <= 5 | ||
| and math.abs(language_cache.last_col - col) <= 10 | ||
| then |
There was a problem hiding this comment.
[nitpick] The magic numbers 5 and 10 for cache position tolerance should be extracted into named constants or made configurable. This would make the cache invalidation logic more maintainable and allow users to tune the cache sensitivity.
| callback = function() | ||
| -- Debounce: only track XP after configured delay of no typing | ||
| if typing_timer then | ||
| vim.fn.timer_stop(typing_timer) |
There was a problem hiding this comment.
The timer stop operation should be wrapped in a pcall to handle cases where the timer might have already been stopped or become invalid. This prevents potential runtime errors when stopping timers.
| vim.fn.timer_stop(typing_timer) | |
| pcall(vim.fn.timer_stop, typing_timer) |
|
@copilot tests schlagen fehl. Fix auch linting wenn nötig |
Co-authored-by: maorun <2291503+maorun@users.noreply.github.com>
Performance Issue Resolution Complete ✅
Problem Identified: The plugin was causing Neovim input delays because it performed expensive operations on every character input.
Root Cause: The autocommand in
events.luatriggered onInsertCharPreandTextChanged, callinglang_detection.detect_language()which does complex TreeSitter parsing at cursor position for every keypress.Performance Issues:
events.lualanguage-detection.luaInsertCharPreImplemented Fixes:
InsertCharPrewith less frequent events (InsertLeave, debouncedTextChangedI)vim.bo.filetypedirectly for most casesTest Compatibility Issues Fixed:
_TEST_MODEflag to all test files for consistent behaviorKey Performance Improvements:
InsertCharPre(every keypress) toInsertLeave+ debouncedTextChangedINew Configuration Options:
Testing Results:
Expected Impact:
Documentation Added:
Fixes #39.
💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.