From 1433b3017392835a86978a3ecf46c9463b09352b Mon Sep 17 00:00:00 2001 From: cedoor Date: Sun, 24 Apr 2022 17:27:20 +0200 Subject: [PATCH 1/2] feat: integrate vim --- package.json | 1 + src/editor.less | 26 ++++++++++++++++++++++++-- src/editor.tsx | 27 ++++++++++++++------------- src/zkrepl.d.ts | 4 ++++ yarn.lock | 5 +++++ 5 files changed, 48 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 33fa8dd..908d59e 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "circom2": "^0.2.2", "ffjavascript": "0.2.48", "monaco-editor": "^0.30.1", + "monaco-vim": "^0.3.4", "patch-package": "^6.4.7", "path-browserify": "^1.0.1", "r1csfile": "0.0.35", diff --git a/src/editor.less b/src/editor.less index f57d0c2..505860a 100644 --- a/src/editor.less +++ b/src/editor.less @@ -32,6 +32,27 @@ a { flex: 1; } +.statusbar, +.statusbar input { + font-family: "Courier New", Courier, monospace; + font-size: 15px; + color: gray; +} + +.statusbar { + display: flex !important; + font-weight: bold; + padding: 0 10px; + flex-basis: 40px; + align-items: center; + + input { + outline: none; + border: none; + background: transparent; + } +} + code { font-family: inherit; font-size: small; @@ -95,13 +116,14 @@ body { font-size: small; text-transform: uppercase; } - .files, .insecure { + .files, + .insecure { font-size: small; padding-left: 20px; padding-bottom: 10px; } .insecure { - color: #ff9800 + color: #ff9800; } .file { &:hover { diff --git a/src/editor.tsx b/src/editor.tsx index 6443c3f..60e195f 100644 --- a/src/editor.tsx +++ b/src/editor.tsx @@ -1,5 +1,7 @@ -import React from "react" - +import Ansi from "ansi-to-react" +// this is a workaround for what seems to be some kind of bug around +// importing raw urls from webworkers in production builds +import wasmURL from "circom2/circom.wasm?url" import "monaco-editor/esm/vs/editor/browser/controller/coreCommands.js" // import 'monaco-editor/esm/vs/editor/browser/widget/codeEditorWidget.js'; // import 'monaco-editor/esm/vs/editor/browser/widget/diffEditorWidget.js'; @@ -32,6 +34,7 @@ import "monaco-editor/esm/vs/editor/contrib/indentation/indentation.js" // import 'monaco-editor/esm/vs/editor/contrib/linkedEditing/linkedEditing.js'; // import 'monaco-editor/esm/vs/editor/contrib/links/links.js'; import "monaco-editor/esm/vs/editor/contrib/multicursor/multicursor.js" +import * as monaco from "monaco-editor/esm/vs/editor/editor.api" // import 'monaco-editor/esm/vs/editor/contrib/parameterHints/parameterHints.js'; // import 'monaco-editor/esm/vs/editor/contrib/rename/rename.js'; // import 'monaco-editor/esm/vs/editor/contrib/smartSelect/smartSelect.js'; @@ -45,6 +48,10 @@ import "monaco-editor/esm/vs/editor/contrib/multicursor/multicursor.js" // import 'monaco-editor/esm/vs/editor/contrib/wordPartOperations/wordPartOperations.js'; // import 'monaco-editor/esm/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.js'; import "monaco-editor/esm/vs/editor/standalone/browser/iPadShowKeyboard/iPadShowKeyboard.js" +import { initVimMode } from "monaco-vim" +import React from "react" +import circomLib from "./data/circomlib.zip?url" +import codeExample from "./data/example.circom?raw" // import 'monaco-editor/esm/vs/editor/standalone/browser/inspectTokens/inspectTokens.js'; // import 'monaco-editor/esm/vs/editor/standalone/browser/quickAccess/standaloneCommandsQuickAccess.js'; // import 'monaco-editor/esm/vs/editor/standalone/browser/quickAccess/standaloneGotoLineQuickAccess.js'; @@ -52,20 +59,10 @@ import "monaco-editor/esm/vs/editor/standalone/browser/iPadShowKeyboard/iPadShow // import 'monaco-editor/esm/vs/editor/standalone/browser/quickAccess/standaloneHelpQuickAccess.js'; // import 'monaco-editor/esm/vs/editor/standalone/browser/referenceSearch/standaloneReferenceSearch.js'; // import 'monaco-editor/esm/vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast.js'; - import "./syntax" -import codeExample from "./data/example.circom?raw" +import { replyHover } from "./syntax" import CircomWorker from "./worker/worker?worker" -import Ansi from "ansi-to-react" - -import * as monaco from "monaco-editor/esm/vs/editor/editor.api" - -// this is a workaround for what seems to be some kind of bug around -// importing raw urls from webworkers in production builds -import wasmURL from "circom2/circom.wasm?url" -import circomLib from "./data/circomlib.zip?url" -import { replyHover } from "./syntax" console.log(circomLib, wasmURL) type Message = { @@ -271,6 +268,8 @@ export default function App() { }, }) + initVimMode(editor, document.getElementsByClassName("statusbar")[0]) + window.addEventListener("beforeunload", () => { sessionStorage.ZKReplState = JSON.stringify(exportJSON()) }) @@ -500,6 +499,8 @@ export default function App() {
+ +
diff --git a/src/zkrepl.d.ts b/src/zkrepl.d.ts index 38e9339..cb30a20 100644 --- a/src/zkrepl.d.ts +++ b/src/zkrepl.d.ts @@ -105,6 +105,10 @@ declare module "r1csfile" { ): Promise } +declare module "monaco-vim" { + export function initVimMode(editor: any, statusBarClass: any): void +} + declare module "ffjavascript" { export const Scalar: any } diff --git a/yarn.lock b/yarn.lock index b15a79c..132dcb2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1062,6 +1062,11 @@ monaco-editor@^0.30.1: resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.30.1.tgz#47f8d18a0aa2264fc5654581741ab8d7bec01689" integrity sha512-B/y4+b2O5G2gjuxIFtCE2EkM17R2NM7/3F8x0qcPsqy4V83bitJTIO4TIeZpYlzu/xy6INiY/+84BEm6+7Cmzg== +monaco-vim@^0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/monaco-vim/-/monaco-vim-0.3.4.tgz#141d3e1129a563e63a7286a1472ccfe72b758abe" + integrity sha512-IVogmrQ6fRwW2PD9XRHFysOZBFj8qcRhgabu7GlGiNR14ApKMHz3pYOL1hDq1ctVPj1DS6hZd98vZrFxWr5d6A== + ms@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" From f3e22518aa517022ff84e4904c1f95c1d299b178 Mon Sep 17 00:00:00 2001 From: cedoor Date: Mon, 25 Apr 2022 12:45:00 +0200 Subject: [PATCH 2/2] feat: add toolbar and vim statusbar --- src/editor.less | 60 +++++++++++++++++++++++++++++++++---------------- src/editor.tsx | 52 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 87 insertions(+), 25 deletions(-) diff --git a/src/editor.less b/src/editor.less index 505860a..bf7a22f 100644 --- a/src/editor.less +++ b/src/editor.less @@ -1,12 +1,10 @@ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; -} - -body { background: #202030; color: white; } + a { color: white; text-decoration: none; @@ -20,6 +18,7 @@ a { } .primary { + position: relative; width: 70vw; height: 100vh; display: flex; @@ -32,6 +31,24 @@ a { flex: 1; } +.toolbar { + display: flex; + flex-basis: 30px; + align-items: center; + justify-content: right; + + .button { + cursor: pointer; + padding: 5px; + color: #9e9e9e; + } + + .button:hover, + .button.active { + color: #525252; + } +} + .statusbar, .statusbar input { font-family: "Courier New", Courier, monospace; @@ -40,16 +57,24 @@ a { } .statusbar { - display: flex !important; - font-weight: bold; - padding: 0 10px; - flex-basis: 40px; + z-index: 1; + position: absolute; + bottom: 31px; + width: 100%; + height: 30px; + border-top: 1px solid #ddd; align-items: center; + padding: 5px; + background: white; - input { - outline: none; - border: none; - background: transparent; + div { + width: 100%; + + input { + outline: none; + border: none; + background: transparent; + } } } @@ -66,14 +91,6 @@ body { display: flex; } -.sidebar { - flex: 1; - height: 100vh; - width: 0; - display: flex; - flex-direction: column; -} - .heading { background: #303052; color: white; @@ -91,12 +108,16 @@ body { height: 30px; } } + .hidden-file { position: absolute; top: -1000px; left: -1000px; } + .sidebar { + display: flex; + flex-direction: column; flex: 1; white-space: pre-wrap; word-wrap: break-word; @@ -267,6 +288,7 @@ button { .editor { border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; } .embed-snippet { diff --git a/src/editor.tsx b/src/editor.tsx index 60e195f..419fd33 100644 --- a/src/editor.tsx +++ b/src/editor.tsx @@ -79,8 +79,10 @@ export default function App() { const [messages, setMessages] = React.useState([]) const [editor, setEditor] = React.useState(null) + const [vimMode, setVimMode] = React.useState() const modelsRef = React.useRef([]) const monacoEl = React.useRef(null) + const statusBarEl = React.useRef(null) const workerRef = React.useRef<(Worker & { running?: boolean }) | null>( null ) @@ -257,7 +259,7 @@ export default function App() { } } React.useEffect(() => { - if (monacoEl && !editor) { + if (monacoEl && statusBarEl && !editor) { const editor = monaco.editor.create(monacoEl.current!, { language: "circom", theme: "vs", @@ -268,8 +270,6 @@ export default function App() { }, }) - initVimMode(editor, document.getElementsByClassName("statusbar")[0]) - window.addEventListener("beforeunload", () => { sessionStorage.ZKReplState = JSON.stringify(exportJSON()) }) @@ -344,11 +344,18 @@ export default function App() { }) run() } + setEditor(editor) + + if (localStorage.getItem("vim-editor")) { + const vimMode = initVimMode(editor, statusBarEl.current) + + setVimMode(vimMode) + } } return () => editor?.dispose() - }, [monacoEl.current]) + }, [monacoEl.current, statusBarEl.current]) const switchEditor = (file: monaco.editor.ITextModel) => { const saveState = editor?.saveViewState() @@ -500,13 +507,46 @@ export default function App() {
-
+
+
+
+ +
+
{ + if (!vimMode) { + const vimMode = initVimMode( + editor, + statusBarEl.current + ) + + localStorage.setItem("vim-editor", "true") + + setVimMode(vimMode) + } else { + vimMode.dispose() + + localStorage.removeItem("vim-editor") + + setVimMode(null) + } + }} + className={!vimMode ? "button" : "button active"} + > + VIM +
+
- Shift-Enter to{" "} + CMD-Enter to{" "} {