问题
A follow-on to this question: How to get file name or path in vscode extension when user right click on file in explorer/context?
My command expects to receive the uri to the item selected with a right-click; and in fact it does if I invoke the command by choosing it from the context menu....
If, however, I bind a shortcut key to this command (and correctly set the "when" context to only activate when explorer has focus) I do not receive the uri; that parameter is undefined
.
Obviously there are plenty of "built-in" commands ("Reveal in File Explorer" -- Shift+Alt+R) that function they way I would like my own to command operate.
What's the trick to getting the uri to my own command when invoked with a keyboard shortcut?
回答1:
There is a hint in a related issue: Get selected file/folder in the Explorer view.
It is suggested to use
vscode.commands.executeCommand('copyFilePath');
see https://github.com/Microsoft/vscode/issues/3553#issuecomment-438969485
so I investigated that and it can work like this:
async function activate(context) {
let createFile = vscode.commands.registerCommand('folder-operations.createFile', async (folder) => {
// use this if triggered by a menu item,
let newUri = folder; // folder will be undefined when triggered by keybinding
if (!folder) { // so triggered by a keybinding
await vscode.commands.executeCommand('copyFilePath');
folder = await vscode.env.clipboard.readText(); // returns a string
// see note below for parsing multiple files/folders
newUri = await vscode.Uri.file(folder); // make it a Uri
}
createFileOpen(newUri); // use in some function
});
context.subscriptions.push(createFile);
}
NOTE :
This works when multiple folders or files are selected as well. Then folder = await vscode.env.clipboard.readText();
will return something like (on W10):
"C:\\Users\\Mark\\OneDrive\\Test Bed\\zip\r\nC:\\Users\\Mark\\OneDrive\\Test Bed\\zipMultiple"
when two folders, zip
and zipMultiple
in this case, are selected and then the keybinding is triggered for the folder-operations.createFile
command. So you would have to parse/split that string to get the two folders selected. Same with multiple files.
Using some keybinding:
{
"key": "shift+alt+c",
"command": "folder-operations.createFile",
"when": "explorerResourceIsFolder && filesExplorerFocus"
}
Now this will work when some folder is focused in the Explorer and you trigger your keybinding. Demo creating a new file by keybinding:
回答2:
The arguments you get with your keybindings.json
defined key binding is the args
property of the key binding.
In VSC the key bindings are defined different. The command is a function of the key binding and it gets special arguments.
In file src/vs/workbench/contrib/files/electron-browser/fileActions.contribution.ts
const REVEAL_IN_OS_COMMAND_ID = 'revealFileInOS';
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: REVEAL_IN_OS_COMMAND_ID,
weight: KeybindingWeight.WorkbenchContrib,
when: EditorContextKeys.focus.toNegated(),
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_R,
win: {
primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_R
},
handler: (accessor: ServicesAccessor, resource: URI | object) => {
const resources = getMultiSelectedResources(resource, accessor.get(IListService), accessor.get(IEditorService), accessor.get(IExplorerService));
revealResourcesInOS(resources, accessor.get(IElectronService), accessor.get(INotificationService), accessor.get(IWorkspaceContextService));
}
});
In extensions we can't get an object that has the focus.
So the extension has no way of getting the "TreeView" of the File Explorer.
vscode.window
also does not allow us to get to some of the GUI elements.
来源:https://stackoverflow.com/questions/62945928/get-focused-explorer-folder-or-file-in-an-extension-when-command-triggered-by-a