mirror of
https://github.com/Microsoft/vscode
synced 2024-09-18 01:58:27 +00:00
untitled - have a isUntitledWithAssociatedResource
method from the service (#183420)
This commit is contained in:
parent
8cf85bdb16
commit
49f7ecfcb7
|
@ -7,7 +7,7 @@ import { localize } from 'vs/nls';
|
|||
import { isObject, isString, isUndefined, isNumber, withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { IEditorIdentifier, IEditorCommandsContext, CloseDirection, IVisibleEditorPane, EditorsOrder, EditorInputCapabilities, isEditorIdentifier, isEditorInputWithOptionsAndGroup, IUntitledTextResourceEditorInput, isUntitledWithAssociatedResource } from 'vs/workbench/common/editor';
|
||||
import { IEditorIdentifier, IEditorCommandsContext, CloseDirection, IVisibleEditorPane, EditorsOrder, EditorInputCapabilities, isEditorIdentifier, isEditorInputWithOptionsAndGroup, IUntitledTextResourceEditorInput } from 'vs/workbench/common/editor';
|
||||
import { TextCompareEditorVisibleContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, ActiveEditorStickyContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, TextCompareEditorActiveContext, SideBySideEditorActiveContext } from 'vs/workbench/common/contextkeys';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { EditorGroupColumn, columnToEditorGroup } from 'vs/workbench/services/editor/common/editorGroupColumn';
|
||||
|
@ -39,6 +39,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
|||
import { extname } from 'vs/base/common/resources';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { isDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
|
||||
|
||||
export const CLOSE_SAVED_EDITORS_COMMAND_ID = 'workbench.action.closeUnmodifiedEditors';
|
||||
export const CLOSE_EDITORS_IN_GROUP_COMMAND_ID = 'workbench.action.closeEditorsInGroup';
|
||||
|
@ -517,6 +518,7 @@ function registerOpenEditorAPICommands(): void {
|
|||
const openerService = accessor.get(IOpenerService);
|
||||
const pathService = accessor.get(IPathService);
|
||||
const configurationService = accessor.get(IConfigurationService);
|
||||
const untitledTextEditorService = accessor.get(IUntitledTextEditorService);
|
||||
|
||||
const resourceOrString = typeof resourceArg === 'string' ? resourceArg : URI.from(resourceArg, true);
|
||||
const [columnArg, optionsArg] = columnAndOptions ?? [];
|
||||
|
@ -528,7 +530,7 @@ function registerOpenEditorAPICommands(): void {
|
|||
const resource = URI.isUri(resourceOrString) ? resourceOrString : URI.parse(resourceOrString);
|
||||
|
||||
let input: IResourceEditorInput | IUntitledTextResourceEditorInput;
|
||||
if (isUntitledWithAssociatedResource(resource)) {
|
||||
if (untitledTextEditorService.isUntitledWithAssociatedResource(resource)) {
|
||||
// special case for untitled: we are getting a resource with meaningful
|
||||
// path from an extension to use for the untitled editor. as such, we
|
||||
// have to assume it as an associated resource to use when saving. we
|
||||
|
|
|
@ -567,12 +567,6 @@ export function isUntitledResourceEditorInput(editor: unknown): editor is IUntit
|
|||
return candidate.resource === undefined || candidate.resource.scheme === Schemas.untitled || candidate.forceUntitled === true;
|
||||
}
|
||||
|
||||
const UNTITLED_WITHOUT_ASSOCIATED_RESOURCE_REGEX = /Untitled-\d+/;
|
||||
|
||||
export function isUntitledWithAssociatedResource(resource: URI): boolean {
|
||||
return resource.scheme === Schemas.untitled && resource.path.length > 1 && !UNTITLED_WITHOUT_ASSOCIATED_RESOURCE_REGEX.test(resource.path);
|
||||
}
|
||||
|
||||
export function isResourceMergeEditorInput(editor: unknown): editor is IResourceMergeEditorInput {
|
||||
if (isEditorInput(editor)) {
|
||||
return false; // make sure to not accidentally match on typed editor inputs
|
||||
|
|
|
@ -663,8 +663,8 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|||
args: [
|
||||
{
|
||||
isOptional: true,
|
||||
name: 'New Untitled Text File args',
|
||||
description: 'The editor view type, language ID, or resource path if known',
|
||||
name: 'New Untitled Text File arguments',
|
||||
description: 'The editor view type or language ID if known',
|
||||
schema: {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
@ -673,7 +673,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|||
},
|
||||
'languageId': {
|
||||
'type': 'string'
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import { Schemas } from 'vs/base/common/network';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { IEditorSerializer, isUntitledWithAssociatedResource } from 'vs/workbench/common/editor';
|
||||
import { IEditorSerializer } from 'vs/workbench/common/editor';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { ITextEditorService } from 'vs/workbench/services/textfile/common/textEditorService';
|
||||
import { isEqual, toLocalResource } from 'vs/base/common/resources';
|
||||
|
@ -19,11 +19,12 @@ import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/u
|
|||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { IWorkingCopyIdentifier, NO_TYPE_ID } from 'vs/workbench/services/workingCopy/common/workingCopy';
|
||||
import { IWorkingCopyEditorHandler, IWorkingCopyEditorService } from 'vs/workbench/services/workingCopy/common/workingCopyEditorService';
|
||||
import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
|
||||
|
||||
interface ISerializedUntitledTextEditorInput {
|
||||
resourceJSON: UriComponents;
|
||||
modeId: string | undefined; // should be `languageId` but is kept for backwards compatibility
|
||||
encoding: string | undefined;
|
||||
readonly resourceJSON: UriComponents;
|
||||
readonly modeId: string | undefined; // should be `languageId` but is kept for backwards compatibility
|
||||
readonly encoding: string | undefined;
|
||||
}
|
||||
|
||||
export class UntitledTextEditorInputSerializer implements IEditorSerializer {
|
||||
|
@ -89,7 +90,8 @@ export class UntitledTextEditorWorkingCopyEditorHandler extends Disposable imple
|
|||
@IWorkingCopyEditorService workingCopyEditorService: IWorkingCopyEditorService,
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
|
||||
@IPathService private readonly pathService: IPathService,
|
||||
@ITextEditorService private readonly textEditorService: ITextEditorService
|
||||
@ITextEditorService private readonly textEditorService: ITextEditorService,
|
||||
@IUntitledTextEditorService private readonly untitledTextEditorService: IUntitledTextEditorService
|
||||
) {
|
||||
super();
|
||||
|
||||
|
@ -113,7 +115,7 @@ export class UntitledTextEditorWorkingCopyEditorHandler extends Disposable imple
|
|||
|
||||
// If the untitled has an associated resource,
|
||||
// ensure to restore the local resource it had
|
||||
if (isUntitledWithAssociatedResource(workingCopy.resource)) {
|
||||
if (this.untitledTextEditorService.isUntitledWithAssociatedResource(workingCopy.resource)) {
|
||||
editorInputResource = toLocalResource(workingCopy.resource, this.environmentService.remoteAuthority, this.pathService.defaultUriScheme);
|
||||
} else {
|
||||
editorInputResource = workingCopy.resource;
|
||||
|
|
|
@ -140,7 +140,7 @@ export class UntitledTextEditorInput extends AbstractTextResourceEditorInput imp
|
|||
if (typeof options?.preserveViewState === 'number') {
|
||||
untypedInput.encoding = this.getEncoding();
|
||||
untypedInput.languageId = this.getLanguageId();
|
||||
untypedInput.contents = this.model.isDirty() ? this.model.textEditorModel?.getValue() : undefined;
|
||||
untypedInput.contents = this.model.isModified() ? this.model.textEditorModel?.getValue() : undefined;
|
||||
untypedInput.options.viewState = findViewStateForEditor(this, options.preserveViewState, this.editorService);
|
||||
|
||||
if (typeof untypedInput.contents === 'string' && !this.model.hasAssociatedFilePath) {
|
||||
|
|
|
@ -272,6 +272,8 @@ export class UntitledTextEditorModel extends BaseTextEditorModel implements IUnt
|
|||
}
|
||||
|
||||
async revert(): Promise<void> {
|
||||
|
||||
// No longer dirty
|
||||
this.setDirty(false);
|
||||
|
||||
// Emit as event
|
||||
|
|
|
@ -112,6 +112,11 @@ export interface IUntitledTextEditorModelManager {
|
|||
resolve(options?: INewUntitledTextEditorOptions): Promise<IUntitledTextEditorModel>;
|
||||
resolve(options?: INewUntitledTextEditorWithAssociatedResourceOptions): Promise<IUntitledTextEditorModel>;
|
||||
resolve(options?: IExistingUntitledTextEditorOptions): Promise<IUntitledTextEditorModel>;
|
||||
|
||||
/**
|
||||
* Figures out if the given resource has an associated resource or not.
|
||||
*/
|
||||
isUntitledWithAssociatedResource(resource: URI): boolean;
|
||||
}
|
||||
|
||||
export interface IUntitledTextEditorService extends IUntitledTextEditorModelManager {
|
||||
|
@ -123,6 +128,8 @@ export class UntitledTextEditorService extends Disposable implements IUntitledTe
|
|||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
private static readonly UNTITLED_WITHOUT_ASSOCIATED_RESOURCE_REGEX = /Untitled-\d+/;
|
||||
|
||||
private readonly _onDidChangeDirty = this._register(new Emitter<IUntitledTextEditorModel>());
|
||||
readonly onDidChangeDirty = this._onDidChangeDirty.event;
|
||||
|
||||
|
@ -259,6 +266,10 @@ export class UntitledTextEditorService extends Disposable implements IUntitledTe
|
|||
this._onDidChangeDirty.fire(model);
|
||||
}
|
||||
}
|
||||
|
||||
isUntitledWithAssociatedResource(resource: URI): boolean {
|
||||
return resource.scheme === Schemas.untitled && resource.path.length > 1 && !UntitledTextEditorService.UNTITLED_WITHOUT_ASSOCIATED_RESOURCE_REGEX.test(resource.path);
|
||||
}
|
||||
}
|
||||
|
||||
registerSingleton(IUntitledTextEditorService, UntitledTextEditorService, InstantiationType.Delayed);
|
||||
|
|
|
@ -16,7 +16,7 @@ import { Range } from 'vs/editor/common/core/range';
|
|||
import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput';
|
||||
import { IUntitledTextEditorModel } from 'vs/workbench/services/untitled/common/untitledTextEditorModel';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { EditorInputCapabilities, isUntitledWithAssociatedResource } from 'vs/workbench/common/editor';
|
||||
import { EditorInputCapabilities } from 'vs/workbench/common/editor';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { isReadable, isReadableStream } from 'vs/base/common/stream';
|
||||
import { readableToBuffer, streamToBuffer, VSBufferReadable, VSBufferReadableStream } from 'vs/base/common/buffer';
|
||||
|
@ -46,7 +46,7 @@ suite('Untitled text editors', () => {
|
|||
const input1 = instantiationService.createInstance(UntitledTextEditorInput, service.create());
|
||||
await input1.resolve();
|
||||
assert.strictEqual(service.get(input1.resource), input1.model);
|
||||
assert.ok(!isUntitledWithAssociatedResource(input1.resource));
|
||||
assert.ok(!accessor.untitledTextEditorService.isUntitledWithAssociatedResource(input1.resource));
|
||||
|
||||
assert.ok(service.get(input1.resource));
|
||||
assert.ok(!service.get(URI.file('testing')));
|
||||
|
@ -55,6 +55,7 @@ suite('Untitled text editors', () => {
|
|||
assert.ok(!input1.hasCapability(EditorInputCapabilities.Readonly));
|
||||
assert.ok(!input1.hasCapability(EditorInputCapabilities.Singleton));
|
||||
assert.ok(!input1.hasCapability(EditorInputCapabilities.RequiresTrust));
|
||||
assert.ok(!input1.hasCapability(EditorInputCapabilities.Scratchpad));
|
||||
|
||||
const input2 = instantiationService.createInstance(UntitledTextEditorInput, service.create());
|
||||
assert.strictEqual(service.get(input2.resource), input2.model);
|
||||
|
@ -138,7 +139,7 @@ suite('Untitled text editors', () => {
|
|||
});
|
||||
|
||||
const model = service.create({ associatedResource: file });
|
||||
assert.ok(isUntitledWithAssociatedResource(model.resource));
|
||||
assert.ok(accessor.untitledTextEditorService.isUntitledWithAssociatedResource(model.resource));
|
||||
const untitled = instantiationService.createInstance(UntitledTextEditorInput, model);
|
||||
assert.ok(untitled.isDirty());
|
||||
assert.strictEqual(model, onDidChangeDirtyModel);
|
||||
|
|
|
@ -135,7 +135,7 @@ export class UntitledFileWorkingCopy<M extends IUntitledFileWorkingCopyModel> ex
|
|||
this._register(workingCopyService.registerWorkingCopy(this));
|
||||
}
|
||||
|
||||
//#region Dirty
|
||||
//#region Dirty/Modified
|
||||
|
||||
private modified = this.hasAssociatedFilePath || Boolean(this.initialContents && this.initialContents.markModified !== false);
|
||||
|
||||
|
|
|
@ -171,8 +171,10 @@ export class UntitledFileWorkingCopyManager<M extends IUntitledFileWorkingCopyMo
|
|||
}
|
||||
|
||||
// Handle untitled resource
|
||||
else if (options.untitledResource?.scheme === Schemas.untitled) {
|
||||
massagedOptions.untitledResource = options.untitledResource;
|
||||
else {
|
||||
if (options.untitledResource?.scheme === Schemas.untitled) {
|
||||
massagedOptions.untitledResource = options.untitledResource;
|
||||
}
|
||||
massagedOptions.isScratchpad = options.isScratchpad;
|
||||
}
|
||||
|
||||
|
@ -191,7 +193,7 @@ export class UntitledFileWorkingCopyManager<M extends IUntitledFileWorkingCopyMo
|
|||
do {
|
||||
untitledResource = URI.from({
|
||||
scheme: Schemas.untitled,
|
||||
path: `Untitled-${counter}`,
|
||||
path: options.isScratchpad ? `Scratchpad-${counter}` : `Untitled-${counter}`,
|
||||
query: this.workingCopyTypeId ?
|
||||
`typeId=${this.workingCopyTypeId}` : // distinguish untitled resources among others by encoding the `typeId` as query param
|
||||
undefined // keep untitled resources for text files as they are (when `typeId === ''`)
|
||||
|
|
Loading…
Reference in a new issue