Skip to content

Commit

Permalink
Merge branch 'main' into merogge/new-branch
Browse files Browse the repository at this point in the history
  • Loading branch information
meganrogge committed Jan 17, 2025
2 parents 0596fd6 + ff59377 commit a960359
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 87 deletions.
2 changes: 0 additions & 2 deletions extensions/github-authentication/src/flows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,6 @@ async function exchangeCodeForToken(
headers: {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': body.toString()

},
body: body.toString()
});
Expand Down
9 changes: 7 additions & 2 deletions extensions/github-authentication/src/node/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import fetch from 'node-fetch';

export const fetching = fetch;
let _fetch: typeof fetch;
try {
_fetch = require('electron').net.fetch;
} catch {
_fetch = fetch;
}
export const fetching = _fetch;
6 changes: 3 additions & 3 deletions extensions/microsoft-authentication/src/node/flows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ interface IMsalFlow {
class DefaultLoopbackFlow implements IMsalFlow {
label = 'default';
options: IMsalFlowOptions = {
supportsRemoteExtensionHost: true,
supportsWebWorkerExtensionHost: true
supportsRemoteExtensionHost: false,
supportsWebWorkerExtensionHost: false
};

async trigger({ cachedPca, scopes, loginHint, windowHandle, logger }: IMsalFlowTriggerOptions): Promise<AuthenticationResult> {
Expand All @@ -62,7 +62,7 @@ class DefaultLoopbackFlow implements IMsalFlow {
class UrlHandlerFlow implements IMsalFlow {
label = 'protocol handler';
options: IMsalFlowOptions = {
supportsRemoteExtensionHost: false,
supportsRemoteExtensionHost: true,
supportsWebWorkerExtensionHost: false
};

Expand Down
71 changes: 44 additions & 27 deletions extensions/terminal-suggest/src/terminalSuggestMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import { isExecutable } from './helpers/executable';
const isWindows = osIsWindows();
let cachedAvailableCommandsPath: string | undefined;
let cachedWindowsExecutableExtensions: Object | undefined;
let cachedAvailableCommands: Set<string> | undefined;
const cachedBuiltinCommands: Map<string, string[] | undefined> = new Map();
const cachedWindowsExecutableExtensionsSettingId = 'terminal.integrated.suggest.windowsExecutableExtensions';
let cachedAvailableCommands: Set<ICompletionResource> | undefined;
const cachedBuiltinCommands: Map<string, ICompletionResource[] | undefined> = new Map();

export const availableSpecs: Fig.Spec[] = [
cdSpec,
Expand All @@ -29,14 +29,14 @@ for (const spec of upstreamSpecs) {
availableSpecs.push(require(`./completions/upstream/${spec}`).default);
}

function getBuiltinCommands(shell: string): string[] | undefined {
function getBuiltinCommands(shell: string, existingCommands?: Set<string>): ICompletionResource[] | undefined {
try {
const shellType = path.basename(shell, path.extname(shell));
const cachedCommands = cachedBuiltinCommands.get(shellType);
if (cachedCommands) {
return cachedCommands;
}
const filter = (cmd: string) => cmd;
const filter = (cmd: string) => cmd && !existingCommands?.has(cmd);
const options: ExecOptionsWithStringEncoding = { encoding: 'utf-8', shell };
let commands: string[] | undefined;
switch (shellType) {
Expand Down Expand Up @@ -70,8 +70,10 @@ function getBuiltinCommands(shell: string): string[] | undefined {
break;
}
}
cachedBuiltinCommands.set(shellType, commands);
return commands;

const commandResources = commands?.map(command => ({ label: command }));
cachedBuiltinCommands.set(shellType, commandResources);
return commandResources;

} catch (error) {
console.error('Error fetching builtin commands:', error);
Expand All @@ -94,11 +96,11 @@ export async function activate(context: vscode.ExtensionContext) {
}

const commandsInPath = await getCommandsInPath(terminal.shellIntegration?.env);
const builtinCommands = getBuiltinCommands(shellPath);
if (!commandsInPath || !builtinCommands) {
const builtinCommands = getBuiltinCommands(shellPath, commandsInPath?.labels) ?? [];
if (!commandsInPath?.completionResources) {
return;
}
const commands = [...commandsInPath, ...builtinCommands];
const commands = [...commandsInPath.completionResources, ...builtinCommands];

const prefix = getPrefix(terminalContext.commandLine, terminalContext.cursorPosition);

Expand Down Expand Up @@ -181,20 +183,24 @@ function getLabel(spec: Fig.Spec | Fig.Arg | Fig.Suggestion | string): string[]
return spec.name;
}

function createCompletionItem(cursorPosition: number, prefix: string, label: string, description?: string, kind?: vscode.TerminalCompletionItemKind): vscode.TerminalCompletionItem {
function createCompletionItem(cursorPosition: number, prefix: string, commandResource: ICompletionResource, description?: string, kind?: vscode.TerminalCompletionItemKind): vscode.TerminalCompletionItem {
const endsWithSpace = prefix.endsWith(' ');
const lastWord = endsWithSpace ? '' : prefix.split(' ').at(-1) ?? '';
return {
label,
detail: description ?? '',
label: commandResource.label,
detail: description ?? commandResource.path ?? '',
replacementIndex: cursorPosition - lastWord.length,
replacementLength: lastWord.length,
kind: kind ?? vscode.TerminalCompletionItemKind.Method
};
}

async function getCommandsInPath(env: { [key: string]: string | undefined } = process.env): Promise<Set<string> | undefined> {
// Get PATH value
interface ICompletionResource {
label: string;
path?: string;
}
async function getCommandsInPath(env: { [key: string]: string | undefined } = process.env): Promise<{ completionResources: Set<ICompletionResource> | undefined; labels: Set<string> | undefined } | undefined> {
const labels: Set<string> = new Set<string>();
let pathValue: string | undefined;
if (isWindows) {
const caseSensitivePathKey = Object.keys(env).find(key => key.toLowerCase() === 'path');
Expand All @@ -210,24 +216,26 @@ async function getCommandsInPath(env: { [key: string]: string | undefined } = pr

// Check cache
if (cachedAvailableCommands && cachedAvailableCommandsPath === pathValue) {
return cachedAvailableCommands;
return { completionResources: cachedAvailableCommands, labels };
}

// Extract executables from PATH
const paths = pathValue.split(isWindows ? ';' : ':');
const pathSeparator = isWindows ? '\\' : '/';
const executables = new Set<string>();
const executables = new Set<ICompletionResource>();
for (const path of paths) {
try {
const dirExists = await fs.stat(path).then(stat => stat.isDirectory()).catch(() => false);
if (!dirExists) {
continue;
}
const files = await vscode.workspace.fs.readDirectory(vscode.Uri.file(path));

const fileResource = vscode.Uri.file(path);
const files = await vscode.workspace.fs.readDirectory(fileResource);
for (const [file, fileType] of files) {
if (fileType !== vscode.FileType.Unknown && fileType !== vscode.FileType.Directory && await isExecutable(path + pathSeparator + file, cachedWindowsExecutableExtensions)) {
executables.add(file);
const formattedPath = getFriendlyFilePath(vscode.Uri.joinPath(fileResource, file), pathSeparator);
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);
}
}
} catch (e) {
Expand All @@ -236,7 +244,7 @@ async function getCommandsInPath(env: { [key: string]: string | undefined } = pr
}
}
cachedAvailableCommands = executables;
return executables;
return { completionResources: executables, labels };
}

function getPrefix(commandLine: string, cursorPosition: number): string {
Expand Down Expand Up @@ -269,7 +277,7 @@ export function asArray<T>(x: T | T[]): T[] {
export async function getCompletionItemsFromSpecs(
specs: Fig.Spec[],
terminalContext: { commandLine: string; cursorPosition: number },
availableCommands: string[],
availableCommands: ICompletionResource[],
prefix: string,
shellIntegrationCwd?: vscode.Uri,
token?: vscode.CancellationToken
Expand All @@ -289,7 +297,7 @@ export async function getCompletionItemsFromSpecs(
}

for (const specLabel of specLabels) {
if (!availableCommands.includes(specLabel) || (token && token.isCancellationRequested)) {
if (!availableCommands.find(command => command.label === specLabel) || (token && token.isCancellationRequested)) {
continue;
}

Expand All @@ -300,7 +308,7 @@ export async function getCompletionItemsFromSpecs(
|| !!firstCommand && specLabel.startsWith(firstCommand)
) {
// push it to the completion items
items.push(createCompletionItem(terminalContext.cursorPosition, prefix, specLabel));
items.push(createCompletionItem(terminalContext.cursorPosition, prefix, { label: specLabel }));
}

if (!terminalContext.commandLine.startsWith(specLabel)) {
Expand Down Expand Up @@ -335,7 +343,7 @@ export async function getCompletionItemsFromSpecs(
// Include builitin/available commands in the results
const labels = new Set(items.map((i) => i.label));
for (const command of availableCommands) {
if (!labels.has(command)) {
if (!labels.has(command.label)) {
items.push(createCompletionItem(terminalContext.cursorPosition, prefix, command));
}
}
Expand Down Expand Up @@ -405,7 +413,7 @@ function handleOptions(specLabel: string, spec: Fig.Spec, terminalContext: { com
createCompletionItem(
terminalContext.cursorPosition,
prefix,
optionLabel,
{ label: optionLabel },
option.description,
vscode.TerminalCompletionItemKind.Flag
)
Expand Down Expand Up @@ -467,7 +475,7 @@ function getCompletionItemsFromArgs(args: Fig.SingleOrArray<Fig.Arg> | undefined
}
if (suggestionLabel && suggestionLabel.startsWith(currentPrefix.trim())) {
const description = typeof suggestion !== 'string' ? suggestion.description : '';
items.push(createCompletionItem(terminalContext.cursorPosition, wordBefore ?? '', suggestionLabel, description, vscode.TerminalCompletionItemKind.Argument));
items.push(createCompletionItem(terminalContext.cursorPosition, wordBefore ?? '', { label: suggestionLabel }, description, vscode.TerminalCompletionItemKind.Argument));
}
}
}
Expand All @@ -491,3 +499,12 @@ function getFirstCommand(commandLine: string): string | undefined {
}
return firstCommand;
}

function getFriendlyFilePath(uri: vscode.Uri, pathSeparator: string): string {
let path = uri.fsPath;
// Ensure drive is capitalized on Windows
if (pathSeparator === '\\' && path.match(/^[a-zA-Z]:\\/)) {
path = `${path[0].toUpperCase()}:${path.slice(2)}`;
}
return path;
}
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ suite('Terminal Suggest', () => {
const prefix = commandLine.slice(0, cursorPosition).split(' ').at(-1) || '';
const filesRequested = testSpec.expectedResourceRequests?.type === 'files' || testSpec.expectedResourceRequests?.type === 'both';
const foldersRequested = testSpec.expectedResourceRequests?.type === 'folders' || testSpec.expectedResourceRequests?.type === 'both';
const result = await getCompletionItemsFromSpecs(completionSpecs, { commandLine, cursorPosition }, availableCommands, prefix, testCwd);
const result = await getCompletionItemsFromSpecs(completionSpecs, { commandLine, cursorPosition }, availableCommands.map(c => { return { label: c }; }), prefix, testCwd);
deepStrictEqual(result.items.map(i => i.label).sort(), (testSpec.expectedCompletions ?? []).sort());
strictEqual(result.filesRequested, filesRequested);
strictEqual(result.foldersRequested, foldersRequested);
Expand Down
35 changes: 20 additions & 15 deletions src/vs/editor/browser/gpu/viewGpuContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ export class ViewGpuContext extends Disposable {
readonly canvas: FastDomNode<HTMLCanvasElement>;
readonly ctx: GPUCanvasContext;

readonly device: Promise<GPUDevice>;
static device: Promise<GPUDevice>;
static deviceSync: GPUDevice | undefined;

readonly rectangleRenderer: RectangleRenderer;

Expand Down Expand Up @@ -109,18 +110,23 @@ export class ViewGpuContext extends Disposable {

this.ctx = ensureNonNullable(this.canvas.domNode.getContext('webgpu'));

this.device = GPULifecycle.requestDevice((message) => {
const choices: IPromptChoice[] = [{
label: nls.localize('editor.dom.render', "Use DOM-based rendering"),
run: () => this.configurationService.updateValue('editor.experimentalGpuAcceleration', 'off'),
}];
this._notificationService.prompt(Severity.Warning, message, choices);
}).then(ref => this._register(ref).object);
this.device.then(device => {
if (!ViewGpuContext._atlas) {
ViewGpuContext._atlas = this._instantiationService.createInstance(TextureAtlas, device.limits.maxTextureDimension2D, undefined);
}
});
// Request the GPU device, we only want to do this a single time per window as it's async
// and can delay the initial render.
if (!ViewGpuContext.device) {
ViewGpuContext.device = GPULifecycle.requestDevice((message) => {
const choices: IPromptChoice[] = [{
label: nls.localize('editor.dom.render', "Use DOM-based rendering"),
run: () => this.configurationService.updateValue('editor.experimentalGpuAcceleration', 'off'),
}];
this._notificationService.prompt(Severity.Warning, message, choices);
}).then(ref => {
ViewGpuContext.deviceSync = ref.object;
if (!ViewGpuContext._atlas) {
ViewGpuContext._atlas = this._instantiationService.createInstance(TextureAtlas, ref.object.limits.maxTextureDimension2D, undefined);
}
return ref.object;
});
}

const dprObs = observableValue(this, getActiveWindow().devicePixelRatio);
this._register(addDisposableListener(getActiveWindow(), 'resize', () => {
Expand All @@ -147,8 +153,7 @@ export class ViewGpuContext extends Disposable {
}));
this.contentLeft = contentLeft;


this.rectangleRenderer = this._instantiationService.createInstance(RectangleRenderer, context, this.contentLeft, this.devicePixelRatio, this.canvas.domNode, this.ctx, this.device);
this.rectangleRenderer = this._instantiationService.createInstance(RectangleRenderer, context, this.contentLeft, this.devicePixelRatio, this.canvas.domNode, this.ctx, ViewGpuContext.device);
}

/**
Expand Down
3 changes: 1 addition & 2 deletions src/vs/editor/browser/viewParts/viewLinesGpu/viewLinesGpu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export class ViewLinesGpu extends ViewPart implements IViewLines {
async initWebgpu() {
// #region General

this._device = await this._viewGpuContext.device;
this._device = ViewGpuContext.deviceSync || await ViewGpuContext.device;

if (this._store.isDisposed) {
return;
Expand Down Expand Up @@ -650,7 +650,6 @@ export class ViewLinesGpu extends ViewPart implements IViewLines {
column++;
}

console.log(lineNumber, column);
return new Position(lineNumber, column + 1);
}
}
34 changes: 0 additions & 34 deletions src/vs/platform/quickinput/browser/quickInputController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -897,9 +897,6 @@ class QuickInputDragAndDropController extends Disposable {

private readonly _snapThreshold = 20;
private readonly _snapLineHorizontalRatio = 0.25;
private readonly _snapLineHorizontal: HTMLElement;
private readonly _snapLineVertical1: HTMLElement;
private readonly _snapLineVertical2: HTMLElement;

private _quickInputAlignmentContext = QuickInputAlignmentContextKey.bindTo(this._contextKeyService);

Expand All @@ -911,22 +908,11 @@ class QuickInputDragAndDropController extends Disposable {
@IContextKeyService private readonly _contextKeyService: IContextKeyService
) {
super();

this._snapLineHorizontal = dom.append(this._container, $('.quick-input-widget-snapline.horizontal.hidden'));
this._snapLineVertical1 = dom.append(this._container, $('.quick-input-widget-snapline.vertical.hidden'));
this._snapLineVertical2 = dom.append(this._container, $('.quick-input-widget-snapline.vertical.hidden'));

this.registerMouseListeners();
}

reparentUI(container: HTMLElement): void {
this._container = container;
this._snapLineHorizontal.remove();
this._snapLineVertical1.remove();
this._snapLineVertical2.remove();
dom.append(this._container, this._snapLineHorizontal);
dom.append(this._container, this._snapLineVertical1);
dom.append(this._container, this._snapLineVertical2);
}

setAlignment(alignment: 'top' | 'center' | { top: number; left: number }, done = true): void {
Expand Down Expand Up @@ -1000,7 +986,6 @@ class QuickInputDragAndDropController extends Disposable {
mouseMoveEvent.preventDefault();

if (!isMovingQuickInput) {
this._showSnapLines(snapCoordinateY, snapCoordinateX);
isMovingQuickInput = true;
}

Expand Down Expand Up @@ -1036,9 +1021,6 @@ class QuickInputDragAndDropController extends Disposable {
// Mouse up
const mouseUpListener = dom.addDisposableGenericMouseUpListener(activeWindow, (e: MouseEvent) => {
if (isMovingQuickInput) {
// Hide snaplines
this._hideSnapLines();

// Save position
const state = this.dndViewState.get();
this.dndViewState.set({ top: state?.top, left: state?.left, done: true }, undefined);
Expand All @@ -1062,20 +1044,4 @@ class QuickInputDragAndDropController extends Disposable {
private _getCenterXSnapValue() {
return Math.round(this._container.clientWidth / 2) - Math.round(this._quickInputContainer.clientWidth / 2);
}

private _showSnapLines(horizontal: number, vertical: number) {
this._snapLineHorizontal.style.top = `${horizontal}px`;
this._snapLineVertical1.style.left = `${vertical}px`;
this._snapLineVertical2.style.left = `${vertical + this._quickInputContainer.clientWidth}px`;

this._snapLineHorizontal.classList.remove('hidden');
this._snapLineVertical1.classList.remove('hidden');
this._snapLineVertical2.classList.remove('hidden');
}

private _hideSnapLines() {
this._snapLineHorizontal.classList.add('hidden');
this._snapLineVertical1.classList.add('hidden');
this._snapLineVertical2.classList.add('hidden');
}
}
Loading

0 comments on commit a960359

Please sign in to comment.