add suggest setting `WindowsExecutableExtensions`, default values (#238155)
parent
ff593777e3
commit
c2c7ab5a88
|
@ -6,9 +6,10 @@
|
|||
import { osIsWindows } from './os';
|
||||
import * as fs from 'fs/promises';
|
||||
|
||||
export async function isExecutable(filePath: string): Promise<boolean> {
|
||||
export async function isExecutable(filePath: string, configuredWindowsExecutableExtensions?: Object): Promise<boolean> {
|
||||
if (osIsWindows()) {
|
||||
return windowsExecutableExtensions.find(ext => filePath.endsWith(ext)) !== undefined;
|
||||
const resolvedWindowsExecutableExtensions = resolveWindowsExecutableExtensions(configuredWindowsExecutableExtensions);
|
||||
return resolvedWindowsExecutableExtensions.find(ext => filePath.endsWith(ext)) !== undefined;
|
||||
}
|
||||
try {
|
||||
const stats = await fs.stat(filePath);
|
||||
|
@ -19,7 +20,23 @@ export async function isExecutable(filePath: string): Promise<boolean> {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
const windowsExecutableExtensions: string[] = [
|
||||
|
||||
function resolveWindowsExecutableExtensions(configuredWindowsExecutableExtensions?: Object): string[] {
|
||||
const resolvedWindowsExecutableExtensions: string[] = windowsDefaultExecutableExtensions;
|
||||
const excluded = new Set<string>();
|
||||
if (configuredWindowsExecutableExtensions) {
|
||||
for (const [key, value] of Object.entries(configuredWindowsExecutableExtensions)) {
|
||||
if (value === true) {
|
||||
resolvedWindowsExecutableExtensions.push(key);
|
||||
} else {
|
||||
excluded.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Array.from(new Set(resolvedWindowsExecutableExtensions)).filter(ext => !excluded.has(ext));
|
||||
}
|
||||
|
||||
export const windowsDefaultExecutableExtensions: string[] = [
|
||||
'.exe', // Executable file
|
||||
'.bat', // Batch file
|
||||
'.cmd', // Command script
|
||||
|
|
|
@ -15,6 +15,8 @@ import { isExecutable } from './helpers/executable';
|
|||
|
||||
const isWindows = osIsWindows();
|
||||
let cachedAvailableCommandsPath: string | undefined;
|
||||
let cachedWindowsExecutableExtensions: Object | undefined;
|
||||
const cachedWindowsExecutableExtensionsSettingId = 'terminal.integrated.suggest.windowsExecutableExtensions';
|
||||
let cachedAvailableCommands: Set<ICompletionResource> | undefined;
|
||||
const cachedBuiltinCommands: Map<string, ICompletionResource[] | undefined> = new Map();
|
||||
|
||||
|
@ -110,8 +112,18 @@ export async function activate(context: vscode.ExtensionContext) {
|
|||
return result.items;
|
||||
}
|
||||
}, '/', '\\'));
|
||||
}
|
||||
|
||||
if (isWindows) {
|
||||
cachedWindowsExecutableExtensions = vscode.workspace.getConfiguration(cachedWindowsExecutableExtensionsSettingId);
|
||||
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration(cachedWindowsExecutableExtensionsSettingId)) {
|
||||
cachedWindowsExecutableExtensions = vscode.workspace.getConfiguration(cachedWindowsExecutableExtensionsSettingId);
|
||||
cachedAvailableCommands = undefined;
|
||||
cachedAvailableCommandsPath = undefined;
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the current working directory based on a given prefix if it is a folder.
|
||||
|
@ -221,7 +233,7 @@ async function getCommandsInPath(env: { [key: string]: string | undefined } = pr
|
|||
const files = await vscode.workspace.fs.readDirectory(fileResource);
|
||||
for (const [file, fileType] of files) {
|
||||
const formattedPath = getFriendlyFilePath(vscode.Uri.joinPath(fileResource, file), pathSeparator);
|
||||
if (!labels.has(file) && fileType !== vscode.FileType.Unknown && fileType !== vscode.FileType.Directory && await isExecutable(formattedPath)) {
|
||||
if (!labels.has(file) && fileType !== vscode.FileType.Unknown && fileType !== vscode.FileType.Directory && await isExecutable(formattedPath), cachedWindowsExecutableExtensions) {
|
||||
executables.add({ label: file, path: formattedPath });
|
||||
labels.add(file);
|
||||
}
|
||||
|
|
|
@ -15,9 +15,29 @@ export const enum TerminalSuggestSettingId {
|
|||
RunOnEnter = 'terminal.integrated.suggest.runOnEnter',
|
||||
BuiltinCompletions = 'terminal.integrated.suggest.builtinCompletions',
|
||||
EnableExtensionCompletions = 'terminal.integrated.suggest.enableExtensionCompletions',
|
||||
WindowsExecutableExtensions = 'terminal.integrated.suggest.windowsExecutableExtensions',
|
||||
Providers = 'terminal.integrated.suggest.providers',
|
||||
}
|
||||
|
||||
export const windowsDefaultExecutableExtensions: string[] = [
|
||||
'exe', // Executable file
|
||||
'bat', // Batch file
|
||||
'cmd', // Command script
|
||||
'com', // Command file
|
||||
|
||||
'msi', // Windows Installer package
|
||||
|
||||
'ps1', // PowerShell script
|
||||
|
||||
'vbs', // VBScript file
|
||||
'js', // JScript file
|
||||
'jar', // Java Archive (requires Java runtime)
|
||||
'py', // Python script (requires Python interpreter)
|
||||
'rb', // Ruby script (requires Ruby interpreter)
|
||||
'pl', // Perl script (requires Perl interpreter)
|
||||
'sh', // Shell script (via WSL or third-party tools)
|
||||
];
|
||||
|
||||
export const terminalSuggestConfigSection = 'terminal.integrated.suggest';
|
||||
|
||||
export interface ITerminalSuggestConfiguration {
|
||||
|
@ -106,4 +126,15 @@ export const terminalSuggestConfiguration: IStringDictionary<IConfigurationPrope
|
|||
default: false,
|
||||
tags: ['experimental'],
|
||||
},
|
||||
[TerminalSuggestSettingId.WindowsExecutableExtensions]: {
|
||||
restricted: true,
|
||||
markdownDescription: localize("terminalWindowsExecutableSuggestionSetting", "A set of windows command executable extensions that will be included as suggestions in the terminal. For example, `exe` and `bat`.\n\nMany executables are included by default, listed below:\n\n{0}.\n\nTo exclude an extension, set it to `false`\n\n. To include one not in the list, add it and set it to `true`.",
|
||||
windowsDefaultExecutableExtensions.sort().map(extension => `- ${extension}`).join('\n'),
|
||||
),
|
||||
type: 'object',
|
||||
default: {},
|
||||
tags: ['experimental'],
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue