mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-20 17:22:51 -05:00
* Fix initial build breaks from 1.67 merge (#2514) * Update yarn lock files * Update build scripts * Fix tsconfig * Build breaks * WIP * Update yarn lock files * Misc breaks * Updates to package.json * Breaks * Update yarn * Fix breaks * Breaks * Build breaks * Breaks * Breaks * Breaks * Breaks * Breaks * Missing file * Breaks * Breaks * Breaks * Breaks * Breaks * Fix several runtime breaks (#2515) * Missing files * Runtime breaks * Fix proxy ordering issue * Remove commented code * Fix breaks with opening query editor * Fix post merge break * Updates related to setup build and other breaks (#2516) * Fix bundle build issues * Update distro * Fix distro merge and update build JS files * Disable pipeline steps * Remove stats call * Update license name * Make new RPM dependencies a warning * Fix extension manager version checks * Update JS file * Fix a few runtime breaks * Fixes * Fix runtime issues * Fix build breaks * Update notebook tests (part 1) * Fix broken tests * Linting errors * Fix hygiene * Disable lint rules * Bump distro * Turn off smoke tests * Disable integration tests * Remove failing "activate" test * Remove failed test assertion * Disable other broken test * Disable query history tests * Disable extension unit tests * Disable failing tasks
207 lines
6.2 KiB
TypeScript
207 lines
6.2 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import { Editors } from './editors';
|
|
import { Code } from './code';
|
|
import { QuickInput } from './quickinput';
|
|
import { basename, isAbsolute } from 'path';
|
|
|
|
enum QuickAccessKind {
|
|
Files = 1,
|
|
Commands,
|
|
Symbols
|
|
}
|
|
|
|
export class QuickAccess {
|
|
|
|
constructor(private code: Code, private editors: Editors, private quickInput: QuickInput) { }
|
|
|
|
async openFileQuickAccessAndWait(searchValue: string, expectedFirstElementNameOrExpectedResultCount: string | number): Promise<void> {
|
|
|
|
// make sure the file quick access is not "polluted"
|
|
// with entries from the editor history when opening
|
|
await this.runCommand('workbench.action.clearEditorHistory');
|
|
|
|
const PollingStrategy = {
|
|
Stop: true,
|
|
Continue: false
|
|
};
|
|
|
|
let retries = 0;
|
|
let success = false;
|
|
|
|
while (++retries < 10) {
|
|
let retry = false;
|
|
|
|
try {
|
|
await this.openQuickAccessWithRetry(QuickAccessKind.Files, searchValue);
|
|
await this.quickInput.waitForQuickInputElements(elementNames => {
|
|
this.code.logger.log('QuickAccess: resulting elements: ', elementNames);
|
|
|
|
// Quick access seems to be still running -> retry
|
|
if (elementNames.length === 0) {
|
|
this.code.logger.log('QuickAccess: file search returned 0 elements, will continue polling...');
|
|
|
|
return PollingStrategy.Continue;
|
|
}
|
|
|
|
// Quick access does not seem healthy/ready -> retry
|
|
const firstElementName = elementNames[0];
|
|
if (firstElementName === 'No matching results') {
|
|
this.code.logger.log(`QuickAccess: file search returned "No matching results", will retry...`);
|
|
|
|
retry = true;
|
|
|
|
return PollingStrategy.Stop;
|
|
}
|
|
|
|
// Expected: number of results
|
|
if (typeof expectedFirstElementNameOrExpectedResultCount === 'number') {
|
|
if (elementNames.length === expectedFirstElementNameOrExpectedResultCount) {
|
|
success = true;
|
|
|
|
return PollingStrategy.Stop;
|
|
}
|
|
|
|
this.code.logger.log(`QuickAccess: file search returned ${elementNames.length} results but was expecting ${expectedFirstElementNameOrExpectedResultCount}, will retry...`);
|
|
|
|
retry = true;
|
|
|
|
return PollingStrategy.Stop;
|
|
}
|
|
|
|
// Expected: string
|
|
else {
|
|
if (firstElementName === expectedFirstElementNameOrExpectedResultCount) {
|
|
success = true;
|
|
|
|
return PollingStrategy.Stop;
|
|
}
|
|
|
|
this.code.logger.log(`QuickAccess: file search returned ${firstElementName} as first result but was expecting ${expectedFirstElementNameOrExpectedResultCount}, will retry...`);
|
|
|
|
retry = true;
|
|
|
|
return PollingStrategy.Stop;
|
|
}
|
|
});
|
|
} catch (error) {
|
|
this.code.logger.log(`QuickAccess: file search waitForQuickInputElements threw an error ${error}, will retry...`);
|
|
|
|
retry = true;
|
|
}
|
|
|
|
if (!retry) {
|
|
break;
|
|
}
|
|
|
|
await this.quickInput.closeQuickInput();
|
|
}
|
|
|
|
if (!success) {
|
|
if (typeof expectedFirstElementNameOrExpectedResultCount === 'string') {
|
|
throw new Error(`Quick open file search was unable to find '${expectedFirstElementNameOrExpectedResultCount}' after 10 attempts, giving up.`);
|
|
} else {
|
|
throw new Error(`Quick open file search was unable to find ${expectedFirstElementNameOrExpectedResultCount} result items after 10 attempts, giving up.`);
|
|
}
|
|
}
|
|
}
|
|
|
|
async openFile(path: string): Promise<void> {
|
|
if (!isAbsolute(path)) {
|
|
// we require absolute paths to get a single
|
|
// result back that is unique and avoid hitting
|
|
// the search process to reduce chances of
|
|
// search needing longer.
|
|
throw new Error('QuickAccess.openFile requires an absolute path');
|
|
}
|
|
|
|
const fileName = basename(path);
|
|
|
|
// quick access shows files with the basename of the path
|
|
await this.openFileQuickAccessAndWait(path, basename(path));
|
|
|
|
// open first element
|
|
await this.quickInput.selectQuickInputElement(0);
|
|
|
|
// wait for editor being focused
|
|
await this.editors.waitForActiveTab(fileName);
|
|
await this.editors.selectTab(fileName);
|
|
}
|
|
|
|
private async openQuickAccessWithRetry(kind: QuickAccessKind, value?: string): Promise<void> {
|
|
let retries = 0;
|
|
|
|
// Other parts of code might steal focus away from quickinput :(
|
|
while (retries < 5) {
|
|
|
|
// Open via keybinding
|
|
switch (kind) {
|
|
case QuickAccessKind.Files:
|
|
await this.code.dispatchKeybinding(process.platform === 'darwin' ? 'cmd+p' : 'ctrl+p');
|
|
break;
|
|
case QuickAccessKind.Symbols:
|
|
await this.code.dispatchKeybinding(process.platform === 'darwin' ? 'cmd+shift+o' : 'ctrl+shift+o');
|
|
break;
|
|
case QuickAccessKind.Commands:
|
|
await this.code.dispatchKeybinding(process.platform === 'darwin' ? 'cmd+shift+p' : 'ctrl+shift+p');
|
|
break;
|
|
}
|
|
|
|
// Await for quick input widget opened
|
|
try {
|
|
await this.quickInput.waitForQuickInputOpened(10);
|
|
break;
|
|
} catch (err) {
|
|
if (++retries > 5) {
|
|
throw new Error(`QuickAccess.openQuickAccessWithRetry(kind: ${kind}) failed: ${err}`);
|
|
}
|
|
|
|
// Retry
|
|
await this.code.dispatchKeybinding('escape');
|
|
}
|
|
}
|
|
|
|
// Type value if any
|
|
if (value) {
|
|
await this.quickInput.type(value);
|
|
}
|
|
}
|
|
|
|
async runCommand(commandId: string, keepOpen?: boolean): Promise<void> {
|
|
|
|
// open commands picker
|
|
await this.openQuickAccessWithRetry(QuickAccessKind.Commands, `>${commandId}`);
|
|
|
|
// wait for best choice to be focused
|
|
await this.quickInput.waitForQuickInputElementFocused();
|
|
|
|
// wait and click on best choice
|
|
await this.quickInput.selectQuickInputElement(0, keepOpen);
|
|
}
|
|
|
|
async openQuickOutline(): Promise<void> {
|
|
let retries = 0;
|
|
|
|
while (++retries < 10) {
|
|
|
|
// open quick outline via keybinding
|
|
await this.openQuickAccessWithRetry(QuickAccessKind.Symbols);
|
|
|
|
const text = await this.quickInput.waitForQuickInputElementText();
|
|
|
|
// Retry for as long as no symbols are found
|
|
if (text === 'No symbol information for the file') {
|
|
this.code.logger.log(`QuickAccess: openQuickOutline indicated 'No symbol information for the file', will retry...`);
|
|
|
|
// close and retry
|
|
await this.quickInput.closeQuickInput();
|
|
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|