fix: fold error when using max_messages#469
Draft
phanen wants to merge 14 commits into
Draft
Conversation
Owner
|
Is the MR ready for review or you still need to adjust some things ? |
Contributor
Author
|
not yet, I will take a look again asap |
Problem: when buffer shrinks faster than the cached fold ranges get updated, vim.fn.foldclosed() reports ranges that no longer exist in the buffer. The fold creation loop already had a line_count guard but the foldopen! loop did not, surfacing as 'E16: Invalid range'. Solution: mirror the same line_count guard on the foldopen! loop so out-of-range entries are silently skipped instead of raising.
… buffer var The opencode_folds b:var had to round-trip through vim's lua bridge on every set_folds call (one nvim_buf_set_var write plus one nvim_buf_get_var read). Microbench on a freshly created buffer: bridge set+get round-trip: 1.04 us bridge set only: 0.70 us bridge get only: 0.45 us pure Lua ref: 0.003 us Move fold state to state.windows.output_folds, sitting alongside output_buf and output_was_at_bottom. set_windows replaces the whole windows object on every mount, so output_folds resets with it automatically - no separate clear path needed. Fold state is now fetched with state.ui.get_output_folds(), a pure Lua table read. Also drops the fold_state.starts field that shift_folds was maintaining but nothing was reading.
Problem: diff computations were duplicated across flush + buffer. flush.format_message did a full lines_equal + extmarks_equal walk, and buffer.upsert_*_now each computed unchanged_prefix_len that extmark_clear_range then recomputed internally. append.lua held a hand-rolled tail walk duplicating the same primitive. Solution: introduce output_diff.lua with shared prefix walks, slice helpers, mark equality, and the high-level is_unchanged / is_append_only predicates. Make extmark_clear_range accept a precomputed prefix_len and extract write_in_place so both upsert paths walk once. Collapse append.lua into output_diff.lua.
Problem: update_part_folds aggregated new_global from ctx.part_folds, which stores absolute coordinates computed at the time each part was last updated. When a part's line_start shifts (upsert/append path did not call shift_all before c451c90+x, remove paths still do not), the stored entry becomes stale and the next update_part_folds re-emits fold ranges referencing lines that no longer host the part's content. Solution: rebuild new_global from ctx.formatted_parts (source of truth for what's currently rendered) on every update, recomputing each part's absolute folds from its current cached_part.line_start. This mirrors set_all_folds and stops stale entries from leaking into set_folds.
Problem: remove_part_now and remove_message_now only called output_window.shift_folds to update the canonical fold state, leaving ctx.render_state entries for parts/messages below the removed range with stale line_start/line_end. Any subsequent update_part_folds then fed those stale coordinates back into set_folds. Solution: mirror the upsert path. After shift_folds, call ctx.render_state:shift_all(...) so siblings shift in lockstep with the canonical fold state, and drop ctx.part_folds[part_id] so the removed part does not leak its absolute coords into the next aggregate.
Problem: when an in-place upsert grew or shrunk the rewritten range (other_line_end = write_in_place returns != cached.line_end), only the current part's line_end was updated via update_part_lines. Sibling parts/messages below kept their old line_start, and the canonical fold state was not shifted, so ctx.part_folds for siblings pointed to lines whose content had moved out from under them. Solution: mirror the upsert_message_now path. On non-zero delta, call output_window.shift_folds and ctx.render_state:shift_all starting at old_line_end + 1 so siblings move in lockstep with the buffer.
Problem: append_part_now inserted lines past cached.line_end but only called update_part_lines on the current part. ctx.render_state and the canonical fold state both kept their pre-append coordinates for parts below the insertion, so the next update_part_folds produced fold ranges that targeted lines whose content had been pushed down by the append. Solution: shift both downstream of the insert site after update_part_lines, matching the upsert paths. set_lines moves the buffer; shift_folds and shift_all keep render_state and the canonical fold list aligned.
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.
often get error like this when use
max_messages