vzcode 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/assets/index-BnoPNwcv.js +156 -0
- package/dist/assets/{index-C4h28erw.js → index-Bx5B6Xgl.js} +45 -45
- package/dist/assets/{index-CWMOj-be.css → index-ClPo_hzs.css} +1 -1
- package/dist/assets/worker-CuCF2V0j.js +291 -0
- package/dist/index.html +2 -2
- package/package.json +39 -22
- package/src/client/CodeEditor/getOrCreateEditor.ts +4 -1
- package/src/client/CodeEditor/index.tsx +7 -2
- package/src/client/CodeEditor/json1PresenceDisplay.ts +3 -1
- package/src/client/VZCodeContext.tsx +8 -0
- package/src/client/VZSidebar/index.tsx +2 -1
- package/src/client/VZSidebar/styles.scss +1 -0
- package/src/client/themes/vizhubTheme/index.ts +27 -0
- package/src/client/useEditorCache.ts +1 -0
- package/src/client/useKeyboardShortcuts.ts +176 -2
- package/src/client/useTypeScript/worker/constants.ts +14 -0
- package/src/client/useTypeScript/worker/index.ts +1 -12
- package/src/server/index.js +7 -4
- package/dist/assets/index-BPHulZpL.js +0 -155
- package/dist/assets/worker-BIf7QrAH.js +0 -282
package/dist/index.html
CHANGED
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap"
|
|
21
21
|
rel="stylesheet"
|
|
22
22
|
/>
|
|
23
|
-
<script type="module" crossorigin src="/assets/index-
|
|
24
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
23
|
+
<script type="module" crossorigin src="/assets/index-BnoPNwcv.js"></script>
|
|
24
|
+
<link rel="stylesheet" crossorigin href="/assets/index-ClPo_hzs.css">
|
|
25
25
|
</head>
|
|
26
26
|
<body>
|
|
27
27
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vzcode",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Multiplayer code editor system",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"test-interactive": "cd test/sampleDirectories/kitchenSink && node ../../../src/server/index.js",
|
|
15
15
|
"prettier": "prettier {*.*,**/*.*} --write",
|
|
16
16
|
"tsc": "tsc --noEmit",
|
|
17
|
-
"dev": "concurrently \"npm run test-interactive\" \"vite\"",
|
|
17
|
+
"dev": "EDITOR_PORT=5173 concurrently \"npm run test-interactive\" \"vite\"",
|
|
18
18
|
"build": "vite build",
|
|
19
19
|
"build-release": "vite build --mode release",
|
|
20
20
|
"preview": "concurrently \"npm run test-interactive\" \"vite preview\"",
|
|
@@ -79,6 +79,18 @@
|
|
|
79
79
|
{
|
|
80
80
|
"name": "Nghia Minh Huynh",
|
|
81
81
|
"url": "https://github.com/NghiaMinhHuynh"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"name": "Michael Halpern",
|
|
85
|
+
"url": "https://github.com/michaelhelper"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"name": "Pratheet Joshi",
|
|
89
|
+
"url": "https://github.com/DaCatDude"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "Philip Park",
|
|
93
|
+
"url": "https://github.com/philippark"
|
|
82
94
|
}
|
|
83
95
|
],
|
|
84
96
|
"license": "MIT",
|
|
@@ -87,7 +99,7 @@
|
|
|
87
99
|
},
|
|
88
100
|
"homepage": "https://github.com/vizhub-core/vzcode#readme",
|
|
89
101
|
"dependencies": {
|
|
90
|
-
"@codemirror/autocomplete": "^6.16.
|
|
102
|
+
"@codemirror/autocomplete": "^6.16.2",
|
|
91
103
|
"@codemirror/lang-css": "^6.2.1",
|
|
92
104
|
"@codemirror/lang-html": "^6.4.9",
|
|
93
105
|
"@codemirror/lang-javascript": "^6.2.2",
|
|
@@ -95,23 +107,23 @@
|
|
|
95
107
|
"@codemirror/lang-markdown": "^6.2.5",
|
|
96
108
|
"@codemirror/state": "^6.4.1",
|
|
97
109
|
"@codemirror/theme-one-dark": "^6.1.2",
|
|
98
|
-
"@codemirror/view": "^6.
|
|
110
|
+
"@codemirror/view": "^6.28.0",
|
|
99
111
|
"@lezer/highlight": "^1.2.0",
|
|
100
|
-
"@replit/codemirror-indentation-markers": "^6.5.
|
|
112
|
+
"@replit/codemirror-indentation-markers": "^6.5.2",
|
|
101
113
|
"@replit/codemirror-interact": "^6.3.1",
|
|
102
114
|
"@replit/codemirror-lang-svelte": "^6.0.0",
|
|
103
115
|
"@replit/codemirror-vscode-keymap": "^6.0.2",
|
|
104
116
|
"@teamwork/websocket-json-stream": "^2.0.0",
|
|
105
|
-
"@typescript/vfs": "^1.5.
|
|
106
|
-
"@uiw/codemirror-theme-abcdef": "^4.22.
|
|
107
|
-
"@uiw/codemirror-theme-dracula": "^4.22.
|
|
108
|
-
"@uiw/codemirror-theme-eclipse": "^4.22.
|
|
109
|
-
"@uiw/codemirror-theme-github": "^4.22.
|
|
110
|
-
"@uiw/codemirror-theme-material": "^4.22.
|
|
111
|
-
"@uiw/codemirror-theme-nord": "^4.22.
|
|
112
|
-
"@uiw/codemirror-theme-okaidia": "^4.22.
|
|
113
|
-
"@uiw/codemirror-theme-xcode": "^4.22.
|
|
114
|
-
"@uiw/codemirror-themes": "^4.22.
|
|
117
|
+
"@typescript/vfs": "^1.5.3",
|
|
118
|
+
"@uiw/codemirror-theme-abcdef": "^4.22.2",
|
|
119
|
+
"@uiw/codemirror-theme-dracula": "^4.22.2",
|
|
120
|
+
"@uiw/codemirror-theme-eclipse": "^4.22.2",
|
|
121
|
+
"@uiw/codemirror-theme-github": "^4.22.2",
|
|
122
|
+
"@uiw/codemirror-theme-material": "^4.22.2",
|
|
123
|
+
"@uiw/codemirror-theme-nord": "^4.22.2",
|
|
124
|
+
"@uiw/codemirror-theme-okaidia": "^4.22.2",
|
|
125
|
+
"@uiw/codemirror-theme-xcode": "^4.22.2",
|
|
126
|
+
"@uiw/codemirror-themes": "^4.22.2",
|
|
115
127
|
"body-parser": "^1.20.2",
|
|
116
128
|
"codemirror": "^6.0.1",
|
|
117
129
|
"codemirror-ot": "^4.4.0",
|
|
@@ -124,13 +136,14 @@
|
|
|
124
136
|
"json0-ot-diff": "^1.1.2",
|
|
125
137
|
"ngrok": "^4.3.3",
|
|
126
138
|
"open": "^10.1.0",
|
|
127
|
-
"openai": "^4.
|
|
128
|
-
"prettier-plugin-svelte": "^3.2.
|
|
139
|
+
"openai": "^4.50.0",
|
|
140
|
+
"prettier-plugin-svelte": "^3.2.4",
|
|
141
|
+
"rainbowbrackets": "^2.0.2",
|
|
129
142
|
"react": "^18.3.1",
|
|
130
143
|
"react-bootstrap": "^2.10.2",
|
|
131
144
|
"react-dom": "^18.3.1",
|
|
132
145
|
"react-router-dom": "^6.23.1",
|
|
133
|
-
"sharedb": "^5.0.
|
|
146
|
+
"sharedb": "^5.0.2",
|
|
134
147
|
"sharedb-client-browser": "^5.0.1",
|
|
135
148
|
"vizhub-ui": "^3.23.0",
|
|
136
149
|
"ws": "^8.17.0"
|
|
@@ -138,12 +151,16 @@
|
|
|
138
151
|
"devDependencies": {
|
|
139
152
|
"@types/react": "^18.3.3",
|
|
140
153
|
"@types/react-dom": "^18.3.0",
|
|
141
|
-
"@vitejs/plugin-react": "^4.3.
|
|
154
|
+
"@vitejs/plugin-react": "^4.3.1",
|
|
142
155
|
"concurrently": "^8.2.2",
|
|
143
|
-
"prettier": "^3.2
|
|
144
|
-
"sass": "^1.77.
|
|
156
|
+
"prettier": "^3.3.2",
|
|
157
|
+
"sass": "^1.77.4",
|
|
145
158
|
"typescript": "^5.4.5",
|
|
146
|
-
"vite": "^5.2.
|
|
159
|
+
"vite": "^5.2.13",
|
|
147
160
|
"vitest": "^1.6.0"
|
|
161
|
+
},
|
|
162
|
+
"optionalDependencies": {
|
|
163
|
+
"@rollup/rollup-darwin-arm64": "^4.18.0",
|
|
164
|
+
"@rollup/rollup-win32-x64-msvc": "^4.18.0"
|
|
148
165
|
}
|
|
149
166
|
}
|
|
@@ -39,6 +39,7 @@ import { typeScriptLinter } from './typeScriptLinter';
|
|
|
39
39
|
import { keymap } from '@codemirror/view';
|
|
40
40
|
import { basicSetup } from './basicSetup';
|
|
41
41
|
import { InteractRule } from '@replit/codemirror-interact';
|
|
42
|
+
import rainbowBrackets from 'rainbowbrackets';
|
|
42
43
|
|
|
43
44
|
// Feature flag to enable TypeScript completions & TypeScript Linter.
|
|
44
45
|
const enableTypeScriptCompletions = true;
|
|
@@ -166,7 +167,7 @@ export const getOrCreateEditor = ({
|
|
|
166
167
|
);
|
|
167
168
|
}
|
|
168
169
|
|
|
169
|
-
// Deals with receiving the
|
|
170
|
+
// Deals with receiving the broadcast from other clients and displaying them.
|
|
170
171
|
if (docPresence) {
|
|
171
172
|
extensions.push(
|
|
172
173
|
json1PresenceDisplay({
|
|
@@ -328,6 +329,8 @@ export const getOrCreateEditor = ({
|
|
|
328
329
|
}),
|
|
329
330
|
),
|
|
330
331
|
);
|
|
332
|
+
// adds rainbow brackets
|
|
333
|
+
extensions.push(rainbowBrackets());
|
|
331
334
|
|
|
332
335
|
const editor = new EditorView({
|
|
333
336
|
state: EditorState.create({
|
|
@@ -111,12 +111,17 @@ export const CodeEditor = ({
|
|
|
111
111
|
if (!ref.current) return;
|
|
112
112
|
if (!content) return;
|
|
113
113
|
|
|
114
|
-
// Add the editor to the DOM.
|
|
114
|
+
// Add the editor and apply the prior scroll position to the DOM.
|
|
115
115
|
ref.current.appendChild(editorCacheValue.editor.dom);
|
|
116
|
+
editorCacheValue.editor.scrollDOM.scrollTo({
|
|
117
|
+
top: editorCacheValue.scrollPosition ?? 0,
|
|
118
|
+
});
|
|
116
119
|
|
|
117
120
|
return () => {
|
|
118
|
-
// Remove the old editor from the DOM.
|
|
121
|
+
// Remove the old editor from the DOM and store the current scroll position.
|
|
119
122
|
// This happens every time `activeFileId` changes.
|
|
123
|
+
editorCacheValue.scrollPosition =
|
|
124
|
+
editorCacheValue.editor.scrollDOM.scrollTop;
|
|
120
125
|
ref.current.removeChild(editorCacheValue.editor.dom);
|
|
121
126
|
};
|
|
122
127
|
}, [shareDBDoc, editorCacheValue]);
|
|
@@ -56,7 +56,9 @@ export const json1PresenceDisplay = ({
|
|
|
56
56
|
const { start, end } = presence;
|
|
57
57
|
const from = start[start.length - 1];
|
|
58
58
|
const to = end[end.length - 1];
|
|
59
|
-
const userColor = new ColorHash(
|
|
59
|
+
const userColor = new ColorHash({
|
|
60
|
+
lightness: 0.75,
|
|
61
|
+
}).rgb(id);
|
|
60
62
|
const { username } = presence;
|
|
61
63
|
|
|
62
64
|
presenceDecorations.push({
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
useCallback,
|
|
4
4
|
useReducer,
|
|
5
5
|
useState,
|
|
6
|
+
useRef,
|
|
6
7
|
} from 'react';
|
|
7
8
|
import {
|
|
8
9
|
FileId,
|
|
@@ -126,6 +127,8 @@ export type VZCodeContextValue = {
|
|
|
126
127
|
>;
|
|
127
128
|
runCodeRef: React.MutableRefObject<null | (() => void)>;
|
|
128
129
|
|
|
130
|
+
sidebarRef: React.RefObject<HTMLDivElement>;
|
|
131
|
+
|
|
129
132
|
connected: boolean;
|
|
130
133
|
|
|
131
134
|
hoveredItemId: ItemId | null;
|
|
@@ -174,6 +177,8 @@ export const VZCodeProvider = ({
|
|
|
174
177
|
|
|
175
178
|
const runCodeRef = useRunCode(submitOperation);
|
|
176
179
|
|
|
180
|
+
const sidebarRef = useRef(null);
|
|
181
|
+
|
|
177
182
|
// The error message shows either:
|
|
178
183
|
// * `prettierError` - errors from Prettier, client-side only
|
|
179
184
|
// * `codeError` - errors from an external source, such as
|
|
@@ -316,6 +321,8 @@ export const VZCodeProvider = ({
|
|
|
316
321
|
setActiveFileRight,
|
|
317
322
|
runPrettierRef,
|
|
318
323
|
runCodeRef,
|
|
324
|
+
sidebarRef,
|
|
325
|
+
editorCache,
|
|
319
326
|
});
|
|
320
327
|
|
|
321
328
|
// Track the currently hovered file id.
|
|
@@ -382,6 +389,7 @@ export const VZCodeProvider = ({
|
|
|
382
389
|
handleCreateDirClick,
|
|
383
390
|
runPrettierRef,
|
|
384
391
|
runCodeRef,
|
|
392
|
+
sidebarRef,
|
|
385
393
|
|
|
386
394
|
connected,
|
|
387
395
|
|
|
@@ -46,6 +46,7 @@ export const VZSidebar = ({
|
|
|
46
46
|
handleOpenCreateFileModal,
|
|
47
47
|
handleOpenCreateDirModal,
|
|
48
48
|
connected,
|
|
49
|
+
sidebarRef,
|
|
49
50
|
} = useContext(VZCodeContext);
|
|
50
51
|
|
|
51
52
|
const fileTree = useMemo(
|
|
@@ -102,7 +103,7 @@ export const VZSidebar = ({
|
|
|
102
103
|
onDragLeave={handleDragLeave}
|
|
103
104
|
onDrop={handleDrop}
|
|
104
105
|
>
|
|
105
|
-
<div className="files">
|
|
106
|
+
<div className="files" ref={sidebarRef} tabIndex={-1}>
|
|
106
107
|
<div className="full-box">
|
|
107
108
|
<div className="sidebar-section-hint">Files</div>
|
|
108
109
|
<div className="sidebar-section-buttons">
|
|
@@ -190,6 +190,33 @@ function vizhubThemeInit(
|
|
|
190
190
|
backgroundColor: 'transparent',
|
|
191
191
|
outline: '1px solid #ff2222',
|
|
192
192
|
},
|
|
193
|
+
'.rainbow-bracket-red > span': {
|
|
194
|
+
color: 'white',
|
|
195
|
+
},
|
|
196
|
+
'.rainbow-bracket-orange > span': {
|
|
197
|
+
// red
|
|
198
|
+
color: '#FFB2B2',
|
|
199
|
+
},
|
|
200
|
+
'.rainbow-bracket-yellow > span': {
|
|
201
|
+
// orange
|
|
202
|
+
color: '#FFB2DA',
|
|
203
|
+
},
|
|
204
|
+
'.rainbow-bracket-green > span': {
|
|
205
|
+
// yellow
|
|
206
|
+
color: '#FFFFB2',
|
|
207
|
+
},
|
|
208
|
+
'.rainbow-bracket-blue > span': {
|
|
209
|
+
// green
|
|
210
|
+
color: '#B2FFB2',
|
|
211
|
+
},
|
|
212
|
+
'.rainbow-bracket-indigo > span': {
|
|
213
|
+
// blue
|
|
214
|
+
color: '#B2FFFF',
|
|
215
|
+
},
|
|
216
|
+
'.rainbow-bracket-violet > span': {
|
|
217
|
+
// purple
|
|
218
|
+
color: '#DAB2FF',
|
|
219
|
+
}
|
|
193
220
|
},
|
|
194
221
|
{ dark: true },
|
|
195
222
|
),
|
|
@@ -1,6 +1,154 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
2
|
import { shouldTriggerRun } from './shouldTriggerRun';
|
|
3
|
-
import {
|
|
3
|
+
import { EditorView } from 'codemirror';
|
|
4
|
+
import { syntaxTree } from '@codemirror/language';
|
|
5
|
+
import { SyntaxNode } from '@lezer/common';
|
|
6
|
+
import {
|
|
7
|
+
EditorState,
|
|
8
|
+
SelectionRange,
|
|
9
|
+
} from '@codemirror/state';
|
|
10
|
+
|
|
11
|
+
// Nesting types for the specific language
|
|
12
|
+
const nestingTypes = new Set<string>([
|
|
13
|
+
'FunctionDeclaration',
|
|
14
|
+
'ClassDeclaration',
|
|
15
|
+
'MethodDeclaration',
|
|
16
|
+
'Block',
|
|
17
|
+
'IfStatement',
|
|
18
|
+
'ForStatement',
|
|
19
|
+
'WhileStatement',
|
|
20
|
+
'SwitchStatement',
|
|
21
|
+
'TryStatement',
|
|
22
|
+
'CatchClause',
|
|
23
|
+
'WithStatement',
|
|
24
|
+
'ArrowFunction',
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
// Declaration types for the specific language
|
|
28
|
+
const declarationTypes = new Set<string>([
|
|
29
|
+
'VariableDeclaration',
|
|
30
|
+
'FunctionDeclaration',
|
|
31
|
+
'ClassDeclaration',
|
|
32
|
+
'MethodDeclaration',
|
|
33
|
+
'PropertyDeclaration',
|
|
34
|
+
'ImportDeclaration',
|
|
35
|
+
'ExportDeclaration',
|
|
36
|
+
'CallExpression',
|
|
37
|
+
'ArrayPattern',
|
|
38
|
+
'ObjectPattern',
|
|
39
|
+
'PatternProperty',
|
|
40
|
+
'ArgList',
|
|
41
|
+
'TypeArgList',
|
|
42
|
+
'ParamList',
|
|
43
|
+
'ForOfSpec',
|
|
44
|
+
]);
|
|
45
|
+
|
|
46
|
+
function getIdentifierContext(
|
|
47
|
+
identifier: SyntaxNode,
|
|
48
|
+
): number {
|
|
49
|
+
let levels = 0;
|
|
50
|
+
let current: SyntaxNode = identifier;
|
|
51
|
+
|
|
52
|
+
// Traverse up the tree to find the total depth
|
|
53
|
+
while (current && current.type) {
|
|
54
|
+
const parentType: string = current.type.name;
|
|
55
|
+
|
|
56
|
+
if (nestingTypes.has(parentType)) {
|
|
57
|
+
levels++;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
current = current.parent;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return levels;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function jumpToDefinition(editor: EditorView) {
|
|
67
|
+
// Use current editor state and selection range to find a potential definition
|
|
68
|
+
const state: EditorState = editor.state;
|
|
69
|
+
const location: SelectionRange = state.selection.main;
|
|
70
|
+
const definitions: Array<{
|
|
71
|
+
identifier: SyntaxNode;
|
|
72
|
+
context: number;
|
|
73
|
+
}> = [];
|
|
74
|
+
|
|
75
|
+
// Fetch the current syntax node information using cursor position
|
|
76
|
+
const identifier: SyntaxNode = syntaxTree(
|
|
77
|
+
state,
|
|
78
|
+
).resolveInner(location.from, -1);
|
|
79
|
+
const identifierName: string = state.doc.sliceString(
|
|
80
|
+
identifier.from,
|
|
81
|
+
identifier.to,
|
|
82
|
+
);
|
|
83
|
+
const context: number = getIdentifierContext(identifier);
|
|
84
|
+
|
|
85
|
+
if (identifier) {
|
|
86
|
+
syntaxTree(state).iterate({
|
|
87
|
+
enter(tree) {
|
|
88
|
+
// Traverse syntax tree to find positions of respective identifier definitions within context
|
|
89
|
+
if (
|
|
90
|
+
declarationTypes.has(tree.name) ||
|
|
91
|
+
nestingTypes.has(tree.name)
|
|
92
|
+
) {
|
|
93
|
+
const parent: SyntaxNode = tree.node;
|
|
94
|
+
const children: Array<SyntaxNode> = [
|
|
95
|
+
...parent.getChildren('VariableDefinition'),
|
|
96
|
+
...parent.getChildren('PropertyDefinition'),
|
|
97
|
+
...parent.getChildren('PropertyName'),
|
|
98
|
+
...parent.getChildren('Identifier'),
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
children.forEach((child: SyntaxNode) => {
|
|
102
|
+
const name: string = state.doc.sliceString(
|
|
103
|
+
child.from,
|
|
104
|
+
child.to,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
if (
|
|
108
|
+
name === identifierName &&
|
|
109
|
+
child !== identifier
|
|
110
|
+
) {
|
|
111
|
+
definitions.push({
|
|
112
|
+
identifier: child,
|
|
113
|
+
context: getIdentifierContext(child),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
if (definitions.length > 0) {
|
|
122
|
+
// Sort definitions by their context in the syntax tree
|
|
123
|
+
definitions.sort((a, b) => a.context - b.context);
|
|
124
|
+
|
|
125
|
+
let closestDefinition: SyntaxNode =
|
|
126
|
+
definitions[0].identifier;
|
|
127
|
+
|
|
128
|
+
for (let i = definitions.length - 1; i >= 0; i--) {
|
|
129
|
+
if (definitions[i].context <= context) {
|
|
130
|
+
closestDefinition = definitions[i].identifier;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Set the cursor position to the valid declaration in current scope
|
|
136
|
+
editor.dispatch({
|
|
137
|
+
selection: {
|
|
138
|
+
anchor: closestDefinition.from,
|
|
139
|
+
head: closestDefinition.to,
|
|
140
|
+
},
|
|
141
|
+
scrollIntoView: true,
|
|
142
|
+
effects: EditorView.scrollIntoView(
|
|
143
|
+
closestDefinition.from,
|
|
144
|
+
{
|
|
145
|
+
y: 'center',
|
|
146
|
+
},
|
|
147
|
+
),
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
4
152
|
|
|
5
153
|
// This module implements the keyboard shortcuts
|
|
6
154
|
// for the VZCode editor.
|
|
@@ -18,6 +166,8 @@ export const useKeyboardShortcuts = ({
|
|
|
18
166
|
setActiveFileRight,
|
|
19
167
|
runPrettierRef,
|
|
20
168
|
runCodeRef,
|
|
169
|
+
sidebarRef,
|
|
170
|
+
editorCache,
|
|
21
171
|
}) => {
|
|
22
172
|
useEffect(() => {
|
|
23
173
|
const handleKeyPress = (event: KeyboardEvent) => {
|
|
@@ -32,12 +182,28 @@ export const useKeyboardShortcuts = ({
|
|
|
32
182
|
|
|
33
183
|
// Run the code
|
|
34
184
|
const runCode = runCodeRef.current;
|
|
185
|
+
|
|
35
186
|
if (runCode !== null) {
|
|
36
187
|
runCode();
|
|
37
188
|
}
|
|
38
189
|
return;
|
|
39
190
|
}
|
|
40
191
|
|
|
192
|
+
if (event.ctrlKey) {
|
|
193
|
+
const editor: EditorView =
|
|
194
|
+
editorCache.get(activeFileId).editor;
|
|
195
|
+
const jumpToDefinitionHandler = () => {
|
|
196
|
+
jumpToDefinition(editor);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
// CTRL + Click: Jump to relative definition
|
|
200
|
+
document.addEventListener(
|
|
201
|
+
'mousedown',
|
|
202
|
+
jumpToDefinitionHandler,
|
|
203
|
+
{ once: true },
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
41
207
|
if (event.altKey === true) {
|
|
42
208
|
// Alt-w: Close the current tab
|
|
43
209
|
if (event.key === 'w') {
|
|
@@ -66,6 +232,14 @@ export const useKeyboardShortcuts = ({
|
|
|
66
232
|
return;
|
|
67
233
|
}
|
|
68
234
|
}
|
|
235
|
+
|
|
236
|
+
if (event.ctrlKey == true) {
|
|
237
|
+
if (event.key === '0') {
|
|
238
|
+
if (sidebarRef.current) {
|
|
239
|
+
sidebarRef.current.focus();
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
69
243
|
};
|
|
70
244
|
|
|
71
245
|
document.addEventListener('keydown', handleKeyPress);
|
|
@@ -61,6 +61,17 @@ const LINT_ERROR_CODE_ASSIGNABLE_TO_NEVER = 2345;
|
|
|
61
61
|
// Cannot find name 'd3'.
|
|
62
62
|
export const LINT_ERROR_CODE_CANNOT_FIND_NAME = 2304;
|
|
63
63
|
|
|
64
|
+
// Type '{}' is missing the following properties from type '{ indx:
|
|
65
|
+
//Ignore specific TypeScript warning on object reassignment
|
|
66
|
+
const LINT_ERROR_CODE_OBJ_REASSINGMENT = 2739;
|
|
67
|
+
|
|
68
|
+
// Type 'any' is not assignable to type 'never'.
|
|
69
|
+
const LINT_ERROR_CODE_ANY_NOT_ASSIGNABLE_TO_NEVER = 2322;
|
|
70
|
+
|
|
71
|
+
// This code is for errors like:
|
|
72
|
+
// "Object is of type 'unknown'."
|
|
73
|
+
const LINT_ERROR_CODE_UNKNOWN = 18046;
|
|
74
|
+
|
|
64
75
|
export const excludedErrorCodes = new Set([
|
|
65
76
|
LINT_ERROR_CODE_ANY,
|
|
66
77
|
LINT_ERROR_CODE_IMPORT,
|
|
@@ -70,4 +81,7 @@ export const excludedErrorCodes = new Set([
|
|
|
70
81
|
LINT_ERROR_CODE_NON_EXISTENT_PROPERTY,
|
|
71
82
|
LINT_ERROR_CODE_ITERATED_THROUGH,
|
|
72
83
|
LINT_ERROR_CODE_ASSIGNABLE_TO_NEVER,
|
|
84
|
+
LINT_ERROR_CODE_OBJ_REASSINGMENT,
|
|
85
|
+
LINT_ERROR_CODE_ANY_NOT_ASSIGNABLE_TO_NEVER,
|
|
86
|
+
LINT_ERROR_CODE_UNKNOWN,
|
|
73
87
|
]);
|
|
@@ -1,17 +1,6 @@
|
|
|
1
1
|
import * as tsvfs from '@typescript/vfs';
|
|
2
2
|
import ts from 'typescript';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
AutocompleteRequest,
|
|
6
|
-
AutocompleteResponse,
|
|
7
|
-
LinterRequest,
|
|
8
|
-
LinterResponse,
|
|
9
|
-
} from './requestTypes';
|
|
10
|
-
import {
|
|
11
|
-
LINT_ERROR_CODE_CANNOT_FIND_NAME,
|
|
12
|
-
compilerOptions,
|
|
13
|
-
excludedErrorCodes,
|
|
14
|
-
} from './constants';
|
|
3
|
+
import { compilerOptions } from './constants';
|
|
15
4
|
import { handleMessageUpdateContent } from './handleMessageUpdateContent';
|
|
16
5
|
import { handleMessageAutocompleteRequest } from './handleMessageAutocompleteRequest';
|
|
17
6
|
import { handleMessageLintRequest } from './handleMessageLintRequest';
|
package/src/server/index.js
CHANGED
|
@@ -310,9 +310,12 @@ server.listen(port, async () => {
|
|
|
310
310
|
open(url);
|
|
311
311
|
})();
|
|
312
312
|
} else {
|
|
313
|
-
//
|
|
314
|
-
//
|
|
315
|
-
|
|
316
|
-
|
|
313
|
+
// Sets the port to the one specified in the environment
|
|
314
|
+
// variable (for development) or the default port.
|
|
315
|
+
let livePort = process.env.EDITOR_PORT || port;
|
|
316
|
+
console.log(
|
|
317
|
+
`Editor is live at http://localhost:${livePort}`,
|
|
318
|
+
);
|
|
319
|
+
open(`http://localhost:${livePort}`);
|
|
317
320
|
}
|
|
318
321
|
});
|