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

show symbolic links as decorations in explorer #43815

Merged
merged 6 commits into from Feb 21, 2018
Merged

Conversation

isidorn
Copy link
Contributor

@isidorn isidorn commented Feb 16, 2018

fixes #11539

I have adopted your idea in the fileService to first do an lstat and if only if it is a symbolic link to do an additional stat call.

As for visualisation to not do any icon crazyness I have decided to use decorations similar to what we do for errors and git decorations.
I went through all the ansi arrows and I personally like this one the most ⇲
Here's a list of unicode arrows https://unicode-table.com/en/sets/arrows-symbols/
After we get feedback from users we can decide to do some additional decorating like italic, but not for now imho and also the decoration api does not support italic

fyi @chryw
A nice icon overlay you provided looks great, we can look into adding that to the icon as step 2, after we merge this is and get some feedback.

screen shot 2018-02-16 at 11 02 24

@isidorn isidorn added this to the February 2018 milestone Feb 16, 2018
@bpasero bpasero self-requested a review February 19, 2018 09:15
@bpasero bpasero assigned isidorn and unassigned bpasero Feb 19, 2018
Copy link
Member

@bpasero bpasero left a comment

Choose a reason for hiding this comment

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

@isidorn some feedback provided

@@ -410,6 +410,11 @@ export interface IFileStat extends IBaseStat {
*/
isDirectory: boolean;

/**
* The resource is a simbolic link.
Copy link
Member

Choose a reason for hiding this comment

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

simbolic => symbolic

@@ -19,7 +19,7 @@ function create(relativePath: string): StatResolver {
let absolutePath = relativePath ? path.join(basePath, relativePath) : basePath;
let fsStat = fs.statSync(absolutePath);

return new StatResolver(uri.file(absolutePath), fsStat.isDirectory(), fsStat.mtime.getTime(), fsStat.size, void 0);
return new StatResolver(uri.file(absolutePath), fsStat.isSymbolicLink(), fsStat.isDirectory(), fsStat.mtime.getTime(), fsStat.size, void 0);
Copy link
Member

Choose a reason for hiding this comment

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

@isidorn can we have a test for this too? it looks like node.js allows to create symlinks (fs.symlink).

if (fileStat && fileStat.nonexistentRoot) {
return {
tooltip: localize('canNotResolve', "Can not resolve workspace folder"),
letter: '!',
color: listInvalidItemForeground,
};
}
if (fileStat && fileStat.isSymbolicLink) {
return {
tooltip: localize('symbolicLlink', "Symbolic link"),
Copy link
Member

Choose a reason for hiding this comment

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

Maybe better capital casing: Symbolic Link

if (fileStat && fileStat.isSymbolicLink) {
return {
tooltip: localize('symbolicLlink', "Symbolic link"),
letter: '\u21f2'
Copy link
Member

Choose a reason for hiding this comment

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

Maybe there is a better symbol? Something that looks more like this:

image

@@ -1254,6 +1259,7 @@ export class StatResolver {
const childStat: IFileStat = {
resource: fileResource,
isDirectory: fileStat.isDirectory(),
isSymbolicLink: isSymbolicLink,
Copy link
Member

Choose a reason for hiding this comment

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

Can be simplified to: isSymbolicLink

@@ -913,7 +913,7 @@ export class FileService implements IFileService {
const absolutePath = this.toAbsolutePath(resource);

return pfs.stat(absolutePath).then(stat => {
return new StatResolver(resource, stat.isDirectory(), stat.mtime.getTime(), stat.size, this.options.verboseLogging ? this.options.errorLogger : void 0);
return new StatResolver(resource, false, stat.isDirectory(), stat.mtime.getTime(), stat.size, this.options.verboseLogging ? this.options.errorLogger : void 0);
Copy link
Member

Choose a reason for hiding this comment

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

This is a bit weird, why not introduce a new method pfs.statLink that is implemented like this:

  • executes lstat
  • executes stat only if the stat is a symbolic link
  • returns something like { stat: stat, isSymbolicLink: boolean }

This method could then also be used from within the resolver

@@ -1235,7 +1233,14 @@ export class StatResolver {
},

function stat(this: any): void {
fs.stat(fileResource.fsPath, this);
fs.lstat(fileResource.fsPath, (error, stat) => {
Copy link
Member

Choose a reason for hiding this comment

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

Use the new method from extfs/pfs for this.

@isidorn
Copy link
Contributor Author

isidorn commented Feb 20, 2018

@bpasero I have addressed all your comments. Please review when you get a chance
I have also found a sexy unicode character
Have to check it on linux and win though.

screen shot 2018-02-20 at 12 23 00

Copy link
Member

@bpasero bpasero left a comment

Choose a reason for hiding this comment

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

@isidorn feel free to commit after checking out my changes

@@ -912,8 +912,8 @@ export class FileService implements IFileService {
private toStatResolver(resource: uri): TPromise<StatResolver> {
const absolutePath = this.toAbsolutePath(resource);

return pfs.stat(absolutePath).then(stat => {
return new StatResolver(resource, stat.isDirectory(), stat.mtime.getTime(), stat.size, this.options.verboseLogging ? this.options.errorLogger : void 0);
return pfs.statLink(absolutePath).then(statAndIsLink => {
Copy link
Member

Choose a reason for hiding this comment

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

Can be written nicer:

return pfs.statLink(absolutePath).then(({ isSymbolicLink, stat }) => {
	return new StatResolver(resource, isSymbolicLink, stat.isDirectory(), stat.mtime.getTime(), stat.size, this.options.verboseLogging ? this.options.errorLogger : void 0);
});

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -1235,7 +1233,10 @@ export class StatResolver {
},

function stat(this: any): void {
fs.stat(fileResource.fsPath, this);
extfs.statLink(fileResource.fsPath, (error: Error, statAndIsLink) => {
Copy link
Member

Choose a reason for hiding this comment

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

Can be nicer:

extfs.statLink(fileResource.fsPath, (error: Error, { stat, isSymbolicLink }) => {
	isSymbolicLink = isSymbolicLink;
	this(null, stat);
});

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Did not do this due to name clash of the isSymoblicLink variable a couple of lines up. Decided to leave like it is.

@@ -54,6 +54,16 @@ export function stat(path: string): TPromise<fs.Stats> {
return nfcall(fs.stat, path);
}

export function statLink(path: string): TPromise<{ stat: fs.Stats, isSymbolicLink: boolean }> {
Copy link
Member

@bpasero bpasero Feb 20, 2018

Choose a reason for hiding this comment

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

@isidorn why is this method not simply using extfs? E.g. it should be as simple as:

export function statLink(path: string): TPromise<string> {
	return nfcall(extfs.statLink, path);
}

Copy link
Contributor Author

@isidorn isidorn Feb 21, 2018

Choose a reason for hiding this comment

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

@bpasero you are correct. I was not aware I can depend on extfs in pfs, but now I see it is already done.
Fixed

@isidorn isidorn merged commit 302fd56 into master Feb 21, 2018
@isidorn isidorn deleted the isidorn/symbolicLinks branch February 21, 2018 09:15
@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.

Explorer: indicate symlinks
2 participants