Skip to content

Commit

Permalink
improvement: Set icons properly for all parts of tree view
Browse files Browse the repository at this point in the history
Previously, only some nodes would have their icons set, which would result with some having folder icons added by VS Code but not all. Now, we set icons for each node manually.

The only problem I have is with packages, which doesn't really have a great icon anywhere. symbol-package is the same as symbol-object, which is too similar. So I decided to go with folder, which seems the next best thing.
  • Loading branch information
tgodzik committed Nov 16, 2023
1 parent b5c9e81 commit 5db0d6d
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,19 @@ class ClasspathTreeView[Value, Key](
valueTooltip: Value => String,
toplevels: () => Iterator[Value],
loadSymbols: (Key, String) => Iterator[TreeViewSymbolInformation],
toplevelIcon: String,
) {
val scheme: String = s"$schemeId-${folder.path.toString()}"
val rootUri: String = scheme + ":"

def root(showFolderName: Boolean): TreeViewNode = {
def root(showFolderName: Boolean, icon: String): TreeViewNode = {
val folderPart = if (showFolderName) s" (${folder.nameOrUri})" else ""
TreeViewNode(
viewId,
rootUri,
title + folderPart + s" (${toplevels().size})",
collapseState = MetalsTreeItemCollapseState.collapsed,
icon = icon,
)
}

Expand All @@ -50,7 +52,7 @@ class ClasspathTreeView[Value, Key](

def children(uri: String): Array[TreeViewNode] = {
if (uri == rootUri) {
TreeViewNode.sortAlphabetically(toplevels().map(toViewNode).toArray)
TreeViewNode.sortAlphabetically(toplevels().map(toplevelNode).toArray)
} else {
val node = fromUri(uri)

Expand Down Expand Up @@ -119,6 +121,7 @@ class ClasspathTreeView[Value, Key](
case k.FIELD => "symbol-field"
case k.TYPE_PARAMETER => "symbol-type-parameter"
case k.TYPE => "symbol-type-parameter"
case k.PACKAGE => "symbol-folder"
case _ => null
}

Expand Down Expand Up @@ -170,14 +173,15 @@ class ClasspathTreeView[Value, Key](
}
}

def toViewNode(value: Value): TreeViewNode = {
def toplevelNode(value: Value): TreeViewNode = {
val uri = toUri(id(value)).toUri
TreeViewNode(
viewId,
uri,
valueTitle(value),
tooltip = valueTooltip(value),
collapseState = MetalsTreeItemCollapseState.collapsed,
icon = toplevelIcon,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,54 +260,56 @@ class FolderTreeViewProvider(
private val pendingProjectUpdates =
ConcurrentHashSet.empty[BuildTargetIdentifier]
val libraries = new ClasspathTreeView[AbsolutePath, AbsolutePath](
definitionIndex,
TreeViewProvider.Project,
s"libraries",
s"Libraries",
folder,
identity,
_.toURI.toString(),
_.toAbsolutePath(followSymlink = false),
path => {
definitionIndex = definitionIndex,
viewId = TreeViewProvider.Project,
schemeId = s"libraries",
title = s"Libraries",
folder = folder,
id = identity,
encode = _.toURI.toString(),
decode = _.toAbsolutePath(followSymlink = false),
valueTitle = path => {
if (path.filename == JdkSources.zipFileName) {
maybeUsedJdkVersion
.map(ver => s"jdk-${ver}-sources")
.getOrElse("jdk-sources")
} else
path.filename
},
_.toString,
() => buildTargets.allSourceJars,
(path, symbol) => {
valueTooltip = _.toString,
toplevels = () => buildTargets.allSourceJars,
loadSymbols = (path, symbol) => {
val dialect = ScalaVersions.dialectForDependencyJar(path.filename)
classpath.jarSymbols(path, symbol, dialect)
},
toplevelIcon = "package",
)

val projects = new ClasspathTreeView[BuildTarget, BuildTargetIdentifier](
definitionIndex,
TreeViewProvider.Project,
s"projects",
s"Projects",
folder,
_.getId(),
_.getUri(),
uri => new BuildTargetIdentifier(uri),
_.getName(),
_.baseDirectory,
{ () =>
definitionIndex = definitionIndex,
viewId = TreeViewProvider.Project,
schemeId = s"projects",
title = s"Projects",
folder = folder,
id = _.getId(),
encode = _.getUri(),
decode = uri => new BuildTargetIdentifier(uri),
valueTitle = _.getName(),
valueTooltip = _.baseDirectory,
toplevels = { () =>
buildTargets.all.filter(target =>
buildTargets.buildTargetSources(target.getId()).nonEmpty
)
},
{ (id, symbol) =>
loadSymbols = { (id, symbol) =>
val tops = for {
scalaTarget <- buildTargets.scalaTarget(id).iterator
source <- buildTargets.buildTargetSources(id)
dialect = scalaTarget.dialect(source)
} yield classpath.workspaceSymbols(source, symbol)
tops.flatten
},
toplevelIcon = "target",
)

def setVisible(viewId: String, visibility: Boolean): Unit = {
Expand All @@ -325,7 +327,7 @@ class FolderTreeViewProvider(
if (toUpdate.nonEmpty) {
val nodes = toUpdate.map { target =>
projects
.toViewNode(target)
.toplevelNode(target)
.copy(collapseState = MetalsTreeItemCollapseState.expanded)
}
Some(nodes)
Expand Down Expand Up @@ -387,8 +389,8 @@ class FolderTreeViewProvider(
nodeUri match {
case None if buildTargets.all.nonEmpty =>
Array(
projects.root(showFolderName),
libraries.root(showFolderName),
projects.root(showFolderName, "project"),
libraries.root(showFolderName, "library"),
)
case Some(uri) =>
if (libraries.matches(uri)) {
Expand Down
77 changes: 39 additions & 38 deletions tests/unit/src/test/scala/tests/TreeViewLspSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class TreeViewLspSuite extends BaseLspSuite("tree-view") {
lazy val expectedLibrariesString: String =
(this.expectedLibraries.toVector
.map { (s: String) =>
if (s != jdkSourcesName) s"${s}.jar -" else s"$jdkSourcesName -"
if (s != jdkSourcesName) s"${s}.jar package -"
else s"$jdkSourcesName package -"
})
.mkString("\n")

Expand Down Expand Up @@ -125,8 +126,8 @@ class TreeViewLspSuite extends BaseLspSuite("tree-view") {
)
_ = server.assertTreeViewChildren(
s"projects-$folder:${server.buildTarget("a")}",
"""|_empty_/ -
|a/ -
"""|_empty_/ symbol-folder -
|a/ symbol-folder -
|""".stripMargin,
)
_ = server.assertTreeViewChildren(
Expand Down Expand Up @@ -207,7 +208,7 @@ class TreeViewLspSuite extends BaseLspSuite("tree-view") {
_ = {
server.assertTreeViewChildren(
s"libraries-$folder:${server.jar("sourcecode")}",
"sourcecode/ +",
"sourcecode/ symbol-folder +",
)
server.assertTreeViewChildren(
s"libraries-$folder:",
Expand All @@ -232,12 +233,12 @@ class TreeViewLspSuite extends BaseLspSuite("tree-view") {
)
server.assertTreeViewChildren(
s"libraries-$folder:${server.jar("circe-core")}!/_root_/",
"""|io/ +
"""|io/ symbol-folder +
|""".stripMargin,
)
server.assertTreeViewChildren(
s"libraries-$folder:${server.jar("cats-core")}!/_root_/",
"""|cats/ +
"""|cats/ symbol-folder +
|""".stripMargin,
)
server.assertTreeViewChildren(
Expand Down Expand Up @@ -265,11 +266,11 @@ class TreeViewLspSuite extends BaseLspSuite("tree-view") {
"class Paths",
),
s"""|root
| Libraries (22)
| $jdkSourcesName
| java/
| nio/
| file/
| Libraries (22) library
| $jdkSourcesName package
| java/ symbol-folder
| nio/ symbol-folder
| file/ symbol-folder
| Paths symbol-class
|""".stripMargin,
)
Expand All @@ -292,19 +293,19 @@ class TreeViewLspSuite extends BaseLspSuite("tree-view") {
"sourcecode/SourceContext.scala",
"object File",
isIgnored = { label =>
label.endsWith(".jar") &&
label.endsWith(".jar package") &&
!label.contains("sourcecode")
},
),
s"""|root
| Projects (0)
| Libraries (22)
| Libraries (22)
| $jdkSourcesName
| sourcecode_2.13-0.1.7-sources.jar
| sourcecode_2.13-0.1.7-sources.jar
| sourcecode/
| sourcecode/
| Projects (0) project
| Libraries (22) library
| Libraries (22) library
| $jdkSourcesName package
| sourcecode_2.13-0.1.7-sources.jar package
| sourcecode_2.13-0.1.7-sources.jar package
| sourcecode/ symbol-folder
| sourcecode/ symbol-folder
| Args symbol-class
| Args symbol-object
| ArgsMacros symbol-interface
Expand Down Expand Up @@ -345,27 +346,27 @@ class TreeViewLspSuite extends BaseLspSuite("tree-view") {
"org/eclipse/lsp4j/services/LanguageClient.java",
"registerCapability",
isIgnored = { label =>
label.endsWith(".jar") &&
label.endsWith(".jar package") &&
!label.contains("lsp4j-0")
},
),
s"""|root
| Projects (0)
| Libraries (${expectedLibrariesCount})
| Libraries (${expectedLibrariesCount})
| $jdkSourcesName
| org.eclipse.lsp4j-0.5.0-sources.jar
| org.eclipse.lsp4j-0.5.0-sources.jar
| org/
| org/
| eclipse/
| eclipse/
| lsp4j/
| lsp4j/
| adapters/
| launch/
| services/
| util/
| Projects (0) project
| Libraries (${expectedLibrariesCount}) library
| Libraries (${expectedLibrariesCount}) library
| $jdkSourcesName package
| org.eclipse.lsp4j-0.5.0-sources.jar package
| org.eclipse.lsp4j-0.5.0-sources.jar package
| org/ symbol-folder
| org/ symbol-folder
| eclipse/ symbol-folder
| eclipse/ symbol-folder
| lsp4j/ symbol-folder
| lsp4j/ symbol-folder
| adapters/ symbol-folder
| launch/ symbol-folder
| services/ symbol-folder
| util/ symbol-folder
| ApplyWorkspaceEditParams symbol-class
| ApplyWorkspaceEditResponse symbol-class
| ClientCapabilities symbol-class
Expand Down Expand Up @@ -529,7 +530,7 @@ class TreeViewLspSuite extends BaseLspSuite("tree-view") {
| WorkspaceFoldersOptions symbol-class
| WorkspaceServerCapabilities symbol-class
| WorkspaceSymbolParams symbol-class
| services/
| services/ symbol-folder
| LanguageClient symbol-interface
| LanguageClientAware symbol-interface
| LanguageClientExtensions symbol-interface
Expand Down

0 comments on commit 5db0d6d

Please sign in to comment.