forked from asyncapi/vs-asyncapi-preview
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
improve editing experience w/ content assistance asyncapi#132 asyncap…
- Loading branch information
Showing
6 changed files
with
211 additions
and
116 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import * as vscode from 'vscode'; | ||
import * as path from 'path'; | ||
|
||
export function previewAsyncAPI(context) { | ||
return async (uri: vscode.Uri) => { | ||
uri = uri || (await promptForAsyncapiFile()) as vscode.Uri; | ||
if (uri) { | ||
console.log('Opening asyncapi file', uri.fsPath); | ||
openAsyncAPI(context, uri); | ||
} | ||
}; | ||
} | ||
|
||
export const openAsyncapiFiles: { [id: string]: vscode.WebviewPanel } = {}; // vscode.Uri.fsPath => vscode.WebviewPanel | ||
|
||
export function isAsyncAPIFile(document?: vscode.TextDocument) { | ||
if (!document) { | ||
return false; | ||
} | ||
if (document.languageId === 'json') { | ||
try { | ||
const json = JSON.parse(document.getText()); | ||
return json.asyncapi; | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
if (document.languageId === 'yml' || document.languageId === 'yaml') { | ||
return document.getText().match('^asyncapi:') !== null; | ||
} | ||
return false; | ||
} | ||
|
||
export function openAsyncAPI(context: vscode.ExtensionContext, uri: vscode.Uri) { | ||
const localResourceRoots = [ | ||
vscode.Uri.file(path.dirname(uri.fsPath)), | ||
vscode.Uri.joinPath(context.extensionUri, 'dist/node_modules/@asyncapi/react-component/browser/standalone'), | ||
vscode.Uri.joinPath(context.extensionUri, 'dist/node_modules/@asyncapi/react-component/styles'), | ||
]; | ||
if (vscode.workspace.workspaceFolders) { | ||
vscode.workspace.workspaceFolders.forEach(folder => { | ||
localResourceRoots.push(folder.uri); | ||
}); | ||
} | ||
const panel: vscode.WebviewPanel = | ||
openAsyncapiFiles[uri.fsPath] || | ||
vscode.window.createWebviewPanel('asyncapi-preview', '', vscode.ViewColumn.Two, { | ||
enableScripts: true, | ||
retainContextWhenHidden: true, | ||
localResourceRoots, | ||
}); | ||
panel.title = path.basename(uri.fsPath); | ||
panel.webview.html = getWebviewContent(context, panel.webview, uri); | ||
|
||
panel.onDidDispose(() => { | ||
delete openAsyncapiFiles[uri.fsPath]; | ||
}); | ||
openAsyncapiFiles[uri.fsPath] = panel; | ||
} | ||
|
||
async function promptForAsyncapiFile() { | ||
if (isAsyncAPIFile(vscode.window.activeTextEditor?.document)) { | ||
return vscode.window.activeTextEditor?.document.uri; | ||
} | ||
return await vscode.window.showOpenDialog({ | ||
canSelectFiles: true, | ||
canSelectFolders: false, | ||
canSelectMany: false, | ||
openLabel: 'Open AsyncAPI file', | ||
filters: { | ||
AsyncAPI: ['yml', 'yaml', 'json'], | ||
}, | ||
}); | ||
} | ||
|
||
function getWebviewContent(context: vscode.ExtensionContext, webview: vscode.Webview, asyncapiFile: vscode.Uri) { | ||
const asyncapiComponentJs = webview.asWebviewUri( | ||
vscode.Uri.joinPath(context.extensionUri, 'dist/node_modules/@asyncapi/react-component/browser/standalone/index.js') | ||
); | ||
const asyncapiComponentCss = webview.asWebviewUri( | ||
vscode.Uri.joinPath(context.extensionUri, 'dist/node_modules/@asyncapi/react-component/styles/default.min.css') | ||
); | ||
const asyncapiWebviewUri = webview.asWebviewUri(asyncapiFile); | ||
const asyncapiBasePath = asyncapiWebviewUri.toString().replace('%2B', '+'); // this is loaded by a different library so it requires unescaping the + character | ||
const html = ` | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<link rel="stylesheet" href="${asyncapiComponentCss}"> | ||
</head> | ||
<body x-timestamp="${Date.now()}"> | ||
<div id="asyncapi"></div> | ||
<script src="${asyncapiComponentJs}"></script> | ||
<script> | ||
AsyncApiStandalone.render({ | ||
schema: { | ||
url: '${asyncapiWebviewUri}', | ||
options: { method: "GET", mode: "cors" }, | ||
}, | ||
config: { | ||
show: { | ||
sidebar: true, | ||
errors: true, | ||
}, | ||
parserOptions: { path: '${asyncapiBasePath}' } | ||
}, | ||
}, document.getElementById('asyncapi')); | ||
</script> | ||
</body> | ||
</html> | ||
`; | ||
return html; | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import * as vscode from 'vscode'; | ||
import * as yml from 'js-yaml'; | ||
import { createSchema } from './lib/genson-js/schema-builder'; | ||
|
||
export async function asyncapiSmartPaste() { | ||
let editor = vscode.window.activeTextEditor; | ||
if(!editor) { | ||
return; | ||
} | ||
let start = editor.selection.start; | ||
let end = editor.selection.end; | ||
let selectedText = editor.document.getText(editor.selection); | ||
let currentLineText = editor.document.lineAt(start.line).text; | ||
let clipboad = await vscode.env.clipboard.readText(); | ||
|
||
console.log("Smart Pasting", clipboad); | ||
const json = parse(clipboad); | ||
if(typeof json === 'object') { | ||
const schema = { PastedSchema: createSchema(json) }; | ||
replace(editor, stringify(schema, editor.document.languageId, 4), editor.selection); | ||
return; | ||
} | ||
|
||
|
||
return vscode.commands.executeCommand('editor.action.clipboardPasteAction'); | ||
} | ||
|
||
function insertNewLine(editor: vscode.TextEditor, text: string, line: number) { | ||
editor.edit((editBuilder: vscode.TextEditorEdit) => { | ||
editBuilder.insert(new vscode.Position(line + 1, 0), text + '\n'); | ||
}); | ||
} | ||
|
||
function replace(editor: vscode.TextEditor, text: string, selection: vscode.Selection) { | ||
editor.edit((editBuilder: vscode.TextEditorEdit) => { | ||
editBuilder.replace(selection, text); | ||
editor.revealRange(new vscode.Range(selection.start, selection.start)); | ||
}); | ||
} | ||
|
||
function parse(text: string) { | ||
try { | ||
return JSON.parse(text); | ||
} catch (e) { | ||
try { | ||
return yml.load(text); | ||
} catch (e) { | ||
return text; | ||
} | ||
} | ||
} | ||
|
||
function stringify(schema, languageId: string, indentYml: number) { | ||
if(languageId === 'json') { | ||
return JSON.stringify(schema, null, 2); | ||
} else { | ||
return yml.dump(schema).replace(/^(?!\s*$)/gm, ' '.repeat(indentYml)); | ||
} | ||
} |
This file contains 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
This file contains 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