Skip to content

Commit 400379d

Browse files
fix(Sky): Fix 0-based line indexing for search results and add diagnostic tracing
The search result `RangeLocations` was using 1-based line numbers, causing 'undefined is not an object' errors for single-line previews because `previewLines[1]` was out of bounds. VS Code's `MatchImpl` indexes `_fullPreviewLines` directly with 0-based indexing, so convert both `source` and `preview` to 0-based: `SourceLine = Math.max(0, M.lineNumber - 1)`. Also add comprehensive diagnostic bridging to Mountain.dev.log for service shape probing. The original `console.log` only surfaces in DevTools which is invisible to log dissection. Add `ToMountain` helper that invokes `diagnostic:log` through the same `MountainIPCInvoke` path SkyBridge uses, making service shape and webview registration observable in Mountain's logs. Include `ResourceTree`, `UriIdentity`, `WebviewViews`, and `Markers` in the key probe list, and probe one level deeper for `WebviewViews.register` and `Markers.changeOne` to distinguish stubs from real implementations. This restores search functionality and provides post-mortem visibility into the service initialization that drives the Problems panel and sidebar webviews.
1 parent f87442b commit 400379d

1 file changed

Lines changed: 80 additions & 22 deletions

File tree

Source/Function/SkyBridge.ts

Lines changed: 80 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -247,12 +247,41 @@ function GetServices(): CelServices | null {
247247
{
248248
const ProbeServices = (): void => {
249249
const S = GetServices() as Record<string, unknown> | null;
250+
// Bridge the probe through `MountainIPCInvoke` so the per-key
251+
// service shape lands in `Mountain.dev.log` under the
252+
// `[diagnostic]` tag. The original `console.log` only surfaces
253+
// in DevTools, which is invisible to log dissection - silent
254+
// `Markers=null` / `WebviewViews=null` resolutions caused
255+
// SkyBridge bridges (Problems-panel push, sidebar webview
256+
// resolver) to no-op without any trace anywhere. Use the
257+
// pre-bound `__TAURI__.core.invoke` (same surface SkyBridge
258+
// already uses below) so we don't re-import.
259+
const ToMountain = (Tag: string, Message: string): void => {
260+
try {
261+
const Inv =
262+
(globalThis as any).__TAURI__?.core?.invoke ??
263+
(globalThis as any).__TAURI__?.invoke;
264+
if (typeof Inv === "function") {
265+
Inv("MountainIPCInvoke", {
266+
method: "diagnostic:log",
267+
params: [Tag, Message],
268+
}).catch(() => {});
269+
}
270+
} catch {}
271+
};
250272
if (!S) {
251273
try {
252274
console.warn("[Sky:CEL] __CEL_SERVICES__ missing on probe");
253275
} catch {}
276+
ToMountain("cel-services", "__CEL_SERVICES__ missing on probe");
254277
return;
255278
}
279+
// Every `__CEL_SERVICES__` key the workbench transform installs
280+
// (see `Output/Source/Plugin/Transform/ExposeWorkbenchAccessor.ts`).
281+
// `WebviewViews` and `Markers` are the leverage keys for the
282+
// current "panes don't show / Problems empty" symptoms - keep
283+
// them in the list even if they look incidental, since the
284+
// shape line is the only post-mortem signal we have.
256285
const Keys = [
257286
"Statusbar",
258287
"Commands",
@@ -269,13 +298,24 @@ function GetServices(): CelServices | null {
269298
"ToDisposable",
270299
"Models",
271300
"Languages",
301+
"ResourceTree",
302+
"UriIdentity",
303+
"WebviewViews",
304+
"Markers",
272305
];
273306
const Shape = Keys.map(
274307
(K) => `${K}=${S[K] == null ? "null" : typeof S[K]}`,
275308
).join(" ");
276309
try {
277310
console.log(`[Sky:CEL] services-ready ${Shape}`);
278311
} catch {}
312+
ToMountain("cel-services", `shape ${Shape}`);
313+
// Probe one level deeper for the two services the current bug
314+
// hunt depends on, so a `WebviewViews=object` line that is
315+
// nonetheless missing `.register` (e.g. a stub that resolved
316+
// but isn't the real `WebviewViewService`) still surfaces.
317+
const RegisterShape = `WebviewViews.register=${typeof (S["WebviewViews"] as any)?.register} Markers.changeOne=${typeof (S["Markers"] as any)?.changeOne}`;
318+
ToMountain("cel-services", RegisterShape);
279319
};
280320
if (typeof window !== "undefined") {
281321
// If services already ready by the time this module loads, probe
@@ -1012,41 +1052,46 @@ export async function InstallSkyBridge(): Promise<void> {
10121052
// When Mountain didn't supply columns (older ripgrep
10131053
// path or zero-width match), produce a single full-
10141054
// line range so the row still renders.
1055+
// `MatchImpl` (workbench/contrib/search/.../match.ts:31)
1056+
// indexes `_fullPreviewLines[startLineNumber]` directly,
1057+
// then +1's both axes when constructing the editor
1058+
// `Range`. So both `source` and `preview` must be
1059+
// fully 0-based here. Earlier shape was 1-based on the
1060+
// preview, which made `previewLines[1]` === undefined
1061+
// for single-line previews and produced
1062+
// "undefined is not an object (evaluating
1063+
// 'this._oneLinePreviewText.substring')". Source was
1064+
// also off-by-one (line and column too high by 1).
1065+
const SourceLine = Math.max(0, M.lineNumber - 1);
10151066
const RangeLocations =
10161067
M.columns.length > 0
10171068
? M.columns.map((C) => ({
10181069
source: {
1019-
startLineNumber: M.lineNumber,
1020-
startColumn: C.start + 1,
1021-
endLineNumber: M.lineNumber,
1022-
endColumn: C.end + 1,
1070+
startLineNumber: SourceLine,
1071+
startColumn: C.start,
1072+
endLineNumber: SourceLine,
1073+
endColumn: C.end,
10231074
},
10241075
preview: {
1025-
startLineNumber: 1,
1026-
startColumn: C.start + 1,
1027-
endLineNumber: 1,
1028-
endColumn: C.end + 1,
1076+
startLineNumber: 0,
1077+
startColumn: C.start,
1078+
endLineNumber: 0,
1079+
endColumn: C.end,
10291080
},
10301081
}))
10311082
: [
10321083
{
10331084
source: {
1034-
startLineNumber: M.lineNumber,
1035-
startColumn: 1,
1036-
endLineNumber: M.lineNumber,
1037-
endColumn: Math.max(
1038-
1,
1039-
M.preview.length + 1,
1040-
),
1085+
startLineNumber: SourceLine,
1086+
startColumn: 0,
1087+
endLineNumber: SourceLine,
1088+
endColumn: M.preview.length,
10411089
},
10421090
preview: {
1043-
startLineNumber: 1,
1044-
startColumn: 1,
1045-
endLineNumber: 1,
1046-
endColumn: Math.max(
1047-
1,
1048-
M.preview.length + 1,
1049-
),
1091+
startLineNumber: 0,
1092+
startColumn: 0,
1093+
endLineNumber: 0,
1094+
endColumn: M.preview.length,
10501095
},
10511096
},
10521097
];
@@ -2584,8 +2629,21 @@ export async function InstallSkyBridge(): Promise<void> {
25842629
detail: { handle: Handle, viewId: ViewId, payload: Payload },
25852630
}),
25862631
);
2632+
// Per-fire trace so the SkyEmit -> Sky-listener bridge is
2633+
// observable in Mountain.dev.log. The listener used to silently
2634+
// `return` when `Services?.WebviewViews?.register` was missing,
2635+
// which made post-mortem indistinguishable from "Sky listener
2636+
// never fired".
25872637
try {
25882638
const Services: any = (globalThis as any).__CEL_SERVICES__;
2639+
const Reg = Services?.WebviewViews?.register;
2640+
invoke("MountainIPCInvoke", {
2641+
method: "diagnostic:log",
2642+
params: [
2643+
"webview-bridge",
2644+
`registerView viewId=${ViewId} handle=${Handle} hasRegister=${typeof Reg === "function"}`,
2645+
],
2646+
}).catch(() => {});
25892647
if (!Services?.WebviewViews?.register) return;
25902648
Services.WebviewViews.register(ViewId, {
25912649
resolve: async (WebviewView: any, _Cancellation: any) => {

0 commit comments

Comments
 (0)