Skip to content

Properly format file path on when dragging and dropping a tab into the integrated terminal in Windows (version 2)#31234

Closed
rianadon wants to merge 8 commits intomicrosoft:masterfrom
rianadon:terminal-drag-drop2
Closed

Properly format file path on when dragging and dropping a tab into the integrated terminal in Windows (version 2)#31234
rianadon wants to merge 8 commits intomicrosoft:masterfrom
rianadon:terminal-drag-drop2

Conversation

@rianadon
Copy link
Copy Markdown
Contributor

This is a rewrite of #30070 to make use of the new changes to the codebase since the previous PR.

@mention-bot
Copy link
Copy Markdown

@rianadon, thanks for your PR! By analyzing the history of the files in this pull request, we identified @Tyriar and @dbaeumer to be potential reviewers.

// List of regular expressions, for matching shells, functions to format a path, and booleans indicating whether the shell uses Windows-style paths
const WIN_PATH_FORMATTERS: [RegExp, (path: string) => string, boolean][] = [
// WSL bash
[/^C:\\Windows\\(System32|sysnative)\\bash(.exe)?$/i, path => '/mnt/' + path[1] + path.substring(3), false],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure if WSL bash is available in WoW64, might want to add |SysWoW64 too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure.

import URI from 'vs/base/common/uri';

// List of regular expressions, for matching shells, functions to format a path, and booleans indicating whether the shell uses Windows-style paths
const WIN_PATH_FORMATTERS: [RegExp, (path: string) => string, boolean][] = [
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's use an interface instead of an array so it's nicer to use:

interface IPathFormatter {
  regex: RegExp,
  format: (path: string) =>string,
  usesWindowsStylePaths: boolean
}

const WIN_PATH_FORMATTERS: IPathFormatter[] = [...]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

An interface would be nicer but it does add some verbosity to WIN_PATH_FORMATTERS as the array elements would be switched from arrays to objects. Would doing something like:

type PathFormatter = [Regexp, (path: string) => string, boolean];

const WIN_PATH_FORMATTERS: PathFormatter[] = [...]

be any better? Or given I haven't really seen this used in VS Code would it be better to stick with interfaces?

if (platform.isWindows) {
const terminal = this._terminalService.getActiveInstance();
const shell = terminal.getShellName();
for (const [format, formatter, isWinPath] of WIN_PATH_FORMATTERS) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's use WIN_PATH_FORMATTERS.forEach( to keep it consistent with the rest of the code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Okay.

Is the following pattern used at all?

WIN_PATH_FORMATTERS.forEach(formatArray => {
    const [format, formatter, isWinPath] = formatArray;
    ...
}

Or if I switched to interfaces I wouldn't have to worry about this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Actually never mind. The regular expression for WSL bash is becoming quite long, so I may as well use an interface to split up the line.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't think using forEach will work because I need to break out of the loop. Either I would need to nest an if inside of it which would get ugly or use some other method (such as Array.prototype.find, but it seems the typescript target is set to es5 so that's not an option).

// We only go one level deep when checking for children of processes other then shells
if (SHELL_EXECUTABLES.indexOf(path.basename(result[0].executable)) === -1) {
return TPromise.as(result[0].executable);
return TPromise.as({ program: result[0].executable, shell: parent });
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Perfect 👌

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yay 🎉


/**
* Returns the innermost shell executable running in the terminal
* Updates innermost shell executable and innermost shell running in the terminal
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This comment is a little vague, something like this might be better:

Queries the OS and gets the inner-most shell running in the terminal as well as the program the shell is running if it exists.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah that sounds better.

/**
* Returns the innermost program executable running in the terminal
*/
public getProgramName(): string {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's make these getters:

public get programName(): string { return this._programName; }

You can then refer to them as if they were properties.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oh yeah I forgot that was a thing! Is having this on a single line or multiple lines preferred?

this.refreshShellProcessTree(this._childProcessIdStack[this._childProcessIdStack.length - 1], null).then(result => {
resolve(result);
return new TPromise<void>((resolve) => {
this.refreshShellProcessTree(this._childProcessIdStack[this._childProcessIdStack.length - 1], this._shellName !== this._programName ? this._shellName : null).then(result => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's pull this._shellName !== this._programName ? this._shellName : null into a variable so it's easier to read

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure.

@rianadon
Copy link
Copy Markdown
Contributor Author

@Tyriar I'm not sure if you received any notifications from me responding to your comments or have seen them yet, but if you haven't I'm letting you know that I responded to them and had a few questions 😃.

@Tyriar Tyriar added this to the August 2017 milestone Jul 31, 2017
@rianadon
Copy link
Copy Markdown
Contributor Author

I've revised the PR do use the new native module. However the module only gives the executable name and not the full path so it can't differentiate between WSL bash and Git bash.

@Tyriar Tyriar modified the milestones: August 2017, September 2017 Aug 28, 2017
@Tyriar
Copy link
Copy Markdown
Contributor

Tyriar commented Aug 30, 2017

@rianadon sorry about the delay, I'll try get to this over the next couple of weeks 😃

@rianadon
Copy link
Copy Markdown
Contributor Author

No problem. Since this is anyways going to have to be ported over to use node-pty when it gains support for listing processes on Windows, there isn't any rush to merge or review this.

@microsoft microsoft deleted a comment from msftclas Sep 27, 2017
@Tyriar Tyriar modified the milestones: September 2017, October 2017 Sep 29, 2017
@Tyriar Tyriar removed this from the October 2017 milestone Oct 30, 2017
@Tyriar Tyriar added this to the Backlog milestone Oct 30, 2017
@Tyriar
Copy link
Copy Markdown
Contributor

Tyriar commented May 19, 2018

Unfortunately this has become a bit too slate (my fault) so I'll have to close it. I am planning on improving WSL/Windows in general in the coming months so maybe this could be tackled then too.

@Tyriar Tyriar closed this May 19, 2018
@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.

5 participants