JaroslavTulach commented on a change in pull request #3333:
URL: https://github.com/apache/netbeans/pull/3333#discussion_r757741473



##########
File path: 
ide/editor.completion/src/org/netbeans/spi/editor/completion/support/CompletionUtilities.java
##########
@@ -160,5 +164,152 @@ public static void renderHtml(ImageIcon icon, String 
leftHtmlText, String rightH
                 defaultFont, defaultColor, PatchedHtmlRenderer.STYLE_TRUNCATE, 
true, selected);
         }
     }
-    
+
+    /**
+     * Creates a builder for simple {@link CompletionItem} instances.
+     *
+     * @param insertText a text to be inserted into a document when selecting 
the item.
+     * @return newly created builder
+     *
+     * @since 1.60
+     */
+    public static CompletionItemBuilder newCompletionItemBuilder(String 
insertText) {

Review comment:
       I assume that, in the future, there could be
   ```java
   public static CompletionItemBuilder 
newCompletionItemBuilder(org.netbeans.api.lsp.Completion c)
   ```
   that would initialize the builder from the values of 
[Completion](https://bits.netbeans.org/12.5/javadoc/org-netbeans-api-lsp/org/netbeans/api/lsp/Completion.html).

##########
File path: 
ide/editor.completion/src/org/netbeans/spi/editor/completion/support/CompletionUtilities.java
##########
@@ -160,5 +164,152 @@ public static void renderHtml(ImageIcon icon, String 
leftHtmlText, String rightH
                 defaultFont, defaultColor, PatchedHtmlRenderer.STYLE_TRUNCATE, 
true, selected);
         }
     }
-    
+
+    /**
+     * Creates a builder for simple {@link CompletionItem} instances.
+     *
+     * @param insertText a text to be inserted into a document when selecting 
the item.
+     * @return newly created builder
+     *
+     * @since 1.60
+     */
+    public static CompletionItemBuilder newCompletionItemBuilder(String 
insertText) {
+        return new CompletionItemBuilder(insertText);
+    }
+
+    /**
+     * Builder for simple {@link CompletionItem} instances.
+     *
+     * @since 1.60
+     */
+    public static final class CompletionItemBuilder {
+
+        private String insertText;
+        private String insertTemplateText;
+        private int startOffset = -1;
+        private int endOffset = -1;
+        private String iconResource;
+        private String leftHtmlText;
+        private String rightHtmlText;
+        private int sortPriority = 10000;
+        private CharSequence sortText;
+        private BiConsumer<JTextComponent, Boolean> onSelectCallback;
+
+        private CompletionItemBuilder(String insertText) {
+            this.insertText = insertText;
+        }
+
+        /**
+         * A text to be inserted into a document when selecting the item.
+         *
+         * @since 1.60
+         */
+        public CompletionItemBuilder insertText(String insertText) {
+            this.insertText = insertText;
+            return this;
+        }
+
+        /**
+         * A text of the template to be inserted into a document when 
selecting the item.
+         *
+         * @since 1.60
+         */
+        public CompletionItemBuilder insertTemplate(String templateText) {
+            this.insertTemplateText = templateText;
+            return this;
+        }
+
+        /**
+         * Start offset of the region to be removed on the item's selection. 
If omitted,
+         * the caret offset would be used.
+         *
+         * @since 1.60
+         */
+        public CompletionItemBuilder startOffset(int offset) {
+            this.startOffset = offset;
+            return this;
+        }
+
+        /**
+         * Start offset of the region to be removed on the item's selection. 
If omitted,
+         * the caret offset would be used.
+         *
+         * @since 1.60
+         */
+        public CompletionItemBuilder endOffset(int offset) {
+            this.endOffset = offset;
+            return this;
+        }
+
+        /**
+         * Resource path of the icon. It may be null which means that no icon 
will be displayed.
+         *
+         * @since 1.60
+         */
+        public CompletionItemBuilder iconResource(String iconResource) {
+            this.iconResource = iconResource;
+            return this;
+        }
+
+        /**
+         * An html text that will be displayed on the left side of the item 
next to the icon.
+         * If omitted, insert text would be used instead.
+         *
+         * @since 1.60
+         */
+        public CompletionItemBuilder leftHtmlText(String leftHtmlText) {
+            this.leftHtmlText = leftHtmlText;
+            return this;
+        }
+
+        /**
+         * An html text that will be aligned to the right edge of the item.
+         *
+         * @since 1.60
+         */
+        public CompletionItemBuilder rightHtmlText(String rightHtmlText) {
+            this.rightHtmlText = rightHtmlText;
+            return this;
+        }
+
+        /**
+         * Item's priority. A lower value means a lower index of the item in 
the completion result list.
+         *
+         * @since 1.60
+         */
+        public CompletionItemBuilder sortPriority(int sortPriority) {
+            this.sortPriority = sortPriority;
+            return this;
+        }
+
+        /**
+         * A text used to sort items alphabetically. If omitted, insertText 
would be used instead.
+         *
+         * @since 1.60
+         */
+        public CompletionItemBuilder sortText(CharSequence sortText) {
+            this.sortText = sortText;
+            return this;
+        }
+
+        /**
+         * A callback to process the item insertion. Should be used for 
complex cases
+         * when a simple insertText insertion is not sufficient.
+         *
+         * @since 1.60
+         */
+        public CompletionItemBuilder onSelect(BiConsumer<JTextComponent, 
Boolean> callback) {

Review comment:
       Meaning of `Boolean` in the callback isn't explained. Could 
`JTextComponent` be replaced just with `Document`?
   
   How do you envision evolution of this method? What if you need to add 
another parameter in the future?

##########
File path: 
enterprise/micronaut/src/org/netbeans/modules/micronaut/completion/MicronautDataCompletionProvider.java
##########
@@ -51,17 +56,47 @@ public int getAutoQueryTypes(JTextComponent component, 
String typedText) {
 
     private static class MicronautDataCompletionQuery extends 
AsyncCompletionQuery {
 
+        private static final String ICON = 
"org/netbeans/modules/micronaut/resources/micronaut.png";
+
         @Override
         protected void query(CompletionResultSet resultSet, Document doc, int 
caretOffset) {
             MicronautDataCompletionTask task = new 
MicronautDataCompletionTask();
-            resultSet.addAllItems(task.query(doc, caretOffset, new 
MicronautDataCompletionTask.ItemFactory<MicronautDataCompletionItem>() {
+            resultSet.addAllItems(task.query(doc, caretOffset, new 
MicronautDataCompletionTask.ItemFactory<CompletionItem>() {
                 @Override
-                public MicronautDataCompletionItem 
createFinderMethodItem(String name, String returnType, int offset) {
-                    return 
MicronautDataCompletionItem.createFinderMethodItem(name, returnType, offset);
+                public CompletionItem createFinderMethodItem(String name, 
String returnType, int offset) {
+                    CompletionUtilities.CompletionItemBuilder builder = 
CompletionUtilities.newCompletionItemBuilder(name)
+                            .startOffset(offset)
+                            .iconResource(ICON)
+                            .leftHtmlText("<b>" + name + "</b>")
+                            .sortPriority(10);
+                    if (returnType != null) {
+                        builder.onSelect((component, overwrite) -> {
+                            final BaseDocument doc = (BaseDocument) 
component.getDocument();

Review comment:
       Can we avoid dependency on `BaseDocument` and use just `Document` or 
`NbDocument` utilities?
   
   I don't understand why `doc.remove` must be enclosed in `runAtomic` section. 
Isn't it atomic by default? Why not call just `doc.remove` without the 
`Runnable` wrapper?

##########
File path: 
enterprise/micronaut/src/org/netbeans/modules/micronaut/completion/MicronautDataCompletionProvider.java
##########
@@ -51,17 +56,47 @@ public int getAutoQueryTypes(JTextComponent component, 
String typedText) {
 
     private static class MicronautDataCompletionQuery extends 
AsyncCompletionQuery {
 
+        private static final String ICON = 
"org/netbeans/modules/micronaut/resources/micronaut.png";
+
         @Override
         protected void query(CompletionResultSet resultSet, Document doc, int 
caretOffset) {
             MicronautDataCompletionTask task = new 
MicronautDataCompletionTask();
-            resultSet.addAllItems(task.query(doc, caretOffset, new 
MicronautDataCompletionTask.ItemFactory<MicronautDataCompletionItem>() {
+            resultSet.addAllItems(task.query(doc, caretOffset, new 
MicronautDataCompletionTask.ItemFactory<CompletionItem>() {
                 @Override
-                public MicronautDataCompletionItem 
createFinderMethodItem(String name, String returnType, int offset) {
-                    return 
MicronautDataCompletionItem.createFinderMethodItem(name, returnType, offset);
+                public CompletionItem createFinderMethodItem(String name, 
String returnType, int offset) {
+                    CompletionUtilities.CompletionItemBuilder builder = 
CompletionUtilities.newCompletionItemBuilder(name)

Review comment:
       OK, using a builder is a good idea from [evolution 
perspective](http://wiki.apidesign.org/wiki/Evolution). Builder pattern is 
easily extensible.

##########
File path: 
enterprise/micronaut/src/org/netbeans/modules/micronaut/completion/MicronautConfigCompletionProvider.java
##########
@@ -89,17 +121,133 @@ public MicronautConfigCompletionQuery(Project project) {
 
         @Override
         protected void query(CompletionResultSet resultSet, Document doc, int 
caretOffset) {
-            resultSet.addAllItems(new 
MicronautConfigCompletionTask().query(doc, caretOffset, project, new 
MicronautConfigCompletionTask.ItemFactory<MicronautConfigCompletionItem>() {
+            resultSet.addAllItems(new 
MicronautConfigCompletionTask().query(doc, caretOffset, project, new 
MicronautConfigCompletionTask.ItemFactory<CompletionItem>() {
                 @Override
-                public MicronautConfigCompletionItem 
createPropertyItem(ConfigurationMetadataProperty property, int offset, int 
baseIndent, int indentLevelSize, int idx) {
+                public CompletionItem 
createPropertyItem(ConfigurationMetadataProperty property, int offset, int 
baseIndent, int indentLevelSize, int idx) {
                     resultSet.setAnchorOffset(offset);
-                    return 
MicronautConfigCompletionItem.createPropertyItem(property, offset, baseIndent, 
indentLevelSize, idx);
+                    String propName = property.getId();
+                    String propType = property.getType();
+                    CompletionUtilities.CompletionItemBuilder builder = 
CompletionUtilities.newCompletionItemBuilder(propName)
+                            .iconResource(ICON)
+                            .leftHtmlText(property.isDeprecated()
+                                    ? PROPERTY_NAME_COLOR + "<s>" + propName + 
"</s></font>"
+                                    : PROPERTY_NAME_COLOR + propName + 
"</font>")
+                            .sortPriority(property.isDeprecated() ? 30 : 20)
+                            .documentationTask(() -> {
+                                return new AsyncCompletionTask(new 
MicronautConfigDocumentationQuery(property));
+                            })
+                            .onSelect((component, overwrite) -> {
+                                try {

Review comment:
       The following logic is a bit more complex than I'd like it to be. 
Somehow I find the [lsp 
version](https://github.com/apache/netbeans/blob/071012fd3528ffb1d2966ed0405919e6a8c900b9/enterprise/micronaut/src/org/netbeans/modules/micronaut/completion/MicronautDataCompletionCollector.java)
 simpler. I don't get why the NetBeans version has to be so verbose while the 
VSCode version fits into seven lines of code.

##########
File path: 
ide/editor.completion/src/org/netbeans/spi/editor/completion/support/CompletionUtilities.java
##########
@@ -160,5 +164,152 @@ public static void renderHtml(ImageIcon icon, String 
leftHtmlText, String rightH
                 defaultFont, defaultColor, PatchedHtmlRenderer.STYLE_TRUNCATE, 
true, selected);
         }
     }
-    
+
+    /**
+     * Creates a builder for simple {@link CompletionItem} instances.
+     *
+     * @param insertText a text to be inserted into a document when selecting 
the item.
+     * @return newly created builder
+     *
+     * @since 1.60
+     */
+    public static CompletionItemBuilder newCompletionItemBuilder(String 
insertText) {
+        return new CompletionItemBuilder(insertText);
+    }
+
+    /**
+     * Builder for simple {@link CompletionItem} instances.

Review comment:
       Sample `{@codesnippet ...}` with the simplest possible usage to create 
some useful code completion content might be nice here.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

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

Reply via email to