From 41a409784ef7e08cb83029ed822c57ff40412dd3 Mon Sep 17 00:00:00 2001 From: "qingyi.xjh" Date: Fri, 30 Jun 2023 15:54:27 +0800 Subject: [PATCH 1/2] feat: support merge editor minimap --- .../merge-editor/merge-editor.service.ts | 11 ++- .../src/browser/contrib/merge-editor/types.ts | 7 ++ .../contrib/merge-editor/view/grid.tsx | 15 +++- .../view/merge-editor.module.less | 35 +++++++- .../contrib/merge-editor/view/mini-map.tsx | 83 +++++++++++++++++++ 5 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 packages/monaco/src/browser/contrib/merge-editor/view/mini-map.tsx diff --git a/packages/monaco/src/browser/contrib/merge-editor/merge-editor.service.ts b/packages/monaco/src/browser/contrib/merge-editor/merge-editor.service.ts index 7b795c6909..7d5bdd9265 100644 --- a/packages/monaco/src/browser/contrib/merge-editor/merge-editor.service.ts +++ b/packages/monaco/src/browser/contrib/merge-editor/merge-editor.service.ts @@ -19,7 +19,7 @@ import { MappingManagerService } from './mapping-manager.service'; import { IMergeEditorEditorConstructionOptions } from './merge-editor-widget'; import { ComputerDiffModel } from './model/computer-diff'; import { LineRangeMapping } from './model/line-range-mapping'; -import { ACCEPT_CURRENT_ACTIONS } from './types'; +import { ACCEPT_CURRENT_ACTIONS, IEditorMountParameter } from './types'; import { ActionsManager } from './view/actions-manager'; import { CurrentCodeEditor } from './view/editors/currentCodeEditor'; import { IncomingCodeEditor } from './view/editors/incomingCodeEditor'; @@ -60,6 +60,9 @@ export class MergeEditorService extends Disposable { private readonly _onDidInputNutrition = new Emitter(); public readonly onDidInputNutrition: Event = this._onDidInputNutrition.event; + private readonly _onDidMount = new Emitter(); + public readonly onDidMount: Event = this._onDidMount.event; + private readonly _onRestoreState = new Emitter(); public readonly onRestoreState: Event = this._onRestoreState.event; @@ -105,6 +108,12 @@ export class MergeEditorService extends Disposable { this.stickinessConnectManager.mount(this.currentView, this.resultView, this.incomingView); this.actionsManager.mount(this.currentView, this.resultView, this.incomingView); + this._onDidMount.fire({ + currentView: this.currentView, + resultView: this.resultView, + incomingView: this.incomingView, + }); + this.initListenEvent(); } diff --git a/packages/monaco/src/browser/contrib/merge-editor/types.ts b/packages/monaco/src/browser/contrib/merge-editor/types.ts index 6b7e946644..7fb0921327 100644 --- a/packages/monaco/src/browser/contrib/merge-editor/types.ts +++ b/packages/monaco/src/browser/contrib/merge-editor/types.ts @@ -6,6 +6,7 @@ import { IModelDecorationOptions } from '../../monaco-api/editor'; import { LineRange } from './model/line-range'; import { LineRangeMapping } from './model/line-range-mapping'; +import { BaseCodeEditor } from './view/editors/baseCodeEditor'; import styles from './view/merge-editor.module.less'; export interface IRangeContrast { @@ -169,3 +170,9 @@ export interface IMergeEditorViewState { turnLeft: LineRangeMapping[]; turnRight: LineRangeMapping[]; } + +export interface IEditorMountParameter { + currentView: BaseCodeEditor; + resultView: BaseCodeEditor; + incomingView: BaseCodeEditor; +} diff --git a/packages/monaco/src/browser/contrib/merge-editor/view/grid.tsx b/packages/monaco/src/browser/contrib/merge-editor/view/grid.tsx index f54e2ee850..77f38715cd 100644 --- a/packages/monaco/src/browser/contrib/merge-editor/view/grid.tsx +++ b/packages/monaco/src/browser/contrib/merge-editor/view/grid.tsx @@ -15,6 +15,7 @@ import { MergeEditorService } from '../merge-editor.service'; import { EditorViewType } from '../types'; import styles from './merge-editor.module.less'; +import { MiniMap } from './mini-map'; import { WithViewStickinessConnectComponent } from './stickiness-connect-manager'; const TitleHead: React.FC<{ contrastType: EditorViewType }> = ({ contrastType }) => { @@ -159,7 +160,12 @@ export const Grid = () => {
-
+
+
+ +
+
+
@@ -175,7 +181,12 @@ export const Grid = () => {
-
+
+
+
+ +
+
diff --git a/packages/monaco/src/browser/contrib/merge-editor/view/merge-editor.module.less b/packages/monaco/src/browser/contrib/merge-editor/view/merge-editor.module.less index b2e678f995..4278f74dc0 100644 --- a/packages/monaco/src/browser/contrib/merge-editor/view/merge-editor.module.less +++ b/packages/monaco/src/browser/contrib/merge-editor/view/merge-editor.module.less @@ -2,7 +2,6 @@ height: 100%; overflow: hidden; position: relative; - padding-left: 8px; .merge_actions_container { position: absolute; @@ -77,6 +76,40 @@ display: flex; flex-direction: column; + .content { + height: inherit; + display: flex; + + .minimap_container { + height: 100%; + width: 15px; + + .minimap_content { + position: relative; + height: inherit; + + .block { + position: absolute; + width: 100%; + + &.insert { + background-color: var(--mergeEditor-insertedInnerCharColor); + } + &.modify { + background-color: var(--mergeEditor-modifyInnerCharColor); + } + &.remove { + background-color: var(--mergeEditor-removedInnerCharColor); + } + } + } + } + + .editor_container { + width: calc(100% - 15px); + } + } + .stickiness_connect_container { height: 100%; position: relative; diff --git a/packages/monaco/src/browser/contrib/merge-editor/view/mini-map.tsx b/packages/monaco/src/browser/contrib/merge-editor/view/mini-map.tsx new file mode 100644 index 0000000000..2afbab7b19 --- /dev/null +++ b/packages/monaco/src/browser/contrib/merge-editor/view/mini-map.tsx @@ -0,0 +1,83 @@ +import cls from 'classnames'; +import React, { useCallback, useEffect } from 'react'; + +import { Disposable, Event, useInjectable } from '@opensumi/ide-core-browser'; +import { EditorOption } from '@opensumi/monaco-editor-core/esm/vs/editor/common/config/editorOptions'; + +import { MergeEditorService } from '../merge-editor.service'; +import { LineRange } from '../model/line-range'; +import { EditorViewType } from '../types'; + +import { BaseCodeEditor } from './editors/baseCodeEditor'; +import styles from './merge-editor.module.less'; + +interface BlockPiece { + top: string; + height: string; + className: string; +} + +export const MiniMap: React.FC<{ contrastType: EditorViewType }> = ({ contrastType }) => { + const mergeEditorService = useInjectable(MergeEditorService); + const [blocks, setBlocks] = React.useState([]); + + useEffect(() => { + const disposables = new Disposable(); + + disposables.addDispose( + mergeEditorService.onDidMount((data) => { + const { currentView, incomingView } = data; + + if (contrastType === EditorViewType.CURRENT) { + disposables.addDispose( + Event.debounce( + currentView.onDidChangeDecorations, + () => {}, + 1, + )(() => { + computePiece(currentView, currentView.documentMapping.getOriginalRange()); + }), + ); + } else if (contrastType === EditorViewType.INCOMING) { + disposables.addDispose( + Event.debounce( + incomingView.onDidChangeDecorations, + () => {}, + 1, + )(() => { + computePiece(incomingView, incomingView.documentMapping.getModifiedRange()); + }), + ); + } + }), + ); + + return () => disposables.dispose(); + }, [mergeEditorService, contrastType]); + + const computePiece = useCallback((viewEditor: BaseCodeEditor, ranges: LineRange[]) => { + const editor = viewEditor.getEditor(); + + const lineHeight = editor.getOption(EditorOption.lineHeight); + const contentHeight = editor.getContentHeight(); + const blocks: BlockPiece[] = []; + + ranges.forEach((range) => { + blocks.push({ + top: (((range.startLineNumber - 1) * lineHeight) / contentHeight) * 100 + '%', + height: ((range.length * lineHeight) / contentHeight) * 100 + '%', + className: styles[range.type], + }); + }); + + setBlocks(blocks); + }, []); + + return ( +
+ {blocks.map((block) => ( + + ))} +
+ ); +}; From 2b5c53b226e640f4f634f3a5784c2d1de27633fc Mon Sep 17 00:00:00 2001 From: "qingyi.xjh" Date: Fri, 30 Jun 2023 16:00:43 +0800 Subject: [PATCH 2/2] fix: improve code --- .../src/browser/contrib/merge-editor/view/mini-map.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/monaco/src/browser/contrib/merge-editor/view/mini-map.tsx b/packages/monaco/src/browser/contrib/merge-editor/view/mini-map.tsx index 2afbab7b19..826be48dc8 100644 --- a/packages/monaco/src/browser/contrib/merge-editor/view/mini-map.tsx +++ b/packages/monaco/src/browser/contrib/merge-editor/view/mini-map.tsx @@ -63,6 +63,10 @@ export const MiniMap: React.FC<{ contrastType: EditorViewType }> = ({ contrastTy const blocks: BlockPiece[] = []; ranges.forEach((range) => { + if (range.isComplete) { + return; + } + blocks.push({ top: (((range.startLineNumber - 1) * lineHeight) / contentHeight) * 100 + '%', height: ((range.length * lineHeight) / contentHeight) * 100 + '%', @@ -76,8 +80,8 @@ export const MiniMap: React.FC<{ contrastType: EditorViewType }> = ({ contrastTy return (
{blocks.map((block) => ( - - ))} + + ))}
); };