Get focused Explorer folder or file in an extension when command triggered by a shortcut, not by context menu

三世轮回 提交于 2021-01-28 12:11:57

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!