Skip to content

refactor(async): decompose the process_async_messages god function#2425

Merged
sinelaw merged 1 commit into
masterfrom
claude/epic-turing-i2o587
Jun 22, 2026
Merged

refactor(async): decompose the process_async_messages god function#2425
sinelaw merged 1 commit into
masterfrom
claude/epic-turing-i2o587

Conversation

@sinelaw

@sinelaw sinelaw commented Jun 22, 2026

Copy link
Copy Markdown
Owner

What

Editor::process_async_messages (in crates/fresh-editor/src/app/async_dispatch.rs) was the lowest-hanging maintainability fruit in the project: a single 1033-line function whose body is one match over ~50 AsyncMessage variants.

The offense was inconsistency under load. Most arms already delegated to a handle_* method (one line each), but ~12 arms inlined substantial logic directly in the dispatcher:

Arm Inlined lines
TerminalExited ~140
RemoteAttachReady ~126
GrammarRegistryBuilt ~70
Plugin(..) (nested sub-match) ~66
LspError ~62
TerminalOutput ~58
RemoteAttachFailed, LspInitialized, QuickOpenFilesLoaded, LspApplyEdit, LspCodeActionResolved, PathChanged 11–42 each

These fat arms buried the dispatch structure — you couldn't see the routing for the logic.

Change

Extract each fat arm into a dedicated private handle_* method on Editor, following the convention the file already established for its thin arms. The match is now a uniform dispatch table: every arm is a pattern plus a single delegating call. process_async_messages drops from 1033 → 424 lines (the remainder being multi-line match patterns and the unchanged post-loop orchestration).

  • The two early-return continues in the remote-attach arms became return in their handlers — identical control flow (skip the rest of this message, continue to the next).
  • No behavior change: logic is moved verbatim, not rewritten.
  • No new traits, generics, or macros — just method extraction. Each handler is now independently readable and unit-testable.

Conflict avoidance

Selected specifically to avoid the active PR surface. The two larger god functions (app/render.rs::render, input/actions.rs::action_to_events) were rejected because they're under active development (#2388 touches render.rs; #2292 touches actions.rs), as are input.rs (#2292) and plugin_dispatch.rs (#2399). async_dispatch.rs has no pending changes in any open PR.

Verification

  • cargo check -p fresh-editor --lib — clean (only pre-existing, unrelated warnings)
  • cargo fmt — applied
  • cargo clippy -p fresh-editor --lib — zero warnings in the changed file
  • Per instructions, the test suite was left for CI.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AsDPyw77hJM7ECYBXF1xD5


Generated by Claude Code

`Editor::process_async_messages` had grown into a 1000+ line god
function: a single `match` over ~50 `AsyncMessage` variants where most
arms already delegated to a `handle_*` method, but a dozen arms inlined
15–140 lines of logic each (TerminalExited ~140, RemoteAttachReady ~126,
GrammarRegistryBuilt ~70, the plugin-message sub-match ~66, TerminalOutput
~58, LspError ~62, …). The fat arms drowned the dispatch structure and
made the function impossible to read at a glance.

Extract each fat arm into a dedicated private `handle_*` method on
`Editor`, following the convention the file already used for its thin
arms. The `match` is now a uniform dispatch table: every arm is a pattern
plus a single delegating call. The two early-out `continue`s in the
remote-attach arms become `return` in their handlers (same control flow:
skip the rest of this message, move on to the next).

No behavior change — logic is moved verbatim, not rewritten. No new
traits, generics, or macros.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AsDPyw77hJM7ECYBXF1xD5
@sinelaw sinelaw merged commit 33e2ed1 into master Jun 22, 2026
7 of 8 checks passed
@sinelaw sinelaw deleted the claude/epic-turing-i2o587 branch June 22, 2026 08:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants