diff --git a/src/main/java/org/springframework/shell/core/SimpleParser.java b/src/main/java/org/springframework/shell/core/SimpleParser.java index 36c4babb..7630b0e5 100644 --- a/src/main/java/org/springframework/shell/core/SimpleParser.java +++ b/src/main/java/org/springframework/shell/core/SimpleParser.java @@ -783,15 +783,18 @@ public class SimpleParser implements Parser { for (String key : option.key()) { if (key.equals(lastOptionKey)) { List allValues = new ArrayList(); - String suffix = " "; - + // We'll append the closing delimiter to proposals + String suffix = "" + tokenizer.getLastValueDelimiter(); + if (!suffix.endsWith(" ")) { + suffix += " "; + } // Let's use a Converter if one is available for (Converter candidate : converters) { if (candidate.supports(parameterType, option.optionContext())) { // Found a usable converter - boolean addSpace = candidate.getAllPossibleValues(allValues, parameterType, + boolean allComplete = candidate.getAllPossibleValues(allValues, parameterType, lastOptionValue, option.optionContext(), methodTarget); - if (!addSpace) { + if (!allComplete) { suffix = ""; } break; diff --git a/src/test/java/org/springframework/shell/core/SimpleParserTests.java b/src/test/java/org/springframework/shell/core/SimpleParserTests.java index 0f101554..7049a119 100644 --- a/src/test/java/org/springframework/shell/core/SimpleParserTests.java +++ b/src/test/java/org/springframework/shell/core/SimpleParserTests.java @@ -324,6 +324,50 @@ public class SimpleParserTests { // assertThat(SimpleParser.isMatch("hello ", "hellothere", true), is(nullValue())); } + @Test + public void testValueCompletionsThatCanContinue() { + + parser.add(new MyCommands()); + parser.add(new StringCompletions(Arrays.asList("abd", "def"), false)); + + // With space as delimiter + buffer = "bar --option1 "; + offset = parser.completeAdvanced(buffer, buffer.length(), candidates); + + assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 abd"))))); + assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 def"))))); + + // With quotes as delimiter + buffer = "bar --option1 \""; + candidates.clear(); + offset = parser.completeAdvanced(buffer, buffer.length(), candidates); + + assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 \"abd"))))); + assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 \"def"))))); + } + + @Test + public void testValueCompletionsThatCannotContinue() { + + parser.add(new MyCommands()); + parser.add(new StringCompletions(Arrays.asList("abd", "def"), true)); + + // With space as delimiter + buffer = "bar --option1 "; + offset = parser.completeAdvanced(buffer, buffer.length(), candidates); + + assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 abd "))))); + assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 def "))))); + + // With quotes as delimiter + buffer = "bar --option1 \""; + candidates.clear(); + offset = parser.completeAdvanced(buffer, buffer.length(), candidates); + + assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 \"abd\" "))))); + assertThat(candidates, hasItem(completionThat(is(equalTo("bar --option1 \"def\" "))))); + } + /** * Return a matcher that asserts that a completion, when added to {@link #buffer} at the given {@link #offset}, * indeed matches the provided matcher. @@ -408,8 +452,15 @@ public class SimpleParserTests { private final List completions; + private final boolean canContinue; + public StringCompletions(List completions) { + this(completions, false); + } + + public StringCompletions(List completions, boolean canContinue) { this.completions = completions; + this.canContinue = canContinue; } public boolean supports(Class type, String optionContext) { @@ -425,7 +476,7 @@ public class SimpleParserTests { for (String s : this.completions) { completions.add(new Completion(s)); } - return false; + return canContinue; } }