mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c (#8525)
* Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c * remove files we don't want * fix hygiene * update distro * update distro * fix hygiene * fix strict nulls * distro * distro * fix tests * fix tests * add another edit * fix viewlet icon * fix azure dialog * fix some padding * fix more padding issues
This commit is contained in:
186
extensions/search-result/src/extension.ts
Normal file
186
extensions/search-result/src/extension.ts
Normal file
@@ -0,0 +1,186 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as pathUtils from 'path';
|
||||
|
||||
const FILE_LINE_REGEX = /^(\S.*):$/;
|
||||
const RESULT_LINE_REGEX = /^(\s+)(\d+):(\s+)(.*)$/;
|
||||
const SEARCH_RESULT_SELECTOR = { language: 'search-result' };
|
||||
|
||||
let cachedLastParse: { version: number, parse: ParsedSearchResults } | undefined;
|
||||
|
||||
export function activate() {
|
||||
|
||||
vscode.commands.registerCommand('searchResult.rerunSearch', () => vscode.commands.executeCommand('search.action.rerunEditorSearch'));
|
||||
|
||||
vscode.languages.registerDocumentSymbolProvider(SEARCH_RESULT_SELECTOR, {
|
||||
provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): vscode.DocumentSymbol[] {
|
||||
const results = parseSearchResults(document, token)
|
||||
.filter(isFileLine)
|
||||
.map(line => new vscode.DocumentSymbol(
|
||||
line.path,
|
||||
'',
|
||||
vscode.SymbolKind.File,
|
||||
line.allLocations.map(({ originSelectionRange }) => originSelectionRange!).reduce((p, c) => p.union(c), line.location.originSelectionRange!),
|
||||
line.location.originSelectionRange!,
|
||||
));
|
||||
|
||||
return results;
|
||||
}
|
||||
});
|
||||
|
||||
vscode.languages.registerCompletionItemProvider(SEARCH_RESULT_SELECTOR, {
|
||||
provideCompletionItems(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem[] {
|
||||
|
||||
const line = document.lineAt(position.line);
|
||||
if (position.line > 3) { return []; }
|
||||
if (position.character === 0 || (position.character === 1 && line.text === '#')) {
|
||||
const header = Array.from({ length: 4 }).map((_, i) => document.lineAt(i).text);
|
||||
|
||||
return ['# Query:', '# Flags:', '# Including:', '# Excluding:']
|
||||
.filter(suggestion => header.every(line => line.indexOf(suggestion) === -1))
|
||||
.map(flag => ({ label: flag, insertText: (flag.slice(position.character)) + ' ' }));
|
||||
}
|
||||
|
||||
if (line.text.indexOf('# Flags:') === -1) { return []; }
|
||||
|
||||
return ['RegExp', 'CaseSensitive', 'IgnoreExcludeSettings', 'WordMatch']
|
||||
.filter(flag => line.text.indexOf(flag) === -1)
|
||||
.map(flag => ({ label: flag, insertText: flag + ' ' }));
|
||||
}
|
||||
}, '#');
|
||||
|
||||
vscode.languages.registerDefinitionProvider(SEARCH_RESULT_SELECTOR, {
|
||||
provideDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): vscode.DefinitionLink[] {
|
||||
const lineResult = parseSearchResults(document, token)[position.line];
|
||||
if (!lineResult) { return []; }
|
||||
if (lineResult.type === 'file') {
|
||||
// TODO: The multi-match peek UX isnt very smooth.
|
||||
// return lineResult.allLocations.length > 1 ? lineResult.allLocations : [lineResult.location];
|
||||
return [];
|
||||
}
|
||||
|
||||
return [lineResult.location];
|
||||
}
|
||||
});
|
||||
|
||||
vscode.languages.registerDocumentLinkProvider(SEARCH_RESULT_SELECTOR, {
|
||||
async provideDocumentLinks(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.DocumentLink[]> {
|
||||
return parseSearchResults(document, token)
|
||||
.filter(({ type }) => type === 'file')
|
||||
.map(({ location }) => ({ range: location.originSelectionRange!, target: location.targetUri }));
|
||||
}
|
||||
});
|
||||
|
||||
vscode.window.onDidChangeActiveTextEditor(e => {
|
||||
if (e?.document.languageId === 'search-result') {
|
||||
// Clear the parse whenever we open a new editor.
|
||||
// Conservative because things like the URI might remain constant even if the contents change, and re-parsing even large files is relatively fast.
|
||||
cachedLastParse = undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function relativePathToUri(path: string, resultsUri: vscode.Uri): vscode.Uri | undefined {
|
||||
if (pathUtils.isAbsolute(path)) { return vscode.Uri.file(path); }
|
||||
if (path.indexOf('~/') === 0) {
|
||||
return vscode.Uri.file(pathUtils.join(process.env.HOME!, path.slice(2)));
|
||||
}
|
||||
|
||||
|
||||
if (vscode.workspace.workspaceFolders) {
|
||||
const multiRootFormattedPath = /^(.*) • (.*)$/.exec(path);
|
||||
if (multiRootFormattedPath) {
|
||||
const [, workspaceName, workspacePath] = multiRootFormattedPath;
|
||||
const folder = vscode.workspace.workspaceFolders.filter(wf => wf.name === workspaceName)[0];
|
||||
if (folder) {
|
||||
return vscode.Uri.file(pathUtils.join(folder.uri.fsPath, workspacePath));
|
||||
}
|
||||
}
|
||||
|
||||
else if (vscode.workspace.workspaceFolders.length === 1) {
|
||||
return vscode.Uri.file(pathUtils.join(vscode.workspace.workspaceFolders[0].uri.fsPath, path));
|
||||
} else if (resultsUri.scheme !== 'untitled') {
|
||||
// We're in a multi-root workspace, but the path is not multi-root formatted
|
||||
// Possibly a saved search from a single root session. Try checking if the search result document's URI is in a current workspace folder.
|
||||
const prefixMatch = vscode.workspace.workspaceFolders.filter(wf => resultsUri.toString().startsWith(wf.uri.toString()))[0];
|
||||
if (prefixMatch) { return vscode.Uri.file(pathUtils.join(prefixMatch.uri.fsPath, path)); }
|
||||
}
|
||||
}
|
||||
|
||||
console.error(`Unable to resolve path ${path}`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
type ParsedSearchFileLine = { type: 'file', location: vscode.LocationLink, allLocations: vscode.LocationLink[], path: string };
|
||||
type ParsedSearchResultLine = { type: 'result', location: vscode.LocationLink };
|
||||
type ParsedSearchResults = Array<ParsedSearchFileLine | ParsedSearchResultLine>;
|
||||
const isFileLine = (line: ParsedSearchResultLine | ParsedSearchFileLine): line is ParsedSearchFileLine => line.type === 'file';
|
||||
|
||||
|
||||
function parseSearchResults(document: vscode.TextDocument, token: vscode.CancellationToken): ParsedSearchResults {
|
||||
|
||||
if (cachedLastParse && cachedLastParse.version === document.version) {
|
||||
return cachedLastParse.parse;
|
||||
}
|
||||
|
||||
const lines = document.getText().split(/\r?\n/);
|
||||
const links: ParsedSearchResults = [];
|
||||
|
||||
let currentTarget: vscode.Uri | undefined = undefined;
|
||||
let currentTargetLocations: vscode.LocationLink[] | undefined = undefined;
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (token.isCancellationRequested) { return []; }
|
||||
const line = lines[i];
|
||||
|
||||
const fileLine = FILE_LINE_REGEX.exec(line);
|
||||
if (fileLine) {
|
||||
const [, path] = fileLine;
|
||||
|
||||
currentTarget = relativePathToUri(path, document.uri);
|
||||
if (!currentTarget) { continue; }
|
||||
currentTargetLocations = [];
|
||||
|
||||
const location: vscode.LocationLink = {
|
||||
targetRange: new vscode.Range(0, 0, 0, 1),
|
||||
targetUri: currentTarget,
|
||||
originSelectionRange: new vscode.Range(i, 0, i, line.length),
|
||||
};
|
||||
|
||||
|
||||
links[i] = { type: 'file', location, allLocations: currentTargetLocations, path };
|
||||
}
|
||||
|
||||
if (!currentTarget) { continue; }
|
||||
|
||||
const resultLine = RESULT_LINE_REGEX.exec(line);
|
||||
if (resultLine) {
|
||||
const [, indentation, _lineNumber, resultIndentation] = resultLine;
|
||||
const lineNumber = +_lineNumber - 1;
|
||||
const resultStart = (indentation + _lineNumber + ':' + resultIndentation).length;
|
||||
|
||||
const location: vscode.LocationLink = {
|
||||
targetRange: new vscode.Range(Math.max(lineNumber - 3, 0), 0, lineNumber + 3, line.length),
|
||||
targetSelectionRange: new vscode.Range(lineNumber, 0, lineNumber, line.length),
|
||||
targetUri: currentTarget,
|
||||
originSelectionRange: new vscode.Range(i, resultStart, i, line.length),
|
||||
};
|
||||
|
||||
currentTargetLocations?.push(location);
|
||||
|
||||
links[i] = { type: 'result', location };
|
||||
}
|
||||
}
|
||||
|
||||
cachedLastParse = {
|
||||
version: document.version,
|
||||
parse: links
|
||||
};
|
||||
|
||||
return links;
|
||||
}
|
||||
4
extensions/search-result/src/media/refresh-dark.svg
Normal file
4
extensions/search-result/src/media/refresh-dark.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.56253 2.51577C3.46348 3.4501 2 5.55414 2 7.99999C2 11.3137 4.68629 14 8 14C11.3137 14 14 11.3137 14 7.99999C14 5.32519 12.2497 3.05919 9.83199 2.28482L9.52968 3.23832C11.5429 3.88454 13 5.7721 13 7.99999C13 10.7614 10.7614 13 8 13C5.23858 13 3 10.7614 3 7.99999C3 6.31104 3.83742 4.81767 5.11969 3.91245L5.56253 2.51577Z" fill="#C5C5C5"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 3H2V2H5.5L6 2.5V6H5V3Z" fill="#C5C5C5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 587 B |
4
extensions/search-result/src/media/refresh-light.svg
Normal file
4
extensions/search-result/src/media/refresh-light.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.56253 2.51577C3.46348 3.4501 2 5.55414 2 7.99999C2 11.3137 4.68629 14 8 14C11.3137 14 14 11.3137 14 7.99999C14 5.32519 12.2497 3.05919 9.83199 2.28482L9.52968 3.23832C11.5429 3.88454 13 5.7721 13 7.99999C13 10.7614 10.7614 13 8 13C5.23858 13 3 10.7614 3 7.99999C3 6.31104 3.83742 4.81767 5.11969 3.91245L5.56253 2.51577Z" fill="#424242"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 3H2V2H5.5L6 2.5V6H5V3Z" fill="#424242"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 587 B |
7
extensions/search-result/src/typings/refs.d.ts
vendored
Normal file
7
extensions/search-result/src/typings/refs.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/// <reference path='../../../../src/vs/vscode.d.ts'/>
|
||||
/// <reference path='../../../../src/vs/vscode.proposed.d.ts'/>
|
||||
Reference in New Issue
Block a user