Skip to content

Commit 732d648

Browse files
authored
Search provider (#6)
1 parent 2964030 commit 732d648

File tree

6 files changed

+2662
-5
lines changed

6 files changed

+2662
-5
lines changed

packages/ethereum-viewer/package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@
1515
},
1616
"dependencies": {
1717
"fast-json-stable-stringify": "^2.1.0",
18+
"match-sorter": "^6.3.1",
1819
"p-finally": "^2.0.1",
1920
"path-browserify": "^1.0.1",
2021
"ts-essentials": "^9.0.0"
2122
},
2223
"devDependencies": {
23-
"typescript": "^4.5.3",
24-
"@types/vscode": "^1.63.0"
24+
"@types/vscode": "^1.63.0",
25+
"typescript": "^4.5.3"
2526
},
2627
"engines": {
2728
"vscode": "^1.63.0"
@@ -32,6 +33,11 @@
3233
"categories": [
3334
"Other"
3435
],
36+
"enableProposedApi": true,
37+
"enabledApiProposals": [
38+
"fileSearchProvider",
39+
"textSearchProvider"
40+
],
3541
"activationEvents": [
3642
"*"
3743
],

packages/ethereum-viewer/src/extension.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import path from "path/posix";
21
import * as vscode from "vscode";
32

43
import { addresses } from "./addresses";
54
import * as etherscan from "./etherscan";
5+
import { StaticFileSearchProvider } from "./fileSearchProvider";
66
import { FileSystem } from "./filesystem";
77
import { fixtures } from "./test/fixtures";
8+
// import { StaticTextSearchProvider } from "./textSearchProvider";
89

910
let initialized = false;
1011
const fs = FileSystem();
@@ -36,7 +37,7 @@ async function main(context: vscode.ExtensionContext) {
3637
name: network,
3738
});
3839

39-
let contractAddress: string | null = addresses.DAI;
40+
let contractAddress: string | null = addresses.L1ChugSplashProxy;
4041

4142
if (IN_DETH_HOST)
4243
contractAddress = await vscode.commands.executeCommand<string | null>(
@@ -55,13 +56,26 @@ async function main(context: vscode.ExtensionContext) {
5556

5657
const mainFile = getMainContractFile(entries, info);
5758

59+
context.subscriptions.push(
60+
vscode.workspace.registerFileSearchProvider(
61+
"memfs",
62+
new StaticFileSearchProvider(entries.map(([path]) => path))
63+
)
64+
);
65+
// context.subscriptions.push(
66+
// vscode.workspace.registerTextSearchProvider(
67+
// "memfs",
68+
// new StaticTextSearchProvider(entries)
69+
// )
70+
// );
71+
5872
// We're instead trying to open the file even if it doesn't exist yet.
5973
await showTextDocument(mainFile);
6074
// This seems to be very slow:
6175
// // onFileChangeOnce(
6276
// // context,
6377
// // fs,
64-
// // mainFile,
78+
// // mainFile,
6579
// // (e) => void showTextDocument(e.uri.path)
6680
// // );
6781
// It's causing some errors in the console, but in the end it provides better UX.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { matchSorter } from "match-sorter";
2+
import {
3+
CancellationToken,
4+
Disposable,
5+
FileSearchOptions,
6+
FileSearchProvider,
7+
FileSearchQuery,
8+
ProviderResult,
9+
Uri,
10+
} from "vscode";
11+
12+
export class StaticFileSearchProvider
13+
implements FileSearchProvider, Disposable
14+
{
15+
static scheme = "github1s";
16+
private readonly disposable?: Disposable;
17+
18+
// HACK: We don't support searching for added files.
19+
constructor(private filePaths: string[]) {}
20+
21+
dispose() {
22+
this.disposable?.dispose();
23+
}
24+
25+
provideFileSearchResults(
26+
query: FileSearchQuery,
27+
_options: FileSearchOptions,
28+
_token: CancellationToken
29+
): ProviderResult<Uri[]> {
30+
return matchSorter(this.filePaths, query.pattern).map((path) =>
31+
Uri.from({ scheme: "memfs", path: path })
32+
);
33+
}
34+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import {
2+
CancellationToken,
3+
Disposable,
4+
Position,
5+
Progress,
6+
Range,
7+
TextSearchComplete,
8+
TextSearchOptions,
9+
TextSearchProvider,
10+
TextSearchQuery,
11+
TextSearchResult,
12+
Uri,
13+
} from "vscode";
14+
15+
export class StaticTextSearchProvider
16+
implements TextSearchProvider, Disposable
17+
{
18+
private readonly disposable?: Disposable;
19+
20+
constructor(
21+
private readonly files: readonly [string /* key */, string /* contents */][]
22+
) {}
23+
24+
dispose() {
25+
this.disposable?.dispose();
26+
}
27+
28+
provideTextSearchResults(
29+
query: TextSearchQuery,
30+
options: TextSearchOptions,
31+
progress: Progress<TextSearchResult>,
32+
_token: CancellationToken
33+
): TextSearchComplete {
34+
const matchesQuery = (content: string) => {
35+
let pattern = query.pattern;
36+
37+
if (!query.isCaseSensitive) {
38+
content = content.toLowerCase();
39+
pattern = pattern.toLowerCase();
40+
}
41+
42+
if (query.isRegExp) return content.match(new RegExp(pattern));
43+
44+
return content.includes(pattern);
45+
};
46+
47+
// @todo handle options.includes and options.excludes
48+
// @todo handle all options on query
49+
const files = this.files.filter(([, content]) => matchesQuery(content));
50+
51+
for (const [path, content] of files) {
52+
const lines = content.split("\n");
53+
const lineIndex = lines.findIndex(matchesQuery);
54+
const line = lines[lineIndex];
55+
if (line) {
56+
const lineNumber = lineIndex;
57+
console.log({ path, lineNumber, line })
58+
progress.report({
59+
uri: Uri.from({ scheme: "memfs", path: "/" + path }),
60+
lineNumber,
61+
text: line,
62+
ranges: [
63+
// This is really bad. I'm not handling column number at all.
64+
new Range(
65+
new Position(lineNumber, 0),
66+
new Position(lineNumber, line.length)
67+
),
68+
],
69+
preview: {
70+
text: line,
71+
matches: [
72+
new Range(
73+
new Position(lineNumber, 0),
74+
new Position(lineNumber, line.length)
75+
)
76+
],
77+
}
78+
});
79+
}
80+
}
81+
82+
return { limitHit: files.length >= options.maxResults };
83+
}
84+
}

0 commit comments

Comments
 (0)