make multiselect dialogue rendering more efficient#129
Conversation
Summary of ChangesHello @TheBearodactyl, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly refactors the terminal rendering mechanism for the multiselect dialogue. The primary goal is to enhance the visual smoothness and responsiveness of the interactive prompt by implementing a more granular and precise method for updating the terminal display, thereby minimizing visual artifacts like flickering. Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request successfully refactors the rendering logic to be more efficient and reduce flickering by overwriting lines instead of clearing and re-rendering. The approach is solid. However, I've identified a regression in the cleanup function, which no longer clears the prompt upon cancellation. Additionally, I have a couple of suggestions for the new reposition_and_write function to further improve its efficiency and readability. Please see my detailed comments below.
* fix(multiselect): off-by-one in redraw causing menu to drift up each keypress `reposition_and_write` was moving the cursor up by `last_line_count` to return to the top of the previous render, but the redraw loop emits no trailing newline after the last line — so the cursor sits at the *end* of row N-1, not at row N. Moving up by N landed one row above the prior top, and every keypress shifted the menu up by another row (visible in `mise up -i` and any other multi-iteration `MultiSelect` redraw). Fix by moving up `last_line_count - 1`, matching the invariant the pre-#129 code expressed via `height = lines().count() - 1`. The shrink branch had the same off-by-one in mirrored form; restructure it so the cursor lands on the last line of the new render, preserving the same invariant for the next iteration. Adds two regression tests that drive the redraw path through a `Term::read_write_pair` whose writer captures bytes into a shared `Vec`, replays the bytes through a `vt100` emulator, and asserts that the cursor row is stable across iterations (drift case) and repositions correctly when the render shrinks. Both tests fail without the fix — the drift trace `[26, 25, 24, 23, 22, 21]` is the smoking gun. Drive-by clippy fixes across the workspace (collapsible match in select, needless `vec!` in spinner test, needless `return`/borrow in examples and the non-TTY integration test) so `cargo clippy -- -D warnings` passes again on stable. * ci: add test-ci aggregator job for branch protection Mirrors the pattern in jdx/mise — a single one-minute job that needs the matrix `test` job and re-emits its result. Lets branch protection gate on one check (`test-ci`) instead of all three matrix instances (ubuntu/macos/windows), so adding or removing platforms doesn't require rule updates. Uses `if: !cancelled()` rather than `always()` so workflow cancellation doesn't spin up a wasted runner.
before:
demand-before.mp4
after:
demand-after.mp4