Repository navigation
fix(console): show each log line once and stop following on user input - #1951
Merged
Merged
Conversation
Logback's STDOUT ConsoleAppender resolves System.out on every write, so after ClientUI swapped System.out for the console tee every log line reached the panel twice: once through the tee and once through ConsoleLogAppender. Bind System.out console appenders to the original stdout when the console is installed; plain System.out prints still go through the tee. Wheel-up, key presses and mouse presses/drags in the text area now stop following immediately; following resumes only when the view is back at the bottom with no selection. The caret moves made while following no longer scroll the view from their deferred visibility update, which could undo a wheel-up. The pending buffer is compacted only once it doubles and a flush inserts at most what the document keeps (100k chars while following). The saved sidebar tab is restored only during startup, and removing the open tab's plugin stores the tab that is shown instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
Contributor
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 5 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This was referenced Oct 13, 2026
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.
Follow-ups from the review of #1939: console duplicates, follow/scroll behaviour, the pending buffer, and sidebar tab restore.
Problem
STDOUTConsoleAppender(ConsoleTarget.SystemOut) looks upSystem.outagain on every write. OnceClientUI.initializeConsoleLoggingreplacedSystem.outwith the console tee, each logback line reached the panel twice: once through the tee and once throughConsoleLogAppender.followTail == trueand pulled the view back down. There was a second path too: eachsetCaretPosition(end)made while following queues a deferredDefaultCaret.adjustVisibility, which scrolls to the caret no matter whatfollowTailsays by then.appendpast the cap also ran an O(n)StringBuilder.deleteunder the appender lock.Change
ConsoleLogAppender.bindStdoutAppenders, called frominitializeConsoleLogging, points everySystem.outConsoleAppenderat the original stdout stream. Logback lines now reach the panel only throughConsoleLogAppender, and the terminal still gets them once. PlainSystem.outprints still go through the tee.System.errwas not captured before and still is not.LogConsolePanel:followTail = falsestraight away; wheel-down still re-checks after the scroll.DefaultCaretsubclass that skipsadjustVisibilityfor the caret position the console set itself. Caret moves made by the user still scroll.ClientUI(upstream file, small diff):sidebarTabRestoredis set at the end ofshow()'s EDT runnable. That runnable runs after the navigation buttons queued bystartPlugins, so the restore only happens at startup.removeNavigationsaves the tab the user now sees after the fallbackopenPanel.saveSidebarTab().Testing
ConsoleLogAppenderTest: one log line plus oneprintln, each counted in the panel and in the terminal.LogConsolePanelTestwith 6 cases: wheel-up against an already-queued snap/caret update, PgUp, Ctrl+End resuming after PgUp, drag-selection surviving a batch, wheel-down resuming, and a starved EDT given 1M+ chars.origin/development, 5 of the 7 failed, deterministically across 3 runs: dedupe (expected:<1> but was:<2>), PgUp, drag-select, starved EDT (largest insert 400000), wheel-up. Also checked:wheelDownToTheBottomResumesFollowingis a guard against over-correction and passes on both../gradlew :client:runUnitTests --offline: 2344 passed, 2 skipped (ShaderTest, EssencePouchOverlayTest), 0 failed. The ClientThreadGuardrail baseline was unchanged.printlnlines/s for about 20 s (187,100 lines):printlnx1 in the console. The terminal stdout still got the logback lines.WINDOW_CLOSING(not a kill):Configurationwas restored at startup;Configurationand savedConfiguration(the old code skipped saving during the removal, soHiscorestayed saved; read from the code, not re-run);Hiscoresaved and the plugin disabled at startup, enabling it mid-session left the sidebar with no tab selected.Not verified / known limits
NEVER_UPDATE) shifts under a view that stays put; the probe saw the selected text change while its length stayed the same. This predates this PR and only matters when more than 400k chars arrive while scrolled up.🤖 Generated with Claude Code
https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV