From 1833f91eff6a6a504b86905732160f0ef1db6460 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Fri, 5 Jun 2026 07:51:51 +0200 Subject: [PATCH] Code completion and navigation for Kotlin --- java/kotlin.editor/manifest.mf | 1 + .../nbproject/project.properties | 2 +- java/kotlin.editor/nbproject/project.xml | 88 +- .../lsp/LanguageServerProviderImpl.java | 70 ++ .../modules/kotlin/editor/lsp/Settings.java | 73 ++ .../kotlin/editor/lsp/UnconfiguredHint.java | 105 +++ .../editor/lsp/options/Bundle.properties | 3 + .../KotlinOptionsOptionsPanelController.java | 99 +++ .../lsp/options/KotlinOptionsPanel.form | 116 +++ .../lsp/options/KotlinOptionsPanel.java | 139 +++ nb/updatecenters/build.xml | 16 + nb/updatecenters/extras/build.xml | 8 + .../extras/libs.kotlin.lsp/.gitignore | 1 + .../extras/libs.kotlin.lsp/build.xml | 24 + .../extras/libs.kotlin.lsp/licenseReport.html | 790 ++++++++++++++++++ .../extras/libs.kotlin.lsp/manifest.mf | 6 + .../libs.kotlin.lsp/nbproject/build-impl.xml | 45 + .../nbproject/genfiles.properties | 8 + .../nbproject/project.properties | 20 + .../libs.kotlin.lsp/nbproject/project.xml | 72 ++ .../nbproject/suite.properties | 17 + .../release/kotlin-lsp/server.zip.external | 5 + .../libs/kotlin/lsp/Bundle.properties | 20 + .../libs/kotlin/lsp/UnpackAndInstall.java | 82 ++ .../extras/nbproject/build-impl.xml | 50 ++ .../extras/nbproject/genfiles.properties | 11 + .../extras/nbproject/platform.properties | 19 + .../extras/nbproject/platform.xml | 34 + .../extras/nbproject/project.properties | 3 + nb/updatecenters/extras/nbproject/project.xml | 9 + 30 files changed, 1926 insertions(+), 10 deletions(-) create mode 100644 java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/LanguageServerProviderImpl.java create mode 100644 java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/Settings.java create mode 100644 java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/UnconfiguredHint.java create mode 100644 java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/Bundle.properties create mode 100644 java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/KotlinOptionsOptionsPanelController.java create mode 100644 java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/KotlinOptionsPanel.form create mode 100644 java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/KotlinOptionsPanel.java create mode 100644 nb/updatecenters/extras/build.xml create mode 100644 nb/updatecenters/extras/libs.kotlin.lsp/.gitignore create mode 100644 nb/updatecenters/extras/libs.kotlin.lsp/build.xml create mode 100644 nb/updatecenters/extras/libs.kotlin.lsp/licenseReport.html create mode 100644 nb/updatecenters/extras/libs.kotlin.lsp/manifest.mf create mode 100644 nb/updatecenters/extras/libs.kotlin.lsp/nbproject/build-impl.xml create mode 100644 nb/updatecenters/extras/libs.kotlin.lsp/nbproject/genfiles.properties create mode 100644 nb/updatecenters/extras/libs.kotlin.lsp/nbproject/project.properties create mode 100644 nb/updatecenters/extras/libs.kotlin.lsp/nbproject/project.xml create mode 100644 nb/updatecenters/extras/libs.kotlin.lsp/nbproject/suite.properties create mode 100644 nb/updatecenters/extras/libs.kotlin.lsp/release/kotlin-lsp/server.zip.external create mode 100644 nb/updatecenters/extras/libs.kotlin.lsp/src/org/netbeans/libs/kotlin/lsp/Bundle.properties create mode 100644 nb/updatecenters/extras/libs.kotlin.lsp/src/org/netbeans/libs/kotlin/lsp/UnpackAndInstall.java create mode 100644 nb/updatecenters/extras/nbproject/build-impl.xml create mode 100644 nb/updatecenters/extras/nbproject/genfiles.properties create mode 100644 nb/updatecenters/extras/nbproject/platform.properties create mode 100644 nb/updatecenters/extras/nbproject/platform.xml create mode 100644 nb/updatecenters/extras/nbproject/project.properties create mode 100644 nb/updatecenters/extras/nbproject/project.xml diff --git a/java/kotlin.editor/manifest.mf b/java/kotlin.editor/manifest.mf index 5876b02ebd67..332032914ac2 100644 --- a/java/kotlin.editor/manifest.mf +++ b/java/kotlin.editor/manifest.mf @@ -3,3 +3,4 @@ AutoUpdate-Show-In-Client: true OpenIDE-Module: org.netbeans.modules.kotlin.editor OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/kotlin/editor/Bundle.properties OpenIDE-Module-Specification-Version: 1.24 +OpenIDE-Module-Recommends: org.netbeans.libs.kotlin.lsp diff --git a/java/kotlin.editor/nbproject/project.properties b/java/kotlin.editor/nbproject/project.properties index 5137752915a4..60729d846776 100644 --- a/java/kotlin.editor/nbproject/project.properties +++ b/java/kotlin.editor/nbproject/project.properties @@ -15,5 +15,5 @@ # specific language governing permissions and limitations # under the License. -javac.source=1.8 +javac.release=17 javac.compilerargs=-Xlint -Xlint:-serial diff --git a/java/kotlin.editor/nbproject/project.xml b/java/kotlin.editor/nbproject/project.xml index b05317c76f72..90cd0cbec6ee 100644 --- a/java/kotlin.editor/nbproject/project.xml +++ b/java/kotlin.editor/nbproject/project.xml @@ -42,6 +42,77 @@ 1.49 + + org.netbeans.modules.autoupdate.services + + + + 1.85 + + + + org.netbeans.modules.editor + + + + 3 + 1.116 + + + + org.netbeans.modules.editor.lib2 + + + + 1 + 2.49 + + + + org.netbeans.modules.editor.mimelookup + + + + 1 + 1.69 + + + + org.netbeans.modules.lsp.client + + + + 0 + 1.31 + + + + org.netbeans.modules.options.api + + + + 1 + 1.74 + + + + org.netbeans.modules.textmate.lexer + + + + 0 + 1.2 + + + + org.netbeans.spi.editor.hints + + + + 0 + 1.71 + + org.openide.awt @@ -74,6 +145,14 @@ 7.72 + + org.openide.modules + + + + 7.77 + + org.openide.nodes @@ -122,15 +201,6 @@ 6.81 - - org.netbeans.modules.textmate.lexer - - - - 0 - 1.2 - - diff --git a/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/LanguageServerProviderImpl.java b/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/LanguageServerProviderImpl.java new file mode 100644 index 000000000000..70fd5d4b2d13 --- /dev/null +++ b/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/LanguageServerProviderImpl.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.kotlin.editor.lsp; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.WeakHashMap; +import java.util.prefs.PreferenceChangeEvent; +import java.util.prefs.PreferenceChangeListener; +import org.netbeans.api.editor.mimelookup.MimeRegistration; +import org.netbeans.modules.lsp.client.spi.LanguageServerProvider; +import org.netbeans.modules.lsp.client.spi.ServerRestarter; +import org.openide.util.Exceptions; +import org.openide.util.Lookup; + +@MimeRegistration(mimeType="text/x-kotlin", service=LanguageServerProvider.class) +public class LanguageServerProviderImpl implements LanguageServerProvider { + + @Override + public LanguageServerDescription startServer(Lookup lookup) { + try { + String serverPath = Settings.getKotlinLSPPath(); + + if (serverPath == null || serverPath.isBlank()) { + return null; + } + + File server = new File(serverPath); + + if (!server.canExecute()) { + return null; + } + + ServerRestarter restarter = lookup.lookup(ServerRestarter.class); + Settings.settings().addPreferenceChangeListener(new PreferenceChangeListener() { + @Override + public void preferenceChange(PreferenceChangeEvent evt) { + restarter.restart(); + Settings.settings().removePreferenceChangeListener(this); + } + }); + + Process p = new ProcessBuilder(server.getAbsolutePath()).redirectError(ProcessBuilder.Redirect.INHERIT).start(); + return LanguageServerDescription.create(p.getInputStream(), p.getOutputStream(), p); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + return null; + } +} diff --git a/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/Settings.java b/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/Settings.java new file mode 100644 index 000000000000..75d5000add69 --- /dev/null +++ b/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/Settings.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.kotlin.editor.lsp; + +import java.io.File; +import java.util.prefs.Preferences; +import org.openide.modules.ModuleInfo; +import org.openide.modules.Places; +import org.openide.util.Lookup; +import org.openide.util.NbPreferences; +import org.openide.util.Utilities; + +public class Settings { + + public static final String KOTLIN_LSP_MODULE_CNB = "org.netbeans.libs.kotlin.lsp"; + private static final String KEY_KOTLIN_LSP_PATH = "lsp-path"; + + public static String getKotlinLSPPath() { + String path = getRawKotlinLSPPath(); + + if (path.isBlank()) { + return getDefaultPath(); + } else { + return path; + } + } + + public static String getRawKotlinLSPPath() { + return settings().get(KEY_KOTLIN_LSP_PATH, ""); + } + + public static void setRawKotlinLSPPath(String path) { + settings().put(KEY_KOTLIN_LSP_PATH, path); + } + + public static Preferences settings() { + return NbPreferences.forModule(Settings.class); + } + + private static String getDefaultPath() { + String version = null; + + for (ModuleInfo mi : Lookup.getDefault().lookupAll(ModuleInfo.class)) { + if (KOTLIN_LSP_MODULE_CNB.equals(mi.getCodeNameBase())) { + version = mi.getSpecificationVersion().toString(); + } + } + + if (version == null) { + return null; + } + + File serverDir = Places.getCacheSubdirectory("kotlin-lsp/" + version); + + return new File(new File(serverDir, "bin"), "kotlin-language-server" + (Utilities.isWindows() ? ".bat" : "")).getAbsolutePath(); + } +} diff --git a/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/UnconfiguredHint.java b/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/UnconfiguredHint.java new file mode 100644 index 000000000000..60bf77564d62 --- /dev/null +++ b/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/UnconfiguredHint.java @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.kotlin.editor.lsp; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.prefs.PreferenceChangeEvent; +import java.util.prefs.PreferenceChangeListener; +import javax.swing.text.Document; +import javax.swing.text.JTextComponent; +import org.netbeans.api.autoupdate.PluginInstaller; +import org.netbeans.api.editor.EditorRegistry; +import org.netbeans.modules.editor.NbEditorUtilities; +import org.netbeans.spi.editor.hints.ChangeInfo; +import org.netbeans.spi.editor.hints.ErrorDescription; +import org.netbeans.spi.editor.hints.ErrorDescriptionFactory; +import org.netbeans.spi.editor.hints.Fix; +import org.netbeans.spi.editor.hints.HintsController; +import org.netbeans.spi.editor.hints.Severity; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.modules.OnStart; +import org.openide.util.Lookup; + +@OnStart +public class UnconfiguredHint implements Runnable { + + private static final Set KOTLIN_MIME_TYPES = new HashSet<>(Arrays.asList("text/x-kotlin")); + + private JTextComponent selectedComponent; + + @Override + public void run() { + EditorRegistry.addPropertyChangeListener(new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + updateFocused(); + } + }); + Settings.settings().addPreferenceChangeListener(new PreferenceChangeListener() { + @Override + public void preferenceChange(PreferenceChangeEvent evt) { + updateFocused(); + } + }); + updateFocused(); + } + + private synchronized void updateFocused() { + selectedComponent = EditorRegistry.focusedComponent(); + if (selectedComponent == null) { + return ; + } + Document doc = selectedComponent.getDocument(); + FileObject file = NbEditorUtilities.getFileObject(doc); + if (file == null || !KOTLIN_MIME_TYPES.contains(FileUtil.getMIMEType(file))) { + return ; + } + List errors = new ArrayList<>(); + String lsp = Settings.getKotlinLSPPath(); + if (lsp == null || !new File(lsp).canExecute()) { + errors.add(ErrorDescriptionFactory.createErrorDescription(Severity.WARNING, "Kotlin LSP server not installed.", Collections.singletonList(new ConfigureLSPServer()), doc, 0)); + } + HintsController.setErrors(doc, UnconfiguredHint.class.getName(), errors); + } + + private static final class ConfigureLSPServer implements Fix { + + @Override + public String getText() { + return "Install Kotlin LSP server"; + } + + @Override + public ChangeInfo implement() throws Exception { + PluginInstaller.getDefault().install(Settings.KOTLIN_LSP_MODULE_CNB, "Kotlin LSP", Lookup.EMPTY); + return null; + } + + } + +} diff --git a/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/Bundle.properties b/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/Bundle.properties new file mode 100644 index 000000000000..3174ab810e67 --- /dev/null +++ b/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/Bundle.properties @@ -0,0 +1,3 @@ +KotlinOptionsPanel.jLabel1.text=Custom Kotlin LSP Server executable: +KotlinOptionsPanel.browse.text=... +KotlinOptionsPanel.customLSPServerExecutable.text= diff --git a/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/KotlinOptionsOptionsPanelController.java b/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/KotlinOptionsOptionsPanelController.java new file mode 100644 index 000000000000..7d2575b43476 --- /dev/null +++ b/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/KotlinOptionsOptionsPanelController.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.kotlin.editor.lsp.options; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import javax.swing.JComponent; +import javax.swing.SwingUtilities; +import org.netbeans.spi.options.OptionsPanelController; +import org.openide.util.HelpCtx; +import org.openide.util.Lookup; + +@OptionsPanelController.SubRegistration( + displayName = "#AdvancedOption_DisplayName_KotlinOptions", + keywords = "#AdvancedOption_Keywords_KotlinOptions", + keywordsCategory = "Advanced/KotlinOptions" +) +@org.openide.util.NbBundle.Messages({"AdvancedOption_DisplayName_KotlinOptions=Kotlin", "AdvancedOption_Keywords_KotlinOptions=kotlin"}) +public final class KotlinOptionsOptionsPanelController extends OptionsPanelController { + + private KotlinOptionsPanel panel; + private final PropertyChangeSupport pcs = new PropertyChangeSupport(this); + private boolean changed; + + public void update() { + getPanel().load(); + changed = false; + } + + public void applyChanges() { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + getPanel().store(); + changed = false; + } + }); + } + + public void cancel() { + // need not do anything special, if no changes have been persisted yet + } + + public boolean isValid() { + return getPanel().valid(); + } + + public boolean isChanged() { + return changed; + } + + public HelpCtx getHelpCtx() { + return null; // new HelpCtx("...ID") if you have a help set + } + + public JComponent getComponent(Lookup masterLookup) { + return getPanel(); + } + + public void addPropertyChangeListener(PropertyChangeListener l) { + pcs.addPropertyChangeListener(l); + } + + public void removePropertyChangeListener(PropertyChangeListener l) { + pcs.removePropertyChangeListener(l); + } + + private KotlinOptionsPanel getPanel() { + if (panel == null) { + panel = new KotlinOptionsPanel(this); + } + return panel; + } + + void changed() { + if (!changed) { + changed = true; + pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true); + } + pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null); + } + +} diff --git a/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/KotlinOptionsPanel.form b/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/KotlinOptionsPanel.form new file mode 100644 index 000000000000..38c88489ce2a --- /dev/null +++ b/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/KotlinOptionsPanel.form @@ -0,0 +1,116 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/KotlinOptionsPanel.java b/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/KotlinOptionsPanel.java new file mode 100644 index 000000000000..1df0e2faaaad --- /dev/null +++ b/java/kotlin.editor/src/org/netbeans/modules/kotlin/editor/lsp/options/KotlinOptionsPanel.java @@ -0,0 +1,139 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.kotlin.editor.lsp.options; + +import java.io.File; +import javax.swing.JFileChooser; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import org.netbeans.modules.kotlin.editor.lsp.Settings; + +final class KotlinOptionsPanel extends javax.swing.JPanel { + + private final KotlinOptionsOptionsPanelController controller; + + KotlinOptionsPanel(KotlinOptionsOptionsPanelController controller) { + this.controller = controller; + initComponents(); + help.setText("If the above input is empty, and the Kotlin LSP module is installed, the LSP server from that module is used."); + customLSPServerExecutable.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent de) { + controller.changed(); + } + @Override + public void removeUpdate(DocumentEvent de) { + controller.changed(); + } + @Override + public void changedUpdate(DocumentEvent de) {} + }); + // TODO listen to changes in form fields and call controller.changed() + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + customLSPServerExecutable = new javax.swing.JTextField(); + browse = new javax.swing.JButton(); + jScrollPane1 = new javax.swing.JScrollPane(); + help = new javax.swing.JTextArea(); + + org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(KotlinOptionsPanel.class, "KotlinOptionsPanel.jLabel1.text")); // NOI18N + + customLSPServerExecutable.setText(org.openide.util.NbBundle.getMessage(KotlinOptionsPanel.class, "KotlinOptionsPanel.customLSPServerExecutable.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(browse, org.openide.util.NbBundle.getMessage(KotlinOptionsPanel.class, "KotlinOptionsPanel.browse.text")); // NOI18N + browse.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + browseActionPerformed(evt); + } + }); + + jScrollPane1.setBorder(null); + + help.setColumns(20); + help.setRows(5); + help.setEnabled(false); + jScrollPane1.setViewportView(help); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(customLSPServerExecutable, javax.swing.GroupLayout.DEFAULT_SIZE, 223, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(browse)) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(customLSPServerExecutable, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(browse)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 37, Short.MAX_VALUE) + .addContainerGap()) + ); + }// //GEN-END:initComponents + + private void browseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseActionPerformed + JFileChooser fc = new JFileChooser(); + fc.setFileSelectionMode(JFileChooser.FILES_ONLY); + fc.setSelectedFile(new File(customLSPServerExecutable.getText())); + if (fc.showDialog(this, "Select") == JFileChooser.APPROVE_OPTION) { + customLSPServerExecutable.setText(fc.getSelectedFile().getAbsolutePath()); + } + }//GEN-LAST:event_browseActionPerformed + + void load() { + customLSPServerExecutable.setText(Settings.getRawKotlinLSPPath()); + } + + void store() { + Settings.setRawKotlinLSPPath(customLSPServerExecutable.getText()); + } + + boolean valid() { + // TODO check whether form is consistent and complete + return true; + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton browse; + private javax.swing.JTextField customLSPServerExecutable; + private javax.swing.JTextArea help; + private javax.swing.JLabel jLabel1; + private javax.swing.JScrollPane jScrollPane1; + // End of variables declaration//GEN-END:variables +} diff --git a/nb/updatecenters/build.xml b/nb/updatecenters/build.xml index 4054c4638275..56528ec5f69d 100644 --- a/nb/updatecenters/build.xml +++ b/nb/updatecenters/build.xml @@ -44,6 +44,22 @@ + + + + + + + + + + + + + + + + diff --git a/nb/updatecenters/extras/build.xml b/nb/updatecenters/extras/build.xml new file mode 100644 index 000000000000..765fe19cbe97 --- /dev/null +++ b/nb/updatecenters/extras/build.xml @@ -0,0 +1,8 @@ + + + + + + Builds the module suite extras. + + diff --git a/nb/updatecenters/extras/libs.kotlin.lsp/.gitignore b/nb/updatecenters/extras/libs.kotlin.lsp/.gitignore new file mode 100644 index 000000000000..567609b1234a --- /dev/null +++ b/nb/updatecenters/extras/libs.kotlin.lsp/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/nb/updatecenters/extras/libs.kotlin.lsp/build.xml b/nb/updatecenters/extras/libs.kotlin.lsp/build.xml new file mode 100644 index 000000000000..dc96f7c4bf18 --- /dev/null +++ b/nb/updatecenters/extras/libs.kotlin.lsp/build.xml @@ -0,0 +1,24 @@ + + + Builds, tests, and runs the project org.netbeans.libs.kotlin.lsp. + + diff --git a/nb/updatecenters/extras/libs.kotlin.lsp/licenseReport.html b/nb/updatecenters/extras/libs.kotlin.lsp/licenseReport.html new file mode 100644 index 000000000000..493de7cc1343 --- /dev/null +++ b/nb/updatecenters/extras/libs.kotlin.lsp/licenseReport.html @@ -0,0 +1,790 @@ + + + + Open source licenses + + +

Notice for packages:

+ + + diff --git a/nb/updatecenters/extras/libs.kotlin.lsp/manifest.mf b/nb/updatecenters/extras/libs.kotlin.lsp/manifest.mf new file mode 100644 index 000000000000..bd02c53357f6 --- /dev/null +++ b/nb/updatecenters/extras/libs.kotlin.lsp/manifest.mf @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +AutoUpdate-Show-In-Client: true +OpenIDE-Module: org.netbeans.libs.kotlin.lsp/1 +OpenIDE-Module-Localizing-Bundle: org/netbeans/libs/kotlin/lsp/Bundle.properties +OpenIDE-Module-Provides: org.netbeans.libs.kotlin.lsp +OpenIDE-Module-Specification-Version: 1.3.13 diff --git a/nb/updatecenters/extras/libs.kotlin.lsp/nbproject/build-impl.xml b/nb/updatecenters/extras/libs.kotlin.lsp/nbproject/build-impl.xml new file mode 100644 index 000000000000..499fbd7e7364 --- /dev/null +++ b/nb/updatecenters/extras/libs.kotlin.lsp/nbproject/build-impl.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + You must set 'suite.dir' to point to your containing module suite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nb/updatecenters/extras/libs.kotlin.lsp/nbproject/genfiles.properties b/nb/updatecenters/extras/libs.kotlin.lsp/nbproject/genfiles.properties new file mode 100644 index 000000000000..6c91401331c6 --- /dev/null +++ b/nb/updatecenters/extras/libs.kotlin.lsp/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=c7160377 +build.xml.script.CRC32=a0fde343 +build.xml.stylesheet.CRC32=15ca8a54@2.101 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=e177d6a2 +nbproject/build-impl.xml.script.CRC32=e00d1b11 +nbproject/build-impl.xml.stylesheet.CRC32=49aa68b0@2.101 diff --git a/nb/updatecenters/extras/libs.kotlin.lsp/nbproject/project.properties b/nb/updatecenters/extras/libs.kotlin.lsp/nbproject/project.properties new file mode 100644 index 000000000000..fcb3c24d2462 --- /dev/null +++ b/nb/updatecenters/extras/libs.kotlin.lsp/nbproject/project.properties @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +javac.release=17 +is.autoload=true +license.file=${basedir}/licenseReport.html +nbm.needs.restart = true diff --git a/nb/updatecenters/extras/libs.kotlin.lsp/nbproject/project.xml b/nb/updatecenters/extras/libs.kotlin.lsp/nbproject/project.xml new file mode 100644 index 000000000000..c5fd03467b5b --- /dev/null +++ b/nb/updatecenters/extras/libs.kotlin.lsp/nbproject/project.xml @@ -0,0 +1,72 @@ + + + org.netbeans.modules.apisupport.project + + + org.netbeans.libs.kotlin.lsp + + + + org.openide.filesystems + + + + 9.42 + + + + org.openide.modules + + + + 7.77 + + + + org.openide.util + + + + 9.37 + + + + org.openide.util.lookup + + + + 8.63 + + + + org.openide.util.ui + + + + 9.38 + + + + + + + diff --git a/nb/updatecenters/extras/libs.kotlin.lsp/nbproject/suite.properties b/nb/updatecenters/extras/libs.kotlin.lsp/nbproject/suite.properties new file mode 100644 index 000000000000..ca0e1b903a5b --- /dev/null +++ b/nb/updatecenters/extras/libs.kotlin.lsp/nbproject/suite.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +suite.dir=${basedir}/.. diff --git a/nb/updatecenters/extras/libs.kotlin.lsp/release/kotlin-lsp/server.zip.external b/nb/updatecenters/extras/libs.kotlin.lsp/release/kotlin-lsp/server.zip.external new file mode 100644 index 000000000000..c4cf49868957 --- /dev/null +++ b/nb/updatecenters/extras/libs.kotlin.lsp/release/kotlin-lsp/server.zip.external @@ -0,0 +1,5 @@ +CRC: 562379239 +URL: https://github.com/fwcd/kotlin-language-server/releases/download/1.3.13/server.zip +SIZE: 87291855 +MessageDigest: SHA-256 4fe7d71d087b307c7869036171bd9d8c6a4284cd7c25b89098b0a24eb2d9b6d2 +MessageDigest: SHA-512 54f26288d8d6bff738ea2be118083d99b81279f13ada4ef6e290b470de740618f28dba4599355a429573807be9e40a10f7baca71495dfccb1cfecfcaff2139ed diff --git a/nb/updatecenters/extras/libs.kotlin.lsp/src/org/netbeans/libs/kotlin/lsp/Bundle.properties b/nb/updatecenters/extras/libs.kotlin.lsp/src/org/netbeans/libs/kotlin/lsp/Bundle.properties new file mode 100644 index 000000000000..88a617aa188a --- /dev/null +++ b/nb/updatecenters/extras/libs.kotlin.lsp/src/org/netbeans/libs/kotlin/lsp/Bundle.properties @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +OpenIDE-Module-Display-Category=Kotlin +OpenIDE-Module-Name=Kotlin LSP +OpenIDE-Module-Short-Description=Kotlin Language Server diff --git a/nb/updatecenters/extras/libs.kotlin.lsp/src/org/netbeans/libs/kotlin/lsp/UnpackAndInstall.java b/nb/updatecenters/extras/libs.kotlin.lsp/src/org/netbeans/libs/kotlin/lsp/UnpackAndInstall.java new file mode 100644 index 000000000000..2afd2503f4ed --- /dev/null +++ b/nb/updatecenters/extras/libs.kotlin.lsp/src/org/netbeans/libs/kotlin/lsp/UnpackAndInstall.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.libs.kotlin.lsp; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Enumeration; +import java.util.prefs.Preferences; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.modules.InstalledFileLocator; +import org.openide.modules.OnStart; +import org.openide.modules.Places; +import org.openide.util.*; + +@OnStart +public class UnpackAndInstall implements Runnable { + + private static final String KEY_KOTLIN_LSP_INSTALLED_COUNTER = "lsp-installed-counter"; + + public void run() { + File serverDir = Places.getCacheSubdirectory("kotlin-lsp/1.3.13"); + File lspExecutable = new File(new File(serverDir, "bin"), "kotlin-language-server"); + boolean modified = false; + + if (!lspExecutable.canRead()) { + File serverZip = InstalledFileLocator.getDefault().locate("kotlin-lsp/server.zip", "org.netbeans.libs.kotlin.lsp", false); + FileObject serverContent = FileUtil.getArchiveRoot(FileUtil.toFileObject(serverZip)); + Enumeration children = serverContent.getChildren(true); + + while (children.hasMoreElements()) { + FileObject current = children.nextElement(); + + if (!current.isData()) { + continue; + } + + File target = new File(serverDir, FileUtil.getRelativePath(serverContent, current).replace("server/", "")); + + target.getParentFile().mkdirs(); + + try (InputStream in = current.getInputStream(); + OutputStream out = new FileOutputStream(target)) { + FileUtil.copy(in, out); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + modified = true; + } + + if (!lspExecutable.canExecute() && !Utilities.isWindows()) { + lspExecutable.setExecutable(true, true); + modified = true; + } + + if (modified) { + Preferences kotlinEditorSettingsRoot = NbPreferences.root().node("org/netbeans/modules/kotlin/editor");//NOI18N + kotlinEditorSettingsRoot.putInt(KEY_KOTLIN_LSP_INSTALLED_COUNTER, kotlinEditorSettingsRoot.getInt(KEY_KOTLIN_LSP_INSTALLED_COUNTER, 0) + 1); + } + } + +} diff --git a/nb/updatecenters/extras/nbproject/build-impl.xml b/nb/updatecenters/extras/nbproject/build-impl.xml new file mode 100644 index 000000000000..b721535a5e59 --- /dev/null +++ b/nb/updatecenters/extras/nbproject/build-impl.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nb/updatecenters/extras/nbproject/genfiles.properties b/nb/updatecenters/extras/nbproject/genfiles.properties new file mode 100644 index 000000000000..a6b4e4037c95 --- /dev/null +++ b/nb/updatecenters/extras/nbproject/genfiles.properties @@ -0,0 +1,11 @@ +build.xml.data.CRC32=b590e819 +build.xml.script.CRC32=6e1aa5dd +build.xml.stylesheet.CRC32=70ce5c94@2.101 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=b590e819 +nbproject/build-impl.xml.script.CRC32=1de6f712 +nbproject/build-impl.xml.stylesheet.CRC32=473dc988@2.101 +nbproject/platform.xml.data.CRC32=b590e819 +nbproject/platform.xml.script.CRC32=6dcbd131 +nbproject/platform.xml.stylesheet.CRC32=ae64f0b6@2.101 diff --git a/nb/updatecenters/extras/nbproject/platform.properties b/nb/updatecenters/extras/nbproject/platform.properties new file mode 100644 index 000000000000..ae910badd680 --- /dev/null +++ b/nb/updatecenters/extras/nbproject/platform.properties @@ -0,0 +1,19 @@ +cluster.path=\ + ${nbplatform.active.dir}/javafx:\ + ${nbplatform.active.dir}/websvccommon:\ + ${nbplatform.active.dir}/enterprise:\ + ${nbplatform.active.dir}/profiler:\ + ${nbplatform.active.dir}/php:\ + ${nbplatform.active.dir}/apisupport:\ + ${nbplatform.active.dir}/webcommon:\ + ${nbplatform.active.dir}/nb:\ + ${nbplatform.active.dir}/ide:\ + ${nbplatform.active.dir}/extide:\ + ${nbplatform.active.dir}/java:\ + ${nbplatform.active.dir}/groovy:\ + ${nbplatform.active.dir}/platform:\ + ${nbplatform.active.dir}/extra:\ + ${nbplatform.active.dir}/cpplite:\ + ${nbplatform.active.dir}/ergonomics:\ + ${nbplatform.active.dir}/harness +nbplatform.active=default diff --git a/nb/updatecenters/extras/nbproject/platform.xml b/nb/updatecenters/extras/nbproject/platform.xml new file mode 100644 index 000000000000..020ab53b8abd --- /dev/null +++ b/nb/updatecenters/extras/nbproject/platform.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nb/updatecenters/extras/nbproject/project.properties b/nb/updatecenters/extras/nbproject/project.properties new file mode 100644 index 000000000000..fd89e4249170 --- /dev/null +++ b/nb/updatecenters/extras/nbproject/project.properties @@ -0,0 +1,3 @@ +modules=\ + ${project.org.netbeans.libs.kotlin.lsp} +project.org.netbeans.libs.kotlin.lsp=libs.kotlin.lsp diff --git a/nb/updatecenters/extras/nbproject/project.xml b/nb/updatecenters/extras/nbproject/project.xml new file mode 100644 index 000000000000..5c13128535b6 --- /dev/null +++ b/nb/updatecenters/extras/nbproject/project.xml @@ -0,0 +1,9 @@ + + + org.netbeans.modules.apisupport.project.suite + + + extras + + +