Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A shortcut to select file/files in the explorer. And copy that path to the terminal. #16966

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

Raukie
Copy link

@Raukie Raukie commented Mar 28, 2024

Summary of the Pull Request

A PR to add the functionality specified in #16965
It adds an shortcut, currently ctrl+o that open a file explorer dialog to select files.
When an file or files are selected the appropiate paths are pasted into the terminal.

It also takes in account if quotes are necessary. This is largely based on the same implementation that takes care of pasting paths for dragging and dropping into the terminal.

References and Relevant Issues

#16965

Detailed Description of the Pull Request / Additional comments

An pull request with code to implement #16965.
Known things that still have to be implemented is support for WSL. The code for WSL path support is there, however i was unable to find an function/variable to check if its in WSL context.

This is the code for wsl support. Where it says false there should be an bool called IsWsl.
The rest of the code is too take care of Path Mangling for WSL.

TerminalPage.cpp, Line 3005

   // Fix path for WSL, still has to be implemented
   if (false /*IsWsl*/)
   {
       std::replace(fullPath.begin(), fullPath.end(), L'\\', L'/');

       if (fullPath.size() >= 2 && fullPath.at(1) == L':')
       {
           // C:/foo/bar -> Cc/foo/bar
           fullPath.at(1) = til::tolower_ascii(fullPath.at(0));
           // Cc/foo/bar -> /mnt/c/foo/bar
           fullPath.replace(0, 1, L"/mnt/");
       }
       else
       {
           static constexpr std::wstring_view wslPathPrefixes[] = { L"//wsl.localhost/", L"//wsl$/" };
           for (auto prefix : wslPathPrefixes)
           {
               if (til::starts_with(fullPath, prefix))
               {
                   if (const auto idx = fullPath.find(L'/', prefix.size()); idx != std::wstring::npos)
                   {
                       // //wsl.localhost/Ubuntu-18.04/foo/bar -> /foo/bar
                       fullPath.erase(0, idx);
                   }
                   else
                   {
                       // //wsl.localhost/Ubuntu-18.04 -> /
                       fullPath = L"/";
                   }
                   break;
               }
           }
       }
   }

Validation Steps Performed

PR Checklist

@Raukie
Copy link
Author

Raukie commented Mar 28, 2024

@microsoft-github-policy-service agree

@DHowett
Copy link
Member

DHowett commented Apr 9, 2024

Hey there! Sorry about the delay - we've got a couple vacations on the team and are working through a backlog. Thanks for your patience!

@Raukie
Copy link
Author

Raukie commented Apr 9, 2024

Thats fine, vacation is important haha.
thank you for the notice.

@Raukie
Copy link
Author

Raukie commented Apr 9, 2024

I think visual studio has accidentally auto formatted some things. I already took it it out i thought.

@Raukie
Copy link
Author

Raukie commented May 13, 2024

Has anyone started looking into this PR yet?

@zadjii-msft
Copy link
Member

My apologies, I've been meaning to get back to this sooner, but Build prep keeps coming up as interrupt-priority work.

In terms of raw code feedback:

  • As far as converting paths for WSL goes, I'd probably want to deduplicate the logic you have here in TerminalPage::_OpenFileDialog with what's already in TermControl::_DragDropHandler. I'd probably take the whole section in
    std::wstring allPathsString;
    for (auto& fullPath : fullPaths)
    {
    // Join the paths with spaces
    if (!allPathsString.empty())
    {
    allPathsString += L" ";
    }
    // Fix path for WSL
    // In the fullness of time, we should likely plumb this up
    // to the TerminalApp layer, and have it make the decision
    // if this control should have its path mangled (and do the
    // mangling), rather than exposing the source concept to the
    // Control layer.
    //
    // However, it's likely that the control layer may need to
    // know about the source anyways in the future, to support
    // GH#3158
    const auto isWSL = _interactivity.ManglePathsForWsl();
    if (isWSL)
    {
    std::replace(fullPath.begin(), fullPath.end(), L'\\', L'/');
    if (fullPath.size() >= 2 && fullPath.at(1) == L':')
    {
    // C:/foo/bar -> Cc/foo/bar
    fullPath.at(1) = til::tolower_ascii(fullPath.at(0));
    // Cc/foo/bar -> /mnt/c/foo/bar
    fullPath.replace(0, 1, L"/mnt/");
    }
    else
    {
    static constexpr std::wstring_view wslPathPrefixes[] = { L"//wsl.localhost/", L"//wsl$/" };
    for (auto prefix : wslPathPrefixes)
    {
    if (til::starts_with(fullPath, prefix))
    {
    if (const auto idx = fullPath.find(L'/', prefix.size()); idx != std::wstring::npos)
    {
    // //wsl.localhost/Ubuntu-18.04/foo/bar -> /foo/bar
    fullPath.erase(0, idx);
    }
    else
    {
    // //wsl.localhost/Ubuntu-18.04 -> /
    fullPath = L"/";
    }
    break;
    }
    }
    }
    }
    const auto quotesNeeded = isWSL || fullPath.find(L' ') != std::wstring::npos;
    const auto quotesChar = isWSL ? L'\'' : L'"';
    // Append fullPath and also wrap it in quotes if needed
    if (quotesNeeded)
    {
    allPathsString.push_back(quotesChar);
    }
    allPathsString.append(fullPath);
    if (quotesNeeded)
    {
    allPathsString.push_back(quotesChar);
    }
    }
    _pasteTextWithBroadcast(winrt::hstring{ allPathsString });
    , pull that out into a method like PastePaths on TermControl, project that up through the idl, and then have TerminalPage call that instead.
  • You'd also probably need this version of the filepicker instead:
    winrt::Windows::Foundation::IAsyncOperation<winrt::hstring> OpenFilePicker(HWND parentHwnd, TLambda&& customize)
    . The straight-up UWP one doesn't work in elevated (admin) windows (IIRC), so we need to use the COM version instead.
  • I'd hard-block adding a default keybinding for this - other CLI apps are already expecting to receive ^O, so the Terminal probably shouldn't steal that keystroke.
  • Otherwise, the rest of the plumbing here looks totally as I'd expect.

I have other big-picture thoughts that I want to have the team have another quick chat about, but that'll unfortunately have to wait until after Build at this point. Thanks for your patience!

Copy link
Member

@zadjii-msft zadjii-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(as noted)

@microsoft-github-policy-service microsoft-github-policy-service bot added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label May 14, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot added the No-Recent-Activity This issue/PR is going stale and may be auto-closed without further activity. label May 23, 2024
@Raukie
Copy link
Author

Raukie commented May 24, 2024

I would rather it not be closed for these reasons. I don't have as much time now as i had two months ago when it was opened.

I will make the changes but need to find some time for it.

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs-Attention The core contributors need to come back around and look at this ASAP. and removed Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something No-Recent-Activity This issue/PR is going stale and may be auto-closed without further activity. labels May 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs-Attention The core contributors need to come back around and look at this ASAP.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

A shortcut to select file/files in the explorer. And copy that path to the terminal.
3 participants