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

Recognize root of Enso repository as VSCode project #6942

Merged
merged 1 commit into from
Jun 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import javax.swing.Action;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.enso.tools.enso4igv.EnsoSbtClassPathProvider.EnsoSources;
import org.enso.tools.enso4igv.EnsoSbtClassPathProvider.OtherEnsoSources;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.api.project.SourceGroup;
Expand All @@ -21,11 +19,11 @@
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.util.NbCollections;
import org.openide.util.lookup.Lookups;

@ActionReferences({
@ActionReference(position = 3100, id = @ActionID(category = "Project", id = "org-netbeans-modules-project-ui-CloseProject"), path = "Projects/ensosbtprj/Actions", separatorBefore = 3000),
@ActionReference(position = 3100, id = @ActionID(category = "Project", id = "org.netbeans,modules.project.ui.CloseProject"), path = "Projects/ensosbtprj/Actions", separatorBefore = 3000),
@ActionReference(position = 3200, id = @ActionID(category = "Project", id = "org.netbeans.modules.project.ui.actions.OpenSubprojects"), path = "Projects/ensosbtprj/Actions"),
})
final class EnsoLogicalView implements LogicalViewProvider {
private final EnsoSbtProject p;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.enso.tools.enso4igv;

import java.io.IOException;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectManager;
import org.netbeans.spi.project.ProjectFactory;
import org.netbeans.spi.project.ProjectFactory2;
import org.netbeans.spi.project.ProjectState;
import org.openide.filesystems.FileObject;
import org.openide.util.ImageUtilities;
import org.openide.util.lookup.ServiceProvider;

@ServiceProvider(service = ProjectFactory.class, position = 135)
public final class EnsoProjectFactory implements ProjectFactory2 {
static int isProjectCheck(FileObject fo) {
if (!fo.isFolder()) {
return 0;
}
if (fo.getFileObject(".enso-sources") != null) {
return 1;
} else if (
fo.getFileObject("README.md") != null &&
fo.getFileObject("build.sbt") != null &&
fo.getFileObject("engine/runtime") != null
) {
return 2;
} else {
return 0;
}
}

private static Project createProjectOrNull(FileObject fo, ProjectState ps) {
return switch (isProjectCheck(fo)) {
case 1 -> new EnsoSbtProject(fo, ps);
case 2 -> new EnsoRootProject(fo, ps);
default -> null;
};
}

@Override
public boolean isProject(FileObject fo) {
return isProjectCheck(fo) != 0;
}

@Override
public Project loadProject(FileObject fo, ProjectState ps) throws IOException {
return createProjectOrNull(fo, ps);
}


public void saveProject(Project prjct) throws IOException, ClassCastException {
}

@Override
public ProjectManager.Result isProject2(FileObject fo) {
if (isProject(fo)) {
java.awt.Image img = ImageUtilities.loadImage("org/enso/tools/enso4igv/enso.svg");
return new ProjectManager.Result(ImageUtilities.image2Icon(img));
}
return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package org.enso.tools.enso4igv;

import java.io.IOException;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import javax.swing.Action;
import javax.swing.event.ChangeListener;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectManager;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.spi.project.ProjectContainerProvider;
import org.netbeans.spi.project.ProjectState;
import org.netbeans.spi.project.SubprojectProvider;
import org.netbeans.spi.project.ui.LogicalViewProvider;
import org.netbeans.spi.project.ui.support.CommonProjectActions;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.util.Lookup;
import org.openide.util.lookup.Lookups;

final class EnsoRootProject implements Project {

private final FileObject prj;
private final ProjectState ps;
private final Lookup lkp;

EnsoRootProject(FileObject fo, ProjectState ps) {
this.prj = fo;
this.ps = ps;
this.lkp = Lookups.fixed(
this,
new LogicalView(),
new Subprojects()
);
}

@Override
public FileObject getProjectDirectory() {
return prj;
}

@Override
public Lookup getLookup() {
return lkp;
}

@Override
public String toString() {
return "EnsoRootProject{prj=" + prj + "}";
}

private final class LogicalView implements LogicalViewProvider {

LogicalView() {
}

@Override
public Node createLogicalView() {
return new MainNode(EnsoRootProject.this);
}

@Override
public Node findPath(Node node, Object o) {
return org.openide.nodes.NodeOp.findChild(node, (String) o);
}
}

private final class Subprojects implements ProjectContainerProvider, SubprojectProvider, Comparator<Project> {
@Override
public Set<? extends Project> getSubprojects() {
var found = new TreeSet<Project>(this);
searchForProjects(getProjectDirectory(), found, 3);
System.err.println("subprojects: " + found);
return found;
}

private static void searchForProjects(FileObject fo, Collection<Project> found, int depth) {
if (fo.isFolder() && depth > 0) {
if (EnsoProjectFactory.isProjectCheck(fo) == 1) {
try {
var p = ProjectManager.getDefault().findProject(fo);
if (p != null) {
found.add(p);
}
} catch (IllegalArgumentException | IOException ex) {
}
} else {
for (var ch : fo.getChildren()) {
searchForProjects(ch, found, depth - 1);
}
}
}
}

@Override
public void addChangeListener(ChangeListener cl) {
}

@Override
public void removeChangeListener(ChangeListener cl) {
}

@Override
public int compare(Project o1, Project o2) {
var p1 = o1.getProjectDirectory().getPath();
var p2 = o2.getProjectDirectory().getPath();
return p1.compareTo(p2);
}

@Override
public Result getContainedProjects() {
var result = new Result(getSubprojects(), false);
System.err.println("get contained fop: " + result.getProjects());
return result;
}

private final class Factory extends ChildFactory<FileObject> {
@Override
protected boolean createKeys(List<FileObject> list) {
list.add(getProjectDirectory().getFileObject("README.md"));
list.add(getProjectDirectory().getFileObject("build.sbt"));
for (var p : getSubprojects()) {
list.add(p.getProjectDirectory());
}
return true;
}

protected Node createNodeForKey(FileObject key) {
try {
try {
var p = ProjectManager.getDefault().findProject(key);
if (p != null && p.getLookup().lookup(LogicalViewProvider.class) instanceof LogicalViewProvider lvp) {
return lvp.createLogicalView();
}
} catch (IOException | IllegalArgumentException ex) {
}
return DataObject.find(key).getNodeDelegate();
} catch (DataObjectNotFoundException ex) {
return null;
}
}
}

}

private static final class MainNode extends AbstractNode {

private final EnsoRootProject project;

private MainNode(EnsoRootProject p) {
super(Children.create(p.getLookup().lookup(Subprojects.class).new Factory(), true), Lookups.fixed(p));
this.project = p;
setDisplayName();
setIconBaseWithExtension("org/enso/tools/enso4igv/enso.svg");
}

private void setDisplayName() {
setDisplayName(ProjectUtils.getInformation(project).getDisplayName());
}

@Override
public String getHtmlDisplayName() {
return null;
}

@Override
public Action[] getActions(boolean context) {
return CommonProjectActions.forType("ensosbtprj"); // NOI18N
}
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
package org.enso.tools.enso4igv;

import java.io.IOException;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectManager;
import org.netbeans.spi.project.ProjectFactory;
import org.netbeans.spi.project.ProjectFactory2;
import org.netbeans.spi.project.ProjectState;
import org.openide.filesystems.FileObject;
import org.openide.util.ImageUtilities;
import org.openide.util.Lookup;
import org.openide.util.lookup.Lookups;
import org.openide.util.lookup.ServiceProvider;

public class EnsoSbtProject implements Project {
private final FileObject prj;
private final ProjectState ps;
private final Lookup lkp;

private EnsoSbtProject(FileObject fo, ProjectState ps) {
EnsoSbtProject(FileObject fo, ProjectState ps) {
this.prj = fo;
this.ps = ps;
this.lkp = Lookups.fixed(
Expand All @@ -39,31 +33,4 @@ public Lookup getLookup() {
public String toString() {
return "EnsoSbtProject{prj=" + prj + "}";
}

@ServiceProvider(service = ProjectFactory.class)
public static final class Factory implements ProjectFactory2 {
public boolean isProject(FileObject fo) {
return fo.getFileObject(".enso-sources") != null;
}

public Project loadProject(FileObject fo, ProjectState ps) throws IOException {
if (isProject(fo)) {
return new EnsoSbtProject(fo, ps);
} else {
return null;
}
}

public void saveProject(Project prjct) throws IOException, ClassCastException {
}

@Override
public ProjectManager.Result isProject2(FileObject fo) {
if (isProject(fo)) {
var img = ImageUtilities.loadImage("org/enso/tools/enso4igv/enso.svg");
return new ProjectManager.Result(ImageUtilities.image2Icon(img));
}
return null;
}
}
}