Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/mattirn/jline3 into matti…
Browse files Browse the repository at this point in the history
…rn-brackets
  • Loading branch information
gnodet committed Jan 29, 2019
2 parents f230c87 + b8dd35d commit 2d1e01e
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 7 deletions.
33 changes: 28 additions & 5 deletions reader/src/main/java/org/jline/reader/impl/DefaultParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ public ParsedLine parse(final String line, final int cursor, ParseContext contex
int rawWordLength = -1;
int rawWordStart = 0;
BracketChecker bracketChecker = new BracketChecker();
boolean quotedWord = false;

for (int i = 0; (line != null) && (i < line.length()); i++) {
// once we reach the cursor, set the
Expand All @@ -160,12 +161,20 @@ public ParsedLine parse(final String line, final int cursor, ParseContext contex
if (quoteStart < 0 && isQuoteChar(line, i)) {
// Start a quote block
quoteStart = i;
if (current.length()==0) {
quotedWord = true;
} else {
current.append(line.charAt(i));
}
} else if (quoteStart >= 0 && line.charAt(quoteStart) == line.charAt(i) && !isEscaped(line, i)) {
// End quote block
quoteStart = -1;
if (rawWordCursor >= 0 && rawWordLength < 0) {
if (!quotedWord) {
current.append(line.charAt(i));
} else if (rawWordCursor >= 0 && rawWordLength < 0) {
rawWordLength = i - rawWordStart + 1;
}
quoteStart = -1;
quotedWord = false;
} else if (quoteStart < 0 && isDelimiter(line, i)) {
// Delimiter
if (current.length() > 0) {
Expand Down Expand Up @@ -212,7 +221,7 @@ public ParsedLine parse(final String line, final int cursor, ParseContext contex
throw new EOFError(-1, -1, "Missing closing brackets", "add: " + bracketChecker.getMissingClosingBrackets());
}

String openingQuote = quoteStart >= 0 ? line.substring(quoteStart, quoteStart + 1) : null;
String openingQuote = quotedWord ? line.substring(quoteStart, quoteStart + 1) : null;
return new ArgumentList(line, words, wordIndex, wordCursor, cursor, openingQuote, rawWordCursor, rawWordLength);
}

Expand Down Expand Up @@ -480,13 +489,27 @@ public CharSequence escape(CharSequence candidate, boolean complete) {
StringBuilder sb = new StringBuilder(candidate);
Predicate<Integer> needToBeEscaped;
String quote = openingQuote;
boolean middleQuotes = false;
if (openingQuote==null) {
for (int i=0; i < sb.length(); i++) {
if (isQuoteChar(sb, i)) {
middleQuotes = true;
break;
}
}
}
if (escapeChars != null) {
// Completion is protected by an opening quote:
// Delimiters (spaces) don't need to be escaped, nor do other quotes, but everything else does.
// Also, close the quote at the end
if (openingQuote != null) {
needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i)) || String.valueOf(sb.charAt(i)).equals(openingQuote);
}
// Completion is protected by middle quotes:
// Delimiters (spaces) don't need to be escaped, nor do quotes, but everything else does.
else if (middleQuotes) {
needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i));
}
// No quote protection, need to escape everything: delimiter chars (spaces), quote chars
// and escapes themselves
else {
Expand All @@ -497,7 +520,7 @@ public CharSequence escape(CharSequence candidate, boolean complete) {
sb.insert(i++, escapeChars[0]);
}
}
} else if (openingQuote == null) {
} else if (openingQuote == null && !middleQuotes) {
for (int i = 0; i < sb.length(); i++) {
if (isDelimiterChar(sb, i)) {
quote = "'";
Expand Down Expand Up @@ -525,4 +548,4 @@ public int rawWordLength() {
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ public void testQuotedDelimit() {

delimited = parser.parse("1 '2 3'", 0);
assertEquals(Arrays.asList("1", "2 3"), delimited.words());

delimited = parser.parse("0'1 2' 3", 0);
assertEquals(Arrays.asList("0'1 2'", "3"), delimited.words());

delimited = parser.parse("'01 '2 3", 0);
assertEquals(Arrays.asList("01 2", "3"), delimited.words());
}

@Test
Expand All @@ -61,7 +67,7 @@ public void testMixedQuotes() {
assertEquals(Arrays.asList("1' '2", "3"), delimited.words());

delimited = parser.parse("'1\" 2' 3\"", 0);
assertEquals(Arrays.asList("1\" 2", "3"), delimited.words());
assertEquals(Arrays.asList("1\" 2", "3\""), delimited.words());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,27 @@ public void escapeChars() throws Exception {
assertBuffer("bar'f", new TestBuffer("bar'f").tab());
}

}
@Test
public void middleQuotesEscapeCharsNull() throws Exception {
DefaultParser dp = (DefaultParser) reader.getParser();
dp.setEscapeChars(null);
reader.setVariable(LineReader.ERRORS, 0);
reader.setParser(dp);
reader.setCompleter(new StringsCompleter("/foo?name='foo bar'","/foo?name='foo qux'"));

assertBuffer("/foo?name='foo ", new TestBuffer("/f").tab());
assertBuffer("/foo?name='foo bar' ", new TestBuffer("/foo?name='foo b").tab());
}

@Test
public void middleQuotesEscapeChars() throws Exception {
DefaultParser dp = (DefaultParser) reader.getParser();
dp.setEscapeChars(new char[] { '\\' });
reader.setVariable(LineReader.ERRORS, 0);
reader.setParser(dp);
reader.setCompleter(new StringsCompleter("/foo?name='foo bar'","/foo?name='foo qux'"));

assertBuffer("/foo?name='foo ", new TestBuffer("/f").tab());
assertBuffer("/foo?name='foo bar' ", new TestBuffer("/foo?name='foo b").tab());
}
}

0 comments on commit 2d1e01e

Please sign in to comment.