Skip to content
Merged
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
2 changes: 0 additions & 2 deletions web/craco.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const CircularDependencyPlugin = require('circular-dependency-plugin');
const CracoAlias = require("craco-alias");

Expand All @@ -10,7 +9,6 @@ module.exports = {
},
plugins: {
add: [
new MonacoWebpackPlugin(),
new CircularDependencyPlugin({
// exclude detection of files based on a RegExp
exclude: /a\.js|node_modules/,
Expand Down
6 changes: 3 additions & 3 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
"dependencies": {
"@craco/craco": "^6.4.3",
"@fluentui/react": "^8.52.3",
"@monaco-editor/loader": "^1.4.0",
"@monaco-editor/react": "^4.6.0",
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
Expand All @@ -27,14 +29,12 @@
"craco-alias": "^3.0.1",
"dexie": "^3.2.3",
"file-saver": "^2.0.5",
"monaco-editor": "^0.33.0",
"monaco-editor-webpack-plugin": "^7.0.1",
"monaco-editor": "^0.45.0",
"monaco-vim": "^0.3.4",
"re-resizable": "^6.9.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-icons": "^4.3.1",
"react-monaco-editor": "^0.47.0",
"react-redux": "^7.2.6",
"react-router-dom": "^5.3.0",
"react-scripts": "5.0.0",
Expand Down
52 changes: 40 additions & 12 deletions web/src/components/features/workspace/CodeEditor/CodeEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import React from 'react';
import MonacoEditor from 'react-monaco-editor';
import * as monaco from 'monaco-editor';
import {editor, IKeyboardEvent} from 'monaco-editor';
import { Spinner } from '@fluentui/react';
import MonacoEditor, { type Monaco } from '@monaco-editor/react';
import {
KeyMod,
KeyCode,
type editor,
type IKeyboardEvent,
} from 'monaco-editor';

import {
createVimModeAdapter,
Expand Down Expand Up @@ -57,17 +62,19 @@ const mapWorkspaceProps = ({files, selectedFile}: WorkspaceState) => {
}))
export class CodeEditor extends React.Component<any, CodeEditorState> {
private analyzer?: Analyzer;
private _previousTimeout: any;
private editorInstance?: editor.IStandaloneCodeEditor;
private vimAdapter?: VimModeKeymap;
private vimCommandAdapter?: StatusBarAdapter;
private monaco?: Monaco;

private debouncedAnalyzeFunc = wrapAsyncWithDebounce((fileName: string, code: string) => (
this.doAnalyze(fileName, code)
), ANALYZE_DEBOUNCE_TIME);

editorDidMount(editorInstance: editor.IStandaloneCodeEditor, _: monaco.editor.IEditorConstructionOptions) {
editorDidMount(editorInstance: editor.IStandaloneCodeEditor, monacoInstance: Monaco) {
this.editorInstance = editorInstance;
this.monaco = monacoInstance;

editorInstance.onKeyDown(e => this.onKeyDown(e));
const [ vimAdapter, statusAdapter ] = createVimModeAdapter(
this.props.dispatch,
Expand Down Expand Up @@ -101,7 +108,7 @@ export class CodeEditor extends React.Component<any, CodeEditorState> {
label: 'Build And Run Code',
contextMenuGroupId: 'navigation',
keybindings: [
monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter
KeyMod.CtrlCmd | KeyCode.Enter
],
run: (ed, ...args) => {
this.props.dispatch(runFileDispatcher);
Expand All @@ -112,7 +119,7 @@ export class CodeEditor extends React.Component<any, CodeEditorState> {
label: 'Format Code (goimports)',
contextMenuGroupId: 'navigation',
keybindings: [
monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.KeyF
KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyF
],
run: (ed, ...args) => {
this.props.dispatch(dispatchFormatFile());
Expand All @@ -124,6 +131,9 @@ export class CodeEditor extends React.Component<any, CodeEditorState> {
actions.forEach(action => editorInstance.addAction(action));
attachCustomCommands(editorInstance);
editorInstance.focus();

const { fileName, code } = this.props;
this.debouncedAnalyzeFunc(fileName, code);
}

private isFileOrEnvironmentChanged(prevProps) {
Expand All @@ -149,7 +159,7 @@ export class CodeEditor extends React.Component<any, CodeEditorState> {
componentDidUpdate(prevProps) {
if (this.isFileOrEnvironmentChanged(prevProps)) {
// Update editor markers on file or environment changes;
this.debouncedAnalyzeFunc(this.props.code);
this.debouncedAnalyzeFunc(this.props.fileName, this.props.code);
}

this.applyVimModeChanges(prevProps);
Expand All @@ -158,9 +168,19 @@ export class CodeEditor extends React.Component<any, CodeEditorState> {
componentWillUnmount() {
this.analyzer?.dispose();
this.vimAdapter?.dispose();

// Shutdown instance to avoid dangling markers.
this.monaco?.editor.removeAllMarkers(
this.editorInstance?.getId() as string
);
this.editorInstance?.dispose();
}

onChange(newValue: string, _: editor.IModelContentChangedEvent) {
onChange(newValue: string|undefined, _: editor.IModelContentChangedEvent) {
if (!newValue) {
return;
}

this.props.dispatch(dispatchUpdateFile(this.props.fileName, newValue));
const { fileName, code } = this.props;
this.debouncedAnalyzeFunc(fileName, code);
Expand Down Expand Up @@ -188,7 +208,7 @@ export class CodeEditor extends React.Component<any, CodeEditorState> {
return r.value ?? [];
});

editor.setModelMarkers(
this.monaco?.editor.setModelMarkers(
this.editorInstance?.getModel() as editor.ITextModel,
this.editorInstance?.getId() as string,
markers
Expand All @@ -212,10 +232,18 @@ export class CodeEditor extends React.Component<any, CodeEditorState> {
language={LANGUAGE_GOLANG}
theme={this.props.darkMode ? 'vs-dark' : 'vs-light'}
value={this.props.code}
// path={this.props.fileName}
defaultValue={this.props.code}
path={this.props.fileName}
options={options}
onChange={(newVal, e) => this.onChange(newVal, e)}
editorDidMount={(e, m: any) => this.editorDidMount(e, m)}
onMount={(e, m) => this.editorDidMount(e, m)}
loading={(
<Spinner
key='spinner'
label='Loading editor...'
labelPosition='right'
/>
)}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const ContentPlaceholder: React.FC<Props> = ({isLoading, error, onUploadC
{ isLoading ? (
<Spinner
key='spinner'
label='Loading editor...'
label='Loading snippet...'
labelPosition='right'
/>
) : error?.length ? (
Expand Down
9 changes: 8 additions & 1 deletion web/src/store/reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import notificationReducers from './notifications/reducers';
import { initialTerminalState } from './terminal/state';
import { reducers as terminalReducers } from './terminal/reducers';

import { WorkspaceAction } from '~/store/workspace/actions';
import { type FilePayload, WorkspaceAction } from '~/store/workspace/actions';
import { initialWorkspaceState } from '~/store/workspace/state';
import { reducers as workspaceReducers } from '~/store/workspace/reducers';

Expand Down Expand Up @@ -74,6 +74,13 @@ const reducers = {
lastError: null,
}
),
[WorkspaceAction.REMOVE_FILE]: ({markers, ...state}: StatusState, { payload: {filename}}: Action<FilePayload>) => {
const { [filename]: _, ...newMarkers } = markers || {};
return {
...state,
markers: newMarkers,
};
},
[ActionType.ERROR]: (s: StatusState, a: Action<string>) => (
{
...s,
Expand Down
45 changes: 25 additions & 20 deletions web/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1699,6 +1699,20 @@
resolved "https://registry.yarnpkg.com/@microsoft/load-themed-styles/-/load-themed-styles-1.10.31.tgz#ab94e84fc677a09c35b9ee13976356630e4dc031"
integrity sha512-+DT6/kBHX2e06CXHgLDfgVZGoAFP9pGiyggcBfeUdJkDx/skcW1/6RFRtuQtfqW8hTBRKRyADiQoler6igalpw==

"@monaco-editor/loader@^1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@monaco-editor/loader/-/loader-1.4.0.tgz#f08227057331ec890fa1e903912a5b711a2ad558"
integrity sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==
dependencies:
state-local "^1.0.6"

"@monaco-editor/react@^4.6.0":
version "4.6.0"
resolved "https://registry.yarnpkg.com/@monaco-editor/react/-/react-4.6.0.tgz#bcc68671e358a21c3814566b865a54b191e24119"
integrity sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==
dependencies:
"@monaco-editor/loader" "^1.4.0"

"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
Expand Down Expand Up @@ -6369,7 +6383,7 @@ loader-utils@^1.4.0:
emojis-list "^3.0.0"
json5 "^1.0.1"

loader-utils@^2.0.0, loader-utils@^2.0.2:
loader-utils@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129"
integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==
Expand Down Expand Up @@ -6642,17 +6656,10 @@ mkdirp@^0.5.5, mkdirp@~0.5.1:
dependencies:
minimist "^1.2.5"

monaco-editor-webpack-plugin@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-7.0.1.tgz#ba19c60aba990184e36ad8722b1ed6a564527c7c"
integrity sha512-M8qIqizltrPlIbrb73cZdTWfU9sIsUVFvAZkL3KGjAHmVWEJ0hZKa/uad14JuOckc0GwnCaoGHvMoYtJjVyCzw==
dependencies:
loader-utils "^2.0.2"

monaco-editor@^0.33.0:
version "0.33.0"
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.33.0.tgz#842e244f3750a2482f8a29c676b5684e75ff34af"
integrity sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw==
monaco-editor@^0.45.0:
version "0.45.0"
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.45.0.tgz#6939123a6254aea9fea2d647697f846306dd4448"
integrity sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA==

monaco-vim@^0.3.4:
version "0.3.4"
Expand Down Expand Up @@ -7714,7 +7721,7 @@ prop-types@^15.6.2:
object-assign "^4.1.1"
react-is "^16.8.1"

prop-types@^15.7.2, prop-types@^15.8.1:
prop-types@^15.7.2:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
Expand Down Expand Up @@ -7885,13 +7892,6 @@ react-is@^17.0.1, react-is@^17.0.2:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==

react-monaco-editor@^0.47.0:
version "0.47.0"
resolved "https://registry.yarnpkg.com/react-monaco-editor/-/react-monaco-editor-0.47.0.tgz#6933f6c507297d2de283af9e4f74407f827cfc0f"
integrity sha512-uXZMzYJReIHSA41Qjka2LZckEEawPQC0smpeUgkUvyaMiT8y9qFodIcQtLmSUj3g7gd/6W15a73jBs1d6sr+Mw==
dependencies:
prop-types "^15.8.1"

react-redux@^7.2.6:
version "7.2.6"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.6.tgz#49633a24fe552b5f9caf58feb8a138936ddfe9aa"
Expand Down Expand Up @@ -8607,6 +8607,11 @@ stackframe@^1.1.1:
resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303"
integrity sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==

state-local@^1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/state-local/-/state-local-1.0.7.tgz#da50211d07f05748d53009bee46307a37db386d5"
integrity sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==

statuses@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
Expand Down