jline / jline3

JLine is a Java library for handling console input.
Other
1.46k stars 215 forks source link

Nesting RegexCompleters only completes first word #1069

Open maxbechtold opened 1 week ago

maxbechtold commented 1 week ago

I'm having trouble getting nested RegexCompleters to work even though I've read nothing that speaks against it. Here's a reproduction example, I'm using JLine 3.26.3 on Windows 10, JDK 17. The LineReader options don't seem to make a difference.

Initially, Tab completes the line to "Word-A", but following this there's no further suggestion/candidate, although the grammar "a b" implies "Word-B" as the only viable text to follow.

What am I missing?

import org.jline.builtins.Completers;
import org.jline.reader.Completer;
import org.jline.reader.LineReader;
import org.jline.reader.LineReaderBuilder;
import org.jline.reader.impl.completer.StringsCompleter;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) throws IOException {
        Terminal terminal = TerminalBuilder.builder()
            .system(true)
            .build();

        LineReader lineReader = LineReaderBuilder.builder()
            .terminal(terminal)
            .option(LineReader.Option.CASE_INSENSITIVE, true)
            .option(LineReader.Option.DISABLE_EVENT_EXPANSION, true)
            .completer(buildCompleter())
            .build();
        lineReader.readLine();
    }

    private static Completer buildCompleter() {
        Map<String, Completer> map = new HashMap<>();
        map.put("0", new Completers.RegexCompleter("a b", s -> {
            if ("a".equals(s)) {
                return new StringsCompleter("Word-A");
            }
            return new StringsCompleter("Word-B");
        }));
        return new Completers.RegexCompleter("0", map::get);
    }

}
maxbechtold commented 1 week ago

One more note, my intent is to split a command system of about 30 commands into separate RegexCompleters. But I guess just chaining all in a long <C1-syntax> | <C2-syntax> |... <C30-syntax> syntax for a single RegexCompleter is also feasible

gnodet commented 1 week ago

@maxbechtold I'm not sure exactly why your example does not work, but here's a working one: https://github.com/jline/jline3/blob/4ccf282c91daa0fc96ed6030e053dd28a4aba342/builtins/src/test/java/org/jline/example/Example.java#L328-L335

The fact that you're using 2 regex completers seems problematic.