From 9d901c3d60ad1902e9699f7ba03c0e6b7fe92b0f Mon Sep 17 00:00:00 2001 From: jiming Date: Mon, 7 Mar 2022 16:20:26 +0800 Subject: [PATCH 1/2] fix: enable the editor to save viewState --- src/controller/__tests__/editor.test.ts | 36 +++++++++++++++++++++++++ src/controller/editor.tsx | 9 +++++++ 2 files changed, 45 insertions(+) create mode 100644 src/controller/__tests__/editor.test.ts diff --git a/src/controller/__tests__/editor.test.ts b/src/controller/__tests__/editor.test.ts new file mode 100644 index 000000000..ae90dc5dc --- /dev/null +++ b/src/controller/__tests__/editor.test.ts @@ -0,0 +1,36 @@ +import 'reflect-metadata'; +import { container } from 'tsyringe'; +import { EditorService, StatusBarService, BuiltinService } from 'mo/services'; +import { EditorController } from '../editor'; +import { editor as MonacoEditor, Position } from 'mo/monaco'; + +const editorController = container.resolve(EditorController); +const editorService = container.resolve(EditorService); +const statusBarService = container.resolve(StatusBarService); +const builtinService = container.resolve(BuiltinService); + +describe('The ediotr controller', () => { + test('The open method', () => { + const testTab = { + id: 'testTab', + name: 'testTab', + }; + editorController.open(testTab); + const { current } = editorService.getState(); + expect(current?.activeTab).toEqual('testTab'); + }); + + test('The updateEditorLineColumnInfo method', () => { + const editorInstance = {} as MonacoEditor.IStandaloneCodeEditor; + const position = { lineNumber: 1, column: 1 } as Position; + const { STATUS_EDITOR_INFO } = builtinService.getModules(); + editorInstance.getPosition = jest.fn(() => position); + statusBarService.setState({ rightItems: [STATUS_EDITOR_INFO] }); + + editorController.updateEditorLineColumnInfo(editorInstance); + expect(statusBarService.getState().rightItems[0]?.data).toEqual({ + ln: 1, + col: 1, + }); + }); +}); diff --git a/src/controller/editor.tsx b/src/controller/editor.tsx index 703a88f4a..c796440ea 100644 --- a/src/controller/editor.tsx +++ b/src/controller/editor.tsx @@ -273,6 +273,15 @@ export class EditorController extends Controller implements IEditorController { editorInstance.onDidChangeCursorSelection(() => { this.updateEditorLineColumnInfo(editorInstance); }); + + editorInstance.onDidBlurEditorText(() => { + const { current } = this.editorService.getState(); + const tab = current?.tab; + if (tab?.id) { + const viewState = editorInstance?.saveViewState(); + this.editorStates.set(tab.id?.toString(), viewState); + } + }); } /** From be74604ba92f115e999123b970d4c12a9ac6d1e9 Mon Sep 17 00:00:00 2001 From: jiming Date: Mon, 7 Mar 2022 19:39:54 +0800 Subject: [PATCH 2/2] test: add test code --- src/controller/__tests__/editor.test.ts | 69 +++++++++++++++++++++---- src/controller/editor.tsx | 11 +++- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/controller/__tests__/editor.test.ts b/src/controller/__tests__/editor.test.ts index ae90dc5dc..42dc1e35a 100644 --- a/src/controller/__tests__/editor.test.ts +++ b/src/controller/__tests__/editor.test.ts @@ -2,7 +2,7 @@ import 'reflect-metadata'; import { container } from 'tsyringe'; import { EditorService, StatusBarService, BuiltinService } from 'mo/services'; import { EditorController } from '../editor'; -import { editor as MonacoEditor, Position } from 'mo/monaco'; +import { editor as MonacoEditor, IDisposable, Position } from 'mo/monaco'; const editorController = container.resolve(EditorController); const editorService = container.resolve(EditorService); @@ -10,27 +10,74 @@ const statusBarService = container.resolve(StatusBarService); const builtinService = container.resolve(BuiltinService); describe('The ediotr controller', () => { - test('The open method', () => { + test('The initEditorEvents method', () => { + const editorInstance = {} as MonacoEditor.IStandaloneCodeEditor; + const position = { lineNumber: 1, column: 1 } as Position; + let contentListener; + let focusListener; + let cursorListener; + let blurListener; + + editorInstance.onDidChangeModelContent = jest.fn((listener) => { + contentListener = listener; + return {} as IDisposable; + }); + editorInstance.onDidFocusEditorText = jest.fn((listener) => { + focusListener = listener; + return {} as IDisposable; + }); + editorInstance.onDidChangeCursorSelection = jest.fn((listener) => { + cursorListener = listener; + return {} as IDisposable; + }); + editorInstance.onDidBlurEditorText = jest.fn((listener) => { + blurListener = listener; + return {} as IDisposable; + }); + editorInstance.getPosition = jest.fn(() => position); + const testTab = { id: 'testTab', name: 'testTab', }; - editorController.open(testTab); + editorService.open(testTab); const { current } = editorService.getState(); - expect(current?.activeTab).toEqual('testTab'); - }); + editorController.initEditorEvents(editorInstance, current?.id!); - test('The updateEditorLineColumnInfo method', () => { - const editorInstance = {} as MonacoEditor.IStandaloneCodeEditor; - const position = { lineNumber: 1, column: 1 } as Position; + // focus + focusListener?.(); + expect(editorService.getState().current?.tab?.id).toEqual(testTab.id); + + // change content + editorInstance.getModel = jest.fn(() => { + return { getValue: () => 'newValue' } as MonacoEditor.ITextModel; + }); + contentListener?.(); + expect(editorService.getState().current?.tab?.data?.value).toEqual( + 'newValue' + ); + + // change cursor const { STATUS_EDITOR_INFO } = builtinService.getModules(); - editorInstance.getPosition = jest.fn(() => position); statusBarService.setState({ rightItems: [STATUS_EDITOR_INFO] }); - - editorController.updateEditorLineColumnInfo(editorInstance); + cursorListener?.(); expect(statusBarService.getState().rightItems[0]?.data).toEqual({ ln: 1, col: 1, }); + + // blur + const viewState = { + viewState: { scrollTop: 10 }, + } as MonacoEditor.ICodeEditorViewState; + editorInstance.saveViewState = jest.fn(() => viewState); + blurListener?.(); + expect( + editorController.getViewState(current?.tab?.id?.toString()!) + ).toEqual(viewState); + + // reset services + statusBarService.reset(); + editorService.setState({ current: null, groups: [] }); }); }); diff --git a/src/controller/editor.tsx b/src/controller/editor.tsx index c796440ea..edf375436 100644 --- a/src/controller/editor.tsx +++ b/src/controller/editor.tsx @@ -46,6 +46,11 @@ export interface IEditorController extends Partial { onClickActions: (action: IEditorActionsProps) => void; onUpdateEditorIns?: (editorInstance: any, groupId: UniqueId) => void; onPaneSizeChange?: (newSize: number[]) => void; + initEditorEvents?: ( + editorInstance: MonacoEditor.IStandaloneCodeEditor, + groupId: UniqueId + ) => void; + getViewState?: (id: UniqueId) => MonacoEditor.ICodeEditorViewState; } @singleton() export class EditorController extends Controller implements IEditorController { @@ -239,7 +244,7 @@ export class EditorController extends Controller implements IEditorController { this.layoutService.setGroupSplitSize(newSize); }; - private initEditorEvents( + public initEditorEvents( editorInstance: MonacoEditor.IStandaloneCodeEditor, groupId: UniqueId ) { @@ -284,6 +289,10 @@ export class EditorController extends Controller implements IEditorController { }); } + public getViewState = (id: UniqueId) => { + return this.editorStates.get(id); + }; + /** * Called when Editor props changed */