mirror of
https://github.com/Microsoft/vscode
synced 2024-10-04 02:14:06 +00:00
This commit is contained in:
parent
911e119dfc
commit
f7c5c0dbab
|
@ -10,6 +10,7 @@ import { IRevertOptions, SaveSourceRegistry } from 'vs/workbench/common/editor';
|
|||
import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
||||
import { IFileService, FileOperationError, FileOperationResult, IFileStatWithMetadata, ICreateFileOptions, IFileStreamContent } from 'vs/platform/files/common/files';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { extname as pathExtname } from 'vs/base/common/path';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { IUntitledTextEditorService, IUntitledTextEditorModelManager } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
|
||||
import { UntitledTextEditorModel } from 'vs/workbench/services/untitled/common/untitledTextEditorModel';
|
||||
|
@ -43,6 +44,7 @@ import { Emitter } from 'vs/base/common/event';
|
|||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { listErrorForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { firstOrDefault } from 'vs/base/common/arrays';
|
||||
|
||||
/**
|
||||
* The workbench file service implementation implements the raw file service spec and adds additional methods on top.
|
||||
|
@ -576,19 +578,16 @@ export abstract class AbstractTextFileService extends Disposable implements ITex
|
|||
}
|
||||
|
||||
// Untitled without associated file path: use name
|
||||
// of untitled model if it is a valid path name,
|
||||
// otherwise fallback to `basename`.
|
||||
let untitledName = model.name;
|
||||
if (!(await this.pathService.hasValidBasename(joinPath(defaultFilePath, untitledName), untitledName))) {
|
||||
untitledName = basename(resource);
|
||||
}
|
||||
// of untitled model if it is a valid path name and
|
||||
// figure out the file extension from the mode if any.
|
||||
|
||||
// Add language file extension if specified
|
||||
if (await this.pathService.hasValidBasename(joinPath(defaultFilePath, model.name), model.name)) {
|
||||
const languageId = model.getLanguageId();
|
||||
if (languageId && languageId !== PLAINTEXT_LANGUAGE_ID) {
|
||||
suggestedFilename = this.suggestFilename(languageId, untitledName);
|
||||
suggestedFilename = this.suggestFilename(languageId, model.name);
|
||||
} else {
|
||||
suggestedFilename = untitledName;
|
||||
suggestedFilename = model.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -606,18 +605,31 @@ export abstract class AbstractTextFileService extends Disposable implements ITex
|
|||
suggestFilename(languageId: string, untitledName: string) {
|
||||
const languageName = this.languageService.getLanguageName(languageId);
|
||||
if (!languageName) {
|
||||
return untitledName;
|
||||
return untitledName; // unknown language, so we cannot suggest a better name
|
||||
}
|
||||
|
||||
const extension = this.languageService.getExtensions(languageId)[0];
|
||||
if (extension) {
|
||||
if (!untitledName.endsWith(extension)) {
|
||||
return untitledName + extension;
|
||||
}
|
||||
const untitledExtension = pathExtname(untitledName);
|
||||
|
||||
const extensions = this.languageService.getExtensions(languageId);
|
||||
if (extensions.includes(untitledExtension)) {
|
||||
return untitledName; // preserve extension if it is compatible with the mode
|
||||
}
|
||||
|
||||
const filename = this.languageService.getFilenames(languageId)[0];
|
||||
return filename || untitledName;
|
||||
const primaryExtension = firstOrDefault(extensions);
|
||||
if (primaryExtension) {
|
||||
if (untitledExtension) {
|
||||
return `${untitledName.substring(0, untitledName.indexOf(untitledExtension))}${primaryExtension}`;
|
||||
}
|
||||
|
||||
return `${untitledName}${primaryExtension}`;
|
||||
}
|
||||
|
||||
const filenames = this.languageService.getFilenames(languageId);
|
||||
if (filenames.includes(untitledName)) {
|
||||
return untitledName; // preserve name if it is compatible with the mode
|
||||
}
|
||||
|
||||
return firstOrDefault(filenames) ?? untitledName;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
|
|
@ -160,6 +160,28 @@ suite('Files - TextFileService', () => {
|
|||
registration.dispose();
|
||||
});
|
||||
|
||||
test('Filename Suggestion - Preserve extension if it matchers', () => {
|
||||
const registration = accessor.languageService.registerLanguage({
|
||||
id: 'plumbus2',
|
||||
extensions: ['.shleem', '.gazorpazorp'],
|
||||
});
|
||||
|
||||
const suggested = accessor.textFileService.suggestFilename('plumbus2', 'Untitled-1.gazorpazorp');
|
||||
assert.strictEqual(suggested, 'Untitled-1.gazorpazorp');
|
||||
registration.dispose();
|
||||
});
|
||||
|
||||
test('Filename Suggestion - Rewrite extension according to language', () => {
|
||||
const registration = accessor.languageService.registerLanguage({
|
||||
id: 'plumbus2',
|
||||
extensions: ['.shleem', '.gazorpazorp'],
|
||||
});
|
||||
|
||||
const suggested = accessor.textFileService.suggestFilename('plumbus2', 'Untitled-1.foobar');
|
||||
assert.strictEqual(suggested, 'Untitled-1.shleem');
|
||||
registration.dispose();
|
||||
});
|
||||
|
||||
test('Filename Suggestion - Suggest filename if there are no extensions', () => {
|
||||
const registration = accessor.languageService.registerLanguage({
|
||||
id: 'plumbus2',
|
||||
|
@ -170,4 +192,26 @@ suite('Files - TextFileService', () => {
|
|||
assert.strictEqual(suggested, 'plumbus');
|
||||
registration.dispose();
|
||||
});
|
||||
|
||||
test('Filename Suggestion - Preserve filename if it matches', () => {
|
||||
const registration = accessor.languageService.registerLanguage({
|
||||
id: 'plumbus2',
|
||||
filenames: ['plumbus', 'shleem', 'gazorpazorp']
|
||||
});
|
||||
|
||||
const suggested = accessor.textFileService.suggestFilename('plumbus2', 'gazorpazorp');
|
||||
assert.strictEqual(suggested, 'gazorpazorp');
|
||||
registration.dispose();
|
||||
});
|
||||
|
||||
test('Filename Suggestion - Rewrites filename according to language', () => {
|
||||
const registration = accessor.languageService.registerLanguage({
|
||||
id: 'plumbus2',
|
||||
filenames: ['plumbus', 'shleem', 'gazorpazorp']
|
||||
});
|
||||
|
||||
const suggested = accessor.textFileService.suggestFilename('plumbus2', 'foobar');
|
||||
assert.strictEqual(suggested, 'plumbus');
|
||||
registration.dispose();
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue