/
AmmoniteFileCompletions.scala
102 lines (90 loc) 路 2.85 KB
/
AmmoniteFileCompletions.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package scala.meta.internal.pc
package completions
import java.nio.file.Files
import java.nio.file.Path
import scala.meta.internal.mtags.MtagsEnrichments.*
import dotty.tools.dotc.ast.tpd.*
import dotty.tools.dotc.ast.tpd.Tree
import dotty.tools.dotc.ast.untpd.ImportSelector
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.StdNames.*
import org.eclipse.lsp4j as l
object AmmoniteFileCompletions:
private def translateImportToPath(tree: Tree): String =
tree match
case Select(qual, name) =>
val pathPart = name.toString()
translateImportToPath(qual) + "/" + {
if pathPart == "^" then ".."
else pathPart
}
case Ident(_) =>
""
case _ => ""
def contribute(
select: Tree,
selector: List[ImportSelector],
posRange: l.Range,
rawPath: String,
workspace: Option[Path],
rawFileName: String,
)(using Context): List[CompletionValue] =
val fileName = rawFileName
.split("/")
.last
.stripSuffix(".amm.sc.scala")
val split = rawPath
.split("\\$file")
.toList
val editRange = selector.headOption.map { sel =>
if sel.sourcePos.span.isZeroExtent then posRange
else sel.imported.sourcePos.toLsp
}
val query = selector.collectFirst { case sel: ImportSelector =>
if sel.name.isEmpty || sel.name == nme.ERROR then ""
else sel.name.toString.replace(Cursor.value, "")
}
def parent =
val name = "^"
CompletionValue.FileSystemMember(
name,
editRange,
isDirectory = true,
)
(split, workspace) match
case (_ :: script :: Nil, Some(workspace)) =>
// drop / or \
val current = workspace.resolve(script.drop(1))
val importPath = translateImportToPath(select).drop(1)
val currentPath = current.getParent.resolve(importPath).toAbsolutePath
val parentTextEdit =
if query.exists(_.isEmpty()) &&
Files.exists(currentPath.getParent) && Files.isDirectory(
currentPath
)
then List(parent)
else Nil
Files
.list(currentPath)
.asScala
.toList
.filter(_.getFileName.toString.stripSuffix(".sc") != fileName)
.collect {
case file
if (Files.isDirectory(
file
) || file.toAbsolutePath.toString.isAmmoniteScript) &&
query.exists(
CompletionFuzzy.matches(_, file.getFileName.toString)
) =>
CompletionValue.FileSystemMember(
file.getFileName.toString,
editRange,
isDirectory = Files.isDirectory(file),
)
} ++ parentTextEdit
case _ =>
Nil
end match
end contribute
end AmmoniteFileCompletions