--- editor.codetemplates/src/org/netbeans/lib/editor/codetemplates/CodeTemplateInsertHandler.java +++ editor.codetemplates/src/org/netbeans/lib/editor/codetemplates/CodeTemplateInsertHandler.java @@ -44,9 +44,11 @@ package org.netbeans.lib.editor.codetemplates; +import static java.lang.Integer.MAX_VALUE; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.logging.Level; import java.util.logging.LogRecord; @@ -335,8 +337,11 @@ } TextRegion caretTextRegion = null; + + List prioritizedMasterParameters = prioritizeParameters(masterParameters); + // Go through all master parameters and create region infos for them - for (CodeTemplateParameter master : masterParameters) { + for (CodeTemplateParameter master : prioritizedMasterParameters) { CodeTemplateParameterImpl masterImpl = CodeTemplateParameterImpl.get(master); if (CodeTemplateParameter.CURSOR_PARAMETER_NAME.equals(master.getName())) { // Add explicit ${cursor} as last into text sync group to jump to it by TAB as last param @@ -587,7 +592,38 @@ } return sb.toString(); } + /** + * #181703 - Allow prioritizing parameters in a code-template. + * Package private for testing + */ + static List prioritizeParameters(List params) { + List result = new ArrayList<>(params); + Collections.sort(result, new Comparator() { + @Override + public int compare(CodeTemplateParameter p1, CodeTemplateParameter p2) { + return getPrio(p1) - getPrio(p2); + } + + private int getPrio(CodeTemplateParameter templateParam) throws NumberFormatException { + if (null == templateParam) { + return MAX_VALUE; + } + String value = templateParam.getHints().get(CodeTemplateParameter.ORDERING_HINT_NAME); + if (null != value) { + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + // ignore + return MAX_VALUE; + } + } + return MAX_VALUE; + } + }); + return result; + } + private static final class TemplateInsertUndoEdit extends AbstractUndoableEdit { private Document doc; --- editor.codetemplates/src/org/netbeans/lib/editor/codetemplates/spi/CodeTemplateParameter.java +++ editor.codetemplates/src/org/netbeans/lib/editor/codetemplates/spi/CodeTemplateParameter.java @@ -112,7 +112,24 @@ */ public static final String EDITABLE_HINT_NAME = "editable"; // NOI18N - + /** + * The ordering attribute defines the sequence in which placeholders are + * completed. Use 0 for the first element, 1 for the second... Placeholders + * without ordering information will be placed after the last placeholder + * with ordering information. + * + *

+ * Example of ordering of parameters : + *

+     * // paramC comes first, then paramB, then paramA
+     * ${paramA} ${paramB ordering=2} ${paramC ordering=1}
+     * 
+ *

+ * https://netbeans.org/bugzilla/show_bug.cgi?id=181703 + * @since 1.42.0 + */ + public static final String ORDERING_HINT_NAME = "ordering"; // NOI18N + private final CodeTemplateParameterImpl impl; CodeTemplateParameter(CodeTemplateParameterImpl impl) { --- editor.codetemplates/test/unit/src/org/netbeans/lib/editor/codetemplates/CodeTemplateInsertHandlerTest.java +++ editor.codetemplates/test/unit/src/org/netbeans/lib/editor/codetemplates/CodeTemplateInsertHandlerTest.java @@ -0,0 +1,67 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2016 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2016 Sun Microsystems, Inc. + */ +package org.netbeans.lib.editor.codetemplates; + +import java.util.Arrays; +import java.util.List; +import org.junit.Test; +import static org.junit.Assert.*; +import org.netbeans.lib.editor.codetemplates.spi.CodeTemplateParameter; + +/** + * + * @author markiewb + */ +public class CodeTemplateInsertHandlerTest { + + @Test + public void testPrioritizeParameters() { + CodeTemplateSpiPackageAccessor get = CodeTemplateSpiPackageAccessor.get(); + CodeTemplateParameter paramA = get.createParameter(new CodeTemplateParameterImpl(null, "${paramA}", 0)); + CodeTemplateParameter paramB = get.createParameter(new CodeTemplateParameterImpl(null, "${paramB ordering=\"2\"}", 0)); + CodeTemplateParameter paramC = get.createParameter(new CodeTemplateParameterImpl(null, "${paramC ordering=\"1\"}", 0)); + + List prioritizeParameters = CodeTemplateInsertHandler.prioritizeParameters(Arrays.asList(paramA, paramB, paramC)); + assertEquals(Arrays.asList(paramC, paramB, paramA), prioritizeParameters); + } + +} --- groovy.editor/src/org/netbeans/modules/groovy/editor/resources/DefaultAbbrevs.xml +++ groovy.editor/src/org/netbeans/modules/groovy/editor/resources/DefaultAbbrevs.xml @@ -132,7 +132,7 @@ - --- java.editor/src/org/netbeans/modules/java/editor/resources/DefaultAbbrevs.xml +++ java.editor/src/org/netbeans/modules/java/editor/resources/DefaultAbbrevs.xml @@ -176,7 +176,7 @@ -