diff --git a/ide/lsp.client/nbproject/project.xml b/ide/lsp.client/nbproject/project.xml
index b5bb7c5e5a46..f2ef766bd0dc 100644
--- a/ide/lsp.client/nbproject/project.xml
+++ b/ide/lsp.client/nbproject/project.xml
@@ -85,6 +85,15 @@
1.50
+
+ org.netbeans.core.multiview
+
+
+
+ 1
+ 1.71
+
+
org.netbeans.libs.flexmark
diff --git a/ide/lsp.client/src/org/netbeans/modules/lsp/client/options/GenericDataObject.java b/ide/lsp.client/src/org/netbeans/modules/lsp/client/options/GenericDataObject.java
index c438bebfd16b..9f70924a531a 100644
--- a/ide/lsp.client/src/org/netbeans/modules/lsp/client/options/GenericDataObject.java
+++ b/ide/lsp.client/src/org/netbeans/modules/lsp/client/options/GenericDataObject.java
@@ -20,9 +20,7 @@
import java.awt.Image;
import java.beans.PropertyVetoException;
-import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStream;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
@@ -30,7 +28,7 @@
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import javax.imageio.ImageIO;
+import org.netbeans.core.spi.multiview.text.MultiViewEditorElement;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataLoaderPool;
@@ -41,7 +39,7 @@
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.util.Exceptions;
-import org.openide.util.ImageUtilities;
+import org.openide.util.Lookup;
/**
*
@@ -57,7 +55,7 @@ public class GenericDataObject extends MultiDataObject {
public GenericDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {
super(pf, loader);
this.mimeType = FileUtil.getMIMEType(pf);
- registerEditor(mimeType, false);
+ registerEditor(mimeType, true);
synchronized (REGISTRY) {
REGISTRY.add(new WeakReference<>(this));
}
@@ -144,5 +142,8 @@ public static Factory factory() {
}
};
}
-}
+ public static MultiViewEditorElement createEditor(Lookup lkp) {
+ return new MultiViewEditorElement(lkp);
+ }
+}
\ No newline at end of file
diff --git a/ide/lsp.client/src/org/netbeans/modules/lsp/client/options/LanguageStorage.java b/ide/lsp.client/src/org/netbeans/modules/lsp/client/options/LanguageStorage.java
index a00dfde1909b..31d61b38fce0 100644
--- a/ide/lsp.client/src/org/netbeans/modules/lsp/client/options/LanguageStorage.java
+++ b/ide/lsp.client/src/org/netbeans/modules/lsp/client/options/LanguageStorage.java
@@ -33,18 +33,19 @@
import java.util.Set;
import java.util.stream.Collectors;
import javax.swing.event.ChangeEvent;
-import org.eclipse.tm4e.core.registry.IRegistryOptions;
-import org.eclipse.tm4e.core.registry.Registry;
import org.netbeans.modules.lsp.client.debugger.api.RegisterDAPBreakpoints;
import org.eclipse.tm4e.core.internal.grammar.raw.RawGrammarReader;
import org.eclipse.tm4e.core.registry.IGrammarSource;
+import org.netbeans.core.spi.multiview.MultiViewFactory;
import org.netbeans.modules.textmate.lexer.TextmateTokenId;
import org.netbeans.spi.navigator.NavigatorPanel;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataLoaderPool;
import org.openide.loaders.DataObject;
+import org.openide.modules.OnStart;
import org.openide.util.Exceptions;
+import org.openide.util.NbBundle.Messages;
import org.openide.util.NbPreferences;
/**
@@ -53,6 +54,23 @@
*/
public class LanguageStorage {
+ /**
+ * Startup handler for language store. This handler reapplies the language
+ * descriptions at startup so that the runtime view matches the one expected
+ * by the running IDE. This is mostly relevant when the IDE requires new
+ * files (like the MultiView description when that feature was introduced).
+ */
+ @OnStart
+ public static class StartupHandler implements Runnable {
+
+ @Override
+ public void run() {
+ // load language definitions and reapply them
+ store(load());
+ }
+
+ }
+
private static final String KEY = "language.descriptions";
static List load() {
@@ -60,6 +78,7 @@ static List load() {
return Arrays.stream(new Gson().fromJson(descriptions, LanguageDescription[].class)).collect(Collectors.toList());
}
+ @Messages("Source=&Source")
static void store(List languages) {
Set originalMimeTypes = load().stream().map(ld -> ld.mimeType).collect(Collectors.toSet());
Set mimeTypesToClear = new HashSet<>(originalMimeTypes);
@@ -74,7 +93,7 @@ static void store(List languages) {
Exceptions.printStackTrace(ex);
}
}
-
+
for (FileObject children : mimeResolver.getChildren()) {
if ("synthetic".equals(children.getAttribute(LanguageServersPanel.class.getName()))) {
try {
@@ -133,6 +152,19 @@ static void store(List languages) {
loader.setAttribute("dataObjectClass", GenericDataObject.class.getName());
loader.setAttribute("mimeType", description.mimeType);
+ deleteConfigFileIfExists("Editors/" + description.mimeType + "/MultiView/source.instance");
+ FileObject multiViewRegistration = FileUtil.createData(FileUtil.getConfigRoot(), "Editors/" + description.mimeType + "/MultiView/source.instance");
+ Method createMultiViewDescription = MultiViewFactory.class.getDeclaredMethod("createMultiViewDescription", Map.class);
+ multiViewRegistration.setAttribute("methodvalue:instanceCreate", createMultiViewDescription);
+ multiViewRegistration.setAttribute("instanceClass", "org.netbeans.core.multiview.ContextAwareDescription");
+ multiViewRegistration.setAttribute("class", GenericDataObject.class.getName());
+ multiViewRegistration.setAttribute("mimeType", description.mimeType);
+ multiViewRegistration.setAttribute("displayName", Bundle.Source());
+ multiViewRegistration.setAttribute("preferredID", "lsp.source");
+ multiViewRegistration.setAttribute("persistenceType", 1);
+ multiViewRegistration.setAttribute("position", 100);
+ multiViewRegistration.setAttribute("method", "createEditor");
+
FileObject icon = FileUtil.getConfigFile("Loaders/" + description.mimeType + "/Factories/icon.png");
if (icon != null) {
icon.delete();
@@ -146,8 +178,9 @@ static void store(List languages) {
}
loader.setAttribute("iconBase", icon.getNameExt());
+ multiViewRegistration.setAttribute("iconBase", icon.getNameExt());
}
-
+
if (description.languageServer != null && !description.languageServer.isEmpty()) {
FileObject langServer = FileUtil.createData(FileUtil.getConfigRoot(), "Editors/" + description.mimeType + "/org-netbeans-modules-lsp-client-options-GenericLanguageServer.instance");
langServer.setAttribute("command", description.languageServer.split(" "));
@@ -187,6 +220,7 @@ static void store(List languages) {
deleteConfigFileIfExists("Loaders/" + mimeType + "/Factories/data-object.instance");
deleteConfigFileIfExists("Editors/" + mimeType + "/generic-breakpoints.instance");
deleteConfigFileIfExists("Editors/" + mimeType + "/GlyphGutterActions/generic-toggle-breakpoint.shadow");
+ deleteConfigFileIfExists("Editors/" + mimeType + "/MultiView/source.instance");
} catch (Exception ex) {
Exceptions.printStackTrace(ex);
}
diff --git a/platform/openide.filesystems/src/org/openide/filesystems/MIMESupport.java b/platform/openide.filesystems/src/org/openide/filesystems/MIMESupport.java
index 347fe2c20fba..08c9b5caa805 100644
--- a/platform/openide.filesystems/src/org/openide/filesystems/MIMESupport.java
+++ b/platform/openide.filesystems/src/org/openide/filesystems/MIMESupport.java
@@ -254,8 +254,8 @@ private static synchronized List declarativeResolvers() {
try {
// For now, just assume it has the right DTD. Could check this if desired.
declmimes.add(MIMEResolverImpl.forDescriptor(f)); // NOI18N
- } catch (IOException ex) {
- Exceptions.printStackTrace(ex);
+ } catch (IOException | IllegalArgumentException ex) {
+ ERR.log(Level.INFO, "Failed to parse declarative MIMEResolver: " + f, ex);
}
}
}