lapce’s highest-priority risk is concentrated in its command dispatch and proxy layers: run_workbench_command in lapce-app/src/window_tab.rs carries an activity risk of 18.06, meaning it is both extraordinarily complex (cyclomatic complexity of 294) and actively changing right now — a live regression risk, not a cleanup item. lapce is a GPU-accelerated, cross-platform code editor written in Rust, and at 1,728 analyzed functions with 103 rated critical, the codebase is operating under meaningful structural pressure. The top five hotspots alone span the UI command layer, syntax highlighting engine, proxy dispatch, app launch, and palette — a wide cross-section of subsystems that signals systemic, not isolated, complexity.
The table below ranks functions by activity-weighted risk — a score that multiplies structural complexity by recent commit frequency. A function that is both hard to understand (high cyclomatic complexity) and actively changing is a higher priority than one that is complex but untouched. CC = cyclomatic complexity (independent execution paths); ND = max nesting depth; FO = fan-out (distinct callees).
Top 5 Hotspots
| Function | File | Risk | CC | ND | FO |
|---|---|---|---|---|---|
run_workbench_command | lapce-app/src/window_tab.rs | 18.1 | 294 | 4 | 62 |
next | lapce-core/src/syntax/highlight.rs | 17.6 | 48 | 7 | 11 |
handle_request | lapce-proxy/src/dispatch.rs | 16.3 | 88 | 4 | 44 |
launch | lapce-app/src/app.rs | 15.6 | 25 | 3 | 34 |
select | lapce-app/src/palette.rs | 15.5 | 54 | 4 | 13 |
Hotspot Analysis
run_workbench_command — lapce-app/src/window_tab.rs
Based on its name and location in the window tab module, this function is almost certainly the central dispatcher for all workbench-level commands — keyboard shortcuts, menu actions, and editor commands likely all route through here. A cyclomatic complexity of 294 means there are 294 independent execution paths, each a required test case and a potential bug surface; a fan-out of 62 means it calls into 62 distinct functions, making it a textbook god function with enormous blast radius. Its ‘fire’ quadrant placement means this complexity is not sitting still — it is being actively modified, making every commit a regression risk across dozens of downstream callees.
Recommendation: Decompose by command category: group related command arms into dedicated handler functions (e.g., handle_editor_command, handle_file_command) and route to them, reducing both cyclomatic complexity and fan-out incrementally. Before refactoring, add characterization tests that exercise the existing paths to prevent silent regressions during the split.
next — lapce-core/src/syntax/highlight.rs
Located in the core syntax highlighting module, next is almost certainly an iterator-style method that advances through the token or highlight event stream — the kind of function that must handle every edge case in a language grammar’s output. Its cyclomatic complexity of 48 combined with a max nesting depth of 7 means the logic is both wide in branching and deeply stacked, making it genuinely hard to reason about in isolation; ND 7 is a strong refactoring signal on its own. Critically, this function is in the ‘debt’ quadrant — it has not been recently touched — but its structural weight means it carries a high blast radius the next time syntax highlighting behavior needs to change.
Recommendation: Flatten the nesting by extracting inner match arms or loop bodies into named helper functions, targeting the ND 7 depth first; this will also naturally reduce the CC of 48 by making sub-paths independently visible and testable.
handle_request — lapce-proxy/src/dispatch.rs
This function sits in the proxy dispatch layer and, from its name and path, almost certainly routes incoming LSP or plugin requests to their appropriate handlers — a classic protocol multiplexer. Its cyclomatic complexity of 88 and fan-out of 44 confirm it is doing far too much in a single function, branching across dozens of request types while calling into 44 distinct functions. It is in the ‘fire’ quadrant, meaning new request types or protocol changes are actively landing here, compounding regression risk with each addition.
Recommendation: Introduce a request handler registry or trait-based dispatch table to replace the branching logic, so new request types are registered rather than added as additional branches in a single function — this directly reduces cyclomatic complexity and makes each handler independently testable.
Patterns Found
Antipatterns detected across the top functions in this snapshot:
| Pattern | Occurrences |
|---|---|
long_function | 13 |
god_function | 9 |
complex_branching | 7 |
exit_heavy | 7 |
stale_complex | 5 |
deeply_nested | 3 |
These labels belong to two tiers — Tier 1 (structural): complex_branching, deeply_nested, exit_heavy, long_function, god_function. Tier 2 (relational/temporal): hub_function, cyclic_hub, middle_man, neighbor_risk, stale_complex, churn_magnet, shotgun_target, volatile_god.
Key Takeaways
run_workbench_command(CC 294, FO 62, activity risk 18.06) is the single highest-leverage refactoring target in the codebase — decompose it by command category before the next feature lands in window_tab.rs.- The
nextfunction inlapce-core/src/syntax/highlight.rshas a max nesting depth of 7 and CC of 48 but sits in the ‘debt’ quadrant — schedule a refactoring pass before the next syntax engine change to avoid a high-blast-radius regression. - With 9 god functions and 13 long functions in the top hotspots, extract-method refactoring is the most broadly applicable technique across lapce’s critical tier — start with
handle_request(FO 44) to reduce proxy coupling.
Reproduce This Analysis
git clone https://github.com/lapce/lapce
cd lapce
git checkout c9e4c33948033f10f003991a037d949a708eedf8
hotspots analyze . --mode snapshot --explain-patterns --force
To run the same analysis on your own codebase, run hotspots analyze . --mode snapshot in any local git repo — no configuration required.
Hotspots highlights structural and activity risk — not “bad code.” Findings are a prioritization aid, not a bug predictor. Editorial policy →