Skip to content

Commit 90003f5

Browse files
committed
wip: path-intel
1 parent 532eb66 commit 90003f5

File tree

3 files changed

+223
-1
lines changed

3 files changed

+223
-1
lines changed

package.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"onLanguage:solidity",
3131
"onLanguage:json",
3232
"onLanguage:tree"
33-
],
33+
],
3434
"contributes": {
3535
"commands": [
3636
{
@@ -104,6 +104,14 @@
104104
"title": "Solidity Inspector",
105105
"properties": {}
106106
},
107+
"keybindings":[
108+
{
109+
"command": "vscode-solidity-inspector.pathIntel",
110+
"key": "ctrl+alt+x",
111+
"mac": "cmd+alt+x",
112+
"when": "editorTextFocus"
113+
}
114+
],
107115
"menus": {
108116
"explorer/context": [
109117
{

src/commands/path-intel.js

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
const vscode = require("vscode");
2+
const path = require("path");
3+
const fs = require("fs");
4+
5+
6+
function pathIntel(context) {
7+
let disposable = vscode.commands.registerCommand("vscode-solidity-inspector" + ".pathIntel", async () => {
8+
const editor = vscode.window.activeTextEditor;
9+
if (!editor) {
10+
return; // No open text editor
11+
}
12+
13+
const document = editor.document;
14+
const position = editor.selection.start;
15+
const linePrefix = document.lineAt(position).text.substr(0, position.character);
16+
const match = linePrefix.match(/import\s+([A-Za-z0-9_]*)$/);
17+
18+
if (!match) {
19+
return; // No matching pattern
20+
}
21+
22+
const workspaceFolders = vscode.workspace.workspaceFolders;
23+
if (!workspaceFolders) {
24+
return; // No workspace folder open
25+
}
26+
27+
const rootPath = workspaceFolders[0].uri.fsPath;
28+
const remappingsPath = path.join(rootPath, 'remappings.txt');
29+
let remappings = {};
30+
31+
// Read and parse the remappings file
32+
if (fs.existsSync(remappingsPath)) {
33+
const remappingsContent = fs.readFileSync(remappingsPath, 'utf8');
34+
remappingsContent.split('\n').forEach(line => {
35+
const [key, val] = line.split('=');
36+
remappings[key.trim()] = val.trim();
37+
});
38+
}
39+
40+
const searchPattern = match[1] + '*.sol';
41+
const solidityFiles = await vscode.workspace.findFiles('**/' + searchPattern, '**/node_modules/**', 100);
42+
const filteredPaths = solidityFiles.map(file => {
43+
const relativePath = vscode.workspace.asRelativePath(file.path).replace(/\\/g, '/');
44+
return {
45+
label: path.basename(file.path),
46+
description: relativePath,
47+
fullPath: file.path
48+
};
49+
});
50+
51+
const pickedFile = await vscode.window.showQuickPick(filteredPaths, {
52+
placeHolder: 'Select a file',
53+
matchOnDescription: true
54+
});
55+
56+
if (pickedFile) {
57+
let finalPath = vscode.workspace.asRelativePath(pickedFile.fullPath).replace(/\\/g, '/');
58+
let isRemapped = false;
59+
60+
// Apply remappings
61+
Object.entries(remappings).forEach(([key, value]) => {
62+
if (finalPath.startsWith(value)) {
63+
finalPath = `${key}${finalPath.substring(value.length)}`;
64+
isRemapped = true;
65+
}
66+
});
67+
68+
if (!isRemapped) {
69+
// Calculate the relative path for non-remapped imports
70+
const currentFileDir = path.dirname(document.uri.fsPath);
71+
finalPath = path.relative(currentFileDir, pickedFile.fullPath).replace(/\\/g, '/');
72+
if (!finalPath.startsWith('.')) {
73+
finalPath = './' + finalPath; // Ensure it's recognized as a relative path
74+
}
75+
}
76+
77+
const contractName = path.basename(pickedFile.label, '.sol');
78+
const importStatement = `import {${contractName}} from "${finalPath}";`;
79+
80+
editor.edit(editBuilder => {
81+
editBuilder.replace(new vscode.Range(position.line, 0, position.line, linePrefix.length), importStatement);
82+
});
83+
}
84+
});
85+
86+
87+
context.subscriptions.push(disposable);
88+
}
89+
90+
module.exports = {pathIntel};
91+
92+
// class SolidityImportCompletionItemProvider {
93+
// constructor() {
94+
// this.filesCache = [];
95+
// this.lastCacheUpdate = Date.now();
96+
// this.remappings = {};
97+
// this.loadRemappings();
98+
// this.updateFilesCache(); // Initial cache update
99+
// }
100+
// async provideCompletionItems(document, position, token, context) {
101+
// const linePrefix = document.lineAt(position).text.substr(0, position.character);
102+
// if (!linePrefix.endsWith('import "') && !linePrefix.endsWith("import '")) {
103+
// return undefined;
104+
// }
105+
106+
// const currentFilePath = document.uri.fsPath;
107+
// const cacheAge = Date.now() - this.lastCacheUpdate;
108+
// if (this.filesCache.length === 0 || cacheAge > 10000) { // 10 seconds cache timeout
109+
// await this.updateFilesCache();
110+
// }
111+
112+
// return this.filesCache.map(filePath => {
113+
// const contractName = path.basename(filePath, '.sol');
114+
// console.log("contractName",contractName,filePath);
115+
// const relativeOrRemappedPath = this.getCompletionItemPath(filePath, currentFilePath);
116+
// console.log("contractName",contractName,filePath);
117+
118+
// const insertText = `import {${contractName}} from "${relativeOrRemappedPath}";`;
119+
120+
// const completionItem = new vscode.CompletionItem(contractName, vscode.CompletionItemKind.File);
121+
// completionItem.insertText = new vscode.SnippetString(insertText);
122+
// return completionItem;
123+
// });
124+
// }
125+
126+
127+
// async updateFilesCache() {
128+
// // Reset cache
129+
// this.filesCache = [];
130+
131+
// // Define the glob pattern for Solidity files
132+
// const solidityFilesGlob = '**/*.sol';
133+
// // Exclude node_modules from the search
134+
// const excludePattern = '**/node_modules/**';
135+
136+
// try {
137+
// const files = await vscode.workspace.findFiles(solidityFilesGlob, excludePattern);
138+
// this.filesCache = files.map(fileUri => vscode.workspace.asRelativePath(fileUri.path));
139+
140+
// this.lastCacheUpdate = Date.now();
141+
// } catch (error) {
142+
// console.error('Error updating Solidity files cache:', error);
143+
// }
144+
// }
145+
// loadRemappings() {
146+
// const workspaceFolders = vscode.workspace.workspaceFolders;
147+
// if (!workspaceFolders) return;
148+
149+
// const rootPath = workspaceFolders[0].uri.fsPath;
150+
// const remappingsPath = path.join(rootPath, 'remappings.txt');
151+
// if (fs.existsSync(remappingsPath)) {
152+
// const remappingsContent = fs.readFileSync(remappingsPath, 'utf8');
153+
// remappingsContent.split('\n').forEach(line => {
154+
// const [key, val] = line.split('=');
155+
// if (key && val) {
156+
// this.remappings[key.trim()] = val.trim();
157+
// }
158+
// });
159+
// }
160+
// }
161+
162+
// getCompletionItemPath(fileUri, currentFilePath) {
163+
// try {
164+
// const relativePath = vscode.workspace.asRelativePath(fileUri);
165+
// if (!relativePath) {
166+
// throw new Error('File is not within the workspace.');
167+
// }
168+
// const filePath = relativePath.replace(/\\/g, '/');
169+
170+
// // Apply remappings
171+
// for (const [remappedPrefix, remappedValue] of Object.entries(this.remappings)) {
172+
// if (filePath.startsWith(remappedValue)) {
173+
// return filePath.replace(remappedValue, remappedPrefix);
174+
// }
175+
// }
176+
177+
// // Calculate relative path if not remapped
178+
// const currentDir = path.dirname(currentFilePath);
179+
// let finalPath = path.relative(currentDir, fileUri.fsPath).replace(/\\/g, '/');
180+
// if (!finalPath.startsWith('.')) {
181+
// finalPath = './' + finalPath;
182+
// }
183+
// return finalPath;
184+
// } catch (error) {
185+
// console.error('Error while determining file path:', error.message);
186+
// // Return an empty string or handle the error as appropriate for your use case
187+
// return '';
188+
// }
189+
// }
190+
191+
192+
// async maybeUpdateCache() {
193+
// const cacheAge = Date.now() - this.lastCacheUpdate;
194+
// if (this.filesCache.length === 0 || cacheAge > 10000) { // E.g., 10 seconds cache timeout
195+
// await this.updateFilesCache();
196+
// }
197+
// }
198+
// }
199+
200+
201+
202+
// module.exports = {SolidityImportCompletionItemProvider};
203+
204+

src/extension.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ const { treeFilesCodeActionProvider, treeFilesDiagnosticCollection } = require("
3939

4040
const { scaffoldActiveFile, scaffoldContextMenu } = require("./commands/bulloak-scaffold");
4141

42+
const { pathIntel } = require("./commands/path-intel");
43+
44+
4245
/** global vars */
4346
const EXTENSION_PREFIX = "vscode-solidity-inspector";
4447

@@ -148,11 +151,18 @@ function onActivate(context) {
148151
context.subscriptions.push(scaffoldActiveFileSubscription);
149152
context.subscriptions.push(scaffoldContextMenuSubscription);
150153

154+
pathIntel(context);
155+
151156
vscode.window.visibleTextEditors.map(editor => {
152157
if (editor && editor.document && editor.document.languageId == "solidity") {
153158
unusedImportsActiveFile(editor);
154159
}
155160
});
161+
162+
// const provider = new SolidityImportCompletionItemProvider();
163+
// const selector = { language: 'solidity', scheme: 'file' };
164+
// const triggerCharacters = ['"', "'", "{"];
165+
// context.subscriptions.push(vscode.languages.registerCompletionItemProvider(selector, provider, ...triggerCharacters));
156166
}
157167
/* exports */
158168
exports.activate = onActivate;

0 commit comments

Comments
 (0)