feat: 增加通过快捷键唤出正则图解的功能

This commit is contained in:
microud 2020-03-23 00:06:40 +08:00
parent 475be25ab2
commit 3d646548e3
7 changed files with 114 additions and 20 deletions

View File

@ -33,6 +33,14 @@
], ],
"main": "./out/extension.js", "main": "./out/extension.js",
"contributes": { "contributes": {
"keybindings": [
{
"command": "extension.showDiagram",
"key": "ctrl+f10",
"mac": "cmd+f10",
"when": "editorTextFocus"
}
],
"configuration": { "configuration": {
"type": "object", "type": "object",
"title": "any-rule", "title": "any-rule",
@ -54,6 +62,10 @@
] ]
}, },
"commands": [ "commands": [
{
"command": "extension.showDiagram",
"title": "查看当前行正则的图解"
},
{ {
"command": "extension.rule0", "command": "extension.rule0",
"title": "$(rocket) zz: 火车车次" "title": "$(rocket) zz: 火车车次"
@ -316,7 +328,7 @@
"mocha": "^6.1.4", "mocha": "^6.1.4",
"ts-loader": "^6.2.1", "ts-loader": "^6.2.1",
"tslint": "^5.12.1", "tslint": "^5.12.1",
"typescript": "^3.3.1", "typescript": "^3.8.3",
"vsce": "^1.74.0", "vsce": "^1.74.0",
"vscode-test": "^1.0.2", "vscode-test": "^1.0.2",
"webpack": "^4.41.6", "webpack": "^4.41.6",
@ -326,6 +338,7 @@
"axios": "^0.19.2", "axios": "^0.19.2",
"react": "^16.13.1", "react": "^16.13.1",
"react-dom": "^16.13.1", "react-dom": "^16.13.1",
"regulex-cjs": "^0.0.7",
"transliteration": "^2.1.8" "transliteration": "^2.1.8"
} }
} }

View File

@ -1,4 +1,4 @@
import { Webview, window, ViewColumn, Uri, ExtensionContext } from 'vscode'; import { TextEditor, window, ViewColumn, Uri, ExtensionContext, Range, commands } from 'vscode';
import * as path from 'path'; import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
@ -32,14 +32,34 @@ function getWebViewContent(context: ExtensionContext, templatePath: string) {
} }
export default function useDiagram(context: ExtensionContext) { export default function useDiagram(context: ExtensionContext) {
commands.registerTextEditorCommand('extension.showDiagram', (editor, edit) => {
console.log('show diagram triggered');
const position = editor?.selection.active;
const line = editor?.document.lineAt(position?.line!);
const text = editor?.document.getText(new Range(line?.range.start!, line?.range.end!));
const regex = /(?<!\\)\/(.+?)(?<!\\)\//g;
const regexpList: string[] = []; // text?.match(/(?<!\\)\/(.+?)(?<!\\)\//g);
let matches;
while ((matches = regex.exec(text)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (matches.index === regex.lastIndex) {
regex.lastIndex++;
}
regexpList.push(matches[1]);
}
const panel = window.createWebviewPanel( const panel = window.createWebviewPanel(
'Diagram', 'Diagram',
'Diagram', 'Diagram',
ViewColumn.One, ViewColumn.Two,
{ {
enableScripts: true, enableScripts: true,
} }
); );
panel.webview.html = getWebViewContent(context, 'out/diagram/index.html') panel.webview.html = getWebViewContent(context, 'out/diagram/index.html')
.replace('{{ inject-script }}', `<script src="${getExtensionFileVscodeResource(context, 'out/diagram/diagram.js')}"></script>`); .replace('{{ inject-script }}', `<script src="${getExtensionFileVscodeResource(context, 'out/diagram/diagram.js')}"></script>`);
panel.webview.postMessage({
regexpGroups: regexpList,
});
});
} }

View File

@ -1,12 +1,12 @@
import * as React from 'react'; import * as React from 'react';
import * as ReactDOM from 'react-dom'; import * as ReactDOM from 'react-dom';
import { RegexpDiagram } from './views/RegexpDiagram'; import { RegexpDiagramView } from './views/RegexpDiagram';
class App extends React.Component { class App extends React.Component {
render() { render() {
return ( return (
<div className="app"> <div className="app">
<RegexpDiagram /> <RegexpDiagramView />
</div> </div>
); );
} }

View File

@ -0,0 +1,20 @@
import * as React from 'react';
import { parse, visualize, Raphael } from 'regulex-cjs';
import { useEffect } from 'react';
interface IDiagramProps {
regexp: string | RegExp;
}
export const RegExpDiagram: React.FC<IDiagramProps> = (props) => {
useEffect(() => {
const regexpString = typeof props.regexp === 'string' ? props.regexp : props.regexp.source;
const ast = parse(regexpString);
const paper = Raphael('regexp-diagram');
visualize(ast, 'g', paper, { color: { background: 'transparent' } });
});
return (
<div id="regexp-diagram" />
);
};

View File

@ -1,3 +1,11 @@
import { Render } from "./App"; import { Render } from "./App";
window.addEventListener('message', event => {
const regexpGroups = event.data.regexpGroups;
console.log(event.data);
// @ts-ignore
window.regexpGroups = regexpGroups;
// @ts-ignore
console.log(window.regexpGroups);
Render(); Render();
});

View File

@ -1,7 +1,15 @@
import * as React from 'react'; import * as React from 'react';
import { RegExpDiagram } from '../components/Diagram';
export const RegexpDiagram: React.FC = () => { export const RegexpDiagramView: React.FC = () => {
// @ts-ignore
const regexpGroups = window.regexpGroups;
console.log(regexpGroups);
return ( return (
<div>Test</div> <>
<div>
{regexpGroups.map((regexp: string) => <RegExpDiagram regexp={new RegExp(regexp)} />)}
</div>
</>
); );
}; };

View File

@ -62,6 +62,11 @@
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
"@types/raphael@^2.1.30":
version "2.1.30"
resolved "https://registry.yarnpkg.com/@types/raphael/-/raphael-2.1.30.tgz#76cbea4a556ba25eb1c6d7fa5e71ac48e72f81cf"
integrity sha1-dsvqSlVrol6xxtf6XnGsSOcvgc8=
"@types/react-dom@^16.9.5": "@types/react-dom@^16.9.5":
version "16.9.5" version "16.9.5"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.5.tgz#5de610b04a35d07ffd8f44edad93a71032d9aaa7" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.5.tgz#5de610b04a35d07ffd8f44edad93a71032d9aaa7"
@ -1267,6 +1272,11 @@ esutils@^2.0.2:
resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
eve-raphael@0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/eve-raphael/-/eve-raphael-0.5.0.tgz#17c754b792beef3fa6684d79cf5a47c63c4cda30"
integrity sha1-F8dUt5K+7z+maE15z1pHxjxM2jA=
events@^3.0.0: events@^3.0.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.npmjs.org/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" resolved "https://registry.npmjs.org/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59"
@ -2856,6 +2866,13 @@ randomfill@^1.0.3:
randombytes "^2.0.5" randombytes "^2.0.5"
safe-buffer "^5.1.0" safe-buffer "^5.1.0"
raphael@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/raphael/-/raphael-2.3.0.tgz#eabeb09dba861a1d4cee077eaafb8c53f3131f89"
integrity sha512-w2yIenZAQnp257XUWGni4bLMVxpUpcIl7qgxEgDIXtmSypYtlNxfXWpOBxs7LBTps5sDwhRnrToJrMUrivqNTQ==
dependencies:
eve-raphael "0.5.0"
react-dom@^16.13.1: react-dom@^16.13.1:
version "16.13.1" version "16.13.1"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f"
@ -2926,6 +2943,14 @@ regex-not@^1.0.0, regex-not@^1.0.2:
extend-shallow "^3.0.2" extend-shallow "^3.0.2"
safe-regex "^1.1.0" safe-regex "^1.1.0"
regulex-cjs@^0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/regulex-cjs/-/regulex-cjs-0.0.7.tgz#bfa626832d1f77a3c5ed0ab0b17544a48d1f565d"
integrity sha512-Bl5wp9OpM3KdAJTfAjN0TGWgJRz2MGt6B0/qlGxTOKvGaCc1bYCHchfhUds3UduS5HuS9O4Uzjq4ZCOKvNg/wQ==
dependencies:
"@types/raphael" "^2.1.30"
raphael "^2.3.0"
remove-trailing-separator@^1.0.1: remove-trailing-separator@^1.0.1:
version "1.1.0" version "1.1.0"
resolved "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" resolved "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
@ -3520,10 +3545,10 @@ typedarray@^0.0.6:
resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
typescript@^3.3.1: typescript@^3.8.3:
version "3.5.3" version "3.8.3"
resolved "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061"
integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g== integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==
uc.micro@^1.0.1, uc.micro@^1.0.5: uc.micro@^1.0.1, uc.micro@^1.0.5:
version "1.0.6" version "1.0.6"