Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a 'recompile' button #141

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@
}
],
"line-comment-position": "error",
"linebreak-style": ["error", "unix"],
"lines-around-comment": "off",
"lines-around-directive": "error",
"lines-between-class-members": [
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ dist
npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json
5 changes: 4 additions & 1 deletion .prettierrc.json
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
{}
{
"endOfLine": "auto",
"printWidth": 90
}
2 changes: 1 addition & 1 deletion make.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ PATH="$(cd -- "$(dirname "$0")" && pwd)/ci/sub/bin:$PATH"
cd "$(dirname "$0")"

lint() {
sh_c hide xargsd "'\.\(ts\|tsx\|scss\|css\)$'" npx eslint@8.36.0
sh_c hide xargsd "'\.\(ts\|tsx\|scss\|css\)$'" npx eslint@8.40.0
}

ensure_changed_files
Expand Down
32 changes: 17 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -316,26 +316,28 @@
"@types/glob": "^8.0.0",
"@types/markdown-it-container": "^2.0.5",
"@types/mocha": "^10.0.0",
"@types/node": "16.x",
"@types/node": "20.12.12",
"@types/vscode": "^1.73.0",
"@typescript-eslint/eslint-plugin": "^5.50.0",
"@typescript-eslint/parser": "^5.50.0",
"@vscode/test-electron": "^2.2.0",
"@vscode/vsce": "^2.15.0",
"eslint": "^8.33.0",
"eslint-config-prettier": "^8.6.0",
"eslint-formatter-pretty": "^4.1.0",
"eslint-webpack-plugin": "^3.2.0",
"glob": "^8.0.3",
"mocha": "^10.1.0",
"prettier": "^2.8.3",
"@typescript-eslint/eslint-plugin": "^7.9.0",
"@typescript-eslint/parser": "^7.9.0",
"@vscode/test-electron": "^2.3.10",
"@vscode/vsce": "^2.26.1",
"eslint": "^9.2.0",
"eslint-config-prettier": "^9.1.0",
"eslint-formatter-pretty": "^6.0.1",
"eslint-webpack-plugin": "^4.1.0",
"glob": "^10.3.15",
"mocha": "^10.4.0",
"prettier": "^3.2.5",
"ts-loader": "^9.4.2",
"typescript": "^4.9.4",
"typescript": "^5.4.5",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0"
"webpack-cli": "^5.1.4"
},
"dependencies": {
"markdown-it-container": "^3.0.0"
"async-mutex": "^0.5.0",
"istanbul-lib-coverage": "^3.2.2",
"markdown-it-container": "^4.0.0"
},
"homepage": "https://d2lang.com",
"icon": "d2-icon.png",
Expand Down
57 changes: 46 additions & 11 deletions pages/previewPage.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
background-color: var(--vscode-button-background);
padding: 5px;
border: 0px;
min-width: 50px;
min-width: 25px;
}

body {
Expand All @@ -66,10 +66,20 @@
height: 100%;
}

path {
fill: var(--vscode-button-foreground);
}

#previewWrapper {
transform-origin: left top;
box-sizing: border-box;
margin-top: 45px;
position: absolute;
top: 10px;
left: 0px;
right: 0px;
}

#progressBar {
position: fixed;
margin-left: -10px;
Expand Down Expand Up @@ -106,7 +116,7 @@
#toastMsg {
margin-top: 0px;
margin-left: 3px;
font-size: x-large;
font-size: larger;
font-family: Arial, Helvetica, sans-serif;
}

Expand Down Expand Up @@ -180,17 +190,18 @@
setZoomLevel(zoomSlider.value);
}
function setZoomText(text) {
if (text === true) {
percent.innerText = zoomLevel.toFixed() + "%";
} else {
percent.innerText = "Fit";
}
percent.innerText = zoomLevel.toFixed() + "%";
}

function roundToZoomLevel(zl) {
var newZl = Math.round(zl + zoomStep) - Math.round(zl % zoomStep);
return Math.max(10, newZl);
}

function refreshPage() {
vscode.postMessage({ command: "refreshPage" });
}

window.addEventListener("DOMContentLoaded", () => {
init();
});
Expand Down Expand Up @@ -265,7 +276,13 @@

<body>
<div id="toolbar">
<button onclick="zoomMinus();" title="Zoom Out">Out</button>
<button onclick="zoomMinus();" title="Zoom Out">
<svg id="zoom-out" viewBox="0 -25 122 140">
<path
d="M49.991,0h0.015v0.006c13.794,0.004,26.294,5.601,35.336,14.645 c9.026,9.031,14.618,21.515,14.628,35.303h0.006v0.034v0.04h-0.006c-0.005,5.557-0.918,10.905-2.594,15.892 c-0.281,0.837-0.576,1.641-0.877,2.409v0.007c-1.446,3.661-3.315,7.12-5.548,10.307l29.08,26.14l0.018,0.015l0.157,0.146 l0.012,0.012c1.641,1.563,2.535,3.656,2.648,5.779c0.11,2.1-0.538,4.248-1.976,5.971l-0.011,0.016l-0.176,0.204l-0.039,0.046 l-0.145,0.155l-0.011,0.011c-1.563,1.642-3.656,2.539-5.782,2.651c-2.104,0.111-4.254-0.54-5.975-1.978l-0.012-0.012l-0.203-0.175 l-0.029-0.024L78.764,90.865c-0.88,0.62-1.779,1.207-2.687,1.763c-1.234,0.756-2.51,1.467-3.816,2.117 c-6.699,3.342-14.266,5.223-22.27,5.223v0.006h-0.016v-0.006c-13.797-0.005-26.297-5.601-35.334-14.644l-0.004,0.005 C5.608,76.3,0.016,63.81,0.007,50.021H0v-0.033v-0.016h0.007c0.005-13.799,5.601-26.297,14.646-35.339 C23.684,5.607,36.169,0.015,49.958,0.006V0H49.991L49.991,0z M67.787,43.397c1.21-0.007,2.353,0.312,3.322,0.872l-0.002,0.002 c0.365,0.21,0.708,0.454,1.01,0.715c0.306,0.264,0.594,0.569,0.851,0.895h0.004c0.873,1.11,1.397,2.522,1.394,4.053 c-0.003,1.216-0.335,2.358-0.906,3.335c-0.454,0.78-1.069,1.461-1.791,1.996c-0.354,0.261-0.751,0.496-1.168,0.688v0.002 c-0.823,0.378-1.749,0.595-2.722,0.6l-35.166,0.248c-1.209,0.011-2.354-0.31-3.327-0.873l0.002-0.002 c-0.37-0.212-0.715-0.458-1.016-0.722c-0.306-0.264-0.589-0.567-0.844-0.891h-0.004c-0.873-1.112-1.397-2.522-1.393-4.053 c0.002-1.213,0.337-2.354,0.906-3.328l-0.004-0.002c0.376-0.642,0.869-1.225,1.442-1.714h0.004 c0.574-0.489,1.236-0.883,1.942-1.151c0.704-0.266,1.484-0.418,2.296-0.423L67.787,43.397L67.787,43.397z M50.006,11.212v0.006 h-0.015h-0.034v-0.006C39.274,11.219,29.59,15.56,22.581,22.566l0.002,0.002c-7.019,7.018-11.365,16.711-11.368,27.404h0.006v0.016 v0.033h-0.006c0.006,10.683,4.347,20.365,11.354,27.377l0.002-0.002c7.018,7.018,16.711,11.365,27.404,11.367v-0.007h0.016h0.033 v0.007c10.685-0.007,20.367-4.348,27.381-11.359c7.012-7.009,11.359-16.702,11.361-27.401H88.76v-0.015v-0.034h0.007 C88.76,39.273,84.419,29.591,77.407,22.58v-0.007C70.398,15.562,60.705,11.214,50.006,11.212L50.006,11.212z"
/>
</svg>
</button>
<input
id="zoomSlider"
title="Zoom"
Expand All @@ -276,10 +293,28 @@
value="100"
step="5"
/>
<button onclick="zoomPlus();" title="Zoom In">In</button>
<button onclick="zoomPlus();" title="Zoom In">
<svg id="zoom-in" viewBox="0 -25 122 140">
<path
d="M49.991,0h0.015v0.006c13.794,0.004,26.294,5.601,35.336,14.645c9.026,9.031,14.618,21.515,14.628,35.303h0.006v0.034v0.04 h-0.006c-0.005,5.557-0.918,10.905-2.594,15.892c-0.281,0.837-0.576,1.641-0.877,2.409v0.007c-1.446,3.661-3.315,7.12-5.548,10.307 l29.08,26.14l0.018,0.015l0.157,0.146l0.012,0.012c1.641,1.563,2.535,3.656,2.648,5.779c0.11,2.1-0.538,4.248-1.976,5.971 l-0.011,0.016l-0.176,0.204l-0.039,0.046l-0.145,0.155l-0.011,0.011c-1.563,1.642-3.656,2.539-5.782,2.651 c-2.104,0.111-4.254-0.54-5.975-1.978l-0.012-0.012l-0.203-0.175l-0.029-0.024L78.764,90.865c-0.88,0.62-1.779,1.207-2.687,1.763 c-1.234,0.756-2.51,1.467-3.816,2.117c-6.699,3.342-14.266,5.223-22.27,5.223v0.006h-0.016v-0.006 c-13.797-0.005-26.297-5.601-35.334-14.644l-0.004,0.005C5.608,76.3,0.016,63.81,0.007,50.021H0v-0.033v-0.016h0.007 c0.005-13.799,5.601-26.297,14.646-35.339C23.684,5.607,36.169,0.015,49.958,0.006V0H49.991L49.991,0z M67.787,43.397 c1.21-0.007,2.353,0.312,3.322,0.872l-0.002,0.002c0.365,0.21,0.708,0.454,1.01,0.715c0.306,0.264,0.594,0.569,0.851,0.895h0.004 c0.873,1.11,1.397,2.522,1.394,4.053c-0.003,1.216-0.335,2.358-0.906,3.335c-0.454,0.78-1.069,1.461-1.791,1.996 c-0.354,0.261-0.751,0.496-1.168,0.688v0.002c-0.823,0.378-1.749,0.595-2.722,0.6l-11.051,0.08l-0.08,11.062 c-0.004,1.034-0.254,2.02-0.688,2.886c-0.188,0.374-0.417,0.737-0.678,1.074l-0.006,0.007c-0.257,0.329-0.551,0.644-0.866,0.919 c-1.169,1.025-2.713,1.649-4.381,1.649v-0.007c-0.609,0-1.195-0.082-1.743-0.232c-1.116-0.306-2.115-0.903-2.899-1.689 c-0.788-0.791-1.377-1.787-1.672-2.893v-0.006c-0.144-0.543-0.22-1.128-0.215-1.728v-0.005l0.075-10.945l-10.962,0.076 c-1.209,0.011-2.354-0.31-3.327-0.873l0.002-0.002c-0.37-0.212-0.715-0.458-1.016-0.722c-0.306-0.264-0.589-0.567-0.844-0.891 h-0.004c-0.873-1.112-1.397-2.522-1.393-4.053c0.002-1.213,0.337-2.354,0.906-3.328l-0.004-0.002 c0.376-0.642,0.869-1.225,1.442-1.714h0.004c0.574-0.489,1.236-0.883,1.942-1.151c0.704-0.266,1.484-0.418,2.296-0.423 l11.051-0.082l0.08-11.062c0.004-1.207,0.345-2.345,0.921-3.309l0.004,0.002c0.224-0.374,0.467-0.715,0.727-1.003 c0.264-0.296,0.576-0.584,0.908-0.839l0.005-0.004v0.002c1.121-0.861,2.533-1.379,4.055-1.375c1.211,0.002,2.352,0.332,3.317,0.897 c0.479,0.279,0.928,0.631,1.32,1.025l0.004-0.004c0.383,0.383,0.73,0.834,1.019,1.333c0.56,0.968,0.879,2.104,0.868,3.304 l-0.075,10.942L67.787,43.397L67.787,43.397z M50.006,11.212v0.006h-0.015h-0.034v-0.006C39.274,11.219,29.59,15.56,22.581,22.566 l0.002,0.002c-7.019,7.018-11.365,16.711-11.368,27.404h0.006v0.016v0.033h-0.006c0.006,10.683,4.347,20.365,11.354,27.377 l0.002-0.002c7.018,7.018,16.711,11.365,27.404,11.367v-0.007h0.016h0.033v0.007c10.685-0.007,20.367-4.348,27.381-11.359 c7.012-7.009,11.359-16.702,11.361-27.401H88.76v-0.015v-0.034h0.007C88.76,39.273,84.419,29.591,77.407,22.58v-0.007 C70.398,15.562,60.705,11.214,50.006,11.212L50.006,11.212z"
/>
</svg>
</button>
<span id="percent"></span>
<button id="zoomFit" onclick="zoomFit()" title="Fit to window">
Fit to window
<button id="zoomFit" onclick="zoomFit()" title="Zoom to Fit">
<svg id="zoom-to-fit" viewBox="0 -25 122 140">
<title>zoom-to-fit</title>
<path
d="M86.64,12a6,6,0,1,1,0-12H113.8a6,6,0,0,1,6,6V33.66a6,6,0,1,1-12,0V20.45L84.12,44.23a6,6,0,0,1-8.47-8.42L99.41,12ZM12,36.24a6,6,0,1,1-12,0V9.08a6,6,0,0,1,6-6H33.66a6,6,0,1,1,0,12H20.45l23.77,23.7a6,6,0,1,1-8.41,8.47L12,23.47V36.24Zm24.27,64.92a6,6,0,0,1,0,12H9.08a6,6,0,0,1-6-6V79.47a6,6,0,1,1,12,0V92.68l23.7-23.77a6,6,0,0,1,8.47,8.41L23.47,101.16Zm74.67-24.27a6,6,0,0,1,12,0v27.16a6,6,0,0,1-6,6H89.22a6,6,0,1,1,0-12h13.21L78.65,74.37a6,6,0,0,1,8.42-8.47l23.84,23.76V76.89Z"
/>
</svg>
</button>
<button id="refresh" onclick="refreshPage()" title="Recompile">
<svg id="refresh" viewBox="0 -15 122 140">
<path
d="M16.08,59.26A8,8,0,0,1,0,59.26a59,59,0,0,1,97.13-45V8a8,8,0,1,1,16.08,0V33.35a8,8,0,0,1-8,8L80.82,43.62a8,8,0,1,1-1.44-15.95l8-.73A43,43,0,0,0,16.08,59.26Zm22.77,19.6a8,8,0,0,1,1.44,16l-10.08.91A42.95,42.95,0,0,0,102,63.86a8,8,0,0,1,16.08,0A59,59,0,0,1,22.3,110v4.18a8,8,0,0,1-16.08,0V89.14h0a8,8,0,0,1,7.29-8l25.31-2.3Z"
/>
</svg>
</button>
</div>
<div id="previewWrapper" style="margin-top: 45px"></div>
Expand Down
5 changes: 4 additions & 1 deletion src/browserWindow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { existsSync, readFileSync } from "fs";
import * as path from "path";
import { Uri, ViewColumn, Webview, WebviewPanel, window, workspace } from "vscode";
import { D2P } from "./docToPreviewGenerator";
import { extContext } from "./extension";
import { extContext, previewGenerator } from "./extension";
import { util } from "./utility";

/**
Expand Down Expand Up @@ -55,6 +55,9 @@ export class BrowserWindow {
this.webViewPanel.webview.onDidReceiveMessage(
(message) => {
switch (message.command) {
case "refreshPage":
previewGenerator.generateAll();
break;
case "clickOnTag_A": {
const f = message.link.trim().toLowerCase();
const isWeb: boolean = f.startsWith("http://") || f.startsWith("https://");
Expand Down
60 changes: 55 additions & 5 deletions src/docToPreviewGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import * as path from "path";
import { TextDocument } from "vscode";
import { TaskEndEvent, tasks, TextDocument } from "vscode";
import { BrowserWindow } from "./browserWindow";
import { outputChannel, taskRunner } from "./extension";
import { d2TaskName, outputChannel, taskRunner } from "./extension";
import { RefreshTimer } from "./refreshTimer";
import { statSync } from "fs";
import { Mutex } from "async-mutex";

/**
* D2P - Document to Preview. This tracks the connection
Expand All @@ -13,16 +15,30 @@ export class D2P {
inputDoc?: TextDocument;
outputDoc?: BrowserWindow;
timer?: RefreshTimer;
fileDateTime: number = 0;
}

/**
* DocToPreviewGenerator - Keeper of the map of D2P objects
* that allow for associating a document to it's preview
* information.
*
* This object is/must be a Singleton.
**/
export class DocToPreviewGenerator {
mutex: Mutex = new Mutex();
mapOfConnection: Map<TextDocument, D2P> = new Map<TextDocument, D2P>();

constructor() {
// Since this object is a singleton, we don't need to dispose
// this event each time the object is disposed.
tasks.onDidEndTask((e: TaskEndEvent) => {
if (e.execution.task.name === d2TaskName) {
this.mutex.release();
}
});
}

createObjectToTrack(inDoc: TextDocument): D2P {
const trk = new D2P();

Expand Down Expand Up @@ -50,7 +66,41 @@ export class DocToPreviewGenerator {
return this.mapOfConnection.get(inDoc);
}

generate(inDoc: TextDocument): void {
/**
* Get the last modified time of each document we are
* tracking.
**/
private getFileTimes(): void {
this.mapOfConnection.forEach((trk: D2P, td: TextDocument) => {
trk.fileDateTime = statSync(td.uri.fsPath).mtimeMs;
});
}

generateAll(): void {
this.getFileTimes();

// Sort the files oldest to newest. This should catch most
// order of dependency problems witout resorting to dependency
// analysis.
const fileMap = new Map(
[...this.mapOfConnection.entries()].sort(
(a: [TextDocument, D2P], b: [TextDocument, D2P]): number => {
return b[1].fileDateTime - a[1].fileDateTime;
}
)
);

// Regenerate the browser view for all open d2 documents, since
// there are dependencies among all the documents, we have to
// regenerate them one at a time.
fileMap.forEach((_: D2P, td: TextDocument) => {
this.mutex.acquire().then(() => {
this.generate(td, false);
});
});
}

generate(inDoc: TextDocument, openPreview: boolean = true): void {
const trkObj = this.getTrackObject(inDoc);
// if we can't find our tracking info, no sense doing anything
if (!trkObj) {
Expand All @@ -67,14 +117,14 @@ export class DocToPreviewGenerator {
return;
}
// If we don't have a preview window already, create one
if (!trkObj.outputDoc) {
if (!trkObj.outputDoc && openPreview) {
trkObj.outputDoc = new BrowserWindow(trkObj);
trkObj.outputDoc.show();
trkObj.outputDoc.showToast();
trkObj.outputDoc.setToastMsg("Loading...");
}

trkObj.outputDoc.showBusy();
trkObj.outputDoc?.showBusy();

taskRunner.genTask(trkObj.inputDoc?.fileName, fileText, (data, error) => {
const p = path.parse(trkObj.inputDoc?.fileName || "");
Expand Down
21 changes: 11 additions & 10 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,20 @@ import { util } from "./utility";
import path = require("path");
import { TextEncoder } from "util";

const d2Ext = "d2";
const d2Lang = "d2";
const previewGenerator: DocToPreviewGenerator = new DocToPreviewGenerator();

export const d2Ext = "d2";
export const d2Lang = "d2";
export const previewGenerator: DocToPreviewGenerator = new DocToPreviewGenerator();
export const d2ConfigSection = "D2";
export const d2TaskName = "D2 Task";
export let ws: WorkspaceConfiguration = workspace.getConfiguration(d2ConfigSection);
export const outputChannel: D2OutputChannel = new D2OutputChannel();
export const taskRunner: TaskRunner = new TaskRunner();
export let extContext: ExtensionContext;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function activate(context: ExtensionContext): any {
export type VSCAny = any;

export function activate(context: ExtensionContext): VSCAny {
extContext = context;

context.subscriptions.push(
Expand Down Expand Up @@ -239,9 +241,9 @@ export function activate(context: ExtensionContext): any {
// Return our markdown renderer
return {
// Sets up our ability to render for markdown files
// eslint-disable-next-line @typescript-eslint/no-explicit-any
extendMarkdownIt(md: any) {
return extendMarkdownItWithD2(md);
extendMarkdownIt(md: VSCAny) {
extendMarkdownItWithD2(md);
return md;
},
};
}
Expand All @@ -253,8 +255,7 @@ const pluginKeyword = "d2";
* This function will be asked by the Markdown system to render
* a d2 snippit in a markdown file
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function extendMarkdownItWithD2(md: any): unknown {
export function extendMarkdownItWithD2(md: VSCAny): unknown {
md.use(mdItContainer, pluginKeyword, {});

const highlight = md.options.highlight;
Expand Down
2 changes: 1 addition & 1 deletion src/refreshTimer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { ws } from "./extension";
type TimerCallback = () => void;

export class RefreshTimer {
timerId?: NodeJS.Timer;
timerId?: NodeJS.Timeout;
callback: TimerCallback;
interval = 0;

Expand Down
5 changes: 2 additions & 3 deletions src/taskRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
tasks,
TaskScope,
} from "vscode";
import { outputChannel } from "./extension";
import { d2TaskName, outputChannel } from "./extension";
import { d2Tasks } from "./tasks";

// eslint-disable-next-line no-unused-vars
Expand All @@ -25,7 +25,6 @@ export type TaskOutput = (text: string, flag?: boolean) => void;
* when the task is finished.
*/
export class TaskRunner {
public retVal = "";
public genTask(filename: string, text: string, callback: TaskRunnerCallback): void {
const pty = new CustomTaskTerminal(filename, text, callback);
const ce = new CustomExecution(
Expand All @@ -38,7 +37,7 @@ export class TaskRunner {
const task = new Task(
{ type: "D2" },
TaskScope.Workspace,
"D2 Task",
d2TaskName,
"D2 Extension",
ce,
["$D2Matcher"]
Expand Down
Loading
Loading