Skip to content

Commit

Permalink
Fix broken TreeCompleter and RegexCompleter, fixes #224
Browse files Browse the repository at this point in the history
  • Loading branch information
gnodet committed Jan 30, 2018
1 parent caf355e commit 2398d96
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 4 deletions.
11 changes: 7 additions & 4 deletions builtins/src/main/java/org/jline/builtins/Completers.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2017, the original author or authors.
* Copyright (c) 2002-2018, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
Expand Down Expand Up @@ -383,7 +383,7 @@ public static Node node(Object... objs) {
cands.add((Candidate) obj);
} else if (obj instanceof Node) {
nodes.add((Node) obj);
} else if (obj instanceof Completer) {
} else if (obj instanceof org.jline.reader.Completer) {
comp = (org.jline.reader.Completer) obj;
} else {
throw new IllegalArgumentException();
Expand Down Expand Up @@ -440,6 +440,7 @@ public static class RegexCompleter implements org.jline.reader.Completer {

private final NfaMatcher<String> matcher;
private final Function<String, org.jline.reader.Completer> completers;
private final ThreadLocal<LineReader> reader = new ThreadLocal<>();

public RegexCompleter(String syntax, Function<String, org.jline.reader.Completer> completers) {
this.matcher = new NfaMatcher<>(syntax, this::doMatch);
Expand All @@ -449,15 +450,17 @@ public RegexCompleter(String syntax, Function<String, org.jline.reader.Completer
@Override
public synchronized void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
List<String> words = line.words().subList(0, line.wordIndex());
this.reader.set(reader);
Set<String> next = matcher.matchPartial(words);
for (String n : next) {
completers.apply(n).complete(reader, new ArgumentLine(n, n.length()), candidates);
completers.apply(n).complete(reader, new ArgumentLine(line.word(), line.wordCursor()), candidates);
}
this.reader.set(null);
}

private boolean doMatch(String arg, String name) {
List<Candidate> candidates = new ArrayList<>();
completers.apply(name).complete(null, new ArgumentLine(arg, arg.length()), candidates);
completers.apply(name).complete(this.reader.get(), new ArgumentLine(arg, arg.length()), candidates);
return candidates.stream().anyMatch(c -> c.value().equals(arg));
}

Expand Down
54 changes: 54 additions & 0 deletions builtins/src/test/java/org/jline/builtins/CompletersTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2002-2018, the original author or authors.
*
* This software is distributable under the BSD license. See the terms of the
* BSD license in the documentation provided with this software.
*
* http://www.opensource.org/licenses/bsd-license.php
*/
package org.jline.builtins;

import org.jline.reader.Candidate;
import org.jline.reader.Completer;
import org.jline.reader.LineReader;
import org.jline.reader.ParsedLine;
import org.jline.reader.impl.DefaultParser;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

import static org.jline.builtins.Completers.TreeCompleter.node;
import static org.junit.Assert.assertEquals;

public class CompletersTest {

@Test
public void testTreeCompleter() {
List<String> words = new ArrayList<>();
Completer test = new Completer() {
@Override
public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
words.add(line.word());
candidates.add(new Candidate("Param1"));
candidates.add(new Candidate("Param2"));
}
};
Completer completer = new Completers.TreeCompleter(
node("Command1",
node("Option1",
node(test)),
node("Option2"),
node("Option3")));
List<Candidate> candidates = new ArrayList<>();
completer.complete(
null,
new DefaultParser().parse("Command1 Option1 ", "Command1 Option1 ".length()),
candidates);
assertEquals(2, candidates.size());
assertEquals("Param1", candidates.get(0).value());
assertEquals("Param2", candidates.get(1).value());
assertEquals(1, words.size());
assertEquals("", words.get(0));
}
}

0 comments on commit 2398d96

Please sign in to comment.