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

lkishalmi 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 6543326b16 Better YAML editing with auto closing quotes and mustache
6543326b16 is described below

commit 6543326b16fdcb05092fbb7af86fe817a07586b3
Author: Laszlo Kishalmi <laszlo.kisha...@gmail.com>
AuthorDate: Mon May 9 13:36:59 2022 -0700

    Better YAML editing with auto closing quotes and mustache
---
 .../netbeans/modules/csl/api/test/CslTestBase.java | 21 ++---
 .../languages/yaml/YamlKeystrokeHandler.java       | 90 +++++++++++++++++++---
 .../languages/yaml/YamlKeystrokeHandlerTest.java   | 65 ++++++++++++++++
 3 files changed, 156 insertions(+), 20 deletions(-)

diff --git 
a/ide/csl.api/test/unit/src/org/netbeans/modules/csl/api/test/CslTestBase.java 
b/ide/csl.api/test/unit/src/org/netbeans/modules/csl/api/test/CslTestBase.java
index 4322769943..2b4721ee61 100644
--- 
a/ide/csl.api/test/unit/src/org/netbeans/modules/csl/api/test/CslTestBase.java
+++ 
b/ide/csl.api/test/unit/src/org/netbeans/modules/csl/api/test/CslTestBase.java
@@ -1249,21 +1249,21 @@ public abstract class CslTestBase extends NbTestCase {
         Formatter formatter = getFormatter(null);
 
         int sourcePos = source.indexOf('^');
-        assertNotNull(sourcePos);
+        assertTrue("Source text must have a caret ^ marker", sourcePos != -1);
         source = source.substring(0, sourcePos) + 
source.substring(sourcePos+1);
 
         int reformattedPos = reformatted.indexOf('^');
-        assertNotNull(reformattedPos);
+        assertTrue("Reformatted text must have a caret ^ marker", 
reformattedPos != -1);
         reformatted = reformatted.substring(0, reformattedPos) + 
reformatted.substring(reformattedPos+1);
 
         JEditorPane ta = getPane(source);
         Caret caret = ta.getCaret();
         caret.setDot(sourcePos);
         if (selection != null) {
-            int start = original.indexOf(selection);
+            int start = source.indexOf(selection);
             assertTrue(start != -1);
             assertTrue("Ambiguous selection - multiple occurrences of 
selection string",
-                    original.indexOf(selection, start+1) == -1);
+                    source.indexOf(selection, start+1) == -1);
             ta.setSelectionStart(start);
             ta.setSelectionEnd(start+selection.length());
             assertEquals(selection, ta.getSelectedText());
@@ -1299,11 +1299,11 @@ public abstract class CslTestBase extends NbTestCase {
         Formatter formatter = getFormatter(null);
 
         int sourcePos = source.indexOf('^');
-        assertNotNull(sourcePos);
+        assertTrue("Source text must have a caret ^ marker", sourcePos != -1);
         source = source.substring(0, sourcePos) + 
source.substring(sourcePos+1);
 
         int reformattedPos = reformatted.indexOf('^');
-        assertNotNull(reformattedPos);
+        assertTrue("Reformatted text must have a caret ^ marker", 
reformattedPos != -1);
         reformatted = reformatted.substring(0, reformattedPos) + 
reformatted.substring(reformattedPos+1);
 
         JEditorPane ta = getPane(source);
@@ -1332,11 +1332,12 @@ public abstract class CslTestBase extends NbTestCase {
         Formatter formatter = getFormatter(null);
 
         int sourcePos = source.indexOf('^');
-        assertNotNull(sourcePos);
+        assertTrue("Source text must have a caret ^ marker", sourcePos != -1);
+
         source = source.substring(0, sourcePos) + 
source.substring(sourcePos+1);
 
         int reformattedPos = reformatted.indexOf('^');
-        assertNotNull(reformattedPos);
+        assertTrue("Reformatted text must have a caret ^ marker", 
reformattedPos != -1);
         reformatted = reformatted.substring(0, reformattedPos) + 
reformatted.substring(reformattedPos+1);
 
         JEditorPane ta = getPane(source);
@@ -2529,12 +2530,12 @@ public abstract class CslTestBase extends NbTestCase {
 
     public void insertNewline(String source, String reformatted, IndentPrefs 
preferences) throws Exception {
         int sourcePos = source.indexOf('^');
-        assertNotNull(sourcePos);
+        assertTrue("Source text must have a caret ^ marker", sourcePos != -1);
         source = source.substring(0, sourcePos) + 
source.substring(sourcePos+1);
         Formatter formatter = getFormatter(null);
 
         int reformattedPos = reformatted.indexOf('^');
-        assertNotNull(reformattedPos);
+        assertTrue("Reformatted text must have a caret ^ marker", 
reformattedPos != -1);
         reformatted = reformatted.substring(0, reformattedPos) + 
reformatted.substring(reformattedPos+1);
 
         JEditorPane ta = getPane(source);
diff --git 
a/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlKeystrokeHandler.java
 
b/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlKeystrokeHandler.java
index 8bdb274bd6..6be5c7b55e 100644
--- 
a/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlKeystrokeHandler.java
+++ 
b/ide/languages.yaml/src/org/netbeans/modules/languages/yaml/YamlKeystrokeHandler.java
@@ -25,6 +25,7 @@ import javax.swing.text.BadLocationException;
 import javax.swing.text.Caret;
 import javax.swing.text.Document;
 import javax.swing.text.JTextComponent;
+import org.netbeans.api.editor.document.LineDocumentUtils;
 import org.netbeans.api.lexer.Token;
 import org.netbeans.api.lexer.TokenHierarchy;
 import org.netbeans.api.lexer.TokenSequence;
@@ -59,7 +60,7 @@ public class YamlKeystrokeHandler implements KeystrokeHandler 
{
                 if ("%=".equals(s) && dotPos >= 3) { // NOI18N
                     s = doc.getText(dotPos - 3, 3);
                 }
-                if ("<%".equals(s) || "<%=".equals(s)) { // NOI18N
+                if ("<%".equals(s) || "<%=".equals(s) || "{{".equals(s)) { // 
NOI18N
                     doc.insertString(dotPos, "  ", null);
                     caret.setDot(dotPos + 1);
                     return true;
@@ -71,6 +72,50 @@ public class YamlKeystrokeHandler implements 
KeystrokeHandler {
             return false;
         }
 
+        if ((c == '{') && (dotPos > 0)) {
+            try {
+                String s = dotPos > 1 ? doc.getText(dotPos - 2, 2) : 
doc.getText(dotPos - 1, 1);
+                if ("{".equals(s) || (s.endsWith("{") && (s.length() > 1) && 
(s.charAt(0) != '{'))) {
+                    doc.insertString(dotPos, "{}}", null);
+                    caret.setDot(dotPos + 1);
+                    return true;
+                }
+            } catch (BadLocationException ble) {
+                Exceptions.printStackTrace(ble);
+            }
+
+            return false;
+        }
+
+        if ((c == '\'') || (c == '"')) {
+            int sstart = target.getSelectionStart();
+            int send = target.getSelectionEnd();
+            if ((sstart != send) && ((dotPos == sstart) || (dotPos == send))) {
+                doc.insertString(sstart, String.valueOf(c), null);
+                doc.insertString(send + 1, String.valueOf(c), null);
+                caret.setDot(send + 2);
+                return true;
+            }
+            int lineStart = LineDocumentUtils.getLineStart(doc, dotPos);
+            int lineEnd = LineDocumentUtils.getLineEnd(doc, dotPos);
+            char[] line = doc.getChars(lineStart, lineEnd - lineStart);
+
+            int quotes = 0;
+            for (char d : line) {
+                if (c == d) quotes++;
+            }
+            // Try to keep the number of quotes even
+            if ( quotes % 2 == 1 ) {
+                // Inserting one if the number of quotes are odd
+                return false;
+            } else {
+                // Inserting double if the number of quotes are even
+                doc.insertString(sstart, String.valueOf(c) + 
String.valueOf(c), null);
+                caret.setDot(dotPos + 1);
+                return true;
+            }
+        }
+
         if ((dotPos > 0) && (c == '%' || c == '>')) {
             TokenHierarchy<Document> th = TokenHierarchy.get((Document) doc);
             TokenSequence<?> ts = th.tokenSequence();
@@ -80,7 +125,7 @@ public class YamlKeystrokeHandler implements 
KeystrokeHandler {
                     Token<?> token = ts.token();
                     if (token.id() == YamlTokenId.TEXT && doc.getText(dotPos - 
1, 1).charAt(0) == '<') {
                         // See if there's anything ahead
-                        int first = Utilities.getFirstNonWhiteFwd(doc, dotPos, 
Utilities.getRowEnd(doc, dotPos));
+                        int first = 
LineDocumentUtils.getNextNonWhitespace(doc, dotPos, 
LineDocumentUtils.getLineEnd(doc, dotPos));
                         if (first == -1) {
                             doc.insertString(dotPos, "%%>", null); // NOI18N
                             caret.setDot(dotPos + 1);
@@ -98,7 +143,7 @@ public class YamlKeystrokeHandler implements 
KeystrokeHandler {
                             }
                         } else if (tokenText.endsWith("<")) {
                             // See if there's anything ahead
-                            int first = Utilities.getFirstNonWhiteFwd(doc, 
dotPos, Utilities.getRowEnd(doc, dotPos));
+                            int first = 
LineDocumentUtils.getNextNonWhitespace(doc, dotPos, 
LineDocumentUtils.getLineEnd(doc, dotPos));
                             if (first == -1) {
                                 doc.insertString(dotPos, "%%>", null); // 
NOI18N
                                 caret.setDot(dotPos + 1);
@@ -137,6 +182,7 @@ public class YamlKeystrokeHandler implements 
KeystrokeHandler {
 
     @Override
     public boolean charBackspaced(Document doc, int dotPos, JTextComponent 
target, char ch) throws BadLocationException {
+        Caret caret = target.getCaret();
         if (ch == '%' && dotPos > 0 && dotPos <= doc.getLength() - 2) {
             String s = doc.getText(dotPos - 1, 3);
             if ("<%>".equals(s)) { // NOI18N
@@ -145,6 +191,30 @@ public class YamlKeystrokeHandler implements 
KeystrokeHandler {
             }
         }
 
+        if ((ch == ' ') && (dotPos > 1) && (dotPos <= doc.getLength() - 3)) {
+            String s = doc.getText(dotPos - 2, 5);
+            if ("{{ }}".equals(s)) {
+                doc.remove(dotPos, 1);
+                return true;
+            }
+        }
+
+        if ((ch == '{') && (dotPos > 0) && (dotPos <= doc.getLength() - 2)) {
+            String s = doc.getText(dotPos - 1, 3);
+            if ("{}}".equals(s)) {
+                doc.remove(dotPos - 1, 3);
+                caret.setDot(dotPos - 1);
+                return true;
+            }
+        }
+
+        if (((ch == '\'') || (ch == '"')) && (dotPos <= doc.getLength() - 1)) {
+            String s = doc.getText(dotPos, 1);
+            if (String.valueOf(ch).equals(s)) {
+                doc.remove(dotPos, 1);
+                return true;
+            }
+        }
         return false;
     }
 
@@ -158,8 +228,8 @@ public class YamlKeystrokeHandler implements 
KeystrokeHandler {
         // Basically, use the same indent as the current line, unless the 
caret is immediately preceeded by a ":" (possibly with whitespace
         // in between)
 
-        int lineBegin = Utilities.getRowStart(doc, offset);
-        int lineEnd = Utilities.getRowEnd(doc, offset);
+        int lineBegin = LineDocumentUtils.getLineStart(doc, offset);
+        int lineEnd = LineDocumentUtils.getLineEnd(doc, offset);
 
         if (lineBegin == offset && lineEnd == offset) {
             // Pressed return on a blank newline - do nothing
@@ -214,7 +284,7 @@ public class YamlKeystrokeHandler implements 
KeystrokeHandler {
             return Collections.emptyList();
         }
 
-        List<OffsetRange> ranges = new ArrayList<OffsetRange>();
+        List<OffsetRange> ranges = new ArrayList<>();
         for (StructureItem item : items) {
             addRanges(ranges, caretOffset, item);
         }
@@ -247,13 +317,13 @@ public class YamlKeystrokeHandler implements 
KeystrokeHandler {
 
     public static int getLineIndent(BaseDocument doc, int offset) {
         try {
-            int start = Utilities.getRowStart(doc, offset);
+            int start = LineDocumentUtils.getLineStart(doc, offset);
             int end;
 
-            if (Utilities.isRowWhite(doc, start)) {
-                end = Utilities.getRowEnd(doc, offset);
+            if (LineDocumentUtils.isLineWhitespace(doc, start)) {
+                end = LineDocumentUtils.getLineEnd(doc, offset);
             } else {
-                end = Utilities.getRowFirstNonWhite(doc, start);
+                end = LineDocumentUtils.getLineFirstNonWhitespace(doc, start);
             }
 
             int indent = Utilities.getVisualColumn(doc, end);
diff --git 
a/ide/languages.yaml/test/unit/src/org/netbeans/modules/languages/yaml/YamlKeystrokeHandlerTest.java
 
b/ide/languages.yaml/test/unit/src/org/netbeans/modules/languages/yaml/YamlKeystrokeHandlerTest.java
index 8cb59d657a..939a03892f 100644
--- 
a/ide/languages.yaml/test/unit/src/org/netbeans/modules/languages/yaml/YamlKeystrokeHandlerTest.java
+++ 
b/ide/languages.yaml/test/unit/src/org/netbeans/modules/languages/yaml/YamlKeystrokeHandlerTest.java
@@ -137,7 +137,72 @@ public class YamlKeystrokeHandlerTest extends YamlTestBase 
{
         insertChar("c^ass", 'l', "cl^ass");
     }
 
+    public void testInsertCurly() throws Exception {
+        insertChar("{^", '{', "{{^}}");
+    }
+
+    public void testDeleteCurly() throws Exception {
+        deleteChar("{{^}}", "^");
+    }
+
+    public void testInsertSpaceCurly() throws Exception {
+        insertChar("{{^}}", ' ', "{{ ^ }}");
+    }
+
+    public void testDeleteSpaceCurly() throws Exception {
+        deleteChar("{{ ^ }}", "{{^}}");
+    }
+
+    public void testInsertSingleQuote1() throws Exception {
+        insertChar("foo: ^", '\'', "foo: '^'");
+    }
+
+    public void testInsertSingleQuote2() throws Exception {
+        insertChar("foo: 'a^", '\'', "foo: 'a'^");
+    }
+
+    public void testInsertSingleQuote3() throws Exception {
+        insertChar("foo: bar^", '\'', "foo: 'bar'^", "bar");
+    }
+
+    public void testInsertSingleQuote4() throws Exception {
+        insertChar("foo: ^bar", '\'', "foo: 'bar'^", "bar");
+    }
+
+    public void testDeleteSingle1() throws Exception {
+        deleteChar("foo: '^'", "foo: ^");
+    }
+
+    public void testDeleteSingle2() throws Exception {
+        deleteChar("foo: ''^", "foo: '^");
+    }
+
+    public void testInsertDoubleQuote1() throws Exception {
+        insertChar("foo: { ^", '"', "foo: { \"^\"");
+    }
+
+    public void testInsertDoubleQuote2() throws Exception {
+        insertChar("foo: { \"bar\": \"baz^ }", '"', "foo: { \"bar\": \"baz\"^ 
}");
+    }
+
+    public void testInsertDoubleQuote3() throws Exception {
+        insertChar("foo: bar^", '"', "foo: \"bar\"^", "bar");
+    }
+
+    public void testInsertDoubleQuote4() throws Exception {
+        insertChar("foo: ^bar", '"', "foo: \"bar\"^", "bar");
+    }
+
+    public void testDeleteDouble1() throws Exception {
+        deleteChar("foo: \"^\"", "foo: ^");
+    }
+
+    public void testDeleteDouble2() throws Exception {
+        deleteChar("foo: \"\"^", "foo: \"^");
+    }
+
     public void testDeleteX() throws Exception {
+
         deleteChar("cl^ass", "c^ass");
     }
 


---------------------------------------------------------------------
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