Skip to content

Commit 7f39cd4

Browse files
Merge branch 'vscodeeffect' of https://github.com/codesandbox/codesandbox-client into vscodeeffect
2 parents 6dfc34e + ea7ba6b commit 7f39cd4

File tree

13 files changed

+119
-152
lines changed

13 files changed

+119
-152
lines changed

packages/app/src/app/components/CodeEditor/Monaco/MonacoReactComponent.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@ class MonacoEditor extends React.PureComponent {
3535
}
3636

3737
// eslint-disable-next-line global-require
38-
require('app/overmind/effects/vscode/vscode-script-loader').default(
39-
['vs/editor/editor.main'],
40-
false
41-
)(() => {
38+
require('app/overmind/effects/vscode/vscode-script-loader').default(false, [
39+
'vs/editor/editor.main',
40+
])(() => {
4241
this.initMonaco();
4342
});
4443
};

packages/app/src/app/overmind/effects/vscode/ModelsHandler.ts

Lines changed: 43 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,22 @@ export type OnFileChangeData = {
3434
model?: any;
3535
};
3636

37+
export type OnOperationAppliedData = {
38+
moduleShortid: string;
39+
title: string;
40+
code: string;
41+
model: any;
42+
};
43+
3744
export type OnFileChangeCallback = (data: OnFileChangeData) => void;
3845

46+
export type OnOperationAppliedCallback = (data: OnOperationAppliedData) => void;
47+
3948
export class ModelsHandler {
4049
private modelAddedListener: { dispose: Function };
4150
private modelRemovedListener: { dispose: Function };
4251
private onChangeCallback: OnFileChangeCallback;
52+
private onOperationAppliedCallback: OnOperationAppliedCallback;
4353
private sandbox: Sandbox;
4454
private editorApi;
4555
private monaco;
@@ -55,11 +65,18 @@ export class ModelsHandler {
5565
};
5666
} = {};
5767

58-
constructor(editorApi, monaco, sandbox: Sandbox, cb: OnFileChangeCallback) {
68+
constructor(
69+
editorApi,
70+
monaco,
71+
sandbox: Sandbox,
72+
onChangeCallback: OnFileChangeCallback,
73+
onOperationAppliedCallback: OnOperationAppliedCallback
74+
) {
5975
this.editorApi = editorApi;
6076
this.monaco = monaco;
6177
this.sandbox = sandbox;
62-
this.onChangeCallback = cb;
78+
this.onChangeCallback = onChangeCallback;
79+
this.onOperationAppliedCallback = onOperationAppliedCallback;
6380
this.listenForChanges();
6481
}
6582

@@ -77,80 +94,43 @@ export class ModelsHandler {
7794
public changeModule = async (module: Module) => {
7895
if (getCurrentModelPath(this.editorApi) !== module.path) {
7996
const file = await this.editorApi.openFile(module.path);
80-
8197
return file.getModel();
8298
}
8399

84100
return Promise.resolve(getModel(this.editorApi));
85101
};
86102

87-
public applyOperations(operations: { [moduleShortid: string]: any }) {
88-
const operationsJSON = operations.toJSON ? operations.toJSON() : operations;
103+
public async applyOperation(moduleShortid: string, operation: any) {
104+
const module = this.sandbox.modules.find(m => m.shortid === moduleShortid);
89105

90-
return Promise.all(
91-
Object.keys(operationsJSON).map(moduleShortid => {
92-
const operation = TextOperation.fromJSON(operationsJSON[moduleShortid]);
93-
94-
const foundModule = this.sandbox.modules.find(
95-
m => m.shortid === moduleShortid
96-
);
97-
98-
if (!foundModule) {
99-
return Promise.resolve();
100-
}
101-
102-
const modulePath = '/sandbox' + foundModule.path;
103-
104-
const modelEditor = this.editorApi.editorService.editors.find(
105-
editor => editor.resource && editor.resource.path === modulePath
106-
);
106+
if (!module) {
107+
return;
108+
}
107109

108-
// Apply the code to the current module code itself
109-
const module = this.sandbox.modules.find(
110-
m => m.shortid === moduleShortid
111-
);
110+
const modulePath = '/sandbox' + module.path;
112111

113-
if (!modelEditor) {
114-
if (!module) {
115-
return Promise.resolve();
116-
}
112+
const modelEditor = this.editorApi.editorService.editors.find(
113+
editor => editor.resource && editor.resource.path === modulePath
114+
);
117115

118-
try {
119-
const code = operation.apply(module.code || '');
120-
121-
// Should this run? We are applying changes from the outside,
122-
// should not trigger a change?
123-
this.onChangeCallback({
124-
code,
125-
moduleShortid: module.shortid,
126-
title: module.title,
127-
});
128-
} catch (e) {
129-
throw new Error('Module state mismatch');
130-
}
116+
let model;
131117

132-
return Promise.resolve();
133-
}
118+
if (modelEditor) {
119+
model = (await modelEditor.textModelReference).object;
120+
} else {
121+
model = await this.editorApi.textFileService.models.loadOrCreate(
122+
this.monaco.Uri.file(modulePath)
123+
);
124+
}
134125

135-
return modelEditor.textModelReference.then(model => {
136-
this.applyOperationToModel(
137-
operation,
138-
false,
139-
model.object.textEditorModel
140-
);
126+
this.applyOperationToModel(operation, false, model.textEditorModel);
141127

142-
if (module) {
143-
// Should this really run? We have applied from the outside
144-
this.onChangeCallback({
145-
code: model.object.textEditorModel.getValue(),
146-
moduleShortid: module.shortid,
147-
title: module.title,
148-
model,
149-
});
150-
}
151-
});
152-
})
153-
);
128+
this.onOperationAppliedCallback({
129+
code: model.textEditorModel.getValue(),
130+
moduleShortid: module.shortid,
131+
title: module.title,
132+
model: model.textEditorModel,
133+
});
154134
}
155135

156136
public updateUserSelections(
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
export const EXTENSIONS_LOCATION = process.env.VSCODE
22
? '/vscode/extensions-bundle'
33
: '/public/vscode-extensions/v10';
4+
5+
export const VIM_EXTENSION_ID = 'vscodevim.vim';

packages/app/src/app/overmind/effects/vscode/extensionHostWorker/workers/ext-host-worker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ self.addEventListener('message', async e => {
4242
process.env = data.data.env || {};
4343
process.env.HOME = '/home';
4444

45-
loader()(() => {
45+
loader(true)(() => {
4646
ctx.require(
4747
['vs/workbench/services/extensions/node/extensionHostProcess'],
4848
() => {

packages/app/src/app/overmind/effects/vscode/index.ts

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,19 @@ import { listen } from 'codesandbox-api';
1818
import FontFaceObserver from 'fontfaceobserver';
1919
import * as childProcess from 'node-services/lib/child_process';
2020

21+
import { VIM_EXTENSION_ID } from './constants';
2122
import {
2223
initializeCustomTheme,
2324
initializeExtensionsFolder,
2425
initializeSettings,
2526
initializeThemeCache,
2627
} from './initializers';
2728
import { Linter } from './Linter';
28-
import { ModelsHandler, OnFileChangeData } from './ModelsHandler';
29+
import {
30+
ModelsHandler,
31+
OnFileChangeData,
32+
OnOperationAppliedData,
33+
} from './ModelsHandler';
2934
import sandboxFsSync from './sandboxFsSync';
3035
import { getSelection } from './utils';
3136
import loadScript from './vscode-script-loader';
@@ -36,6 +41,7 @@ export type VsCodeOptions = {
3641
getCurrentModule: () => Module;
3742
getSandboxFs: () => SandboxFs;
3843
onCodeChange: (data: OnFileChangeData) => void;
44+
onOperationApplied: (data: OnOperationAppliedData) => void;
3945
onSelectionChange: (selection: any) => void;
4046
reaction: Reaction;
4147
// These two should be removed
@@ -117,7 +123,7 @@ export class VSCodeEffect {
117123
this.initialized = Promise.all([
118124
new FontFaceObserver('dm').load(),
119125
new Promise(resolve => {
120-
loadScript(['vs/editor/codesandbox.editor.main'])(resolve);
126+
loadScript(true, ['vs/editor/codesandbox.editor.main'])(resolve);
121127
}),
122128
sandboxFsSync.initialize({
123129
getSandboxFs: options.getSandboxFs,
@@ -174,7 +180,7 @@ export class VSCodeEffect {
174180

175181
public setVimExtensionEnabled(enabled: boolean) {
176182
if (enabled) {
177-
this.enableExtension('vscodevim.vim');
183+
this.enableExtension(VIM_EXTENSION_ID);
178184
} else {
179185
// Auto disable vim extension
180186
if (
@@ -188,24 +194,23 @@ export class VSCodeEffect {
188194
);
189195
}
190196

191-
this.disableExtension('vscodevim.vim');
197+
this.disableExtension(VIM_EXTENSION_ID);
192198
}
193199
}
194200

195-
public async applyOperations(operations: {
196-
[x: string]: (string | number)[];
197-
}) {
201+
public async applyOperation(
202+
moduleShortid: string,
203+
operation: (string | number)[]
204+
) {
198205
this.isApplyingCode = true;
199206

200-
// The call to "apployOperations" should "try" and treat error as "moduleStateMismatch"
201-
// this.props.onModuleStateMismatch();
202-
203207
try {
204-
await this.modelsHandler.applyOperations(operations);
208+
await this.modelsHandler.applyOperation(moduleShortid, operation);
205209
} catch (error) {
206210
this.isApplyingCode = false;
207211
throw error;
208212
}
213+
this.isApplyingCode = false;
209214
}
210215

211216
public updateOptions(options: { readOnly: boolean }) {
@@ -244,7 +249,8 @@ export class VSCodeEffect {
244249
this.editorApi,
245250
this.monaco,
246251
sandbox,
247-
this.onFileChange
252+
this.onFileChange,
253+
this.onOperationApplied
248254
);
249255

250256
this.fs.sync();
@@ -397,7 +403,7 @@ export class VSCodeEffect {
397403
initializeSettings();
398404

399405
if (localStorage.getItem('settings.vimmode') === 'true') {
400-
this.enableExtension('vscodevim.vim');
406+
this.enableExtension(VIM_EXTENSION_ID);
401407
}
402408

403409
this.workbench.addWorkbenchActions();
@@ -605,13 +611,16 @@ export class VSCodeEffect {
605611
}
606612
};
607613

608-
private onFileChange = (data: OnFileChangeData) => {
609-
if (this.isApplyingCode) {
610-
return;
614+
private onOperationApplied = (data: OnOperationAppliedData) => {
615+
if (data.moduleShortid === this.options.getCurrentModule().shortid) {
616+
this.lint(data.title, data.model);
611617
}
612618

613-
this.lint(data.title, data.model);
619+
this.options.onOperationApplied(data);
620+
};
614621

622+
private onFileChange = (data: OnFileChangeData) => {
623+
this.lint(data.title, data.model);
615624
this.options.onCodeChange(data);
616625
};
617626

packages/app/src/app/overmind/effects/vscode/vscode-script-loader.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ function initializeRequires() {
364364
});
365365
}
366366

367-
export default function(requiredModule?: string[], isVSCode = true) {
367+
export default function(isVSCode: boolean, requiredModule?: string[]) {
368368
var METADATA = isVSCode ? VSCODE_METADATA : MONACO_METADATA;
369369
var IS_FILE_PROTOCOL = global.location.protocol === 'file:';
370370
var DIRNAME = null;

packages/app/src/app/overmind/namespaces/editor/actions.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,24 @@ export const codeSaved: AsyncAction<{
171171
}
172172
);
173173

174+
export const onOperationApplied: Action<{
175+
moduleShortid: string;
176+
code: string;
177+
}> = ({ state, actions }, { code, moduleShortid }) => {
178+
const module = state.editor.currentSandbox.modules.find(
179+
m => m.shortid === moduleShortid
180+
);
181+
182+
if (!module) {
183+
return;
184+
}
185+
186+
actions.editor.internal.setModuleCode({
187+
module,
188+
code,
189+
});
190+
};
191+
174192
export const codeChanged: Action<{
175193
moduleShortid: string;
176194
code: string;
@@ -332,11 +350,6 @@ export const moduleSelected: Action<{
332350
actions.editor.internal.setCurrentModule(module);
333351

334352
if (state.live.isLive) {
335-
/*
336-
state.editor.pendingUserSelections = actions.live.internal.getSelectionsForModule(
337-
module
338-
);
339-
*/
340353
effects.vscode.updateUserSelections(
341354
actions.live.internal.getSelectionsForModule(module)
342355
);

packages/app/src/app/overmind/namespaces/editor/state.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { ViewConfig } from '@codesandbox/common/lib/templates/template';
55
import {
66
DevToolsTabPosition,
77
DiffTab,
8-
EditorSelection,
98
Module,
109
ModuleCorrection,
1110
ModuleError,
@@ -38,10 +37,6 @@ type State = {
3837
error: string | null;
3938
isResizing: boolean;
4039
changedModuleShortids: string[];
41-
pendingOperations: {
42-
[id: string]: Array<string | number>;
43-
};
44-
pendingUserSelections: EditorSelection[];
4540
currentTabId: string;
4641
tabs: Tabs;
4742
errors: ModuleError[];
@@ -88,8 +83,6 @@ export const state: State = {
8883
errors: [],
8984
sessionFrozen: true,
9085
corrections: [],
91-
pendingOperations: {},
92-
pendingUserSelections: [],
9386
isInProjectView: false,
9487
forceRender: 0,
9588
initialPath: '/',

packages/app/src/app/overmind/namespaces/files/actions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ export const moduleCreated: AsyncAction<{
472472
module.id = updatedModule.id;
473473
module.shortid = updatedModule.shortid;
474474

475+
effects.vscode.fs.writeFile(state.editor.modulesByPath, module);
475476
state.editor.currentModuleShortid = module.shortid;
476477

477478
if (state.live.isCurrentEditor) {

0 commit comments

Comments
 (0)