Не подтверждена Коммит cde4b9f6 создал по автору Megan Rogge's avatar Megan Rogge Зафиксировано автором GitHub
Просмотр файлов

Merge pull request #241543 from microsoft/merogge/filepaths

add `fileExtensions` to terminal completion resource request config
владелец 27ada980
// import { filepaths } from "@fig/autocomplete-generators";
import { filepaths } from '../../helpers/filepaths';
const packages: Fig.Generator = {
// only trigger when the token length transitions to or from 0
......@@ -134,10 +134,9 @@ const completionSpec: Fig.Spec = {
name: "package",
description: "The package you want to install",
isVariadic: true,
template: 'filepaths',
generators: [
packages,
// filepaths({ extensions: ["deb"] })
filepaths({ extensions: ["deb"] })
],
},
options: [
......
// import { filepaths } from "@fig/autocomplete-generators";
import { filepaths } from '../../helpers/filepaths';
const completionSpec: Fig.Subcommand = {
name: "node",
......@@ -6,11 +6,10 @@ const completionSpec: Fig.Subcommand = {
args: {
name: "node script",
isScript: true,
template: 'folders',
// generators: filepaths({
// extensions: ["mjs", "js", "cjs"],
// editFileSuggestions: { priority: 76 },
// }),
generators: filepaths({
extensions: ["mjs", "js", "cjs"],
editFileSuggestions: { priority: 76 },
}),
},
options: [
{
......
// import { filepaths } from "@fig/autocomplete-generators";
import { filepaths } from '../../helpers/filepaths';
const completionSpec: Fig.Spec = {
name: "python",
name: ["python", "python3"],
description: "Run the python interpreter",
generateSpec: async (tokens, executeShellCommand) => {
const isDjangoManagePyFilePresentCommand = "cat manage.py | grep -q django";
......@@ -21,11 +21,10 @@ const completionSpec: Fig.Spec = {
},
args: {
name: "python script",
template: "filepaths",
// generators: filepaths({
// extensions: ["py"],
// editFileSuggestions: { priority: 76 },
// }),
generators: filepaths({
extensions: ["py"],
editFileSuggestions: { priority: 76 },
}),
},
options: [
{
......
......@@ -21,6 +21,7 @@ import { IFigExecuteExternals } from './execute';
export interface IFigSpecSuggestionsResult {
filesRequested: boolean;
foldersRequested: boolean;
fileExtensions?: string[];
hasCurrentArg: boolean;
items: vscode.TerminalCompletionItem[];
}
......@@ -91,6 +92,7 @@ export async function getFigSuggestions(
if (completionItemResult) {
result.filesRequested ||= completionItemResult.filesRequested;
result.foldersRequested ||= completionItemResult.foldersRequested;
result.fileExtensions ||= completionItemResult.fileExtensions;
if (completionItemResult.items) {
result.items.push(...completionItemResult.items);
}
......@@ -112,6 +114,7 @@ async function getFigSpecSuggestions(
): Promise<IFigSpecSuggestionsResult | undefined> {
let filesRequested = false;
let foldersRequested = false;
let fileExtensions: string[] | undefined;
const command = getCommand(terminalContext.commandLine, {}, terminalContext.cursorPosition);
if (!command || !shellIntegrationCwd) {
......@@ -136,11 +139,13 @@ async function getFigSpecSuggestions(
if (completionItemResult) {
filesRequested = completionItemResult.filesRequested;
foldersRequested = completionItemResult.foldersRequested;
fileExtensions = completionItemResult.fileExtensions;
}
return {
filesRequested,
foldersRequested,
fileExtensions,
hasCurrentArg: !!parsedArguments.currentArg,
items: items,
};
......@@ -157,9 +162,10 @@ export async function collectCompletionItemResult(
env: Record<string, string>,
items: vscode.TerminalCompletionItem[],
executeExternals: IFigExecuteExternals
): Promise<{ filesRequested: boolean; foldersRequested: boolean } | undefined> {
): Promise<{ filesRequested: boolean; foldersRequested: boolean; fileExtensions: string[] | undefined } | undefined> {
let filesRequested = false;
let foldersRequested = false;
let fileExtensions: string[] | undefined;
const addSuggestions = async (specArgs: SpecArg[] | Record<string, SpecArg> | undefined, kind: vscode.TerminalCompletionItemKind, parsedArguments?: ArgumentParserResult) => {
if (kind === vscode.TerminalCompletionItemKind.Argument && parsedArguments?.currentArg?.generators) {
......@@ -199,6 +205,15 @@ export async function collectCompletionItemResult(
const generatorResults = s.triggerGenerators(parsedArguments, executeExternals);
for (const generatorResult of generatorResults) {
for (const item of (await generatorResult?.request) ?? []) {
if (item.type === 'file') {
filesRequested = true;
foldersRequested = true;
fileExtensions = item._internal?.fileExtensions as string[] | undefined;
}
if (item.type === 'folder') {
foldersRequested = true;
}
if (!item.name) {
continue;
}
......@@ -288,7 +303,7 @@ export async function collectCompletionItemResult(
await addSuggestions(parsedArguments.completionObj.options, vscode.TerminalCompletionItemKind.Flag, parsedArguments);
}
return { filesRequested, foldersRequested };
return { filesRequested, foldersRequested, fileExtensions };
}
function convertEnvRecordToArray(env: Record<string, string>): EnvironmentVariable[] {
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export function filepaths(options: { extensions?: string[]; editFileSuggestions?: { priority: number } }): Fig.Generator {
return {
custom: async (tokens, executeCommand, generatorContext) => {
const fileExtensionsMap: Record<string, string[]> = { fileExtensions: options.extensions || [] };
return [{ type: 'file', _internal: fileExtensionsMap }, { type: 'folder' }];
},
trigger: (oldToken, newToken) => {
return true;
},
getQueryTerm: (token) => token
};
}
......@@ -120,7 +120,7 @@ export async function activate(context: vscode.ExtensionContext) {
}
if (result.cwd && (result.filesRequested || result.foldersRequested)) {
return new vscode.TerminalCompletionList(result.items, { filesRequested: result.filesRequested, foldersRequested: result.foldersRequested, cwd: result.cwd, env: terminal.shellIntegration?.env.value });
return new vscode.TerminalCompletionList(result.items, { filesRequested: result.filesRequested, foldersRequested: result.foldersRequested, fileExtensions: result.fileExtensions, cwd: result.cwd, env: terminal.shellIntegration?.env.value });
}
return result.items;
}
......@@ -209,11 +209,12 @@ export async function getCompletionItemsFromSpecs(
name: string,
token?: vscode.CancellationToken,
executeExternals?: IFigExecuteExternals,
): Promise<{ items: vscode.TerminalCompletionItem[]; filesRequested: boolean; foldersRequested: boolean; cwd?: vscode.Uri }> {
): Promise<{ items: vscode.TerminalCompletionItem[]; filesRequested: boolean; foldersRequested: boolean; fileExtensions?: string[]; cwd?: vscode.Uri }> {
const items: vscode.TerminalCompletionItem[] = [];
let filesRequested = false;
let foldersRequested = false;
let hasCurrentArg = false;
let fileExtensions: string[] | undefined;
let precedingText = terminalContext.commandLine.slice(0, terminalContext.cursorPosition + 1);
if (isWindows) {
......@@ -230,6 +231,7 @@ export async function getCompletionItemsFromSpecs(
hasCurrentArg ||= result.hasCurrentArg;
filesRequested ||= result.filesRequested;
foldersRequested ||= result.foldersRequested;
fileExtensions = result.fileExtensions;
if (result.items) {
items.push(...result.items);
}
......@@ -276,7 +278,7 @@ export async function getCompletionItemsFromSpecs(
cwd = await resolveCwdFromPrefix(prefix, shellIntegrationCwd) ?? shellIntegrationCwd;
}
return { items, filesRequested, foldersRequested, cwd };
return { items, filesRequested, foldersRequested, fileExtensions, cwd };
}
function compareItems(existingItem: vscode.TerminalCompletionItem, command: ICompletionResource): vscode.TerminalCompletionItem | undefined {
......
......@@ -2480,6 +2480,7 @@ export class TerminalCompletionListDto<T extends ITerminalCompletionItemDto = IT
export interface TerminalResourceRequestConfigDto {
filesRequested?: boolean;
foldersRequested?: boolean;
fileExtensions?: string[];
cwd?: UriComponents;
pathSeparator: string;
}
......
......@@ -2202,6 +2202,7 @@ export class TerminalCompletionList<T extends TerminalCompletionItem = TerminalC
export interface TerminalResourceRequestConfig {
filesRequested?: boolean;
foldersRequested?: boolean;
fileExtensions?: string[];
cwd?: vscode.Uri;
}
......
......@@ -50,6 +50,7 @@ export class TerminalCompletionList<ITerminalCompletion> {
export interface TerminalResourceRequestConfig {
filesRequested?: boolean;
foldersRequested?: boolean;
fileExtensions?: string[];
cwd?: UriComponents;
pathSeparator: string;
env?: { [key: string]: string | null | undefined };
......@@ -209,6 +210,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
// provide diagnostics when a folder is provided where a file is expected.
const foldersRequested = (resourceRequestConfig.foldersRequested || resourceRequestConfig.filesRequested) ?? false;
const filesRequested = resourceRequestConfig.filesRequested ?? false;
const fileExtensions = resourceRequestConfig.fileExtensions ?? undefined;
const cwd = URI.revive(resourceRequestConfig.cwd);
if (!cwd || (!foldersRequested && !filesRequested)) {
......@@ -378,6 +380,13 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo
label += resourceRequestConfig.pathSeparator;
}
if (child.isFile && fileExtensions) {
const extension = child.name.split('.').length > 1 ? child.name.split('.').at(-1) : undefined;
if (extension && !fileExtensions.includes(extension)) {
continue;
}
}
resourceCompletions.push({
label,
provider,
......
......@@ -126,6 +126,10 @@ declare module 'vscode' {
* Show folders as completion items.
*/
foldersRequested?: boolean;
/**
* File extensions to filter by.
*/
fileExtensions?: string[];
/**
* If no cwd is provided, no resources will be shown as completions.
*/
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать