diff --git a/ide/db.sql.editor/nbproject/project.xml b/ide/db.sql.editor/nbproject/project.xml index b17121685e30..d4f99343d05a 100644 --- a/ide/db.sql.editor/nbproject/project.xml +++ b/ide/db.sql.editor/nbproject/project.xml @@ -157,6 +157,15 @@ 1.27 + + org.netbeans.modules.options.editor + + + + 1 + 1.88 + + org.netbeans.modules.projectapi diff --git a/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/OptionsUtils.java b/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/OptionsUtils.java index b39d11b36afb..dd8a1f9c9d7f 100644 --- a/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/OptionsUtils.java +++ b/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/OptionsUtils.java @@ -32,7 +32,9 @@ */ public final class OptionsUtils { // package visible to allow access from unit tests - static final String PAIR_CHARACTERS_COMPLETION = "pair-characters-completion"; + public static final String PAIR_CHARACTERS_COMPLETION = "pair-characters-completion"; //NOI18N + public static final String SQL_AUTO_COMPLETION_SUBWORDS = "sql-completion-subwords"; //NOI18N + public static final boolean SQL_AUTO_COMPLETION_SUBWORDS_DEFAULT = false; private static final AtomicBoolean INITED = new AtomicBoolean(false); private static final PreferenceChangeListener PREFERENCES_TRACKER = new PreferenceChangeListener() { @@ -40,17 +42,20 @@ public final class OptionsUtils { public void preferenceChange(PreferenceChangeEvent evt) { String settingName = evt == null ? null : evt.getKey(); - if (settingName == null - || PAIR_CHARACTERS_COMPLETION.equals(settingName)) { - pairCharactersCompletion = preferences.getBoolean( - PAIR_CHARACTERS_COMPLETION, true); + if (settingName == null || PAIR_CHARACTERS_COMPLETION.equals(settingName)) { + pairCharactersCompletion = preferences.getBoolean(PAIR_CHARACTERS_COMPLETION, true); } + + if (settingName == null || SQL_AUTO_COMPLETION_SUBWORDS.equals(settingName)) { + sqlCompletionSubwords = preferences.getBoolean(SQL_AUTO_COMPLETION_SUBWORDS, SQL_AUTO_COMPLETION_SUBWORDS_DEFAULT); } + } }; private static Preferences preferences; private static boolean pairCharactersCompletion = true; + private static boolean sqlCompletionSubwords = SQL_AUTO_COMPLETION_SUBWORDS_DEFAULT; private OptionsUtils() { } @@ -65,6 +70,16 @@ public static boolean isPairCharactersCompletion() { return pairCharactersCompletion; } + /** + * Option: "Subword Completion" + * + * @return true if code completion should be subword based + */ + public static boolean isSqlCompletionSubwords() { + lazyInit(); + return sqlCompletionSubwords; + } + private static void lazyInit() { if (INITED.compareAndSet(false, true)) { preferences = MimeLookup.getLookup(SQLLanguageConfig.mimeType).lookup(Preferences.class); diff --git a/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/completion/SQLCompletionItems.java b/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/completion/SQLCompletionItems.java index f191d95f0ef4..b9411aed70f3 100644 --- a/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/completion/SQLCompletionItems.java +++ b/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/completion/SQLCompletionItems.java @@ -23,6 +23,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Set; @@ -38,6 +39,7 @@ import org.netbeans.modules.db.metadata.model.api.Tuple; import org.netbeans.modules.db.metadata.model.api.View; import org.netbeans.modules.db.sql.analyzer.QualIdent; +import org.netbeans.modules.db.sql.editor.OptionsUtils; import org.netbeans.modules.db.sql.editor.api.completion.SQLCompletionResultSet; import org.netbeans.modules.db.sql.editor.api.completion.SubstitutionHandler; import org.netbeans.spi.editor.completion.CompletionResultSet; @@ -48,7 +50,7 @@ */ public class SQLCompletionItems implements Iterable { - private final List items = new ArrayList(); + private final List items = new ArrayList<>(); private final Quoter quoter; private final SubstitutionHandler substitutionHandler; @@ -67,32 +69,28 @@ public void addKeywords(String prefix, final int substitutionOffset, String... k } public Set addCatalogs(Metadata metadata, Set restrict, String prefix, final boolean quote, final int substitutionOffset) { - Set result = new TreeSet(); - filterMetadata(metadata.getCatalogs(), restrict, prefix, new Handler() { - public void handle(Catalog catalog) { - String catalogName = catalog.getName(); - items.add(SQLCompletionItem.catalog( - catalogName, - doQuote(catalogName, quote), - substitutionOffset, - substitutionHandler)); - } + Set result = new TreeSet<>(); + filterMetadata(metadata.getCatalogs(), restrict, prefix, (Catalog catalog) -> { + String catalogName = catalog.getName(); + items.add(SQLCompletionItem.catalog( + catalogName, + doQuote(catalogName, quote), + substitutionOffset, + substitutionHandler)); }); return result; } public Set addSchemas(Catalog catalog, Set restrict, String prefix, final boolean quote, final int substitutionOffset) { - Set result = new TreeSet(); - filterMetadata(catalog.getSchemas(), restrict, prefix, new Handler() { - public void handle(Schema schema) { - if (!schema.isSynthetic()) { - String schemaName = schema.getName(); - items.add(SQLCompletionItem.schema( - schemaName, - doQuote(schemaName, quote), - substitutionOffset, - substitutionHandler)); - } + Set result = new TreeSet<>(); + filterMetadata(catalog.getSchemas(), restrict, prefix, (Schema schema) -> { + if (!schema.isSynthetic()) { + String schemaName = schema.getName(); + items.add(SQLCompletionItem.schema( + schemaName, + doQuote(schemaName, quote), + substitutionOffset, + substitutionHandler)); } }); return result; @@ -110,17 +108,15 @@ private void addTables(Schema schema, QualIdent fullyTypedIdent, Set res final String schema4display = fullyTypedIdent == null ? "" : fullyTypedIdent.getSimpleName () + '.'; // NOI18N final int ownOffset = fullyTypedIdent == null ? substitutionOffset : substitutionOffset - (fullyTypedIdent.getSimpleName ().length () + 1); - filterMetadata(schema.getTables(), restrict, prefix, new Handler() { - public void handle(Table table) { - String tableName = table.getName(); - items.add(SQLCompletionItem.table( - tableName, - doQuote(tableName, quote), - ownOffset, - ownHandler ? + filterMetadata(schema.getTables(), restrict, prefix, (Table table) -> { + String tableName = table.getName(); + items.add(SQLCompletionItem.table( + tableName, + doQuote(tableName, quote), + ownOffset, + ownHandler ? new ExtendedSubstitutionHandler (substitutionHandler, schema4display, " (") // NOI18N : substitutionHandler)); - } }); } @@ -136,26 +132,22 @@ private void addViews(Schema schema, QualIdent fullyTypedIdent, Set rest final String schema4display = fullyTypedIdent == null ? "" : fullyTypedIdent.getSimpleName () + '.'; // NOI18N final int ownOffset = fullyTypedIdent == null ? substitutionOffset : substitutionOffset - (fullyTypedIdent.getSimpleName ().length () + 1); - filterMetadata(schema.getViews(), restrict, prefix, new Handler() { - public void handle(View view) { - String viewName = view.getName(); - items.add(SQLCompletionItem.view( - viewName, - doQuote(viewName, quote), - ownOffset, - ownHandler ? + filterMetadata(schema.getViews(), restrict, prefix, (View view) -> { + String viewName = view.getName(); + items.add(SQLCompletionItem.view( + viewName, + doQuote(viewName, quote), + ownOffset, + ownHandler ? new ExtendedSubstitutionHandler (substitutionHandler, schema4display, " (") // NOI18N : substitutionHandler)); - } }); } public void addAliases(Map aliases, String prefix, final boolean quote, final int substitutionOffset) { - filterMap(aliases, null, prefix, new ParamHandler() { - public void handle(String alias, QualIdent tableName) { - // Issue 145173: do not quote aliases. - items.add(SQLCompletionItem.alias(alias, tableName, alias, substitutionOffset, substitutionHandler)); - } + filterMap(aliases, null, prefix, (String alias, QualIdent tableName) -> { + // Issue 145173: do not quote aliases. + items.add(SQLCompletionItem.alias(alias, tableName, alias, substitutionOffset, substitutionHandler)); }); } @@ -170,7 +162,7 @@ public void addColumns(Tuple tuple, String prefix, final boolean quote, final in private void addColumns(final Tuple tuple, QualIdent fullyTypedIdent, String prefix, final boolean quote, final int substitutionOffset, final boolean ownHandler) { Schema schema = tuple.getParent(); Catalog catalog = schema.getParent(); - List parts = new ArrayList(3); + List parts = new ArrayList<>(3); if (!catalog.isDefault()) { parts.add(catalog.getName()); } @@ -183,20 +175,18 @@ private void addColumns(final Tuple tuple, QualIdent fullyTypedIdent, String pre fullyTypedIdent.getFirstQualifier () + '.' + fullyTypedIdent.getSecondQualifier (); // NOI18N final int ownOffset = fullyTypedIdent == null ? substitutionOffset : substitutionOffset - (fullyTypedIdent.getFirstQualifier ().length () + fullyTypedIdent.getSecondQualifier ().length () + 2); - filterMetadata(tuple.getColumns(), null, prefix, new Handler() { - public void handle(Column column) { - String columnName = column.getName(); - items.add(SQLCompletionItem.column ( - tuple instanceof View, - qualTableName, - columnName, - column.getTypeName(), - doQuote(columnName, quote), - ownOffset, - ownHandler ? + filterMetadata(tuple.getColumns(), null, prefix, (Column column) -> { + String columnName = column.getName(); + items.add(SQLCompletionItem.column ( + tuple instanceof View, + qualTableName, + columnName, + column.getTypeName(), + doQuote(columnName, quote), + ownOffset, + ownHandler ? new ExtendedSubstitutionHandler (substitutionHandler, table4display + " (", null) // NOI18N : substitutionHandler)); - } }); } @@ -208,6 +198,7 @@ public void fill(SQLCompletionResultSet resultSet) { resultSet.addAllItems(items); } + @Override public Iterator iterator() { return items.iterator(); } @@ -224,8 +215,18 @@ private static boolean startsWithIgnoreCase(String text, String prefix) { return text.regionMatches(true, 0, prefix, 0, prefix.length()); } + private static boolean containsIgnoreCase(String text, String prefix) { + return text.toLowerCase(Locale.ROOT).contains(prefix.toLowerCase(Locale.ROOT)); + } + private static boolean filter(String string, String prefix) { - return prefix == null || startsWithIgnoreCase(string, prefix); + if(prefix == null) { + return true; + } else if (OptionsUtils.isSqlCompletionSubwords()) { + return containsIgnoreCase(string, prefix); + } else { + return startsWithIgnoreCase(string, prefix); + } } private static

void filterMap(Map strings, Set restrict, String prefix, ParamHandler handler) { @@ -267,6 +268,7 @@ public ExtendedSubstitutionHandler (SubstitutionHandler handler, String prefix, this.prefix = prefix == null ? "" : prefix; this.postfix = postfix == null ? "" : postfix; } + @Override public void substituteText (JTextComponent component, int offset, String text) { original.substituteText (component, offset, prefix + text + postfix); } diff --git a/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/resources/layer.xml b/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/resources/layer.xml index d989aafb01aa..20b703cea207 100644 --- a/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/resources/layer.xml +++ b/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/resources/layer.xml @@ -158,5 +158,23 @@ + + + + + + + + + + + + + + + + + + diff --git a/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/ui/options/Bundle.properties b/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/ui/options/Bundle.properties new file mode 100644 index 000000000000..abd96b731e72 --- /dev/null +++ b/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/ui/options/Bundle.properties @@ -0,0 +1,19 @@ +# 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. + +CodeCompletionPanel.sqlAutoCompletionSubwords.toolTipText= +CodeCompletionPanel.sqlAutoCompletionSubwords.text=&Subword completion diff --git a/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/ui/options/CodeCompletionPanel.form b/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/ui/options/CodeCompletionPanel.form new file mode 100644 index 000000000000..307c8a6ba3b9 --- /dev/null +++ b/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/ui/options/CodeCompletionPanel.form @@ -0,0 +1,80 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/ui/options/CodeCompletionPanel.java b/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/ui/options/CodeCompletionPanel.java new file mode 100644 index 000000000000..dd52e5c96fd0 --- /dev/null +++ b/ide/db.sql.editor/src/org/netbeans/modules/db/sql/editor/ui/options/CodeCompletionPanel.java @@ -0,0 +1,146 @@ +/* + * 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.db.sql.editor.ui.options; + +import java.util.HashMap; +import java.util.Map; +import java.util.prefs.Preferences; +import javax.swing.JComponent; +import org.netbeans.modules.options.editor.spi.PreferencesCustomizer; +import org.openide.util.HelpCtx; + +import static org.netbeans.modules.db.sql.editor.OptionsUtils.SQL_AUTO_COMPLETION_SUBWORDS; +import static org.netbeans.modules.db.sql.editor.OptionsUtils.SQL_AUTO_COMPLETION_SUBWORDS_DEFAULT; + +public class CodeCompletionPanel extends javax.swing.JPanel { + private final Preferences preferences; + + private final Map id2Saved = new HashMap<>(); + + /** Creates new form FmtTabsIndents */ + @SuppressWarnings("this-escape") + public CodeCompletionPanel(Preferences p) { + initComponents(); + preferences = p; + sqlAutoCompletionSubwords.setSelected(preferences.getBoolean(SQL_AUTO_COMPLETION_SUBWORDS, SQL_AUTO_COMPLETION_SUBWORDS_DEFAULT)); + + id2Saved.put(SQL_AUTO_COMPLETION_SUBWORDS, sqlAutoCompletionSubwords.isSelected()); + } + + public static PreferencesCustomizer.Factory getCustomizerFactory() { + return CodeCompletionPreferencesCustomizer::new; + } + + /** 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() { + java.awt.GridBagConstraints gridBagConstraints; + + sqlAutoCompletionSubwords = new javax.swing.JCheckBox(); + filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 32767)); + + setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0)); + setLayout(new java.awt.GridBagLayout()); + + org.openide.awt.Mnemonics.setLocalizedText(sqlAutoCompletionSubwords, org.openide.util.NbBundle.getMessage(CodeCompletionPanel.class, "CodeCompletionPanel.sqlAutoCompletionSubwords.text")); // NOI18N + sqlAutoCompletionSubwords.setToolTipText(org.openide.util.NbBundle.getMessage(CodeCompletionPanel.class, "CodeCompletionPanel.sqlAutoCompletionSubwords.toolTipText")); // NOI18N + sqlAutoCompletionSubwords.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + sqlAutoCompletionSubwordsActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.insets = new java.awt.Insets(6, 6, 6, 6); + add(sqlAutoCompletionSubwords, gridBagConstraints); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(filler1, gridBagConstraints); + }// //GEN-END:initComponents + + private void sqlAutoCompletionSubwordsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sqlAutoCompletionSubwordsActionPerformed + preferences.putBoolean(SQL_AUTO_COMPLETION_SUBWORDS, sqlAutoCompletionSubwords.isSelected()); + }//GEN-LAST:event_sqlAutoCompletionSubwordsActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.Box.Filler filler1; + private javax.swing.JCheckBox sqlAutoCompletionSubwords; + // End of variables declaration//GEN-END:variables + + private static class CodeCompletionPreferencesCustomizer implements PreferencesCustomizer { + + private final Preferences preferences; + private CodeCompletionPanel component; + + private CodeCompletionPreferencesCustomizer(Preferences p) { + preferences = p; + } + + @Override + public String getId() { + throw new UnsupportedOperationException("Not supported yet."); //NOI18N + } + + @Override + public String getDisplayName() { + throw new UnsupportedOperationException("Not supported yet."); //NOI18N + } + + @Override + public HelpCtx getHelpCtx() { + return new HelpCtx("netbeans.optionsDialog.editor.codeCompletion.sql"); //NOI18N + } + + @Override + public JComponent getComponent() { + if (component == null) { + component = new CodeCompletionPanel(preferences); + } + return component; + } + } + + String getSavedValue(String key) { + return id2Saved.get(key).toString(); + } + + public static final class CustomCustomizerImpl extends PreferencesCustomizer.CustomCustomizer { + + @Override + public String getSavedValue(PreferencesCustomizer customCustomizer, String key) { + if (customCustomizer instanceof CodeCompletionPreferencesCustomizer) { + return ((CodeCompletionPanel) customCustomizer.getComponent()).getSavedValue(key); + } + return null; + } + } +} diff --git a/ide/options.editor/manifest.mf b/ide/options.editor/manifest.mf index 285ed895e6df..61e56f39824f 100644 --- a/ide/options.editor/manifest.mf +++ b/ide/options.editor/manifest.mf @@ -2,6 +2,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.options.editor/1 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/options/editor/Bundle.properties OpenIDE-Module-Layer: org/netbeans/modules/options/editor/mf-layer.xml -OpenIDE-Module-Specification-Version: 1.87 +OpenIDE-Module-Specification-Version: 1.88 AutoUpdate-Show-In-Client: false diff --git a/ide/options.editor/nbproject/project.xml b/ide/options.editor/nbproject/project.xml index 2ba0ae7734ab..917da4fb1353 100644 --- a/ide/options.editor/nbproject/project.xml +++ b/ide/options.editor/nbproject/project.xml @@ -353,6 +353,7 @@ org.netbeans.modules.cnd.completion org.netbeans.modules.cnd.editor org.netbeans.modules.csl.api + org.netbeans.modules.db.sql.editor org.netbeans.modules.diff org.netbeans.modules.editor.indent.project org.netbeans.modules.groovy.grailsproject