@theia/monaco 1.63.0-next.52 → 1.63.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.
- package/lib/browser/index.d.ts +1 -0
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +1 -0
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/monaco-code-action-save-participant.d.ts +2 -5
- package/lib/browser/monaco-code-action-save-participant.d.ts.map +1 -1
- package/lib/browser/monaco-code-action-save-participant.js +4 -85
- package/lib/browser/monaco-code-action-save-participant.js.map +1 -1
- package/lib/browser/monaco-code-action-service.d.ts +41 -0
- package/lib/browser/monaco-code-action-service.d.ts.map +1 -0
- package/lib/browser/monaco-code-action-service.js +132 -0
- package/lib/browser/monaco-code-action-service.js.map +1 -0
- package/lib/browser/monaco-editor-model.d.ts +9 -4
- package/lib/browser/monaco-editor-model.d.ts.map +1 -1
- package/lib/browser/monaco-editor-model.js +5 -13
- package/lib/browser/monaco-editor-model.js.map +1 -1
- package/lib/browser/monaco-editor-provider.d.ts.map +1 -1
- package/lib/browser/monaco-editor-provider.js +5 -26
- package/lib/browser/monaco-editor-provider.js.map +1 -1
- package/lib/browser/monaco-frontend-module.d.ts.map +1 -1
- package/lib/browser/monaco-frontend-module.js +3 -0
- package/lib/browser/monaco-frontend-module.js.map +1 -1
- package/lib/browser/monaco-utilities.d.ts +3 -0
- package/lib/browser/monaco-utilities.d.ts.map +1 -0
- package/lib/browser/monaco-utilities.js +45 -0
- package/lib/browser/monaco-utilities.js.map +1 -0
- package/package.json +9 -9
- package/src/browser/index.ts +1 -0
- package/src/browser/monaco-code-action-save-participant.ts +9 -103
- package/src/browser/monaco-code-action-service.ts +187 -0
- package/src/browser/monaco-editor-model.ts +10 -15
- package/src/browser/monaco-editor-provider.ts +5 -29
- package/src/browser/monaco-frontend-module.ts +3 -0
- package/src/browser/monaco-utilities.ts +46 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 STMicroelectronics and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { CancellationToken } from '@theia/core';
|
|
18
|
+
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
19
|
+
import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices';
|
|
20
|
+
import { ILanguageFeaturesService } from '@theia/monaco-editor-core/esm/vs/editor/common/services/languageFeatures';
|
|
21
|
+
import { CodeActionKind, CodeActionSet, CodeActionTriggerSource } from '@theia/monaco-editor-core/esm/vs/editor/contrib/codeAction/common/types';
|
|
22
|
+
import { applyCodeAction, ApplyCodeActionReason, getCodeActions } from '@theia/monaco-editor-core/esm/vs/editor/contrib/codeAction/browser/codeAction';
|
|
23
|
+
import { HierarchicalKind } from '@theia/monaco-editor-core/esm/vs/base/common/hierarchicalKind';
|
|
24
|
+
import { EditorPreferences } from '@theia/editor/lib/browser';
|
|
25
|
+
import { ITextModel } from '@theia/monaco-editor-core/esm/vs/editor/common/model';
|
|
26
|
+
import { CodeActionProvider, CodeActionTriggerType } from '@theia/monaco-editor-core/esm/vs/editor/common/languages';
|
|
27
|
+
import { IProgress } from '@theia/monaco-editor-core/esm/vs/platform/progress/common/progress';
|
|
28
|
+
import { IInstantiationService } from '@theia/monaco-editor-core/esm/vs/platform/instantiation/common/instantiation';
|
|
29
|
+
|
|
30
|
+
export const MonacoCodeActionService = Symbol('MonacoCodeActionService');
|
|
31
|
+
|
|
32
|
+
/*---------------------------------------------------------------------------------------------
|
|
33
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
34
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
35
|
+
*--------------------------------------------------------------------------------------------*/
|
|
36
|
+
// Partially copied from https://github.com/microsoft/vscode/blob/f66e839a38dfe39ee66a86619a790f9c2336d698/src/vs/workbench/contrib/codeEditor/browser/saveParticipants.ts#L272
|
|
37
|
+
|
|
38
|
+
export interface MonacoCodeActionService {
|
|
39
|
+
/**
|
|
40
|
+
* Gets all code actions that should be applied on save for the given model and language identifier.
|
|
41
|
+
* @param model The text model to get code actions for
|
|
42
|
+
* @param languageId The language identifier for preference lookup
|
|
43
|
+
* @param uri The URI string for preference scoping
|
|
44
|
+
* @param token Cancellation token
|
|
45
|
+
* @returns Array of code action sets to apply, or undefined if no actions should be applied
|
|
46
|
+
*/
|
|
47
|
+
getAllCodeActionsOnSave(model: ITextModel, languageId: string, uri: string, token: CancellationToken): Promise<CodeActionSet[] | undefined>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Applies the provided code actions for the given model.
|
|
51
|
+
* @param model The text model to apply code actions to
|
|
52
|
+
* @param codeActionSets Array of code action sets to apply
|
|
53
|
+
* @param token Cancellation token
|
|
54
|
+
*/
|
|
55
|
+
applyCodeActions(model: ITextModel, codeActionSets: CodeActionSet[], token: CancellationToken): Promise<void>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Applies all code actions that should be run on save for the given model and language identifier.
|
|
59
|
+
* This is a convenience method that retrieves all on-save code actions and applies them.
|
|
60
|
+
* @param model The text model to apply code actions to
|
|
61
|
+
* @param languageId The language identifier for preference lookup
|
|
62
|
+
* @param uri The URI string for preference scoping
|
|
63
|
+
* @param token Cancellation token
|
|
64
|
+
*/
|
|
65
|
+
applyOnSaveCodeActions(model: ITextModel, languageId: string, uri: string, token: CancellationToken): Promise<void>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@injectable()
|
|
69
|
+
export class MonacoCodeActionServiceImpl implements MonacoCodeActionService {
|
|
70
|
+
@inject(EditorPreferences)
|
|
71
|
+
protected readonly editorPreferences: EditorPreferences;
|
|
72
|
+
|
|
73
|
+
async applyOnSaveCodeActions(model: ITextModel, languageId: string, uri: string, token: CancellationToken): Promise<void> {
|
|
74
|
+
const codeActionSets = await this.getAllCodeActionsOnSave(model, languageId, uri, token);
|
|
75
|
+
|
|
76
|
+
if (!codeActionSets || token.isCancellationRequested) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
await this.applyCodeActions(model, codeActionSets, token);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async getAllCodeActionsOnSave(model: ITextModel, languageId: string, uri: string, token: CancellationToken): Promise<CodeActionSet[] | undefined> {
|
|
84
|
+
const setting = this.editorPreferences.get({
|
|
85
|
+
preferenceName: 'editor.codeActionsOnSave',
|
|
86
|
+
overrideIdentifier: languageId
|
|
87
|
+
}, undefined, uri);
|
|
88
|
+
|
|
89
|
+
if (!setting) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const settingItems: string[] = Array.isArray(setting)
|
|
94
|
+
? setting
|
|
95
|
+
: Object.keys(setting).filter(x => setting[x]);
|
|
96
|
+
|
|
97
|
+
const codeActionsOnSave = this.createCodeActionsOnSave(settingItems);
|
|
98
|
+
|
|
99
|
+
if (!codeActionsOnSave.length) {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (!Array.isArray(setting)) {
|
|
104
|
+
codeActionsOnSave.sort((a, b) => {
|
|
105
|
+
if (CodeActionKind.SourceFixAll.contains(a)) {
|
|
106
|
+
if (CodeActionKind.SourceFixAll.contains(b)) {
|
|
107
|
+
return 0;
|
|
108
|
+
}
|
|
109
|
+
return -1;
|
|
110
|
+
}
|
|
111
|
+
if (CodeActionKind.SourceFixAll.contains(b)) {
|
|
112
|
+
return 1;
|
|
113
|
+
}
|
|
114
|
+
return 0;
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const excludedActions = Array.isArray(setting)
|
|
119
|
+
? []
|
|
120
|
+
: Object.keys(setting)
|
|
121
|
+
.filter(x => setting[x] === false)
|
|
122
|
+
.map(x => new HierarchicalKind(x));
|
|
123
|
+
|
|
124
|
+
const codeActionSets: CodeActionSet[] = [];
|
|
125
|
+
|
|
126
|
+
for (const codeActionKind of codeActionsOnSave) {
|
|
127
|
+
const actionsToRun = await this.getActionsToRun(model, codeActionKind, excludedActions, token);
|
|
128
|
+
|
|
129
|
+
if (token.isCancellationRequested) {
|
|
130
|
+
actionsToRun.dispose();
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
codeActionSets.push(actionsToRun);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return codeActionSets;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async applyCodeActions(model: ITextModel, codeActionSets: CodeActionSet[], token: CancellationToken): Promise<void> {
|
|
141
|
+
|
|
142
|
+
const instantiationService = StandaloneServices.get(IInstantiationService);
|
|
143
|
+
|
|
144
|
+
for (const codeActionSet of codeActionSets) {
|
|
145
|
+
if (token.isCancellationRequested) {
|
|
146
|
+
codeActionSet.dispose();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
for (const action of codeActionSet.validActions) {
|
|
152
|
+
await instantiationService.invokeFunction(applyCodeAction, action, ApplyCodeActionReason.OnSave, {}, token);
|
|
153
|
+
if (token.isCancellationRequested) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
} catch {
|
|
158
|
+
// Failure to apply a code action should not block other on save actions
|
|
159
|
+
} finally {
|
|
160
|
+
codeActionSet.dispose();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private createCodeActionsOnSave(settingItems: readonly string[]): HierarchicalKind[] {
|
|
166
|
+
const kinds = settingItems.map(x => new HierarchicalKind(x));
|
|
167
|
+
|
|
168
|
+
// Remove subsets
|
|
169
|
+
return kinds.filter(kind => kinds.every(otherKind => otherKind.equals(kind) || !otherKind.contains(kind)));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
private getActionsToRun(model: ITextModel, codeActionKind: HierarchicalKind, excludes: readonly HierarchicalKind[], token: CancellationToken): Promise<CodeActionSet> {
|
|
173
|
+
const { codeActionProvider } = StandaloneServices.get(ILanguageFeaturesService);
|
|
174
|
+
|
|
175
|
+
const progress: IProgress<CodeActionProvider> = {
|
|
176
|
+
report(item): void {
|
|
177
|
+
// empty
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
return getCodeActions(codeActionProvider, model, model.getFullModelRange(), {
|
|
182
|
+
type: CodeActionTriggerType.Auto,
|
|
183
|
+
triggerAction: CodeActionTriggerSource.OnSave,
|
|
184
|
+
filter: { include: codeActionKind, excludes: excludes, includeSourceActions: true },
|
|
185
|
+
}, progress, token);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -34,12 +34,17 @@ import { createTextBufferFactoryFromStream } from '@theia/monaco-editor-core/esm
|
|
|
34
34
|
import { editorGeneratedPreferenceProperties } from '@theia/editor/lib/browser/editor-generated-preference-schema';
|
|
35
35
|
import { MarkdownString } from '@theia/core/lib/common/markdown-rendering';
|
|
36
36
|
import { BinaryBuffer } from '@theia/core/lib/common/buffer';
|
|
37
|
+
import { Listener, ListenerList } from '@theia/core';
|
|
37
38
|
|
|
38
39
|
export {
|
|
39
40
|
TextDocumentSaveReason
|
|
40
41
|
};
|
|
41
42
|
|
|
42
|
-
export
|
|
43
|
+
export interface WillSaveMonacoModelEvent {
|
|
44
|
+
model: MonacoEditorModel,
|
|
45
|
+
token: CancellationToken,
|
|
46
|
+
options?: SaveOptions
|
|
47
|
+
}
|
|
43
48
|
|
|
44
49
|
export interface MonacoModelContentChangedEvent {
|
|
45
50
|
readonly model: MonacoEditorModel;
|
|
@@ -91,7 +96,8 @@ export class MonacoEditorModel implements IResolvedTextEditorModel, TextEditorDo
|
|
|
91
96
|
|
|
92
97
|
protected resourceVersion: ResourceVersion | undefined;
|
|
93
98
|
|
|
94
|
-
protected readonly
|
|
99
|
+
protected readonly onWillSaveModelListeners: ListenerList<WillSaveMonacoModelEvent, Promise<void>> = new ListenerList;
|
|
100
|
+
readonly onModelWillSaveModel = this.onWillSaveModelListeners.registration;
|
|
95
101
|
|
|
96
102
|
constructor(
|
|
97
103
|
protected readonly resource: Resource,
|
|
@@ -105,6 +111,7 @@ export class MonacoEditorModel implements IResolvedTextEditorModel, TextEditorDo
|
|
|
105
111
|
this.toDispose.push(this.onDidChangeContentEmitter);
|
|
106
112
|
this.toDispose.push(this.onDidSaveModelEmitter);
|
|
107
113
|
this.toDispose.push(this.onDirtyChangedEmitter);
|
|
114
|
+
this.toDispose.push(this.onDidChangeEncodingEmitter);
|
|
108
115
|
this.toDispose.push(this.onDidChangeValidEmitter);
|
|
109
116
|
this.toDispose.push(Disposable.create(() => this.cancelSave()));
|
|
110
117
|
this.toDispose.push(Disposable.create(() => this.cancelSync()));
|
|
@@ -582,20 +589,8 @@ export class MonacoEditorModel implements IResolvedTextEditorModel, TextEditorDo
|
|
|
582
589
|
}
|
|
583
590
|
}
|
|
584
591
|
|
|
585
|
-
registerWillSaveModelListener(listener: WillSaveMonacoModelListener): Disposable {
|
|
586
|
-
this.willSaveModelListeners.push(listener);
|
|
587
|
-
return Disposable.create(() => {
|
|
588
|
-
const index = this.willSaveModelListeners.indexOf(listener);
|
|
589
|
-
if (index >= 0) {
|
|
590
|
-
this.willSaveModelListeners.splice(index, 1);
|
|
591
|
-
}
|
|
592
|
-
});
|
|
593
|
-
}
|
|
594
|
-
|
|
595
592
|
protected async fireWillSaveModel(token: CancellationToken, options?: SaveOptions): Promise<void> {
|
|
596
|
-
|
|
597
|
-
await listener(this, token, options);
|
|
598
|
-
}
|
|
593
|
+
await Listener.await({ model: this, token, options }, this.onWillSaveModelListeners);
|
|
599
594
|
}
|
|
600
595
|
|
|
601
596
|
protected fireDidSaveModel(): void {
|
|
@@ -45,6 +45,7 @@ import { SimpleMonacoEditor } from './simple-monaco-editor';
|
|
|
45
45
|
import { ICodeEditorWidgetOptions } from '@theia/monaco-editor-core/esm/vs/editor/browser/widget/codeEditor/codeEditorWidget';
|
|
46
46
|
import { timeoutReject } from '@theia/core/lib/common/promise-util';
|
|
47
47
|
import { FileSystemPreferences } from '@theia/filesystem/lib/browser';
|
|
48
|
+
import { insertFinalNewline } from './monaco-utilities';
|
|
48
49
|
|
|
49
50
|
export const MonacoEditorFactory = Symbol('MonacoEditorFactory');
|
|
50
51
|
export interface MonacoEditorFactory {
|
|
@@ -226,7 +227,7 @@ export class MonacoEditorProvider {
|
|
|
226
227
|
}));
|
|
227
228
|
toDispose.push(editor.onLanguageChanged(() => this.updateMonacoEditorOptions(editor)));
|
|
228
229
|
toDispose.push(editor.onDidChangeReadOnly(() => this.updateReadOnlyMessage(options, model.readOnly)));
|
|
229
|
-
toDispose.push(editor.document.
|
|
230
|
+
toDispose.push(editor.document.onModelWillSaveModel(e => this.runSaveParticipants(editor, e.token, e.options)));
|
|
230
231
|
return editor;
|
|
231
232
|
}
|
|
232
233
|
|
|
@@ -552,38 +553,13 @@ export class MonacoEditorProvider {
|
|
|
552
553
|
if (shouldRemoveWhiteSpace) {
|
|
553
554
|
await editor.runAction('editor.action.trimTrailingWhitespace');
|
|
554
555
|
}
|
|
555
|
-
const
|
|
556
|
-
if (
|
|
556
|
+
const shouldInsertFinalNewline = this.filePreferences.get({ preferenceName: 'files.insertFinalNewline', overrideIdentifier }, undefined, uri);
|
|
557
|
+
if (shouldInsertFinalNewline) {
|
|
557
558
|
this.insertFinalNewline(model);
|
|
558
559
|
}
|
|
559
560
|
}
|
|
560
561
|
|
|
561
562
|
protected insertFinalNewline(editorModel: MonacoEditorModel): void {
|
|
562
|
-
|
|
563
|
-
if (!model) {
|
|
564
|
-
return;
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
const lines = model?.getLineCount();
|
|
568
|
-
if (lines === 0) {
|
|
569
|
-
return;
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
const lastLine = model?.getLineContent(lines);
|
|
573
|
-
if (lastLine.trim() === '') {
|
|
574
|
-
return;
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
const lastLineMaxColumn = model?.getLineMaxColumn(lines);
|
|
578
|
-
const range = {
|
|
579
|
-
startLineNumber: lines,
|
|
580
|
-
startColumn: lastLineMaxColumn,
|
|
581
|
-
endLineNumber: lines,
|
|
582
|
-
endColumn: lastLineMaxColumn
|
|
583
|
-
};
|
|
584
|
-
model.applyEdits([{
|
|
585
|
-
range,
|
|
586
|
-
text: model?.getEOL()
|
|
587
|
-
}]);
|
|
563
|
+
insertFinalNewline(editorModel);
|
|
588
564
|
}
|
|
589
565
|
}
|
|
@@ -80,6 +80,7 @@ import { ILogService } from '@theia/monaco-editor-core/esm/vs/platform/log/commo
|
|
|
80
80
|
import { DefaultContentHoverWidgetPatcher } from './default-content-hover-widget-patcher';
|
|
81
81
|
import { MonacoWorkspaceContextService } from './monaco-workspace-context-service';
|
|
82
82
|
import { MonacoCodeActionSaveParticipant } from './monaco-code-action-save-participant';
|
|
83
|
+
import { MonacoCodeActionService, MonacoCodeActionServiceImpl } from './monaco-code-action-service';
|
|
83
84
|
|
|
84
85
|
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|
85
86
|
bind(MonacoThemingService).toSelf().inSingletonScope();
|
|
@@ -92,6 +93,8 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|
|
92
93
|
bind(FrontendApplicationContribution).toService(MonacoFrontendApplicationContribution);
|
|
93
94
|
bind(StylingParticipant).toService(MonacoFrontendApplicationContribution);
|
|
94
95
|
|
|
96
|
+
bind(MonacoCodeActionServiceImpl).toSelf().inSingletonScope();
|
|
97
|
+
bind(MonacoCodeActionService).toService(MonacoCodeActionServiceImpl);
|
|
95
98
|
bind(MonacoCodeActionSaveParticipant).toSelf().inSingletonScope();
|
|
96
99
|
bind(SaveParticipant).toService(MonacoCodeActionSaveParticipant);
|
|
97
100
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 EclipseSource GmbH.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { MonacoEditorModel } from './monaco-editor-model';
|
|
18
|
+
|
|
19
|
+
export function insertFinalNewline(editorModel: MonacoEditorModel): void {
|
|
20
|
+
const model = editorModel.textEditorModel;
|
|
21
|
+
if (!model) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const lines = model?.getLineCount();
|
|
26
|
+
if (lines === 0) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const lastLine = model?.getLineContent(lines);
|
|
31
|
+
if (lastLine.trim() === '') {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const lastLineMaxColumn = model?.getLineMaxColumn(lines);
|
|
36
|
+
const range = {
|
|
37
|
+
startLineNumber: lines,
|
|
38
|
+
startColumn: lastLineMaxColumn,
|
|
39
|
+
endLineNumber: lines,
|
|
40
|
+
endColumn: lastLineMaxColumn
|
|
41
|
+
};
|
|
42
|
+
model.applyEdits([{
|
|
43
|
+
range,
|
|
44
|
+
text: model?.getEOL()
|
|
45
|
+
}]);
|
|
46
|
+
}
|