Skip to content

Commit eea8278

Browse files
authored
Merge pull request #6 from patricklx/improve-symlink-resolve
improve symlink resolve
2 parents a655268 + 8e3a740 commit eea8278

File tree

1 file changed

+69
-22
lines changed

1 file changed

+69
-22
lines changed

src/main/kotlin/com/wsl/symlinks/vfs/WslVirtualFileSystem.kt

+69-22
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import com.intellij.openapi.vfs.VirtualFile
1212
import com.intellij.openapi.vfs.VirtualFileManager
1313
import com.intellij.openapi.vfs.VirtualFileSystem
1414
import com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl
15-
import com.intellij.openapi.vfs.newvfs.impl.FakeVirtualFile
1615
import com.intellij.openapi.vfs.newvfs.impl.StubVirtualFile
1716
import com.intellij.platform.workspace.storage.url.VirtualFileUrl
1817
import com.intellij.util.KeyedLazyInstance
@@ -33,6 +32,37 @@ class StartupListener: AppLifecycleListener {
3332
}
3433
}
3534

35+
class FakeVirtualFile(val resPath: String, val vfile: VirtualFile, fs: WslVirtualFileSystem): StubVirtualFile(fs) {
36+
override fun getPath(): String {
37+
return resPath
38+
}
39+
40+
override fun getParent(): VirtualFile? {
41+
return vfile.parent
42+
}
43+
}
44+
45+
fun <T>Boolean.ifTrue(block: () -> T): T? {
46+
if (this) {
47+
return block.invoke()
48+
}
49+
return null
50+
}
51+
52+
fun <T>Boolean.ifFalse(block: () -> T): T? {
53+
if (!this) {
54+
return block.invoke()
55+
}
56+
return null
57+
}
58+
59+
fun <T>Boolean.ifFalse(value: T): T? {
60+
if (!this) {
61+
return value
62+
}
63+
return null
64+
}
65+
3666

3767
class WslSymlinksProvider(distro: String) {
3868
val LOGGER = Logger.getInstance(WslSymlinksProvider::class.java)
@@ -229,6 +259,11 @@ class WslVirtualFileSystem: LocalFileSystemImpl() {
229259
return this.wslSymlinksProviders[distro]!!
230260
}
231261

262+
fun getRealPath(file: VirtualFile): String {
263+
val symlkinkWsl = file.parentsWithSelf.find { it.isFromWSL() && this.getWslSymlinksProviders(file).isWslSymlink(it) }
264+
return symlkinkWsl?.let { virtualFile -> this.resolveSymLink(virtualFile) } ?: file.path
265+
}
266+
232267
fun getRealVirtualFile(file: VirtualFile): VirtualFile {
233268
val symlkinkWsl = file.parents.find { it.isFromWSL() && this.getWslSymlinksProviders(file).isWslSymlink(it) }
234269
val relative = symlkinkWsl?.path?.let { file.path.replace(it, "") }
@@ -253,24 +288,21 @@ class WslVirtualFileSystem: LocalFileSystemImpl() {
253288
}
254289

255290
override fun getAttributes(vfile: VirtualFile): FileAttributes? {
256-
val file = getRealVirtualFile(vfile)
257-
var attributes = super.getAttributes(file)
258-
259-
if (attributes != null && attributes.type == null && file.isFromWSL() && this.getWslSymlinksProviders(file).isWslSymlink(file)) {
260-
val resolved = this.resolveSymLink(file)?.let { resPath ->
261-
return@let object : StubVirtualFile() {
262-
override fun getPath(): String {
263-
return resPath
264-
}
265-
266-
override fun getParent(): VirtualFile {
267-
return vfile.parent
268-
}
269-
}
291+
var attributes = super.getAttributes(vfile)
292+
293+
if (vfile.isFromWSL() && vfile.parent != null) {
294+
val filePath = getRealPath(vfile.parent)
295+
val file = FakeVirtualFile(filePath + "/" + vfile.name, vfile, this)
296+
val isSymlink = this.getWslSymlinksProviders(file).isWslSymlink(file)
297+
val resolved = isSymlink.ifTrue { this.resolveSymLink(file)?.let { resPath ->
298+
return@let FakeVirtualFile(resPath, vfile, this)
299+
} }
300+
if (!isSymlink && file.path != vfile.path) {
301+
attributes = super.getAttributes(file)
270302
}
271303
if (resolved != null) {
272-
val resolvedAttrs = super.getAttributes(resolved)
273-
attributes = FileAttributes(resolvedAttrs?.isDirectory ?: false, false, true, attributes.isHidden, attributes.length, attributes.lastModified, attributes.isWritable, FileAttributes.CaseSensitivity.SENSITIVE)
304+
val resolvedAttrs = super.getAttributes(resolved) ?: attributes ?: return null
305+
attributes = FileAttributes(resolvedAttrs.isDirectory ?: false, false, true, resolvedAttrs.isHidden, resolvedAttrs.length, resolvedAttrs.lastModified, resolvedAttrs.isWritable, FileAttributes.CaseSensitivity.SENSITIVE)
274306
}
275307
}
276308
return attributes
@@ -289,12 +321,11 @@ class WslVirtualFileSystem: LocalFileSystemImpl() {
289321
}
290322

291323
override fun list(vfile: VirtualFile): Array<String> {
292-
val file = getRealVirtualFile(vfile)
293-
if (file.isFromWSL() && this.getWslSymlinksProviders(file).isWslSymlink(file)) {
294-
val f = this.resolveSymLink(file)?.let { this.findFileByPath(it) }
295-
return f?.let { super.list(it) } ?: emptyArray()
324+
if (vfile.isFromWSL()) {
325+
val file = FakeVirtualFile(getRealPath(vfile), vfile, this)
326+
return super.list(file)
296327
}
297-
return super.list(file)
328+
return super.list(vfile)
298329
}
299330
}
300331

@@ -363,4 +394,20 @@ val VirtualFile.parents: Iterable<VirtualFile>
363394
}
364395
}
365396
}
397+
}
398+
399+
val VirtualFile.parentsWithSelf: Iterable<VirtualFile>
400+
get() = object : Iterable<VirtualFile> {
401+
override fun iterator(): Iterator<VirtualFile> {
402+
var file: VirtualFile? = this@parentsWithSelf
403+
404+
return object : Iterator<VirtualFile> {
405+
override fun hasNext() = file != null
406+
override fun next(): VirtualFile {
407+
val f = file
408+
file = file?.parent
409+
return f!!
410+
}
411+
}
412+
}
366413
}

0 commit comments

Comments
 (0)