Skip to content

Draw extension decorations, and fire the active-editor event when the editor exists - #70

Merged
Seungpyo1007 merged 1 commit into
developfrom
feature/ext-decorations
Aug 6, 2026
Merged

Draw extension decorations, and fire the active-editor event when the editor exists#70
Seungpyo1007 merged 1 commit into
developfrom
feature/ext-decorations

Conversation

@Seungpyo1007

Copy link
Copy Markdown
Member

Track C of the 0.3.0 plan, item 2. Closes the last place in the shim that answered successfully and did nothing.

Decorations

createTextEditorDecorationType returned a working-looking handle; setDecorations accepted ranges. Nothing was ever drawn.

The two APIs have different shapes — VS Code takes CSS directly, Monaco takes class names and expects those classes to exist somewhere. So each type compiles to a rule in a stylesheet and Monaco gets the name.

  • src/ext/decorations.ts holds the conversion as pure functions, tested directly. It also escapes quotes and backslashes in an extension's contentText; without that a crafted string breaks out of the rule and takes the whole stylesheet with it.
  • One shared stylesheet, not one <style> per type — extensions that colour per line create and drop types constantly, and per-type elements would grow head into the thousands.
  • An empty array means "clear what this type drew", and unloading an extension collects what it drew.
  • Creating a type whose options yield nothing drawable logs a warning instead of quietly succeeding — that being the shape this whole area exists to remove.

The bigger find underneath

onDidChangeActiveTextEditor was handing extensions the wrong editor.

openFile fired the notification before its setState, so no pane and no model existed yet — and notifyExtensions bailed at if (!doc) return before reaching the active-editor fire. Opening a file therefore delivered nothing, and the one event that did arrive carried the previous file's editor.

Extensions that draw on editor changes — which is most of the ones that decorate — were drawing onto whatever was open before. The event now waits for the pane to actually exist (bounded, 1s) and fires exactly once per file, from either the open path or the pane mount.

Verification

A temporary extension was installed and driven through CDP. 7/7: the rule reaches the stylesheet, after content included; the classes land in the editor DOM; the computed background is rgba(143, 168, 147, 0.35) and the computed ::after is " ← SZDECO_OK" — actual pixels, not just markup; switching tabs redraws (event counter confirms two events); an empty array clears to zero.

1009 unit tests passing (28 new). npm run typecheck and npm run build clean.

A note on how this was verified

Three probe runs during this work tested a stale bundle. The Vite dev server had died, and the app falls back to dist/ silently, so changes made after the last build were not in what the probe exercised — which is what made this bug look unfixable for several rounds. The runs reported above are from a fresh build.

createTextEditorDecorationType 은 멀쩡해 보이는 핸들을 돌려주고 setDecorations 는
범위를 받아 놓고, 아무것도 그리지 않았다. 0.2.0 이 한 판을 통째로 들여 없앤
"조용히 성공하는 답" 이 마지막으로 남아 있던 자리다.

두 API 의 모양이 다르다. VS Code 는 CSS 를 그대로 받고 Monaco 는 클래스 이름만
받는다. 그래서 타입 하나당 규칙을 만들어 스타일시트에 넣고 Monaco 에는 그 이름을
준다. 변환은 decorations.ts 에 순수 함수로 두어 그대로 시험한다 — 확장이 준
contentText 의 따옴표·역슬래시를 막는 것도 여기다(안 막으면 규칙 밖으로 새어
스타일시트 전체가 깨진다). 스타일시트는 한 장을 공유한다. 타입마다 <style> 을
만들면 줄마다 색이 다른 흔한 확장에서 head 가 수천 개로 불어난다.

빈 배열은 "그 타입으로 그린 것을 전부 지운다" 로 동작하고, 확장이 내려가면
그려 둔 것까지 걷는다. 빈 옵션으로 타입을 만들면 경고한다 — 조용히 성공을
답하는 것이 여기서 없애려던 그 모양이다.

그리고 고치다 더 큰 것을 찾았다. onDidChangeActiveTextEditor 가 잘못된 편집기를
주고 있었다. openFile 이 setState 전에 사건을 쏘는데 그 시점엔 페인도 모델도
없어서 shimDocFor 가 빈손으로 돌아오고, 거기서 사건이 함께 끊겼다. 결과적으로
새 파일을 열면 확장은 사건을 아예 못 받고, 받은 한 번은 이전 파일의 편집기였다.
데코레이션을 쓰는 확장은 거의 다 이 사건에 매달려 그리므로 실사용에서는
아무것도 안 그려졌을 것이다. 이제 페인이 실제로 뜰 때까지 최대 1초 기다렸다
쏘고, 같은 파일로 두 번 쏘지 않는다.

임시 확장을 실제로 깔아 CDP 로 몰아 7/7. 계산된 배경색이
rgba(143,168,147,0.35) 이고 ::after 가 실제로 그려지며, 탭을 바꾸면 다시
그려지는 것까지(사건 2회) 확인했다. 단위 28개 추가(1009개 통과).
@Seungpyo1007 Seungpyo1007 added this to the v0.3 (2026-09-30) milestone Aug 6, 2026
@Seungpyo1007 Seungpyo1007 added the enhancement New feature or request label Aug 6, 2026
@Seungpyo1007 Seungpyo1007 self-assigned this Aug 6, 2026
@Seungpyo1007
Seungpyo1007 merged commit 64725f1 into develop Aug 6, 2026
1 check passed
@Seungpyo1007
Seungpyo1007 deleted the feature/ext-decorations branch August 6, 2026 02:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant