Let extensions actually ask the user something - #41
Merged
Merged
Conversation
셰임에서 묻는 함수는 셋인데 셋 다 묻지 않고 곧장 답했다.
showQuickPick: () => Promise.resolve(undefined),
showInputBox: () => Promise.resolve(undefined),
showInformationMessage: (msg, ..._items) => { toast(...); return undefined; },
vscode 규약에서 undefined 는 "사용자가 취소했다" 다. 그래서 확장은 물음을 띄운
적도 없이 취소당한 줄 알고 흐름을 접었다. 오류도 토스트도 없다. 특히 세 번째가
고약한데, 토스트는 뜨니까 뭔가 일어난 것처럼 보인다 — 정작
`if (await showInformationMessage(m, "Reload") === "Reload")` 는 영원히 거짓이다.
세 물음을 실제 대화창으로 만든다. 고른 항목은 **확장이 넘긴 값 그대로** 돌려준다
(확장은 대개 자기가 붙인 필드를 보고 다음을 정한다). canPickMany, Promise 로 넘긴
항목 목록, matchOnDescription/Detail, password, validateInput 을 지원한다.
검사기는 열 때도 한 번 돌린다. 확장이 준 초기값이 이미 규칙에 어긋날 수 있는데,
그때 아무 표시가 없으면 멀쩡해 보이는 값에 확인을 눌러야 왜 안 되는지 알게 된다.
버튼 없이 부른 알림은 그대로 토스트다 — 알림은 흐름을 막을 일이 아니다.
물음은 늘 누가 묻는지 머리에 밝힌다. 확장이 띄운 창을 앱이 띄운 것으로 오해하면
확장을 지운 뒤에도 앱을 의심하게 된다.
고르는 로직(정규화·필터·커서·검증)은 순수 모듈로 빼서 26개 테스트로 덮는다.
곁들여, 오버레이 zIndex 를 표에서 읽어 가게 했다. "렌더 리터럴과 같아야 한다" 고
주석으로만 적어 뒀더니 실제로 어긋나 있었다 — 확인창은 표에서 233 인데 231 로
그려져 번들 설치(232) 아래였고, 투어는 245 인데 240 이라 가져오기와 같은 층이었다.
Esc 는 표 순서대로 위엣것부터 닫는데 눈에 보이는 순서는 반대가 되는 자리다.
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.
Three shim functions ask the user something. All three answered without asking:
In the VS Code contract
undefinedmeans the user cancelled. So an extension concluded it had been cancelled without a prompt ever appearing, and dropped whatever it was doing — no error, no toast. The third is the worst of them, because a toast does appear, so something looks like it happened. Meanwhile the near-universalwas permanently false.
What it does now
All three open a real dialog. A pick returns the item the extension passed in, not a copy — extensions usually branch on a field they attached themselves. Supported:
canPickMany, item arrays given as a Promise,matchOnDescription/matchOnDetail,password, andvalidateInput.validateInputalso runs when the dialog opens. An extension's initial value can already violate its own rule, and with no marking you have to press OK to find out why OK does not work.A message with no buttons stays a toast. A notification should not block the flow — that distinction is the whole reason VS Code overloads one function.
Every prompt names the extension asking. If a dialog an extension opened reads as one the app opened, uninstalling the extension leaves you suspecting the app.
The filtering logic — normalize, match, cursor, validate — is a pure module with 26 tests.
Also: overlay z-index now comes from the table
The overlay table says a render's
zIndexliteral must equal itsz. Saying it in a comment was not enough, and two had drifted: the confirm dialog is 233 in the table but rendered at 231, below the bundle installer at 232; the tour is 245 but rendered at 240, the same layer as the import dialog. Esc closes top-down by the table while the eye sees the opposite order — you press Esc at the dialog in front and the answer goes to the one hidden behind it. The render now readsoverlayZ(id), so there is nowhere left for them to drift.Verification
A real VS Code extension planted in the extensions folder, calling through
require("vscode")— 18 of 18:descriptionwhen asked to, and returns the original object ({label:"파랑", description:"cool", id:2})canPickManyreturns["a","c"]after Space-toggling two rowsshowInputBoxstarts with the extension's value, shows the validation message straight away, refuses to close while invalid, clears the message when fixed, returns the typed stringshowInformationMessage(msg, "Reload", {title:"Later", isCloseAffordance:true})renders both buttons and returns"Reload"undefinedundefined716 tests,
npm run typecheckclean.Measured against the dev bundle — the harness needs
localStorageto seed a workspace andfile://blocks it. Verification also required #40; without it the probe extension could not load at all.