Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | 27x 27x 4x 2x 1x 1x 16x 16x 16x 16x 16x 16x 16x 7x 7x 6x 6x 16x 6x 6x 6x 16x 4x 4x 2x 4x 16x 4x 4x 1x 1x 3x 3x 1x 16x 4x 3x 16x 11x 4x 7x 2x 5x 4x 5x 16x 1x 1x 1x | import * as vscode from 'vscode';
import { inferFileType } from './editorTypes';
import { applyTextDocumentContent } from './textDocumentEdits';
import { configureEditorWebview, getResourceBaseUri } from './webviewHost';
export class VibeCustomTextEditorProvider implements vscode.CustomTextEditorProvider {
private readonly panels = new Set<vscode.WebviewPanel>();
constructor(private readonly context: vscode.ExtensionContext) {}
toggleMode() {
for (const panel of this.panels) {
if (panel.active) {
panel.webview.postMessage({ type: 'toggleMode' });
return;
}
}
}
async resolveCustomTextEditor(
document: vscode.TextDocument,
panel: vscode.WebviewPanel,
_token: vscode.CancellationToken,
): Promise<void> {
const resourceKey = document.uri.toString();
const fileType = inferFileType(document.uri.fsPath);
let lastSentContent: string | undefined;
let webviewMessageQueue: Promise<unknown> = Promise.resolve();
this.panels.add(panel);
panel.iconPath = new vscode.ThemeIcon('open-preview');
configureEditorWebview(this.context, panel, document.uri);
const postDocumentContent = (force = false) => {
const content = document.getText();
if (!force && content === lastSentContent) return;
lastSentContent = content;
panel.webview.postMessage({
type: 'update',
content,
baseUri: getResourceBaseUri(panel, document.uri),
fileType,
});
};
const enqueueWebviewMessage = <T>(task: () => Promise<T>) => {
const run = webviewMessageQueue.then(task, task);
webviewMessageQueue = run.catch(() => undefined);
return run;
};
const applyContentFromWebview = async (content: string) => {
const applied = await applyTextDocumentContent(document, content);
if (applied) {
lastSentContent = content;
}
return applied;
};
const saveDocument = async (content?: string) => {
const applied = typeof content === 'string'
? await applyContentFromWebview(content)
: true;
if (!applied) {
vscode.window.showErrorMessage(`Failed to apply changes before saving ${document.fileName}.`);
return;
}
const saved = await document.save();
if (!saved) {
vscode.window.showErrorMessage(`Failed to save ${document.fileName}.`);
}
};
const changeListener = vscode.workspace.onDidChangeTextDocument(event => {
if (event.document.uri.toString() === resourceKey) {
postDocumentContent();
}
});
const messageListener = panel.webview.onDidReceiveMessage(message => {
if (message.type === 'ready') {
postDocumentContent(true);
} else if (message.type === 'edit' && typeof message.content === 'string') {
return enqueueWebviewMessage(() => applyContentFromWebview(message.content));
} else if (message.type === 'save') {
return enqueueWebviewMessage(() => saveDocument(typeof message.content === 'string' ? message.content : undefined));
}
return undefined;
});
panel.onDidDispose(() => {
this.panels.delete(panel);
changeListener.dispose();
messageListener.dispose();
});
}
}
|