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

Properly format file path on when dragging and dropping a tab into the integrated terminal in Windows #30070

Merged
merged 1 commit into from
Jul 20, 2017

Conversation

rianadon
Copy link
Contributor

@rianadon rianadon commented Jul 3, 2017

This is a proof-of-concept illustrating a possible fix for #29926.

It uses the wmic process where parentProcessId=... get ... command to query processes spawned by the shell and matches the process executables with a set of known shells (bash.exe, cmd.exe, and powershell.exe). In the case that one of these spawned processes is a shell, its child processes are recursively examined until either there are no more child processes (nothing's running in the shell) or there are only non-shell child processes (a command is running).

After traversing these nested shells, the path of the last reached shell is used to pick a formatter for the path (either putting it in C:\..., /mnt/c/ or /c/ format).

A gif of using different shells is below.

2017-07-03_12-34-30

The way this is implemented currently has a few disadvantages though:

  1. For every nested shell that is traversed a new wmic command must be spawned. When the number of nested shells increases, it can take some time before the path is pasted. This could be solved by caching the current shell, but I wasn't sure how to go about this.

  2. This fails to work correctly in cases that a shell is spawned in the background (i.e. start cmd.exe) as there are no checks to whether the shell being traversed is in the background or foreground.

I'm not going to be able to get back to this for a while soon, so feel free to play around with / heavily edit this.

@msftclas
Copy link

msftclas commented Jul 3, 2017

@rianadon,
Thanks for having already signed the Contribution License Agreement. Your agreement was validated by Microsoft. We will now review your pull request.
Thanks,
Microsoft Pull Request Bot

Copy link
Member

@Tyriar Tyriar left a comment

Choose a reason for hiding this comment

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

First off, this is super cool and I didn't think you could access this sort of process information! This will definitely be very useful in the future when exploring more integration opportunities #20676, as well as fix the issue of the terminal session name on Windows never changing #30152, #29879 (comment)

As for the actual change, the significant delay for the command to finish is a little unfortunate. I suggest for now we rely on the shell that the terminal was originally launched with, that way it will cover the vast majority of cases (as long as you don't launch another shell from the initial shell). You can get at the shell's path via TerminalInstance._shellLaunchConfig.executable.

When the terminal has this information, probably by doing some minimal polling on input or something, then we can change this to work on the active shell instead of the initial shell.

It's also worth noting that everything should work perfectly using the initial shell if you launch your shells using https://marketplace.visualstudio.com/items?itemName=Tyriar.shell-launcher

@@ -232,21 +232,47 @@ export class TerminalPanel extends Panel {
return;
}

// Check if the file was dragged from the tree explorer
let uri = e.dataTransfer.getData('URL');
const winFormatters: [RegExp, (uri: URI) => string][] = [
Copy link
Member

Choose a reason for hiding this comment

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

Let's pull this and the application of the formatter into the _preparePathForTerminal function.

[/powershell.exe$/i, uri => uri.path[1].toUpperCase() + uri.path.substring(2).replace(/\//g, '\\')],
];

const terminal = this._terminalService.getActiveInstance();
Copy link
Member

Choose a reason for hiding this comment

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

A null check/return on terminal just to be safe.


const uriForm = async (uri: URI) => {
if (platform.isWindows) {
const shells = await terminal.getShellList();
Copy link
Member

Choose a reason for hiding this comment

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

Let's expose a ITerminalInstance.shellExecutable instead of getShellList.

@rianadon
Copy link
Contributor Author

rianadon commented Jul 7, 2017 via email

@Tyriar
Copy link
Member

Tyriar commented Jul 7, 2017

@rianadon no problem, get to it when you can.

I believe @Lixire may be looking into #30152 (and #29879) in the July iteration so feel free to just simplify this PR to look at the initial shell executable. After #30152 we should hopefully have reasonably up to date knowledge of the shell at any time.

@Tyriar Tyriar merged commit 53040a1 into microsoft:master Jul 20, 2017
@rianadon
Copy link
Contributor Author

Now that @Lixire has adapted this to change the terminal title and has also made what I had much cleaner and efficient (to the point where I don't think running the command once to get all processes would make a difference), is all that's left using WindowsShellHelper when the tab is dropped onto the terminal? Or is there anything else that needs to get done?

And also since this has already been merged via #30732 I think I would need to create another PR, right?

@Tyriar
Copy link
Member

Tyriar commented Jul 21, 2017

@rianadon you would need to modify WIndowsShellHelper to keep track of the actual shell. Right now it sets the title of the TerminalInstance to the executable under the last recognized shell, for example the following process tree:

  • cmd.exe (last shell)
    • git.exe (set terminal instance title to git)
      • git.exe
        • less.exe

You would also need to differentiate git bash and wsl bash which isn't being done currently.

So I would expect something like:

  • WindowsShellHelper.getShellName should be renamed to something like WindowsShellHelper.updateProgramName
  • Track the shell name inside WindowsShellHelper, this could be pulled into TerminalInstance but since we don't have this yet for Linux/macOS let's keep it into WindowsShellHelper
  • A new WindowsShellHelper.getShellName that actually just returned the shell that was acquired from the last updateProgramName

FYI there's also this change which will improve the reliability of the title on Windows for commands that exit by themselves, like git status, npm install, etc. #31155.

@rianadon
Copy link
Contributor Author

@Tyriar Thanks for the advice. I've revised this in #31234.

@Tyriar Tyriar added this to the July 2017 milestone Jul 22, 2017
@github-actions github-actions bot locked and limited conversation to collaborators Mar 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants