Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File search functionality on vscode for web #790

Merged
merged 10 commits into from
Jan 25, 2024
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
"displayName": "Power Platform Tools",
"description": "Tooling to create Power Platform solutions & packages, manage Power Platform environments and edit Power Apps Portals",
"version": "1.0.1-dev",
"enabledApiProposals": [
"fileSearchProvider",
"textSearchProvider"
],
"scripts": {
"clean": "scorch",
"build": "node node_modules/gulp/bin/gulp.js",
Expand Down
69 changes: 69 additions & 0 deletions src/typings/vscode.proposed.fileSearchProvider.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/



declare module 'vscode' {

// https://github.com/microsoft/vscode/issues/73524

/**
* The parameters of a query for file search.
*/
export interface FileSearchQuery {
/**
* The search pattern to match against file paths.
*/
pattern: string;
}

/**
* Options that apply to file search.
*/
export interface FileSearchOptions extends SearchOptions {
/**
* The maximum number of results to be returned.
*/
maxResults?: number;

/**
* A CancellationToken that represents the session for this search query. If the provider chooses to, this object can be used as the key for a cache,
* and searches with the same session object can search the same cache. When the token is cancelled, the session is complete and the cache can be cleared.
*/
session?: CancellationToken;
}

/**
* A FileSearchProvider provides search results for files in the given folder that match a query string. It can be invoked by quickopen or other extensions.
*
* A FileSearchProvider is the more powerful of two ways to implement file search in the editor. Use a FileSearchProvider if you wish to search within a folder for
* all files that match the user's query.
*
* The FileSearchProvider will be invoked on every keypress in quickopen. When `workspace.findFiles` is called, it will be invoked with an empty query string,
* and in that case, every file in the folder should be returned.
*/
export interface FileSearchProvider {
/**
* Provide the set of files that match a certain file path pattern.
* @param query The parameters for this query.
* @param options A set of options to consider while searching files.
* @param token A cancellation token.
*/
provideFileSearchResults(query: FileSearchQuery, options: FileSearchOptions, token: CancellationToken): ProviderResult<Uri[]>;
}

export namespace workspace {
/**
* Register a search provider.
*
* Only one provider can be registered per scheme.
*
* @param scheme The provider will be invoked for workspace folders that have this file scheme.
* @param provider The provider.
* @return A {@link Disposable} that unregisters this provider when being disposed.
*/
export function registerFileSearchProvider(scheme: string, provider: FileSearchProvider): Disposable;
}
}
283 changes: 283 additions & 0 deletions src/typings/vscode.proposed.textSearchProvider.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/



declare module 'vscode' {

// https://github.com/microsoft/vscode/issues/59921

/**
* The parameters of a query for text search.
*/
export interface TextSearchQuery {
/**
* The text pattern to search for.
*/
pattern: string;

/**
* Whether or not `pattern` should match multiple lines of text.
*/
isMultiline?: boolean;

/**
* Whether or not `pattern` should be interpreted as a regular expression.
*/
isRegExp?: boolean;

/**
* Whether or not the search should be case-sensitive.
*/
isCaseSensitive?: boolean;

/**
* Whether or not to search for whole word matches only.
*/
isWordMatch?: boolean;
}

/**
* A file glob pattern to match file paths against.
* TODO@roblourens merge this with the GlobPattern docs/definition in vscode.d.ts.
* @see {@link GlobPattern}
*/
export type GlobString = string;

/**
* Options common to file and text search
*/
export interface SearchOptions {
/**
* The root folder to search within.
*/
folder: Uri;

/**
* Files that match an `includes` glob pattern should be included in the search.
*/
includes: GlobString[];

/**
* Files that match an `excludes` glob pattern should be excluded from the search.
*/
excludes: GlobString[];

/**
* Whether external files that exclude files, like .gitignore, should be respected.
* See the vscode setting `"search.useIgnoreFiles"`.
*/
useIgnoreFiles: boolean;

/**
* Whether symlinks should be followed while searching.
* See the vscode setting `"search.followSymlinks"`.
*/
followSymlinks: boolean;

/**
* Whether global files that exclude files, like .gitignore, should be respected.
* See the vscode setting `"search.useGlobalIgnoreFiles"`.
*/
useGlobalIgnoreFiles: boolean;

/**
* Whether files in parent directories that exclude files, like .gitignore, should be respected.
* See the vscode setting `"search.useParentIgnoreFiles"`.
*/
useParentIgnoreFiles: boolean;
}

/**
* Options to specify the size of the result text preview.
* These options don't affect the size of the match itself, just the amount of preview text.
*/
export interface TextSearchPreviewOptions {
/**
* The maximum number of lines in the preview.
* Only search providers that support multiline search will ever return more than one line in the match.
*/
matchLines: number;

/**
* The maximum number of characters included per line.
*/
charsPerLine: number;
}

/**
* Options that apply to text search.
*/
export interface TextSearchOptions extends SearchOptions {
/**
* The maximum number of results to be returned.
*/
maxResults: number;

/**
* Options to specify the size of the result text preview.
*/
previewOptions?: TextSearchPreviewOptions;

/**
* Exclude files larger than `maxFileSize` in bytes.
*/
maxFileSize?: number;

/**
* Interpret files using this encoding.
* See the vscode setting `"files.encoding"`
*/
encoding?: string;

/**
* Number of lines of context to include before each match.
*/
beforeContext?: number;

/**
* Number of lines of context to include after each match.
*/
afterContext?: number;
}

/**
* Represents the severity of a TextSearchComplete message.
*/
export enum TextSearchCompleteMessageType {
Information = 1,
Warning = 2,
}

/**
* A message regarding a completed search.
*/
export interface TextSearchCompleteMessage {
/**
* Markdown text of the message.
*/
text: string;
/**
* Whether the source of the message is trusted, command links are disabled for untrusted message sources.
* Messaged are untrusted by default.
*/
trusted?: boolean;
/**
* The message type, this affects how the message will be rendered.
*/
type: TextSearchCompleteMessageType;
}

/**
* Information collected when text search is complete.
*/
export interface TextSearchComplete {
/**
* Whether the search hit the limit on the maximum number of search results.
* `maxResults` on {@linkcode TextSearchOptions} specifies the max number of results.
* - If exactly that number of matches exist, this should be false.
* - If `maxResults` matches are returned and more exist, this should be true.
* - If search hits an internal limit which is less than `maxResults`, this should be true.
*/
limitHit?: boolean;

/**
* Additional information regarding the state of the completed search.
*
* Messages with "Information" style support links in markdown syntax:
* - Click to [run a command](command:workbench.action.OpenQuickPick)
* - Click to [open a website](https://aka.ms)
*
* Commands may optionally return { triggerSearch: true } to signal to the editor that the original search should run be again.
*/
message?: TextSearchCompleteMessage | TextSearchCompleteMessage[];
}

/**
* A preview of the text result.
*/
export interface TextSearchMatchPreview {
/**
* The matching lines of text, or a portion of the matching line that contains the match.
*/
text: string;

/**
* The Range within `text` corresponding to the text of the match.
* The number of matches must match the TextSearchMatch's range property.
*/
matches: Range | Range[];
}

/**
* A match from a text search
*/
export interface TextSearchMatch {
/**
* The uri for the matching document.
*/
uri: Uri;

/**
* The range of the match within the document, or multiple ranges for multiple matches.
*/
ranges: Range | Range[];

/**
* A preview of the text match.
*/
preview: TextSearchMatchPreview;
}

/**
* A line of context surrounding a TextSearchMatch.
*/
export interface TextSearchContext {
/**
* The uri for the matching document.
*/
uri: Uri;

/**
* One line of text.
* previewOptions.charsPerLine applies to this
*/
text: string;

/**
* The line number of this line of context.
*/
lineNumber: number;
}

export type TextSearchResult = TextSearchMatch | TextSearchContext;

/**
* A TextSearchProvider provides search results for text results inside files in the workspace.
*/
export interface TextSearchProvider {
/**
* Provide results that match the given text pattern.
* @param query The parameters for this query.
* @param options A set of options to consider while searching.
* @param progress A progress callback that must be invoked for all results.
* @param token A cancellation token.
*/
provideTextSearchResults(query: TextSearchQuery, options: TextSearchOptions, progress: Progress<TextSearchResult>, token: CancellationToken): ProviderResult<TextSearchComplete>;
}

export namespace workspace {
/**
* Register a text search provider.
*
* Only one provider can be registered per scheme.
*
* @param scheme The provider will be invoked for workspace folders that have this file scheme.
* @param provider The provider.
* @return A {@link Disposable} that unregisters this provider when being disposed.
*/
export function registerTextSearchProvider(scheme: string, provider: TextSearchProvider): Disposable;
}
}
15 changes: 15 additions & 0 deletions src/web/client/context/fileDataMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,19 @@ export class FileDataMap {
}
throw Error("File does not exist in the map"); // TODO - Revisit errors and dialog experience here
}

searchFiles(pattern: string) {
// create case sensitive regex
const regex = new RegExp(pattern, "i");

const files: FileData[] = [];
this.fileMap.forEach((fileData) => {
tyaginidhi marked this conversation as resolved.
Show resolved Hide resolved
const isMatch = regex.test(fileData.fileName);
if (isMatch) {
files.push(fileData);
}
});

return files;
}
}
Loading
Loading