Skip to content

perf(editor): index language modes instead of sorting on every lookup - #2881

Merged
bajrangCoder merged 2 commits into
mainfrom
perf/modelist-path-lookup
Sep 12, 2026
Merged

perf(editor): index language modes instead of sorting on every lookup#2881
bajrangCoder merged 2 commits into
mainfrom
perf/modelist-path-lookup

Conversation

@bajrangCoder

Copy link
Copy Markdown
Member

Summary

getModeForPath copied and sorted every registered language mode on each call. Directory listing hits this via icon resolution for every file; the sidebar tree hits it again while rendering. Icon plugins that wrap helpers.getIconForFile pay the same cost.

This rebuilds a lookup index only when addMode / removeMode run (exact filenames, filename regexes in specificity order, longest extension suffix) and caches results by basename.

File-tree icons are still resolved at render time. Caching the sortDir icon class would skip plugins that replace helpers.getIconForFile (Material Icons and similar), so that shortcut is intentionally not used here.

A dedicated file/folder icon plugin API can replace those monkey-patches later. This PR does not add that API.

Compatibility

Public plugin APIs are unchanged:

  • acode.editorLanguages.*
  • acode.aceModes.*
  • ace.require("ace/ext/modelist")
  • helpers.getIconForFile (still overridable)

getModes() still returns registration order. Later plugin registrations still win on equal specificity. Register/unregister invalidates the index immediately.

Parity-tested against the old sort-and-scan for built-in modes, Dockerfile case sensitivity, compound extensions, nginx/BUILD filename matchers, and plugin install/remove.

Measurements

4000 lookups (js/ts/json/py/md/css/unknown + Dockerfile/nginx/CMakeLists):

Path Time
Old copy+sort ~808ms
Indexed ~7.7ms
Warm cache ~5.4ms

About 105× faster in unit tests. Calling getIconForFile twice per tree row is still cheap after this; the old sort was the hitch.

Follow-up

Add a first-class file/folder icon plugin API so themes like Material Icons do not need to replace helpers.getIconForFile.

getModeForPath copied and sorted all registered modes per file, and the comparator recomputed specificity plus indexOf. File trees and icon
plugins hit this for every entry.

Rebuild a specificity index only when modes are added or removed, look up exact names / filename regexes / longest extension, and cache by
basename. Matching still goes through supportsFile, with a scan fallback,
so plugin register/unregister and later-wins ties stay the same.

Keep resolving file-tree icons at render time so plugins that replace helpers.getIconForFile (for example Material Icons) still apply.
@greptile-apps

greptile-apps Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

The PR appears safe to merge; the previous correctness and flaky-test findings are resolved without introducing a new actionable issue.

Summary

  • Indexes exact filenames, regular-expression matchers, and extension suffixes.
  • Preserves mode-level specificity and later-registration tie-breaking across compound extensions.
  • Invalidates indexed and cached results when modes are added or removed.
  • Replaces timing-sensitive performance assertions with deterministic parity coverage.
  • Keeps file-tree icon resolution at render time so icon plugins continue to apply.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[getModeForPath] --> B[Extract basename]
    B --> C{Cached result?}
    C -->|Yes| D[Return cached mode]
    C -->|No| E{Mode index exists?}
    E -->|No| F[Rank registered modes]
    F --> G[Index names, regexes, and extensions]
    E -->|Yes| H[Resolve filename]
    G --> H
    H --> I[Check ranked filename matches]
    I --> J[Check all matching suffixes by mode rank]
    J --> K[Fallback to ranked supportsFile scan]
    K --> L[Cache and return result]
    M[addMode / removeMode] --> N[Invalidate index and cache]
Loading

Reviews (2) · Last reviewed commit: "fix"

Comment thread src/cm/modelist.ts Outdated
Comment thread tests/unit/modelist.test.js Outdated
@bajrangCoder

This comment was marked as outdated.

@bajrangCoder
bajrangCoder added this pull request to the merge queue Sep 12, 2026
Merged via the queue into main with commit 3412460 Sep 12, 2026
11 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in The Code Board - Acode Sep 12, 2026
@bajrangCoder
bajrangCoder deleted the perf/modelist-path-lookup branch September 12, 2026 04:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant