This is an automated email from the ASF dual-hosted git repository.

matthiasblaesing pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new 952f6a9  Only register LSP based formatting if MimePath has language 
server
     new 8da7ae9  Merge pull request #1996 from 
matthiasblaesing/lsp_formatting_fix
952f6a9 is described below

commit 952f6a909b77ab5a7dfd253b988b81c912e2869a
Author: Matthias Bläsing <mblaes...@doppel-helix.eu>
AuthorDate: Sun Mar 1 21:05:04 2020 +0100

    Only register LSP based formatting if MimePath has language server
    
    It was observed that XML formatting did not work after enabling LSP
    formatting. The problem was caused by the MimeLookup for application/xml
    that returned two ReformatTask.Factory implementations. One was the
    right factory, the other the Formatter provided by the LSP Client
    module.
    
    Instead of registering the ReformatTask.Factory of the LSP client module
    on the empty mime path, it is now dynamically registered by a
    MimeDataProvider (LspMimeDataProvider). That MimeDataProvider ensures
    that the lsp based formatter is only registered if a
    LanguageServerProvider is present on the targetted mime path.
    
    As an implementation note the LspMimeDataProvider is registered with a
    position, which ensures, that it is registered with higher priority than
    LegacyFormattersProvider which unconditionally registers a formatter.
    Having a higher priority (any position has higher priority than no
    position) ensures LspMimeDataProvider is queried first.
---
 .../modules/lsp/client/bindings/Formatter.java     | 16 ++--
 .../lsp/client/bindings/LspMimeDataProvider.java   | 86 ++++++++++++++++++++++
 2 files changed, 96 insertions(+), 6 deletions(-)

diff --git 
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/Formatter.java 
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/Formatter.java
index f399461..045e490 100644
--- a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/Formatter.java
+++ b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/Formatter.java
@@ -19,7 +19,6 @@
 package org.netbeans.modules.lsp.client.bindings;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.logging.Level;
@@ -32,7 +31,6 @@ import org.eclipse.lsp4j.FormattingOptions;
 import org.eclipse.lsp4j.Range;
 import org.eclipse.lsp4j.TextDocumentIdentifier;
 import org.eclipse.lsp4j.TextEdit;
-import org.netbeans.api.editor.mimelookup.MimeRegistration;
 import org.netbeans.modules.editor.NbEditorUtilities;
 import org.netbeans.modules.editor.indent.api.IndentUtils;
 import org.netbeans.modules.editor.indent.spi.Context;
@@ -47,12 +45,18 @@ public class Formatter implements ReformatTask {
 
     private static final Logger LOG = 
Logger.getLogger(Formatter.class.getName());
 
-    @MimeRegistration(mimeType = "", service = ReformatTask.Factory.class)
     public static class Factory implements ReformatTask.Factory {
 
         @Override
         public ReformatTask createTask(Context context) {
-            return new Formatter(context);
+            FileObject file = 
NbEditorUtilities.getFileObject(context.document());
+            if (file != null) {
+                LSPBindings bindings = LSPBindings.getBindings(file);
+                if (bindings != null) {
+                    return new Formatter(context);
+                }
+            }
+            return null;
         }
 
     }
@@ -66,7 +70,7 @@ public class Formatter implements ReformatTask {
     @Override
     public void reformat() throws BadLocationException {
         FileObject file = NbEditorUtilities.getFileObject(ctx.document());
-        if(file != null) {
+        if (file != null) {
             LSPBindings bindings = LSPBindings.getBindings(file);
             if (bindings != null) {
                 Boolean documentFormatting = 
bindings.getInitResult().getCapabilities().getDocumentFormattingProvider();
@@ -120,7 +124,7 @@ public class Formatter implements ReformatTask {
     }
 
     private void applyTextEdits(List<TextEdit> edits) {
-        if(ctx.document() instanceof StyledDocument) {
+        if (ctx.document() instanceof StyledDocument) {
             NbDocument.runAtomic((StyledDocument) ctx.document(), () -> {
                 Utils.applyEditsNoLock(ctx.document(), edits, 
ctx.startOffset(), ctx.endOffset());
             });
diff --git 
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/LspMimeDataProvider.java
 
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/LspMimeDataProvider.java
new file mode 100644
index 0000000..9f97b1a
--- /dev/null
+++ 
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/LspMimeDataProvider.java
@@ -0,0 +1,86 @@
+/*
+ * 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.lsp.client.bindings;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.netbeans.api.editor.mimelookup.MimeLookup;
+import org.netbeans.api.editor.mimelookup.MimePath;
+import org.netbeans.modules.editor.indent.spi.ReformatTask;
+import org.netbeans.modules.lsp.client.bindings.Formatter.Factory;
+import org.netbeans.modules.lsp.client.spi.LanguageServerProvider;
+import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
+import org.openide.util.Lookup;
+import org.openide.util.LookupEvent;
+import org.openide.util.LookupListener;
+import org.openide.util.lookup.Lookups;
+import org.openide.util.lookup.ProxyLookup;
+import org.openide.util.lookup.ServiceProvider;
+
+/**
+ * LspMimeDataProvider allows dynamically registering the lsp based formatter
+ * into a MimeLookup if a matching LanguageServerProvider is found on the
+ * MimeLookup.
+ *
+ * <p>The assumption is: if a LanguageServerProvider is present, we want to
+ * provide the Formatting from it.</p>
+ */
+@ServiceProvider(service = MimeDataProvider.class, position = 1000)
+public class LspMimeDataProvider implements MimeDataProvider {
+
+    private static final Factory lspFormatter = new Formatter.Factory();
+    private static final Lookup lspFormatterLookup = 
Lookups.fixed(lspFormatter);
+
+    @Override
+    public Lookup getLookup(MimePath mimePath) {
+        return new MimeLookupMonitoringLookup(mimePath);
+    }
+
+    private static class MimeLookupMonitoringLookup extends ProxyLookup 
implements LookupListener {
+        private final AtomicBoolean initialized = new AtomicBoolean();
+        private final Result<LanguageServerProvider> lspResult;
+
+        public MimeLookupMonitoringLookup(MimePath mimePath) {
+            // Monitor the MimeLookup - if it changes, the lookup we provided
+            // needs to be updated on the next query
+            lspResult = MimeLookup.getLookup(mimePath)
+                .lookupResult(LanguageServerProvider.class);
+            lspResult.addLookupListener(this);
+        }
+
+        @Override
+        public void resultChanged(LookupEvent ev) {
+            initialized.set(false);
+        }
+
+        @Override
+        protected void beforeLookup(Lookup.Template<?> template) {
+            super.beforeLookup(template);
+            final Class<?> clz = template.getType();
+            if (ReformatTask.Factory.class.isAssignableFrom(clz)) {
+                if (!initialized.getAndSet(true)) {
+                    if (lspResult.allInstances().isEmpty()) {
+                        setLookups();
+                    } else {
+                        setLookups(lspFormatterLookup);
+                    }
+                }
+            }
+        }
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org
For additional commands, e-mail: commits-h...@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to