@opensumi/ide-editor 3.3.4-next-1727344885.0 → 3.3.4-next-1729497448.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.
Files changed (29) hide show
  1. package/lib/browser/doc-model/editor-document-model-service.d.ts.map +1 -1
  2. package/lib/browser/doc-model/editor-document-model-service.js +2 -2
  3. package/lib/browser/doc-model/editor-document-model-service.js.map +1 -1
  4. package/lib/browser/editor-collection.service.d.ts +2 -3
  5. package/lib/browser/editor-collection.service.d.ts.map +1 -1
  6. package/lib/browser/editor-collection.service.js +15 -18
  7. package/lib/browser/editor-collection.service.js.map +1 -1
  8. package/lib/browser/fs-resource/fs-editor-doc.d.ts +3 -0
  9. package/lib/browser/fs-resource/fs-editor-doc.d.ts.map +1 -1
  10. package/lib/browser/fs-resource/fs-editor-doc.js +45 -5
  11. package/lib/browser/fs-resource/fs-editor-doc.js.map +1 -1
  12. package/lib/browser/workbench-editor.service.d.ts.map +1 -1
  13. package/lib/browser/workbench-editor.service.js +0 -1
  14. package/lib/browser/workbench-editor.service.js.map +1 -1
  15. package/lib/common/editor.d.ts +2 -2
  16. package/lib/common/editor.d.ts.map +1 -1
  17. package/lib/common/editor.js +16 -1
  18. package/lib/common/editor.js.map +1 -1
  19. package/lib/common/notebook.d.ts +0 -3
  20. package/lib/common/notebook.d.ts.map +1 -1
  21. package/lib/common/notebook.js +0 -3
  22. package/lib/common/notebook.js.map +1 -1
  23. package/package.json +14 -14
  24. package/src/browser/doc-model/editor-document-model-service.ts +3 -2
  25. package/src/browser/editor-collection.service.ts +16 -23
  26. package/src/browser/fs-resource/fs-editor-doc.ts +51 -12
  27. package/src/browser/workbench-editor.service.ts +0 -1
  28. package/src/common/editor.ts +22 -2
  29. package/src/common/notebook.ts +0 -3
@@ -1,5 +1,5 @@
1
1
  import { Autowired, INJECTOR_TOKEN, Injectable, Injector } from '@opensumi/di';
2
- import { IContextKeyService, IRange, PreferenceService } from '@opensumi/ide-core-browser';
2
+ import { AppConfig, IContextKeyService, IRange, PreferenceService } from '@opensumi/ide-core-browser';
3
3
  import { ResourceContextKey } from '@opensumi/ide-core-browser/lib/contextkey';
4
4
  import { MonacoService } from '@opensumi/ide-core-browser/lib/monaco';
5
5
  import {
@@ -9,7 +9,6 @@ import {
9
9
  Emitter as EventEmitter,
10
10
  ILineChange,
11
11
  ISelection,
12
- LRUCache,
13
12
  OnEvent,
14
13
  URI,
15
14
  WithEventBus,
@@ -32,7 +31,7 @@ import {
32
31
  IUndoStopOptions,
33
32
  ResourceDecorationNeedChangeEvent,
34
33
  } from '../common';
35
- import { IEditorDocumentModel, IEditorDocumentModelRef } from '../common/editor';
34
+ import { IEditorDocumentModel, IEditorDocumentModelRef, isTextEditorViewState } from '../common/editor';
36
35
 
37
36
  import { MonacoEditorDecorationApplier } from './decoration-applier';
38
37
  import { EditorDocumentModelContentChangedEvent, IEditorDocumentModelService } from './doc-model/types';
@@ -514,7 +513,7 @@ export class BrowserCodeEditor extends BaseMonacoEditorWrapper implements ICodeE
514
513
  protected restoreState() {
515
514
  if (this.currentUri) {
516
515
  const state = this.editorState.get(this.currentUri.toString());
517
- if (state) {
516
+ if (isTextEditorViewState(state)) {
518
517
  this.monacoEditor.restoreViewState(state);
519
518
  }
520
519
  }
@@ -559,6 +558,9 @@ export class BrowserDiffEditor extends WithEventBus implements IDiffEditor {
559
558
  @Autowired(EditorCollectionService)
560
559
  private collectionService: EditorCollectionServiceImpl;
561
560
 
561
+ @Autowired(AppConfig)
562
+ private appConfig: AppConfig;
563
+
562
564
  private originalDocModelRef: IEditorDocumentModelRef | null;
563
565
 
564
566
  private modifiedDocModelRef: IEditorDocumentModelRef | null;
@@ -605,8 +607,6 @@ export class BrowserDiffEditor extends WithEventBus implements IDiffEditor {
605
607
 
606
608
  public onRefOpen = this._onRefOpen.event;
607
609
 
608
- private diffEditorModelCache = new LRUCache<string, monaco.editor.IDiffEditorViewModel>(100);
609
-
610
610
  protected saveCurrentState() {
611
611
  if (this.currentUri) {
612
612
  const state = this.monacoDiffEditor.saveViewState();
@@ -616,10 +616,13 @@ export class BrowserDiffEditor extends WithEventBus implements IDiffEditor {
616
616
  }
617
617
  }
618
618
 
619
- protected restoreState() {
619
+ protected restoreState(options: IResourceOpenOptions) {
620
620
  if (this.currentUri) {
621
621
  const state = this.editorState.get(this.currentUri.toString());
622
- if (state) {
622
+ if (isTextEditorViewState(state)) {
623
+ if (options.range || options.originalRange) {
624
+ state.modified!.cursorState = []; // 避免重复的选中态
625
+ }
623
626
  this.monacoDiffEditor.restoreViewState(state);
624
627
  }
625
628
  }
@@ -638,11 +641,6 @@ export class BrowserDiffEditor extends WithEventBus implements IDiffEditor {
638
641
  );
639
642
  }
640
643
 
641
- disposeModel(originalUri: string, modifiedUri: string) {
642
- const key = `${originalUri}-${modifiedUri}`;
643
- this.diffEditorModelCache.delete(key);
644
- }
645
-
646
644
  async compare(
647
645
  originalDocModelRef: IEditorDocumentModelRef,
648
646
  modifiedDocModelRef: IEditorDocumentModelRef,
@@ -657,13 +655,7 @@ export class BrowserDiffEditor extends WithEventBus implements IDiffEditor {
657
655
  }
658
656
  const original = this.originalDocModel.getMonacoModel();
659
657
  const modified = this.modifiedDocModel.getMonacoModel();
660
- const key = `${original.uri.toString()}-${modified.uri.toString()}`;
661
- let model = this.diffEditorModelCache.get(key);
662
- if (!model) {
663
- model = this.monacoDiffEditor.createViewModel({ original, modified });
664
- this.diffEditorModelCache.set(key, model);
665
- }
666
-
658
+ const model = this.monacoDiffEditor.createViewModel({ original, modified });
667
659
  this.monacoDiffEditor.setModel(model);
668
660
 
669
661
  if (rawUri) {
@@ -678,11 +670,14 @@ export class BrowserDiffEditor extends WithEventBus implements IDiffEditor {
678
670
  }),
679
671
  });
680
672
  }
673
+ await model?.waitForDiff();
674
+
675
+ // 需要等待 Diff 渲染,否则无法获取当前的 Diff 代码折叠状态
676
+ this.restoreState(options);
681
677
 
682
678
  if (options.range || options.originalRange) {
683
679
  const range = (options.range || options.originalRange) as monaco.IRange;
684
680
  const currentEditor = options.range ? this.modifiedEditor.monacoEditor : this.originalEditor.monacoEditor;
685
- await model?.waitForDiff();
686
681
  // 必须使用 setTimeout, 因为两边的 editor 出现时机问题,diffEditor 是异步显示和渲染
687
682
  setTimeout(() => {
688
683
  currentEditor.revealRangeInCenter(range);
@@ -697,8 +692,6 @@ export class BrowserDiffEditor extends WithEventBus implements IDiffEditor {
697
692
  currentEditor.revealRangeInCenter(range);
698
693
  });
699
694
  });
700
- } else {
701
- this.restoreState();
702
695
  }
703
696
  this._onRefOpen.fire(originalDocModelRef);
704
697
  this._onRefOpen.fire(modifiedDocModelRef);
@@ -48,6 +48,7 @@ export class BaseFileSystemEditorDocumentProvider implements IEditorDocumentMode
48
48
  protected _fileContentMd5OnBrowserFs: Set<string> = new Set();
49
49
 
50
50
  private _detectedEncodingMap = new Map<string, string>();
51
+ private _detectedEolMap = new Map<string, EOL>();
51
52
 
52
53
  @Autowired(IFileServiceClient)
53
54
  protected readonly fileServiceClient: IFileServiceClient;
@@ -85,21 +86,15 @@ export class BaseFileSystemEditorDocumentProvider implements IEditorDocumentMode
85
86
  }
86
87
 
87
88
  async provideEOL(uri: URI) {
88
- const backendOS = await this.applicationService.getBackendOS();
89
- const eol = this.preferenceService.get<EOL | 'auto'>(
90
- 'files.eol',
91
- 'auto',
92
- uri.toString(),
93
- getLanguageIdFromMonaco(uri)!,
94
- )!;
95
-
96
- if (eol !== 'auto') {
97
- return eol;
89
+ const cache = this._detectedEolMap.get(uri.toString());
90
+ if (cache) {
91
+ return cache;
98
92
  }
93
+ const backendOS = await this.applicationService.getBackendOS();
99
94
  return backendOS === OperatingSystem.Windows ? EOL.CRLF : EOL.LF;
100
95
  }
101
96
 
102
- async read(uri: URI, options: ReadEncodingOptions): Promise<{ encoding: string; content: string }> {
97
+ async read(uri: URI, options: ReadEncodingOptions): Promise<{ encoding: string; content: string; eol: EOL }> {
103
98
  const { content: buffer } = await this.fileServiceClient.readFile(uri.toString());
104
99
 
105
100
  const guessEncoding =
@@ -118,19 +113,63 @@ export class BaseFileSystemEditorDocumentProvider implements IEditorDocumentMode
118
113
 
119
114
  const content = buffer.toString(detected.encoding);
120
115
 
116
+ const eol = await this.getEol(uri, content);
121
117
  const uriString = uri.toString();
122
118
 
123
119
  this._detectedEncodingMap.set(uriString, detected.encoding);
120
+ this._detectedEolMap.set(uriString, eol);
124
121
 
125
- // 记录表示这个文档被[这个editorDocumentProvider]引用了
122
+ // 记录表示这个文档被引用了
126
123
  this._fileContentMd5OnBrowserFs.add(uriString);
127
124
 
128
125
  return {
129
126
  encoding: detected.encoding || UTF8,
130
127
  content,
128
+ eol,
131
129
  };
132
130
  }
133
131
 
132
+ private async getEol(uri: URI, content: string) {
133
+ const contentToDetect = content.slice(0, 2000);
134
+ let cr = 0;
135
+ let lf = 0;
136
+ let crlf = 0;
137
+ const len = contentToDetect.length;
138
+ for (let i = 0; i < len; i++) {
139
+ if (contentToDetect[i] === '\r') {
140
+ if (contentToDetect[i + 1] === '\n') {
141
+ crlf++;
142
+ // 跳过后续 \n
143
+ i++;
144
+ } else {
145
+ cr++;
146
+ }
147
+ } else if (contentToDetect[i] === '\n') {
148
+ lf++;
149
+ }
150
+ }
151
+
152
+ const totalEOLCount = cr + lf + crlf;
153
+ const totalCRCount = cr + crlf;
154
+ const eol = this.preferenceService.get<EOL | 'auto'>(
155
+ 'files.eol',
156
+ 'auto',
157
+ uri.toString(),
158
+ getLanguageIdFromMonaco(uri)!,
159
+ )!;
160
+ if (eol !== 'auto') {
161
+ return eol;
162
+ }
163
+ const defaultEOL = await this.provideEOL(uri);
164
+ if (totalEOLCount === 0) {
165
+ return defaultEOL;
166
+ }
167
+ if (totalCRCount > totalEOLCount / 2) {
168
+ return EOL.CRLF;
169
+ }
170
+ return EOL.LF;
171
+ }
172
+
134
173
  async provideEditorDocumentModelContent(uri: URI, encoding: string) {
135
174
  // TODO: 这部分要优化成buffer获取(长期来看是stream获取,encoding在哪一层做?)
136
175
  // 暂时还是使用 resolveContent 内提供的 decode 功能
@@ -1568,7 +1568,6 @@ export class EditorGroup extends WithEventBus implements IGridEditorGroup {
1568
1568
  const query = uri.getParsedQuery();
1569
1569
  this.doDisposeDocRef(new URI(query.original));
1570
1570
  this.doDisposeDocRef(new URI(query.modified));
1571
- this.diffEditor.disposeModel(query.original, query.modified);
1572
1571
  } else if (uri.scheme === 'mergeEditor') {
1573
1572
  this.mergeEditor && this.mergeEditor.dispose();
1574
1573
  } else {
@@ -22,6 +22,8 @@ import { IDocModelUpdateOptions } from './types';
22
22
 
23
23
  import type {
24
24
  EOL,
25
+ ICodeEditorViewState,
26
+ IDiffEditorViewState,
25
27
  IEditorOptions,
26
28
  ICodeEditor as IMonacoCodeEditor,
27
29
  ITextModel,
@@ -317,8 +319,6 @@ export interface IDiffEditor extends IDisposable {
317
319
  getLineChanges(): ILineChange[] | null;
318
320
 
319
321
  onRefOpen: Event<IEditorDocumentModelRef>;
320
-
321
- disposeModel(originalUri: string, modifiedUri: string): void;
322
322
  }
323
323
 
324
324
  @Injectable()
@@ -989,3 +989,23 @@ export function getSimpleEditorOptions(): IEditorOptions {
989
989
  * in case the column does not exist yet.
990
990
  */
991
991
  export type EditorGroupColumn = number;
992
+
993
+ export function isTextEditorViewState(candidate: unknown): candidate is ICodeEditorViewState | IDiffEditorViewState {
994
+ const viewState = candidate as (ICodeEditorViewState | IDiffEditorViewState) | undefined;
995
+ if (!viewState) {
996
+ return false;
997
+ }
998
+
999
+ const diffEditorViewState = viewState as IDiffEditorViewState;
1000
+ if (diffEditorViewState.modified) {
1001
+ return isTextEditorViewState(diffEditorViewState.modified);
1002
+ }
1003
+
1004
+ const codeEditorViewState = viewState as ICodeEditorViewState;
1005
+
1006
+ return !!(
1007
+ codeEditorViewState.contributionsState &&
1008
+ codeEditorViewState.viewState &&
1009
+ Array.isArray(codeEditorViewState.cursorState)
1010
+ );
1011
+ }
@@ -193,7 +193,4 @@ export interface INotebookService {
193
193
  onDidChangeNotebookDocument: Event<NotebookDocumentChangeDto>;
194
194
  }
195
195
 
196
- /**
197
- * @deprecated use Schemes.notebookCell
198
- */
199
196
  export const notebookCellScheme = 'vscode-notebook-cell';