microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
164.38k stars 29.32k forks source link

Get selected file/folder in the explorer view #3553

Open SamVerschueren opened 8 years ago

SamVerschueren commented 8 years ago

It would be nice if it was possible to retrieve the selected file/folder in the explorer view. The use case where I want to use it for is my vscode-yo extension to be able to run the generator in the selected directory. An API for this would be nice.

bpasero commented 8 years ago

@jrieken fyi

stef-levesque commented 8 years ago

This would be helpful for my vscode-hexdump extension, to retrieve selected file not compatible with TextDocument (i.e. png, jpg, ...). I wouldn't need to show an inputbox to ask for the file path everything :)

riteshatsencha commented 8 years ago

Second that. It will help us for the extension we are developing @Sencha. Here is the link to Stack Overflow question on the same feature.

fantacytyx commented 8 years ago

Some extension need retrieve selected file/folder, such as TortoiseSVN. If can get selected file/folder, even if not integrate SVN, also can be very convenient use SVN by contextmenu of explorer.

jrieken commented 8 years ago

Maybe the menus contribution we have added this summer helps anyone here. The contract is that when invoked from a resource (such as an explorer entry) its URI will be passed to the function

When a command is invoked from a (context) menu, VS Code tries to infer the currently selected resource and passes that as a parameter when invoking the command. For instance, a menu item inside the Explorer is passed the URI of the selected resource and a menu item inside an editor is passed the URI of the document.

fbricon commented 6 years ago

@jrieken executing a command from the menu, I get the uri as expected, except it doesn't work when that command is invoked from a KB shortcut (I get an empty parameter instead).

jrieken commented 6 years ago

except it doesn't work when that command is invoked from a KB shortcut

Yeah, thats the design of things as KB shortcuts are global (not contextual) by definition... It's like someone using you command-id with the executeCommand-api. The rule to always be prepared to be invoked without sufficient arguments. In those cases you need to figure them out by yourself. In this case by using an API that you don't have (yet)

dalvikroid commented 6 years ago

with some api or not?

alianZhen commented 6 years ago

I find out a way to get the path of selected folder. You can contribute a menu of explorer,then run the vscode.commands.executeCommand('copyFilePath');. You can get the value into your clipboard

akosyakov commented 5 years ago

In this case by using an API that you don't have (yet)

@jrieken Do you have an idea for API? Something like window.activeResource, that returns a current selected resource of an active part?

jrieken commented 5 years ago

no

matheus-sales commented 5 years ago

I too need this function for a plugin. Has forecast for implementation?

In Theia was implemented.

HenrikHolmIT commented 5 years ago

I need this feature now. Has it ever been implemented or is there another way to get the selected items in the explorer view?

I need to search for specific files but only in the currently selected folder.

smnbbrv commented 5 years ago

I was surprised today this feature is not existing.

Would be very convenient to have a way to get a list of selected files / folders as well.

fqzhang42 commented 4 years ago

This feature is still not there.

ctf0 commented 4 years ago

am not sure if this solve ur issue, but maybe this could help

and for the command

vscode.commands.registerCommand('extension.hello_world', (e) => {
    let path = e.fsPath

    // do ur work
})
HenrikHolmIT commented 4 years ago

@ctf0 It does not. Extension code is activated by either from the command pallette or a shortcut. There is no interaction with the context menu in the explorer view.

Instead I try to find the currently active editor and trace back form that file.

smurphy917 commented 4 years ago

Just to add my own use case here--I'm looking to enable users to select multiple files within the explorer, which my extension can then act on. As of right now, this doesn't appear to be possible without replicating the entire workspace folder structure in a custom TreeView (not even 100% sure it's possible then). I'd much prefer to just be able to retrieve the current list of selected files/folders on the OOTB explorer view.

DragonFlux commented 4 years ago

I would like to add my usecase as explained here: https://stackoverflow.com/questions/59909657/open-default-file-when-folder-is-selected-in-vscode

I believe we have a good variety of usecases now to back up this request!

ngarg-panw commented 4 years ago

I see that support for multi-file select is there in explorer view. In my extension i want to get the paths of all selected files. Right now, even if I select 5 files, i only get path for 1. I am not finding any relevant API. Do we have the API available for the same?

commonsensesoftware commented 4 years ago

To add to the party, I thought I'd add a related, but different use case. I am not and do not want to build an extension. I am trying to build a Debug task when working with Rust. Rust will build a separate executable per integration test file. The debugging experience works just fine, but changing the launch.json file all the time to choose a different startup item doesn't make sense. The simplest bridge would seem to be to choose the currently selected file, but there is no such variable for this. I can make it work with the ${file} variable, but only after opening the actual executable file and clicking through the Do you really want to open this file prompt. That's workable, but very clunky.

Having an API for extension authors, including Rust, would be great, but it seems there is a use case for just having a variable that exposes that information is also useful. An API would certainly be more comprehensive for multi-select and so. Two new variables that simply indicate the currently selected folder and file would seem to be congruent with the existing ${selectedText} variable.

ghost commented 4 years ago

+1 for wanting this!

rndware commented 3 years ago

@ctf0 I managed to get your solution to work partially.

In my use case I don't want to have to right click a file or folder in the explorer view each time I want to run my extension. Instead I want to use a simple keyboard shortcut.

I tried binding "extension.hello_world" to a keyboard shortcut in my keybindings.json:

    {
        "key": "ctrl+h",
        "command": "extension.hello_world",
        "when": "explorerViewletVisible && filesExplorerFocus"
    },

But if I'm focused on the explorer view and do <C+h> I find the following code:

vscode.commands.registerCommand('extension.hello_world', (e) => {
    let path = e.fsPath

    // do ur work
})

doesn't work as e comes back as 'undefined'.

ctf0 commented 3 years ago

@rndware the api is for right click and chosing a cmnd from the context menu,

there is actually a way to use the same cmnd for both context menu and cmnd pallet while checking later where the value is comming from, thats what i use in https://github.com/ctf0/vscode-file-shortcut

rndware commented 3 years ago

@ctf0 I just debugged the vscode-file-shortcut extension.

The extension gets the path from the window.activeTextEditor.document when triggered from a keybinding because e is undefined:

            let doc = window.activeTextEditor.document
            let path = e ? e.fsPath : doc.uri.fsPath

Which won't be the correct behaviour if a user is highlighting a different item in the explorer view than the current active text document. e.g. a user presses up the up key in the explorer view and has not pressed enter or presses enter on a folder.

it would be really great if we could do somethings like window.activeTreeView and then just query the object for what's highlighted.

ArturoDent commented 3 years ago

Using @alianZhen's idea from above https://github.com/microsoft/vscode/issues/3553#issuecomment-438969485 I implemented a workaround which seems to work well.

See https://stackoverflow.com/a/65257167/836330 👍🏼

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);
}

see more notes on the SO answer.

finnmerlett commented 3 years ago

I would really like to see this implemented, would really help along the way to making it possible to get the full use out of VSCode with just the keyboard! The fix mentioned a few times earlier in this thread does not work properly, it only gets the active editor's file path, not the selected path in the explorer view.

bondiano commented 3 years ago

Also will be cool to have path to selected file/folder in explorer as variable in Tasks like ${selectedFile}/selectedFolder.

moshfeu commented 3 years ago

My extension needs that too. It allows a command only when listDoubleSelection but vscode still allow to set a keybinding. When the user uses this shortcut, there is no option to get the selected resources.

https://github.com/moshfeu/vscode-compare-folders/issues/66

QoobIY commented 3 years ago

I think that if no one has done this in 5 years, we should do it yourself =)

jdneo commented 3 years ago

+1 for this.

When I try to adopt the new contribution point file/newFile, I wish I can create new files under the current selected folder in the file explorer.

FlorianBuhl commented 2 years ago

+1 for this.

JeremyFunk commented 2 years ago

A workaround that should work for most use cases (@ArturoDent version while preserving the clipboard state):

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
       const originalClipboard = await vscode.env.clipboard.readText();

       await vscode.commands.executeCommand('copyFilePath');
       folder = await vscode.env.clipboard.readText();  // returns a string

       await vscode.env.clipboard.writeText(originalClipboard);

       // 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);
}

Using this for my hide files extension.

tjx666 commented 2 years ago

Any progress on this api? I think this is a very basic api.

R35007 commented 1 year ago

Yes I need that as well in part of my vscode. I need to get the list of files or folders selected by the user. Is there any update on this ticket ?

eugeneniemand commented 1 year ago

I found this solution. It wasn't very clear from docs that register command passes a URI which can then be used for getting the path of the selected file when activating your command from the context menu in the explorer

export function activate(context: vscode.ExtensionContext) {
    console.log('Congratulations, your extension "My-lite-switcher" is now active!');
    let disposable = vscode.commands.registerCommand('My-lite-switcher.activate', (uri:vscode.Uri) => {
        let f = uri.fsPath;
        vscode.window.showInformationMessage(`My Lite Switcher: ${f}`);
    });
    context.subscriptions.push(disposable);
}
lramos15 commented 1 year ago

Does the new tabs API help anyone here? That's not limited by the text document and can get you the open file which is often the same as the selected file. I'm trying to understand the use cases in this thread and it seems like at least most would be solved with the tabs API.

r3m0t commented 1 year ago

I think they mean the file or folder which was clicked in the explorer view, or selected with the keyboard, not the open editor.

dian-yu-luo commented 1 year ago

could you convert it to js

Draugor commented 1 year ago

A workaround that should work for most use cases (@ArturoDent version while preserving the clipboard state):

this solution from @JeremyFunk is the closest i found to work, but there is still some situations where it doesn't work

Simon-He95 commented 1 year ago

Indeed, this API is very basic and should be exposed. I hope vscode can support it.

msweeney1999 commented 1 year ago

I need this too! Any updates please?

gravity-api commented 11 months ago

This can be very easily achieved - please follow my post on StackOverflow https://stackoverflow.com/a/77659797/13547712

Simon-He95 commented 11 months ago

This can be very easily achieved - please follow my post on StackOverflow https://stackoverflow.com/a/77659797/13547712

Please take a closer look at our question, we are talking about the file or folder which was clicked in the explorer view, or selected with the keyboard, not the open editor.

msweeney1999 commented 11 months ago

I agree with Simon-He95. Getting the URI for an Explorer Context menu right mouse click is already present in vscode. What is needed is a URI notification for a left mouse click event on a folder.

Something like this proposed API for a Treeview would be fantastic:

https://github.com/microsoft/vscode/blob/main/src/vscode-dts/vscode.proposed.treeViewActiveItem.d.ts#L24

The onDidChangeActiveItem event would specify the URI of the active item in Explorer.

In fact, vscode's own git implementation could use this feature. If I have a multi-rooted workspace, with subfolders containing repos, vscode git will always use the topmost folder as the git repo. It should use the repo of the currently selected folder in Explorer.

frudman commented 9 months ago

adding my 2 cents: such an event emitter would be great to implement the most basic "Show README" for selected folder, a very useful feature when browsing large repos. This is exactly what GITHUB does whenever a folder is selected, the relevant README file is displayed. Would Love Love to get this same feature for vscode. I have the code ready for this (currently implemented as right-click context menu, but that's really a pita).

ChiriVulpes commented 8 months ago

I would love to be able to add keybindings for these commands but can't because the extension can't currently support getting the current file list from the explorer. :<

mirrortom commented 5 months ago

Now, is there such an API? I need to use it too. var selectedWorkspaceFolder=; var fileOrDirs = selectedWorkspaceFolder.getSelectedItems();

tgrue-openai commented 2 months ago

Sadly the workaround where you copy clipboard, load path to clipboard, retrieve it, and restore state has two unacceptable issues for me.

1) Unsurprisingly, it's racey with the user. If they copy to the clipboard mid execution you can end up overwriting what they put in the clipboard. And, afaict, there is no solution to this (since there is no compare_and_swap like clipboard functionality). 2) The readText and writeText calls to the clipboard, at least on mac, lose rich state. This breaks some people's workflows and is particularly noticeable.

Thus, add me to the bucket of people who are trying to show a README.md for a folder in my extension panel, with no way of being able to tell when a folder is selected by a left click.