Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { IWorkspaceContextService } from '../../../../../platform/workspace/comm
import { SnippetsAction } from './abstractSnippetsActions.js';
import { ISnippetsService } from '../snippets.js';
import { SnippetSource } from '../snippetsFile.js';
import { IEditorService } from '../../../../services/editor/common/editorService.js';
import { ITextFileService } from '../../../../services/textfile/common/textfiles.js';
import { IUserDataProfileService } from '../../../../services/userDataProfile/common/userDataProfile.js';

Expand All @@ -34,7 +35,7 @@ interface ISnippetPick extends IQuickPickItem {
hint?: true;
}

async function computePicks(snippetService: ISnippetsService, userDataProfileService: IUserDataProfileService, languageService: ILanguageService, labelService: ILabelService) {
async function computePicks(snippetService: ISnippetsService, userDataProfileService: IUserDataProfileService, languageService: ILanguageService, labelService: ILabelService, activeLanguageId: string | undefined) {

const existing: ISnippetPick[] = [];
const future: ISnippetPick[] = [];
Expand Down Expand Up @@ -138,9 +139,33 @@ async function computePicks(snippetService: ISnippetsService, userDataProfileSer
return a.label.localeCompare(b.label);
});

promoteActiveLanguage(existing, future, activeLanguageId);

return { existing, future };
}

// Move the active editor's language to the front of each group and mark it as detected.
export function promoteActiveLanguage(existing: ISnippetPick[], future: ISnippetPick[], activeLanguageId: string | undefined): void {
if (!activeLanguageId) {
return;
}
const detectedHint = nls.localize('detected', "This file type was detected from the current file.");
promote(existing, existing.findIndex(pick => basename(pick.filepath) === `${activeLanguageId}.json`), detectedHint);
promote(future, future.findIndex(pick => pick.label === activeLanguageId), detectedHint);
}

function promote(picks: ISnippetPick[], index: number, hint: string): void {
if (index < 0) {
return;
}
const pick = picks[index];
pick.tooltip = hint;
pick.description = pick.description ? `${pick.description} *` : '*';
if (index > 0) {
picks.unshift(picks.splice(index, 1)[0]);
}
}

async function createSnippetFile(scope: string, defaultPath: URI, quickInputService: IQuickInputService, fileService: IFileService, textFileService: ITextFileService, opener: IOpenerService) {

function createSnippetUri(input: string) {
Expand Down Expand Up @@ -265,13 +290,14 @@ export class ConfigureSnippetsAction extends SnippetsAction {
const quickInputService = accessor.get(IQuickInputService);
const opener = accessor.get(IOpenerService);
const languageService = accessor.get(ILanguageService);
const editorService = accessor.get(IEditorService);
const userDataProfileService = accessor.get(IUserDataProfileService);
const workspaceService = accessor.get(IWorkspaceContextService);
const fileService = accessor.get(IFileService);
const textFileService = accessor.get(ITextFileService);
const labelService = accessor.get(ILabelService);

const picks = await computePicks(snippetService, userDataProfileService, languageService, labelService);
const picks = await computePicks(snippetService, userDataProfileService, languageService, labelService, editorService.activeTextEditorLanguageId);
const existing: QuickPickInput[] = picks.existing;

type SnippetPick = IQuickPickItem & { uri: URI } & { scope: string };
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import assert from 'assert';
import { URI } from '../../../../../base/common/uri.js';
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
import { promoteActiveLanguage } from '../../browser/commands/configureSnippets.js';

suite('Configure Snippets', () => {

ensureNoDisposablesAreLeakedInTestSuite();

type TestPick = { label: string; filepath: URI };

function file(name: string): TestPick {
return { label: name, filepath: URI.file(`/snippets/${name}`) };
}

function lang(id: string): TestPick {
return { label: id, filepath: URI.file(`/snippets/${id}.json`) };
}

function reorder(existing: TestPick[], future: TestPick[], activeLanguageId: string | undefined) {
promoteActiveLanguage(existing, future, activeLanguageId);
return { existing: existing.map(p => p.label), future: future.map(p => p.label) };
}

test('promotes the active language in both groups', () => {
// existing file for python, and a new-language entry for python -> both jump to front
const existing = [file('global.code-snippets'), file('javascript.json'), file('python.json')];
const future = [lang('csharp'), lang('go'), lang('python')];

assert.deepStrictEqual(reorder(existing, future, 'python'), {
existing: ['python.json', 'global.code-snippets', 'javascript.json'],
future: ['python', 'csharp', 'go']
});
});

test('no-op cases: no active language, already first, or not present', () => {
const existing = () => [file('javascript.json'), file('python.json')];
const future = () => [lang('go'), lang('python')];

// undefined active language leaves order untouched
assert.deepStrictEqual(reorder(existing(), future(), undefined), {
existing: ['javascript.json', 'python.json'],
future: ['go', 'python']
});

// already first in the existing group -> untouched
assert.deepStrictEqual(reorder(existing(), future(), 'javascript'), {
existing: ['javascript.json', 'python.json'],
future: ['go', 'python'] // no future entry for javascript, so future untouched too
});

// language absent from both groups -> untouched
assert.deepStrictEqual(reorder(existing(), future(), 'rust'), {
existing: ['javascript.json', 'python.json'],
future: ['go', 'python']
});
});
});