Skip to content

Commit

Permalink
Merge branch 'microsoft:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
eldoradoAr authored Feb 25, 2025
2 parents 2c16186 + 59990f4 commit 85a90cf
Show file tree
Hide file tree
Showing 145 changed files with 2,069 additions and 985 deletions.
16 changes: 15 additions & 1 deletion extensions/terminal-suggest/scripts/update-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,28 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

// @ts-check

const fs = require('fs');
const path = require('path');

const upstreamSpecs = require('../out/constants.js').upstreamSpecs;

const extRoot = path.resolve(path.join(__dirname, '..'));
const replaceStrings = [
[
'import { filepaths } from "@fig/autocomplete-generators";',
'import { filepaths } from \'../../helpers/filepaths\';'
]
]

for (const spec of upstreamSpecs) {
const source = path.join(extRoot, `third_party/autocomplete/src/${spec}.ts`);
const destination = path.join(extRoot, `src/completions/upstream/${spec}.ts`);
fs.copyFileSync(source, destination);

let content = fs.readFileSync(destination).toString();
for (const replaceString of replaceStrings) {
content = content.replaceAll(replaceString[0], replaceString[1]);
}
fs.writeFileSync(destination, content);
}
27 changes: 27 additions & 0 deletions extensions/terminal-suggest/src/completions/set-location.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

const cdSpec: Fig.Spec = {
name: 'Set-Location',
description: 'Change the shell working directory',
args: {
name: 'folder',
template: 'folders',
suggestions: [
{
name: '-',
description: 'Go to previous directory in history stack',
hidden: true,
},
{
name: '+',
description: 'Go to next directory in history stack',
hidden: true,
},
],
}
};

export default cdSpec;
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { filepaths } from '../../helpers/filepaths';

const completionSpec: Fig.Spec = {
name: ["python", "python3"],
name: "python",
description: "Run the python interpreter",
generateSpec: async (tokens, executeShellCommand) => {
const isDjangoManagePyFilePresentCommand = "cat manage.py | grep -q django";
Expand Down
170 changes: 170 additions & 0 deletions extensions/terminal-suggest/src/completions/upstream/python3.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import { filepaths } from '../../helpers/filepaths';

const completionSpec: Fig.Spec = {
name: "python3",
description: "Run the python interpreter",
generateSpec: async (tokens, executeShellCommand) => {
const isDjangoManagePyFilePresentCommand = "cat manage.py | grep -q django";

if (
(
await executeShellCommand({
command: "bash",
args: ["-c", isDjangoManagePyFilePresentCommand],
})
).status === 0
) {
return {
name: "python3",
subcommands: [{ name: "manage.py", loadSpec: "django-admin" }],
};
}
},
args: {
name: "python script",
isScript: true,
generators: filepaths({
extensions: ["py"],
editFileSuggestions: { priority: 76 },
}),
},
options: [
{
name: "-c",
insertValue: "-c '{cursor}'",
description:
"Execute the Python code in command. command can be one or more statements separated by newlines, with significant leading whitespace as in normal module code",
args: {
name: "command",
isCommand: true,
},
},
{
name: "-m",
insertValue: "-m '{cursor}'",
description:
"Search sys.path for the named module and execute its contents as the __main__ module",
args: {
name: "command",
isCommand: true,
},
},
{
name: ["-?", "-h", "--help"],
description: "Print a short description of all command line options",
},
{
name: ["-V", "--version"],
description: "Print the Python version number and exit",
},
{
name: "-b",
description:
"Issue a warning when comparing bytes or bytearray with str or bytes with int. Issue an error when the option is given twice (-bb)",
},
{
name: "-B",
description:
"If given, Python won’t try to write .pyc files on the import of source modules",
},
{
name: "--check-hash-based-pycs",
description:
"Control the validation behavior of hash-based .pyc files. See Cached bytecode invalidation",
args: {
suggestions: [
{ name: "default" },
{ name: "always" },
{ name: "never" },
],
},
},
{
name: "-d",
description:
"Turn on parser debugging output (for expert only, depending on compilation options)",
},
{
name: "-E",
description:
"Ignore all PYTHON* environment variables, e.g. PYTHONPATH and PYTHONHOME, that might be set",
},
{
name: "-i",
description:
"When a script is passed as first argument or the -c option is used, enter interactive mode after executing the script or the command, even when sys.stdin does not appear to be a terminal",
},
{
name: "-I",
description:
"Run Python in isolated mode. This also implies -E and -s. In isolated mode sys.path contains neither the script’s directory nor the user’s site-packages directory",
},
{
name: "-O",
description:
"Remove assert statements and any code conditional on the value of __debug__",
},
{
name: "-OO",
description: "Do -O and also discard docstrings",
},
{
name: "-g",
description:
"Don’t display the copyright and version messages even in interactive mode",
},
{
name: "-R",
description:
"Turn on hash randomization. This option only has an effect if the PYTHONHASHSEED environment variable is set to 0, since hash randomization is enabled by default",
},
{
name: "-s",
description: "Don’t add the user site-packages directory to sys.path",
},
{
name: "-S",
description:
"Disable the import of the module site and the site-dependent manipulations of sys.path that it entails",
},
{
name: "-u",
description:
"Force the stdout and stderr streams to be unbuffered. This option has no effect on the stdin stream",
},
{
name: "-v",
description:
"Print a message each time a module is initialized, showing the place (filename or built-in module) from which it is loaded",
},
{
name: "-W",
description:
"Warning control. Python’s warning machinery by default prints warning messages to sys.stderr",
args: {},
},
{
name: "-x",
description:
"Skip the first line of the source, allowing use of non-Unix forms of #!cmd. This is intended for a DOS specific hack only",
},
{
name: "-X",
description: "Reserved for various implementation-specific options",
args: {
suggestions: [
{ name: "faulthandler" },
{ name: "showrefcount" },
{ name: "tracemalloc" },
{ name: "showalloccount" },
{ name: "importtime" },
{ name: "dev" },
{ name: "utf8" },
{ name: "pycache_prefix=PATH" },
],
},
},
],
};

export default completionSpec;
1 change: 1 addition & 0 deletions extensions/terminal-suggest/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const upstreamSpecs = [
'npm',
'yarn',
'python',
'python3',
'pnpm',
'node',
'nvm',
Expand Down
6 changes: 0 additions & 6 deletions extensions/terminal-suggest/src/fig/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export const executeCommandTimeout = async (
const command = [input.command, ...input.args].join(' ');
try {
console.info(`About to run shell command '${command}'`);
const start = performance.now();
const result = await withTimeout(
Math.max(timeout, input.timeout ?? 0),
spawnHelper2(input.command, input.args, {
Expand All @@ -30,11 +29,6 @@ export const executeCommandTimeout = async (
timeout: input.timeout,
})
);
const end = performance.now();
console.info(`Result of shell command '${command}'`, {
result,
time: end - start,
});

const cleanStdout = cleanOutput(result.stdout);
const cleanStderr = cleanOutput(result.stderr);
Expand Down
67 changes: 37 additions & 30 deletions extensions/terminal-suggest/src/fig/figInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type { ICompletionResource } from '../types';
import { osIsWindows } from '../helpers/os';
import { removeAnyFileExtension } from '../helpers/file';
import type { EnvironmentVariable } from './api-bindings/types';
import { asArray } from '../terminalSuggestMain';
import { IFigExecuteExternals } from './execute';

export interface IFigSpecSuggestionsResult {
Expand Down Expand Up @@ -67,10 +68,13 @@ export async function getFigSuggestions(
result.items.push(createCompletionItem(
terminalContext.cursorPosition,
prefix,
{ label: { label: specLabel, description } },
{
label: { label: specLabel, description },
kind: vscode.TerminalCompletionItemKind.Method
},
description,
availableCommand.detail)
);
availableCommand.detail
));
}
continue;
}
Expand Down Expand Up @@ -147,7 +151,7 @@ async function getFigSpecSuggestions(
foldersRequested,
fileExtensions,
hasCurrentArg: !!parsedArguments.currentArg,
items: items,
items,
};
}

Expand Down Expand Up @@ -252,43 +256,46 @@ export async function collectCompletionItemResult(
return { filesRequested, foldersRequested };
}
const flagsToExclude = kind === vscode.TerminalCompletionItemKind.Flag ? parsedArguments?.passedOptions.map(option => option.name).flat() : undefined;

function addItem(label: string, item: SpecArg) {
if (flagsToExclude?.includes(label)) {
return;
}

let itemKind = kind;
if (typeof item === 'object' && 'args' in item && (asArray(item.args ?? [])).length > 0) {
itemKind = vscode.TerminalCompletionItemKind.Option;
}
const lastArgType: string | undefined = parsedArguments?.annotations.at(-1)?.type;
if (lastArgType === 'option_arg') {
itemKind = vscode.TerminalCompletionItemKind.OptionValue;
}

items.push(
createCompletionItem(
terminalContext.cursorPosition,
prefix,
{ label },
undefined,
typeof item === 'string' ? item : item.description,
itemKind,
)
);
}

if (Array.isArray(specArgs)) {
for (const item of specArgs) {
const suggestionLabels = getFigSuggestionLabel(item);
if (!suggestionLabels?.length) {
continue;
}
for (const label of suggestionLabels) {
if (flagsToExclude?.includes(label)) {
continue;
}
items.push(
createCompletionItem(
terminalContext.cursorPosition,
prefix,
{ label },
undefined,
typeof item === 'string' ? item : item.description,
kind
)
);
addItem(label, item);
}
}
} else {
for (const [label, item] of Object.entries(specArgs)) {
if (flagsToExclude?.includes(label)) {
continue;
}
items.push(
createCompletionItem(
terminalContext.cursorPosition,
prefix,
{ label },
undefined,
typeof item === 'string' ? item : item.description,
kind
)
);
addItem(label, item);
}
}
};
Expand Down
2 changes: 2 additions & 0 deletions extensions/terminal-suggest/src/terminalSuggestMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import * as vscode from 'vscode';
import cdSpec from './completions/cd';
import codeCompletionSpec from './completions/code';
import codeInsidersCompletionSpec from './completions/code-insiders';
import setLocationSpec from './completions/set-location';
import { upstreamSpecs } from './constants';
import { PathExecutableCache } from './env/pathExecutableCache';
import { osIsWindows } from './helpers/os';
Expand Down Expand Up @@ -49,6 +50,7 @@ export const availableSpecs: Fig.Spec[] = [
cdSpec,
codeInsidersCompletionSpec,
codeCompletionSpec,
setLocationSpec,
];
for (const spec of upstreamSpecs) {
availableSpecs.push(require(`./completions/upstream/${spec}`).default);
Expand Down
Loading

0 comments on commit 85a90cf

Please sign in to comment.