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