Reputation: 28633
In package.json
you can add a command to the File Explorer context menu.
In File Explorer you can select multiple files but my command only gets the last selected file URI as argument.
Can I get a list of all the selected files in the File Explorer?
Upvotes: 2
Views: 1469
Reputation: 180785
You could look at my extension Find and Transform to see how I parse multiple files when an explorer context menu command is triggered. [There is some extra code in there because that command can be triggered by a keybinding or explorer/editor/tab menus so they have to be handled differently.]
let contextMenuCommandFile = vscode.commands.registerCommand('find-and-transform.searchInFile', async (...commandArgs) => {
let args = {};
if (commandArgs?.length === 1 && !(commandArgs[0] instanceof vscode.Uri)) { // if from keybinding
let argsArray = Object.entries(commandArgs[0]).filter(arg => {
return searchCommands.getKeys().includes(arg[0]);
});
Object.assign(args, Object.fromEntries(argsArray));
}
args.filesToInclude = await parseCommands.parseArgs(commandArgs, "file");
args.triggerSearch = true;
searchCommands.useSearchPanel(args);
});
context.subscriptions.push(contextMenuCommandFile);
You might be missing this async (...commandArgs) => {
to get all available passed arguments into an array.
...commandArgs
will be of length 1 if coming from a keybinding and length 2 if trigggered from the context menu no matter how many files were selected in the Explorer before right-clicking on one and choosing the command.
commandArgs[0]
is the single file (i.e., the last file) on which I right-clicked.
commandsArgs[1]
is itself an array of all the selected files in the explorer.
I then send that commandArgs
array to be parsed (since I just need a comma-separated list of the files selected) to parseCommands.parseArgs()
[okay, strangely-named function!).
The operative bit there is:
else if (commandArgs[1][0] instanceof vscode.Uri) { // explorer/context
for (const resource of commandArgs[1]) {
const thisResource = vscode.workspace.asRelativePath(resource.fsPath);
resources += `${ thisResource }, `;
}
resources = resources.substring(0, resources.length - 2); // strip ', ' off end
return resources;
}
It would probably be better to use:
vscode.commands.registerCommand('find-and-transform.searchInFile', async (contextSelection: vscode.Uri, allSelections: vscode.Uri[]) => {
which splits the ...commandArgs
from above into its constituent parts: the item right-clicked on contextSelection
and the array of all selections allSelections
. Then you don't need notation like commandArgs[1]
to refer to all the selections but could use the simpler allSelections
.
Thanks to @PeterWone at https://stackoverflow.com/a/75533230/836330.
Upvotes: 1